mysql ddl crash,MySQL5.6 crash-safe replication一个坑
題圖:《唐伯虎點秋香》
版本背景
1)操作系統(tǒng)
cat?/proc/versionLinux?version?2.6.32-696.el6.x86_64?(mockbuild@c1bm.rdu2.centos.org)?(gcc?version?4.4.7?20120313?(Red?Hat?4.4.7-18)?(GCC)?)?#1?SMP?Tue?Mar?21?19:29:05?UTC?2017
2)mysql數(shù)據(jù)庫版本
mysql?--versionmysql??Ver?14.14?Distrib?5.6.26,?for?linux-glibc2.5?(x86_64)?using??EditLine?wrapper
問題描述
在測試crash-safe 功能時發(fā)現(xiàn)了點問題,如果我指定了 relay_log_info_repository = TABLE,這時主庫執(zhí)行DDL語句后,從庫的 relay_log_info_repository 表中的 Master_log_pos 字段并不會立即被更新(這時ddl操作已經(jīng)被應(yīng)用到從庫,并且從庫show slave status\G; 查看執(zhí)行的位置是正確的),而DML語句不會有該問題(sync_relay_log_info 為默認值 10000)。
如果在主庫執(zhí)行了一個ddl,并且該ddl被從庫應(yīng)用后,緊接著(從庫執(zhí)行該ddl后)從庫異常宕機。那么從庫再啟動后可能會把之前已經(jīng)執(zhí)行過的ddl再次執(zhí)行一遍,導致復制異常 會遇到如下錯誤:
Error 'Duplicate column name 'name_1'' on query. Default database: 'test_shao'. Query: 'alter table test_4 add column name_1 varchar(20)'
問題原因
我們知道,MySQL 5.6 針對復制功能提供了新特性: slave支持crash-safe. 該功能可以解決之前版本中系統(tǒng)異常斷電可能導致的SQL thread 信息不準確的問題。##關(guān)于crash-safe 詳細介紹請參見 MySQL5.6新特性之crash-safe slaves。
實現(xiàn)從庫 crash-safe需要在從庫配置文件中添加如下兩個參數(shù),并重啟實例
relay_log_info_repository = TABLE
relay_log_recovery = ON
從庫實現(xiàn) crash-safe 的大概原理就是把 sql_thread 的執(zhí)行位置記錄到 innodb 表中(relay_log_info_repository = TABLE),并且把 sql_thread 線程執(zhí)行事務(wù)和更新 mysql.slave_relay_log_info 放在一個事物中,從而避免實際已執(zhí)行的binlog位點和寫入relay log info 的位點信息不一致的情況發(fā)生。那怎么保證 io_thread 線程位點的正確性,是通過添加 relay_log_recovery = ON 參數(shù),在從庫實例重啟時會自動把 io_thread 線程位點初始化成 sql_thread位點。
##對于dml 我們可以做到把 dml操作 和 mysql.slave_relay_log_info表的更新放到一個事務(wù)中來保證位點正確性,那么對于 ddl 操作呢?
問題處理
如果我指定了 relay_log_info_repository = TABLE,這時主庫執(zhí)行DDL語句后,從庫的 relay_log_info_repository 表中的 Master_log_pos 字段并不會立即被更新(這時ddl操作已經(jīng)被應(yīng)用到從庫,并且從庫show slave status\G; 查看執(zhí)行的位置是正確的),而DML語句不會有該問題。這時有如下幾種情況會讓從庫的 relay_log_info_repository表信息更新到最新值
1)如果此時主庫再執(zhí)行一個dml操作,我們會發(fā)現(xiàn)從庫 relay_log_info_repository 中記錄的位置被更新為最新值。
2)重啟復制線程 stop slave; start slave;
3)設(shè)置 從庫 sync_relay_log_info = 1
##官方文檔中說到 如果 relay_log_info_repository = TABLE, 對于支持事務(wù)的存儲引擎來說,會忽略 sync_relay_log_info 該參數(shù),但是實測 發(fā)現(xiàn)對于 ddl 如果 sync_relay_log_info 大于 1,則 mysql.slave_relay_log_info 表中 主庫binlog 位置不會及時刷新。設(shè)置為1 時會及時刷新。
4)如果你確定ddl語句已經(jīng)在從庫執(zhí)行,那你可以 set global sql_slave_skip_counter=1; 跳過該錯誤,修復主庫復制
##綜上所述,如果你 設(shè)置了 relay_log_info_repository = TABLE,建議同時設(shè)置 sync_relay_log_info = 1
總結(jié)
以上是生活随笔為你收集整理的mysql ddl crash,MySQL5.6 crash-safe replication一个坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java dump命令例子,常用命令示例
- 下一篇: asp mysql连接已重置,mysql