0 序
- 版本
本文圍繞 mysql 5.7.38 版本開展討論
- 情景1:
- MYSQL數據庫的主從複製架構:1主1從
- MYSQL數據庫的binlog應用情況:存在多個基於binlog同步機制的FlinkCdcJob,從MYSQL中增量同步數據
- 某一天,FlinkCdcJob報如下錯誤:
ConnectException: A slave with the same server_uuid/server_id as this slave has connected to the master; the first event '' at 4, the last event read from './mysql-bin.152542' at 1380734, the last byte read from './mysql-bin.152542' at 1380734. Error code: 1236; SQLSTATE: HY000.
【翻譯】ConnectException:與該從服務器具有相同server_uuid/server_id的從服務器已連接到主服務器;第一個事件在第 4 行,最後一個事件從'./mysql-bin '讀取。152542' at 1380734,從'./mysql-bin '讀取的最後一個字節。152542' at 1380734。錯誤碼:1236;SQLSTATE: HY000。
【特別說明】基於binlog同步機制的FlinkCdcJob應用程序,本質上也是1個MySQL Slave
- 情景2:
- 當我們搭建MySQL集羣時,自然需要完成數據庫的主從同步來保證數據一致性。
- 而主從同步的實現方式也分很多種:一主一從、一主多從、鏈式主從、多主多從。可根據你的需要來進行設置。
- 但只要你需要主從同步,就一定要注意server-id的配置,否則會出現主從複製異常。
- 在控制數據庫數據複製和日誌管理中,有2個重要的配置:
server-id
和server-uuid
它們會影響二進制日誌文件記錄和全局事務標識。
1 server-id
概述
server-id
的查看與配置
-
當你使用主從拓撲時,一定要對所有MySQL實例都分別指定一個獨特的互不相同的
server-id
。 -
默認值爲
0
,當server-id=0
時,對於主機來說依然會記錄二進制日誌,但會拒絕所有的從機連接;對於從機來說則會拒絕連接其它實例。 -
MySQL實例的
server-id
是一個全局變量,可以直接查看:
mysql> show variables like '%server_id%';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| server_id | 171562767 |
+---------------+-----------+
1 row in set (0.00 sec)
mysql> show variables like '%server%id%';
server_id 4198984507
server_id_bits 32
server_uuid c5df5b9e-3d7d-11ed-accf-fa163e42a616
server-id
的配置/修改。
我們可以在線直接修改全局變量
server-id
,但不會立即生效,所以修改後記得重啓服務。
而重啓後又會重新讀取系統配置文件配置,導致剛纔的修改失效,因此建議修改配置文件後重啓服務而不是在線修改。
# my.cnf
[mysqld]
#replication
log-bin=mysql-bin
server-id=171562767
sync_binlog=1
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
server-id
的用途與影響分析
server-id
用於標識數據庫實例,防止在鏈式主從、多主多從拓撲中導致SQL語句的無限循環:
- 標記
binlog event
的源實例- 過濾主庫
binlog
,當發現server-id
相同時,跳過該event
執行,避免無限循環執行。- 如果設置了
replicate-same-server-id=1
,則:執行所有event,但有可能導致無限循環執行SQL語句。
我們用兩個例子來說明server-id爲什麼不要重複:
- 當主庫和備庫是
server-id
重複時:
由於默認情況
replicate-same-server-id=0
,因此備庫會跳過所有主庫同步的數據,導致主從數據的不一致。
- 當兩個備庫
server-id
重複時:
會導致從庫跟主庫的連接時斷時連,產生大量異常。
根據MySQL的設計,主庫和從庫通過事件機制進行連接和同步,當新的連接到來時,如果發現server-id
相同,主庫會斷開之前的連接並重新註冊新連接。
當A庫連接上主庫時,此時B庫連接到來,會斷開A庫連接,A庫再進行重連,週而復始導致大量異常信息。
生成server-id
的規則
既然server-id
不能相同,而當我們有10個實例時,怎麼保證每個都不同呢?有幾種常用的方法:
- 隨機數
- 時間戳
- IP地址+端口
- 在管理中心集中分配,生成自增ID
上面的這些方法都可以,但是注意不要超過了最大值2^32-1
,同時值最好>2
。
推薦採用的方法是:IP地址後兩位+本機MySQL實例序號
但如果是通過docker來進行管理多實例時,這個怎麼生成大家可以想下有沒有什麼優美的解決方案。
2 server-uuid
概述
- MySQL服務會自動創建並生成server-uuid配置:
- 讀取${data_dir}/auto.cnf文件中的UUID
- 如果不存在,自動創建文件和生成新的UUID並讀取
shell> cat ~/mysql/data/auto.cnf
[auto]
server-uuid=fd5d03bc-cfde-11e9-ae59-48d539355108
- 查驗方式
mysql> show variables like '%server%id%';
server_id 4198984507
server_id_bits 32
server_uuid c5df5b9e-3d7d-11ed-accf-fa163e42a616
- 這個
auto.cnf
配置風格類似於my.cnf
,但這個文件只包含一個auto
配置塊和一行server-uuid
配置。它是自動創建的,因此不要修改它的內容。 - 在主從拓撲中,主從可以知道互相的UUID,在主機上使用
show slave hosts
,在從機上使用show slave status
查看Master_UUID
字段。 server-uuid
參數並不能取代server-id
,他們有不同的作用。當主從同步時,如果主從實例的server-uuid
相同會報錯退出,不過我們可以通過設置replicate-same-server-id=1
來避免報錯(但不推薦)。
3 補充:MYSQL主從複製場景
show variables like '%server%id%'
| 在主庫、從庫中查看
- 查詢樣例:
server_id 4198984507
server_id_bits 32
server_uuid c5df5b9e-3d7d-11ed-accf-fa163e42a616
show slave hosts
| 在主庫查看
show slave hosts
- 顯示當前配置爲複製從服務器(slave)的主機信息(包含了所有配置爲複製從服務器的主機信息)
- 通常用於快速檢查和驗證哪些服務器被配置爲複製數據,以及它們的網絡連接狀態
- 在MySQL 5.7及更高版本中使用的,而在更早的版本中,可能需要使用
SHOW SLAVE STATUS;
命令來獲取類似的信息
- 查詢樣例:
mysql> show slave hosts
Server_id | Host | Port | Master_id | ------------------------------------ |
---|---|---|---|---|
166523813 | 3306 | 1306176980 | a8bdde3e-8008-11ed-83c4-fa163e5eb848 |
沒有主從複製架構的MYSQL實例,查詢結果爲空
show slave status
| 在主庫查看
- 查詢樣例:
X 參考文獻
- mysql中的server_id到底有什麼用?詳解mysql配置中的server_id - CSDN 【推薦】
- [數據庫] MYSQL之binlog權限概述 - 博客園/千千寰宇 【推薦】
- SHOW SLAVE HOSTS命令在MySQL中用於顯示當前配置爲從節點(slave)的主機信息 - CSDN
- 雙slave的server_uuid相同問題 - CSDN 【推薦】
MySQL 5.6 用 128 位的 server_uuid 代替了原本的 32 位 server_id 的大部分功能。
原因很簡單,server_id 依賴於 my.cnf 的手工配置,有可能產生衝突 —— 而自動產生 128 位 uuid 的算法可以保證所有的 MySQL uuid 都不會衝突。
在首次啓動時 MySQL 會調用 generate_server_uuid() 自動生成一個 server_uuid,並且保存到 auto.cnf 文件 —— 這個文件目前存在的唯一目的就是保存 server_uuid。
在 MySQL 再次啓動時會讀取 auto.cnf 文件,繼續使用上次生成的 server_uuid。
使用 SHOW 命令可以查看 MySQL 實例當前使用的 server_uuid:SHOW GLOBAL VARIABLES LIKE 'server_uuid';
它是一個 MySQL 5.6 global variables
全局唯一的 server_uuid 的一個好處是:
可以解決由 server_id 配置衝突帶來的 MySQL 主備複製的異常終止
在 MySQL 5.6,Slave 向 Master 申請 binlog 時,會首先發送自己的 server_uuid,Master 用 Slave 發送的 server_uuid 代替 server_id (MySQL 5.6 之前的方式)作爲 kill_zombie_dump_threads 的參數,終止衝突或者僵死的 BINLOG_DUMP 線程。