用幾張圖實戰講解MySQL主從複製

本文分享自華爲雲社區《結合實戰,我爲MySQL主從複製總結了幾張圖!》,作者: 冰 河。

MySQL官方文檔

MySQL 主從複製官方文檔鏈接地址如下所示:

http://dev.mysql.com/doc/refman/8.0/en/replication.html

MySQL 主從複製方式

MySQL5.6 開始主從複製有兩種方式:基於日誌(binlog)、基於 GTID(全局事務標示符)。 這裏,我們主要講基於日誌(binlog)的複製。 關於GTID的主從複製,我們後面再詳細討論。

MySQL主從複製原理

MySQL主從複製原理,也稱爲A/B原理。

(1) Master 將數據改變記錄到二進制日誌(binary log)中,也就是配置文件 log-bin 指定的文件, 這些記錄叫做二進制日誌事件(binary log events);

(2) Slave 通過 I/O 線程讀取 Master 中的 binary log events 並寫入到它的中繼日誌(relay log);

(3) Slave 重做中繼日誌中的事件,把中繼日誌中的事件信息一條一條的在本地執行一次,完 成數據在本地的存儲,從而實現將改變反映到它自己的數據(數據重放)。

001.png

主從配置注意事項

(1)主從服務器操作系統版本和位數一致;

(2) Master 和 Slave 數據庫的版本要一致;

(3) Master 和 Slave 數據庫中的數據要一致;

(4) Master 開啓二進制日誌,Master 和 Slave 的 server_id 在局域網內必須唯一;

主從配置的簡要步驟

1、Master 上的配置

(1) 安裝數據庫;

(2) 修改數據庫配置文件,指明 server_id,開啓二進制日誌(log-bin);

(3) 啓動數據庫,查看當前是哪個日誌,position 號是多少;

(4) 登錄數據庫,授權數據複製用戶(IP 地址爲從機 IP 地址,如果是雙向主從,這裏的 還需要授權本機的 IP 地址,此時自己的 IP 地址就是從 IP 地址);

(5) 備份數據庫(記得加鎖和解鎖);

(6) 傳送備份數據到 Slave 上;

(7) 啓動數據庫;

以下步驟,爲單向主從搭建成功,想搭建雙向主從需要的步驟:

(1) 登錄數據庫,指定 Master 的地址、用戶、密碼等信息(此步僅雙向主從時需要);

(2) 開啓同步,查看狀態;

2、Slave 上的配置

(1) 安裝數據庫;

(2) 修改數據庫配置文件,指明 server_id(如果是搭建雙向主從的話,也要開啓二進制 日誌 log-bin);

(3) 啓動數據庫,還原備份;

(4) 查看當前是哪個日誌,position 號是多少(單向主從此步不需要,雙向主從需要);

(5) 指定 Master 的地址、用戶、密碼等信息;

(6) 開啓同步,查看狀態。

單向主從環境搭建

安裝數據庫

參考《MySQL之——源碼編譯MySQL8.x+升級gcc+升級cmake(親測完整版)》。

配置Master的my.cnf

[root@liuyazhuang131 ~]# vi /etc/my.cnf
# 在 [mysqld] 中增加以下配置項 
# 設置 server_id,一般設置爲 IP 
server_id=131
# 複製過濾:需要備份的數據庫,輸出 binlog
#binlog-do-db=liuyazhuang
# 複製過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步) 
binlog-ignore-db=mysql 
# 開啓二進制日誌功能,可以隨便取,最好有含義 
log-bin=lyz-mysql-bin 
## 爲每個 session 分配的內存,在事務過程中用來存儲二進制日誌的緩存 
binlog_cache_size=1M 
## 主從複製的格式(mixed,statement,row,默認格式是 statement)
binlog_format=mixed
# 二進制日誌自動刪除/過期的天數。默認值爲 0,表示不自動刪除。 
expire_logs_days=7
# 跳過主從複製中遇到的所有錯誤或指定類型的錯誤,避免 slave 端複製中斷。
# 如:1062 錯誤是指一些主鍵重複,1032 錯誤是因爲主從數據庫數據不一致
slave_skip_errors=1062

複製過濾可以讓你只複製服務器中的一部分數據,有兩種複製過濾:

(1) 在 Master 上過濾二進制日誌中的事件;

(2) 在 Slave 上過濾中繼日誌中的事件。如下:

002.png

