技術分享 | MySQL 主從複製中創建複製用戶的時機探討

作者:趙黎明
愛可生 MySQL DBA 團隊成員,Oracle 10g OCM,MySQL 5.7 OCP,擅長數據庫性能問題診斷、事務與鎖問題的分析等,負責處理客戶 MySQL 及我司自研 DMP 平臺日常運維中的問題,對開源數據庫相關技術非常感興趣。
本文來源:原創投稿
* 愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。

背景

該問題來自某客戶,據描述,他們在部署 MySQL 主從複製時,有時候僅在主庫上創建複製用戶,有時候主從實例上都會去分別創建複製用戶,發現這兩種方式都可以成功建立複製。針對這一現象,進行了一輪驗證,來觀察採用不同方式創建複製用戶對主從複製的影響。

通常來說,用得較多的方式是在搭建主從複製前,先在主庫創建好複製用戶,然後做一個 Xtrabackup 物理全備,再拿到從庫上恢復並搭建主從。除此以外,還有哪些方式呢?分別對主從複製有哪些影響?一起來看一下。


驗證

  • MySQL 版本爲 5.7.32,主庫:10.186.60.62,從庫:10.186.60.68。

  • 爲了演示方便,本次搭建主從複製時均採用 mysqldump 進行邏輯備份。

場景 1:僅在主庫創建複製用戶

1. 主庫做一個備份並拷貝到從庫

/usr/local/mysql5732/bin/mysqldump --single-transaction --master-data=2 -B zlm -S /tmp/mysql3332.sock -p > zlm.sql
scp zlm.sql [email protected]:~

2. 登陸從庫執行導入

mysql> source zlm.sql

由於沒有使用參數 --set-gtid-purged=off,導出的語句中會帶有 SET @@GLOBAL.GTID_PURGED='xxxx:1-xx' 並執行,導入前需要先在從庫上執行 reset master。

3. 主庫創建複製用戶

mysql> create user repl1 identified by 'repl1';

4. 從庫配置主從複製並啓動

mysql> change master to master_host='10.186.60.62',master_port=3332,master_user='repl1',master_password='repl1',master_auto_position=1;
mysql> start slave;

啓動複製後,報了 Error 1045 的錯誤,此處並不是密碼錯,而是沒有給複製用戶配置 replication slave 權限,在主庫上對 repl1 用戶執行賦權後(grant replication slave on *.* to repl1;),再啓動複製就正常了。

主從複製正常以後,也會在從庫上創建複製用戶 repl1。

從庫上並沒有創建過複製用戶 repl1,主從複製就正常搭建好了,爲什麼呢?因爲 change master to 語句中指定的 master_user 是主庫上的複製用戶,從庫通過這個用戶連接到主庫進行同步,當開啓複製線程後,主庫上創建複製用戶的語句會在從庫上進行回放,於是從庫上也會有這個複製用戶了。

結論 1

  • 搭建主從複製時,在從庫創建複製用戶不是必須的,僅在主庫創建即可,複製用戶會同步到從庫。

場景 2:主從庫單獨創建複製用戶(create 語句)

1. 主庫做一個備份並拷貝到從庫(gtid_purged=xxxx:1-23)

2. 從庫執行導入

3. 主庫創建複製用戶並賦權

mysql> create user repl2 identified by 'repl2';
mysql> grant replication slave on *.* to repl2;

4. 從庫創建複製用戶

由於不想在從庫上產生由從庫 uuid 寫入的 binlog 事務,此處設置了 sql_log_bin=0,使事務不被記錄到 binlog 中,原因是在數據庫管理平臺對高可用集羣進行管理時,通常是不允許從庫上有主庫不存在的 GTID 事務的。

5. 從庫配置主從複製並啓動

mysql> change master to master_host='10.186.60.62',master_port=3332,master_user='repl2',master_password='repl2',master_auto_position=1;
mysql> start slave;

由於從庫上已經創建了複製用戶,當回放到主庫的這個事務時會報 Error 1396 的錯誤。

可以用 create user 語句創建一個重複用戶來驗證。

解析主庫 binlog,啓動複製後執行的第一個事務就是這個 24 的創建用戶語句。

結論 2

  • 在從庫導入備份後並分別在主、從庫單獨創建複製用戶後,當從庫執行到創建用戶的事務時會導致複製中斷。

場景 3:主從庫單獨創建複製用戶(grant 語句)

1. 主庫做一個備份並拷貝到從庫(gtid_purged=xxxx:1-28)

2. 從庫執行導入

3. 主庫創建複製用戶

mysql> grant replication slave on *.* repl3 identified by 'repl3';

4. 從庫創建複製用戶

5. 從庫配置主從複製並啓動

mysql> change master to master_host='10.186.60.62',master_port=3332,master_user='repl2',master_password='repl2',master_auto_position=1;
mysql> start slave;

這次啓動複製後並沒有報錯。爲何用 grant 語句創建用戶就可以,用 create 語句就不行呢?

create 與 grant 語句都會產生事務並記錄到 binlog 中,但區別是 grant 語句是一個近似冪等的操作,而 create 語句不是。

解析主庫 binlog,29 和 30 都是重複執行 grant 的事務。

觀察 show slave stauts\G,從庫上也把 29,30 這兩個事務都回放掉了,重複執行它們並不影響主從複製。

但要注意的是,在 MySQL 8.0 中已經禁止通過 grant 這種語法來創建用戶了。

結論 3

  • 從庫導入備份並在主從庫分別使用 grant 語句創建用戶後,在從庫回放時不會導致複製中斷。


總結

1. 根據以上驗證結果得知,在搭建主從複製時,採用多種方式創建複製用戶都是可行的,但有些方式存在一些限制,如:在主、從實例上分別創建複製用戶。雖然執行 grant 語句創建用戶不會導致複製中斷,但其並不是標準的 MySQL 創建用戶語法,在 MySQL 8.0 中已被視爲語法錯誤,因此不推薦採用這樣的方式來搭建主從。

2. 創建複製用戶的方式

Create 語句創建用戶時

1. 主庫創建完複製用戶後做備份,再配置主從

2. 備份後僅在主庫創建複製用戶,再配置主從(推薦)

3. 如果要在主、從庫分別創建複製用戶,應先設置 session 級別的 sql_log_bin=0,再配置主從

Grant 語句創建用戶時(MySQL 5.7 及以下版本)

1. 主庫先創建複製用戶後備份,再配置主從

2. 僅在主庫創建複製用戶,再配置主從(推薦)

3. 主、從庫分別創建複製用戶,再配置主從


文章推薦:

技術分享 | binlog 實用解析工具 my2sql

技術分享 | 如何優雅地在 Windows 上從 MySQL 5.6 升級到 5.7

技術分享 | 什麼是半一致性讀?


社區近期動態




本文關鍵字:#MySQL# #主從複製# #複製用戶#
  點一下“閱讀原文”瞭解更多資訊

本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章