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許可權概述 - 部落格園/千千寰宇 【推薦】