[資料庫] 淺談mysql的serverId/serverUuid

千千寰宇發表於2024-04-23

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-idserver-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語句的無限迴圈
  1. 標記binlog event的源例項
  2. 過濾主庫binlog,當發現server-id相同時,跳過該event執行,避免無限迴圈執行
  3. 如果設定了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個例項時,怎麼保證每個都不同呢?有幾種常用的方法:

  1. 隨機數
  2. 時間戳
  3. IP地址+埠
  4. 在管理中心集中分配,生成自增ID

上面的這些方法都可以,但是注意不要超過了最大值2^32-1,同時值最好>2

推薦採用的方法是:IP地址後兩位+本機MySQL例項序號

但如果是透過docker來進行管理多例項時,這個怎麼生成大家可以想下有沒有什麼優美的解決方案。

2 server-uuid概述

  • MySQL服務會自動建立並生成server-uuid配置:
  1. 讀取${data_dir}/auto.cnf檔案中的UUID
  2. 如果不存在,自動建立檔案和生成新的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許可權概述 - 部落格園/千千寰宇 【推薦】

相關文章