複製錯誤案例分享(二)
上期《 複製錯誤案例分享(一) 》為大家分享了兩個案例,本期繼續為大家分享案例。
本期的案例中,雖然是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 主從複製錯誤1837MySql
- MySQL主從複製錯誤——列型別轉換錯誤MySql型別
- SqlServer 主從複製錯誤分析--20598SQLServer
- MySQL GTID複製錯誤修復演示MySql
- MySQL5.7半同步複製報錯案例分析MySql
- MySQL 網路導致的複製報錯案例MySql
- ogg複製程式報ORA-01438錯誤處理
- mysql多源複製跳過錯誤處理方法MySql
- 高階複製錯誤ORA-23474解決方法
- MySQL 8 複製(二)——半同步複製MySql
- MySQL 主從複製,常見的binlog錯誤及解決方法MySql
- mysql 資料表的複製案例MySql
- Sql Server對等複製中將截斷字串或二進位制資料。 (源: MSSQLServer,錯誤號: 8152)SQLServer字串
- 七、Spring Boot 錯誤處理原理 & 定製錯誤頁面Spring Boot
- MySQL主從複製Last_SQL_Errno錯誤程式碼彙總說明MySqlAST
- Azure Data Factory(二)複製資料
- 馬蹄鏈二二複製公排互助系統開發|二二複製公排案例
- 分享一個有意思的錯誤
- Webfunny知識分享:JS錯誤監控WebJS
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- SAXParseException的錯誤解決之二Exception
- 錯誤碼全域性處理(二)
- 半同步複製報錯mysql8.0.25MySql
- VM 虛擬機器linux從主機複製檔案到虛擬機器錯誤虛擬機Linux
- SAP ABAP 系統進行 client 複製時遇到的 63999 table too wide 錯誤訊息clientIDE
- MySQL複製跳過錯誤--slave_skip_errors、sql_slave_skip_counter、slave_exec_modeMySqlError
- Java引用複製、淺複製、深複製Java
- ORA-04031錯誤導致當機案例分析
- JS物件複製:深複製和淺複製JS物件
- 複製和引用複製
- win10系統複製檔案提示0x80004005錯誤程式碼如何修復Win10
- poi操作excel,複製sheet,複製行,複製單元格,複製styleExcel
- 架構設計(二):資料庫複製架構資料庫
- 淺複製與深複製
- MySQL 8 複製(三)——延遲複製與部分複製MySql
- win10 將檔案複製到ftp伺服器時發生錯誤怎麼解決Win10FTP伺服器
- 二、GO 程式設計模式:錯誤處理Go程式設計設計模式