複製錯誤案例分享(二)
上期《 複製錯誤案例分享(一) 》為大家分享了兩個案例,本期繼續為大家分享案例。
本期的案例中,雖然是5.5及以前版本的MySQL複製才會出現的問題,但是現在不少公司的老系統用的就是5.5甚至更古老的5.1或者5.0的資料庫。有時候面對這些老古董的時候,不瞭解這些舊版資料庫的特性的話,那就是自己往坑裡跳。
| 案例三:server_id引起的複製錯誤
環境資訊
-
主庫 IP:192.168.1.130 server_id:3656
-
從庫A IP:192.168.1.36 server_id:56
-
從庫B IP:192.168.1.57 server_id:56
5.5.36版本現象
初始搭建環境之後,檢視各主機狀態。搭建環境的步驟就省略。
主庫(192.168.1.130)
主庫透過show processlist語句檢視,只有一個dump執行緒,但是透過多次重新整理,可以看到連線的是不同的伺服器。可以看到每次透過show processlist語句顯示的dump執行緒的Host欄位中,IP:PORT的值是不斷在更新的,說明dump執行緒在不斷的重連,才會出現佔用不同的埠的現象。
從庫A(192.168.1.36)
透過 show slave status\G 命令檢視複製狀態,多次執行可以看到 Slave_IO_Running 欄位顯示的內容,出現YES或者Connnecting兩種狀態。可以看到I/O執行緒在不斷的進行重連。 並且透過 tail-f 命令檢視error log,可以看到I/O執行緒一直在嘗試重新連線。
可以看到在錯誤日誌中列印的資訊是,I/O執行緒連線
從庫B(192.168.1.57)
從庫B現象與從庫A一致。
5.6.36版本現象
搭建環境步驟省略。
主庫(192.168.1.130)
show processlist檢視有兩個dump執行緒,並且多次重新整理,發現Host欄位中的IP:PORT並沒有修改,說明dump執行緒一直保持連線。
從庫A(192.168.1.36)
tail-f/home/mysql/data/mysqldata5.6/log/error.log 檢視錯誤日誌,沒有不斷斷開連線
從庫B(192.168.1.57)
tail -f /home/mysql/data/mysqldata5.6/log/error.log檢視錯誤日誌,沒有不斷斷開連線
原因分析
這是彭立勳寫的關於多個slave使用相同serverid時衝突的原因的一篇文章。按照彭大大的分析,我理解的是,slave的I/O執行緒連線上主庫的時候,主庫上會呼叫 register_slave() 這個函式,在這個函式中又呼叫了unregisterslave()函式,會將之前使用相同serverid的執行緒給登出掉。從而導致從庫的I/O執行緒不斷斷開重連。
但是仔細看了一下 unregister_slave() 函式的程式碼,並沒有發現MySQL是根據serverid來登出dump執行緒的。並且進一步比較了一下5.5.36和5.6.36版本的程式碼,並沒有發現不同。而從庫設定serverid一致導致I/O執行緒不斷重連的現象只在5.5版本中看到,在5.6版本中並沒有這個現象,所以導致5.5現象的原因不是在unregisterslave()函式中。
進一步看了一下彭大大的文章,發現有人在下面評論,說主要是 kill_zombie_slave_threads() 函式導致的。於是看了一下 kill_zombie_slave_threads() 函式的邏輯,發現MySQL應該就是在這一步根據server_id將執行緒kill了。
-
5.5.36版本 首先來看下5.5.36版本的 kill_zombie_dump_threads() 函式的程式碼。看到這個函式傳入的引數是一個uint32型別的slaveserverid,在函式中做的事情是,遍歷MySQL中的所有執行緒,如果遍歷到一個執行緒是dump執行緒並且執行緒的server_id是等於傳入的引數值話,則跳出遍歷迴圈,並kill掉這個執行緒。
-
5.6.35版本 再來看一下5.6.36版本的 kill_zombie_dump_threads() 函式的程式碼實現,與5.5.36大不相同。首先傳入的引數是一THD型別的指標,在函式中實現的邏輯同樣是遍歷MySQL中的所有執行緒,如果找到dump執行緒,首先看一下這個執行緒有沒有uuid欄位(因為uuid是在5.6之後的版本才有的,這邊是為了相容5.5),如果有uuid則用uuid進行比較,如果沒有uuid,則用server_id進行比較。
-
函式呼叫 知道了 kill_zombie_dump_threads() 執行緒實現的邏輯,那MySQL是在什麼地方會呼叫這個函式的呢。看了一下函式是在 caseCOM_BINLOG_DUMP 中被呼叫的。 在5.5.36版本中是在:
在5.6.36版本中也是在 caseCOM_BINLOG_DUMP 中,只不過是將之前的邏輯封裝在了 com_binlog_dump() 函式中了, kill_zombie_dump_threads() 也是在 com_binlog_dump() 函式中呼叫的。
caseCOM_BINLOG_DUMP 中所進行的操作就是將dump執行緒通知I/O執行緒拉取新的binlog。
總結
整理下來的話,基本上可以確定主要是因為 kill_zombie_dump_threads() 函式導致在5.6之前的版本中,如果是一主多從的架構中,如果在從庫之間的serverid如果設定為一樣,會出現從開I/O執行緒不斷斷開重連的現象。因為在5.6之前的版本中,還沒有UUID的概念,MySQL使用serverid來區分是否是同一臺機器,而在5.6之後的版本是使用的UUID來區分。 總結一句,就是資料庫之間的server_id不要設定成一樣,不然可能會有一些不可預知的錯誤。
| 作者簡介
沈 剛·沃趣科技資料庫技術專家
熟悉MySQL資料庫執行機制,豐富的資料庫及複製架構故障診斷、效能調優、資料庫備份恢復及遷移經驗。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2219571/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 複製錯誤案例分享(一)
- mysql replication複製錯誤(zt)MySql
- mysql複製報錯案例處理MySql
- DG rman duplicate 複製庫錯誤
- MySQL主從複製錯誤——列型別轉換錯誤MySql型別
- MySQL 主從複製錯誤1837MySql
- MySQL GTID複製錯誤修復演示MySql
- SqlServer 主從複製錯誤分析--20598SQLServer
- MySQL 網路導致的複製報錯案例MySql
- MySQL5.7半同步複製報錯案例分析MySql
- mysql master-slave複製錯誤[解決事例]MySqlAST
- mysql多源複製跳過錯誤處理方法MySql
- Goldengate複製程式錯誤Fatal error executing DDLGoError
- MySQL 8 複製(二)——半同步複製MySql
- 高階複製錯誤ORA-23474解決方法
- 【MySQL】複製1594錯誤(從庫relaylog損壞)MySql
- rman複製 資料庫 ORA-01405 錯誤資料庫
- 主從故障處理--session 級別引數複製錯誤Session
- 解決mysql使用GTID主從複製錯誤問題MySql
- 【MySql】複製出現Slave_SQL_Running: No 錯誤解決MySql
- mysql 資料表的複製案例MySql
- ogg複製程式報ORA-01438錯誤處理
- slave_exec_mode設定自動跳過同步複製錯誤
- MySQL併發複製系列二:多執行緒複製MySql執行緒
- 主庫reset master清理binlog日誌到主從複製錯誤AST
- MySQL 主從複製,常見的binlog錯誤及解決方法MySql
- RMAN複製資料庫(二)資料庫
- 事務複製會話 (二)會話
- 一次通過stream複製解決資料單向複製的案例
- MySQL主從複製Last_SQL_Errno錯誤程式碼彙總說明MySqlAST
- Sql Server對等複製中將截斷字串或二進位制資料。 (源: MSSQLServer,錯誤號: 8152)SQLServer字串
- 複製資料庫的報錯資料庫
- 馬蹄鏈二二複製公排互助系統開發|二二複製公排案例
- Azure Data Factory(二)複製資料
- 二進位制檔案複製
- MySQL(二):主從複製結構、半同步複製、雙主複製結構、利用SSL實現安全的MySQL主從複製MySql
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- 【MySQL】複製1236錯誤(不同版本間binlog_checksum配置問題)MySql