91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

回饋開源,我如何排查一個MySQL Bug

發布時間:2020-08-16 22:40:03 來源:ITPUB博客 閱讀:317 作者:XDBTech 欄目:MySQL數據庫

X-Engine是阿里巴巴自研的高性能低成本存儲引擎,經過多年的努力,我們在集團內部以AliSQL(X-Engine)的形式(AliSQL是阿里的MySQL分支)支持了許多業務,為用戶帶來了顯著的成本和性能收益。

時至今日,阿里巴巴數據庫團隊已經向MySQL官方提交了許多有價值的bug及修復方案。我們繼承了這一優良傳統,在生產、測試中遇到MySQL相關的問題,總是積極地思考解決方案,并迅速與官方交流溝通,為開源社區的發展貢獻自己的力量。

下文將介紹我們剛發現的一個MySQL問題及修復方案。遇到相同情況的朋友需要注意了,也許不符合規范的數據已經寫入你們的數據庫了。

背景知識

如果MySQL參數sql_mode包含以下3項:

NO_ZERO_DATE

NO_ZERO_IN_DATE

STRICT_TRANS_TABLES

向DATE類型列,插入'0000-00-00'或者年/月/日3部分任意一部分為0,都將失敗。

回饋開源,我如何排查一個MySQL Bug

異常:‘0000-00-00’竟然插入成功了

在MySQL 8.0.16上依次執行以下語句:

set sql_mode='';

create table test (mydate DATE NOT NULL DEFAULT '0000-00-00');
set sql_mode=default;

show variables like "sql_mode";

insert into test values();

select * from test;

這里先將sql_mode設為空的目的是:建表時將mydate的default value設為'0000-00-00',否則會因default value不符合NO_ZERO_DATE而建表失敗。

建表成功后將sql_mode設回default,包含:

ONLY_FULL_GROUP_BY

NO_ZERO_DATE

NO_ZERO_IN_DATE

STRICT_TRANS_TABLES

ERROR_FOR_DIVISION_BY_ZERO

NO_ENGINE_SUBSTITUTION

然而,這時竟然成功向test庫里插入了一條'0000-00-00'的DATE。顯然,NO_ZERO_DATE的語義被打破了。

回饋開源,我如何排查一個MySQL Bug

抽絲剝繭,原來問題出在這

首先,我們定位到MySQL插入路徑,檢查default value是否合法的函數。

回饋開源,我如何排查一個MySQL Bug

這個函數比較簡單,找出用戶insert lists不包含的、且有default value的列,檢查它們的default value是否合法。write_set是一個bitmap,標識了用戶insert lists里包含哪些列。

我用gdb在該函數處加了斷點,執行上述case,竟然發現write_set里全部bit被設為了1。這顯然不正常的現象,我的插入SQL語句insert into test values();insert list明明為空,write_set全為0才合理。看來有函數錯誤地修改了它。

于是乎,我用gdb給write_set的地址加了一個watchpoint,重新執行insert語句。這次定位到了修改write_set的地方:

回饋開源,我如何排查一個MySQL Bug

該函數在檢查default value是否合法前執行,其作用是當binlog_format為ROW且binlog_row_image為FULL時,write_set會被全部設置為1。

參數binlog_format指定了binlog格式,有三個備選項:

ROW代表主備之間通過log_event同步;

STATEMENT代表主備之間通過SQL語句同步;

MIXED則是混合格式,默認用STATEMENT方式,一些特殊情況下用ROW方式。

由于主備通過STATEMENT同步(雖然它產生的binlog數量小),可能因上下文信息、環境不同等因素,導致結果不一致,因此安全起見,binlog_format默認為ROW。

參數binlog_row_image指定了ROW格式binlog要記錄哪些信息。它也有三個備選項:

FULL表示binlog記錄變更前后的所有列;

MINIMAL表示binlog只記錄唯一標識列和修改列;

NOBLOB表示BLOB是修改列或唯一標識列,才記錄,其它列與FULL相同全部記錄。

binlog_row_image默認為FULL。

當binlog_format為ROW且binlog_row_image為FULL 時,為了保證所有列都寫到binlog里,write_set竟然被全部設置為1。

write_set變量本是用來標識用戶插入列,又被賦予了控制寫binlog的重任。多重語義交織,很容易出bug。這也給我們編碼帶來啟示:每個變量應當有確切的語義。

修復建議

導致這個bug的原因是write_set用處太多。因此可以創建一個新的bitmap:binlog_write_set,專門用于控制寫binlog。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万全县| 北流市| 汉沽区| 襄城县| 赫章县| 恩施市| 莱芜市| 怀来县| 凤翔县| 苏尼特左旗| 汕头市| 尉犁县| 南靖县| 镇安县| 灯塔市| 福海县| 垣曲县| 深圳市| 湛江市| 毕节市| 新丰县| 宜州市| 黄梅县| 珠海市| 北海市| 莲花县| 临安市| 石家庄市| 平定县| 新平| 紫阳县| 平凉市| 灵武市| 固始县| 凤凰县| 太仓市| 大足县| 靖西县| 贺兰县| 新巴尔虎右旗| 高邮市|