MySQL 對於二進制日誌 (binlog)的複製類型

(1) 基於語句的複製:在 Master 上執行的 SQL 語句,在 Slave 上執行同樣的語句。MySQL 默 認採用基於語句的複製,效率比較高。一旦發現沒法精確複製時,會自動選着基於行的複製。

(2) 基於行的複製:把改變的內容複製到 Slave,而不是把命令在 Slave 上執行一遍。從MySQL5.0 開始支持。

(3) 混合類型的複製:默認採用基於語句的複製,一旦發現基於語句的無法精確的複製時,就會採用基於行的複製。

重啓Master庫

啓動/重啓 Master 數據庫服務,登錄數據庫,創建數據同步用戶,並授予相應的權限

[root@liuyazhuang131 ~]# service mysql restart
[root@liuyazhuang131 ~]# mysql -uroot -proot
##創建數據同步用戶,並授予相應的權限 
mysql> grant replication slave, replication client on *.* to 'repl'@'192.168.209.132' identified by '123456'; 
Query OK, 0 rows affected (0.00 sec) ## 刷新授權表信息 
mysql> flush privileges; 
Query OK, 0 rows affected (0.00 sec) 
## 查看 position 號,記下 position 號(從機上需要用到這個 position 號和現在的日誌文件) 
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| lyz-mysql-bin.000001 |     1312 |              | mysql            |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

模擬業務數據庫

創建 lyz 庫、表,並寫入一定量的數據,用於模擬現有的業務系統數據庫

