背景
binlog_row_image這個參數是MySQL5.6新增的參數,默認值是FULL,在5.7版本默認值也是FULL,但今天我看到有客戶的 MySQL5.7版本參數模板採用的是MINIMAL而不是FULL,我對這個修改表示疑惑。sql
通常來講,對一個參數默認值做出修改,咱們都應該考慮清楚影響範圍,因此我準備作一次測試,並得出結論哪一個參數值纔是最佳設置。數據庫
術語解釋安全
前提:
binlog格式必須爲row格式或者mixed格式,不能夠是statement格式。ide
名稱解釋:
before image:前鏡像,即數據庫表中修改前的內容。
after image:後鏡像,即數據庫表中修改後的內容。工具
binlog_row_image三種設置及異同
binlog_row_image參數能夠設置三個合法值: FULL、MINIMAL、NOBLOB
三個不一樣值的做用以下:測試
FULL: Log all columns in both the before image and the after image.
binlog日誌記錄全部前鏡像和後鏡像。ui
MINIMAL: Log only those columns in the before image that are required to identify the row to be changed; log only those columns in the after image where a value was specified by the SQL statement, or generated by auto-increment.
binlog日誌的前鏡像只記錄惟一識別列(惟一索引列、主鍵列),後鏡像只記錄修改列。spa
noblob: Log all columns (same as full), except for BLOB and TEXT columns that are not required to identify rows, or that have not changed.日誌
binlog記錄全部的列,就像full格式同樣。但對於BLOB或TEXT格式的列,若是他不是惟一識別列(惟一索引列、主鍵列),或者沒有修改,那就不記錄。索引
For the before image, it is necessary only that the minimum set of columns required to uniquely identify rows is logged. If the table containing the row has a primary key, then only the primary key column or columns are written to the binary log. Otherwise, if the table has a unique key all of whose columns are NOT NULL, then only the columns in the unique key need be logged. (If the table has neither a primary key nor a unique key without any NULL columns, then all columns must be used in the before image, and logged.) In the after image, it is necessary to log only the columns which have actually changed.
官方提到:若是沒有惟一識別列(惟一索引列、主鍵列),例如只有普通key,那麼MINIMAL格式的前鏡像也會記錄全部全部列,但後鏡像依然只記錄修改列。
分析
1.這個參數若是設置成MINIMAL格式,能夠節省很多磁盤空間,節省必定的io。但因爲前鏡像不記錄修改列,只在後鏡像記錄修改列,若是數據出現誤操做,必然不能經過flashback或binlog2SQL等快速閃回工具恢復數據,由於不能經過BinLog生成反向SQL了。
節省磁盤空間: 高
數據安全性: 低
2.這個參數若是設置成NOBLOB格式,在表中TEXT和BLOB等大字段若是不修改,就不記錄先後鏡像了,其餘小字段的列的修改依然記錄先後鏡像,通常大字段消耗的磁盤空間是很是大的,能夠節省很多磁盤空間。而若是表沒有大字段,NOBLOB和FULL格式並無區別,若是數據出現誤操做,能夠經過flashback或BinLog2SQL等快速閃回工具恢復數據。
節省磁盤空間: 中
數據安全性: 中
3.這個參數若是設置成FULL格式,這是MySQL5.6和MySQL5.7的默認設置,binlog記錄全部數據的先後鏡像,若是數據出現誤操做,能夠能經過flashback或binlog2sql等快速閃回工具恢復數據。在數據列比較大的狀況下,在大量的update、delete操做時,binlog盤增加會很快,比較容易出現「binlog盤快滿」的監控告警。
節省磁盤空間: 低
數據安全性: 高
測試過程以下:
1 測試binlog_row_image=MINIMAL
1.1 測試沒有主鍵沒有惟一索引
看是否前鏡像全保留
日誌以下:
binlog_row_image=MINIMAL,沒有主鍵沒有惟一索引,確實前鏡像全保留,後鏡像只有修改列
1.2 測試有主鍵
看是否前鏡像只有主鍵列,後鏡像只有修改列
日誌以下:
確實前鏡像只有主鍵列,後鏡像只有修改列。就這個緣由,致使不能閃回數據,安全性考慮不該該使用binlog_row_image=MINIMAL。
2 測試 binlog_row_image=noblob
2.1 測試沒有主鍵沒有惟一索引
因爲沒有主鍵沒有惟一索引,因此前鏡像是全保留,由於TEXT/blob是修改列,因此後鏡像的TEXT/blob列也被保留了。總體和FULL格式一致。
日誌以下:
2.2 測試有主鍵
有主鍵,修改列依然是TEXT/blob列,因爲有主鍵了,因此前鏡像不會強迫包含全部列,但前鏡像的的TEXT列被忽略、不包含,後鏡像的TEXT列因爲是修改列,因此包含。
日誌以下:
實驗證實binlog_row_image=noblob這個格式,依然存在缺失前鏡像的問題,致使某些場景沒法閃回,因此也不推薦設置。
2.3 測試有主鍵,修改列也不是TEXT列
日誌以下:
前鏡像和後鏡像包含除TEXT/BLOB列以外的全部列
結論大多數客戶生產的安全性大於一切,在硬盤白菜價的今天,不提倡設置binlog_row_image=MINIMAL參數,應該繼續使用默認值binlog_row_image=FULL格式。