create database if not exists lyz default charset utf8 collate utf8_general_ci;
use lyz; 
DROP TABLE IF EXISTS `lyz_user`; CREATE TABLE `lyz_user` ( 
`Id` int(11) NOT NULL AUTO_INCREMENT, 
`userName` varchar(255) NOT NULL DEFAULT '' COMMENT '用戶名', `pwd` varchar(255) NOT NULL DEFAULT '' COMMENT '密碼',
 PRIMARY KEY (`Id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用戶信息表'; 
INSERT INTO `lyz_user` VALUES (1,'yixiaoqun','123456');

實現初始數據一致

爲保證 Master 和 Slave 的數據一致,我們採用主備份,從還原來實現初始數據一致

## 先臨時鎖表
mysql> flush tables with read lock; Query OK, 0 rows affected (0.00 sec) 
## 這裏我們實行全庫備份,在實際中,我們可能只同步某一個庫,那也可以只備份一個庫
[root@liuyazhuang131 mysql]# mysqldump -u root -proot lyz > /tmp/lyz.sql 
[root@liuyazhuang131 mysql]# cd /tmp
[root@liuyazhuang131 tmp]# ll | grep lyz.sql
-rw-r--r--  1 root  root     2031 Apr 25 01:18 lyz.sql
# 注意:實際生產環境中大數據量(超 2G 數據)的備份,建議不要使用 mysqldump 進行 比分,因爲會非常慢。此時推薦使用 XtraBackup 進行備份。
# 解鎖表
mysql> unlock tables; 
Query OK, 0 rows affected (0.00 sec)

將 Master 上備份的數據遠程傳送到 Slave 上,以用於 Slave 配置時恢復數據

[root@liuyazhuang131 tmp]# scp /tmp/lyz.sql [email protected]:/tmp/lyz.sql
The authenticity of host '192.168.209.132 (192.168.209.132)' can't be established.
RSA key fingerprint is da:70:7b:d5:0c:16:b3:1a:53:b7:3d:9f:20:01:26:3e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.209.132' (RSA) to the list of known hosts.
[email protected]'s password: 
lyz.sql

配置Slave庫

接下來處理 Slave(192.168.209.132),配置文件只需修改一項,其餘配置用命令來操作

[root@liuyazhuang132 ]# vi /etc/my.cnf
# 在 [mysqld] 中增加以下配置項 
# 設置 server_id,一般設置爲 IP 
server_id=132
# 複製過濾:需要備份的數據庫,輸出 binlog #binlog-do-db=lyz
# 複製過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步)
 binlog-ignore-db=mysql 
# 開啓二進制日誌,以備 Slave 作爲其它 Slave 的 Master 時使用 
log-bin=lyz-mysql-slave1-bin 
## 爲每個 session 分配的內存,在事務過程中用來存儲二進制日誌的緩存 binlog_cache_size = 1M 
# 主從複製的格式(mixed,statement,row,默認格式是 statement) 
binlog_format=mixed 
# 二進制日誌自動刪除/過期的天數。默認值爲 0,表示不自動刪除。 
expire_logs_days=7 
# 跳過主從複製中遇到的所有錯誤或指定類型的錯誤,避免 slave 端複製中斷。 
# 如:1062 錯誤是指一些主鍵重複,1032 錯誤是因爲主從數據庫數據不一致 
slave_skip_errors=1062 
## relay_log 配置中繼日誌 
relay_log=lyz-mysql-relay-bin 
## log_slave_updates 表示 slave 將複製事件寫進自己的二進制日誌 
log_slave_updates=1
##防止改變數據(除了特殊的線程)
read_only=1

如果Slave爲其它的Slave的Master時,必須設置bin_log,在這裏,我開啓了二進制日誌,而且顯式的命名(默認名稱爲hostname),但是如果hostname改變則會出現問題。

relay_log配置中繼日誌,log_slave_updates表示slave將複製事件 寫進自己的二進制日誌.當設置log_slave_updates時,你可以讓slave扮演其它slave的master.此時,slave把sql線程執行的事件寫進自己的二進制日誌(binary log)然後,它的slave可以獲取這些事件並執行它。如下圖所示(發送複製事件到其它的Slave):

003.png

還原備份數據

保存後重啓MySQL服務,還原備份數據

[root@liuyazhuang132 ~]# service mysql restart
Shutting down MySQL. SUCCESS! 
Starting MySQL.. SUCCESS!

Slave上創建相同庫

[root@liuyazhuang132 ~]# mysql -uroot -proot
mysql> use lyz;
 Database changed

導入數據

[root@liuyazhuang132 ~]# mysql -uroot -proot lyz < /tmp/lyz.sql 
[root@liuyazhuang132 ~]# mysql -uroot -proot
mysql> use lyz;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from lyz_user;
+----+-----------+--------+
| Id | userName  | pwd    |
+----+-----------+--------+
|  1 | yixiaoqun | 123456 |
+----+-----------+--------+
1 row in set (0.00 sec)

Slave庫添加參數

登錄Slave數據庫,添加相關參數:Master的IP、端口、同步用戶、密碼、position號、讀取哪個日誌文件

change master to master_host='192.168.209.131',master_user='repl',master_password='123456',master_port=3306,
master_log_file='lyz-mysql-bin.000001',master_log_pos=1312,master_connect_retry=30;

上面執行的命令的解釋:

  • master_host=‘192.168.209.131’ ##Master的IP地址
  • master_user=‘repl’ ##用於同步數據的用戶(在Master中授權的用戶)
  • master_password=‘123456’ ##同步數據用戶的密碼
  • master_port=3306 ##master數據庫服務的端口
  • master_log_file=‘lyz-mysql-bin.000001’ ##指定Slave從哪個日誌文件開始讀取複製文件(可在Master上使用show master status查看到日誌文件名)
  • master_log_pos=429 ##從哪個POSITION號開始讀
  • master_connect_retry=30 #當重新建立主從連接時,如果連接建立失敗,間隔多久後重試,單位爲秒,默認設置爲60秒,同步延遲調優參數。

查看主從同步狀態

show slave status\G;

可看到Slave_IO_State爲空,Slave_IO_Runngin和Slave_SQL_Running是No,表時Slave還是沒有開始複製過程。

開啓主從同步

mysql> start slave;

再次查看同步狀態

#show slave status\G;

主要看以下兩個參數,這兩個參數如果是Yes,就表示數據同步正常

Slave_IO_Running:Yes
Slave_SQL_Running:Yes

可查看master和slave上線程的狀態,在master上,可以看到slave的I/O線程創建的連接

Master:mysql>show processlist\G;

1.row爲處理slave的I/O線程的連接。

2.row爲處理MySQL客戶連接線程。

3.row爲處理本地命令行的線程

Slave:mysql>show processlist\G;

1.row爲處理slave的I/O線程的連接。

2.row爲處理MySQL客戶連接線程。

3.row爲處理本地命令行的線程

主從數據複製同步測試

Master:
mysql> insert into lyz_user values(2,'test1','123456');
Slave:
mysql> start slave;

經過以上配置,在192.168.209.131上對數據庫/表進行增刪改查,創建/刪除數據庫/表都會同步到192.168.209.132數據庫上了。

至此,整個配置過程結束。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

 

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