MySQL-主從復制:基於二進制文件復制詳解
前言
主從復制是指把一個MySQL的數據庫服務器作為主服務器(master),然后把master的數據復制到一個或者多個MySQL數據庫服務器作為從服務器(slave)。從master到slave的復制一般是異步復制,所以從服務器的復制可以隨時停止,也不會影響到主服務器的使用。可以通過配置來決定只復制哪些數據庫或者哪些表的數據。
主從復制的優點
- 讀寫分離提高負載:master服務器不在負載讀操作,只處理寫入和更新操作,可顯著提升主服務器的寫操作的性能。而讀操作是通過多個slave服務器來讀取數據,多個slave服務器可以分散讀操作的壓力,減少對單機I/O和帶寬的依賴,也可以提升讀操作的性能。
- 數據安全:因為數據是異步復制過來的,可以在slave服務器上進行測試,或者進行數據分析。即不會更改master服務器的數據,也不會影響master服務器的性能
- 遠程數據分發:當你需要在本地使用數據時,可以通過復制功能把數據復制到本地,這樣就不需要訪問遠程master服務器
基於二進制文件(binary log)復制
原理介紹
1、master服務器把對源數據庫的寫入和更新操作以事件的方式記錄到二進制日志文件(binary log)中。不同的操作方式會以不同的日志格式記錄到文件中
2、slave服務器開啟一個I/O線程連接master服務器去請求binary log,然后寫入到本地的中繼文件(relay log)中
3、master的開啟一個log dump線程讀取binary log並傳送給slave的I/O線程
4、slave開啟一個SQL線程讀取relay log中的命令,在slave服務器上執行
環境准備
操作系統 | 數據庫 | ip地址 | 端口 | 主/從 |
---|---|---|---|---|
window server 2008 r2 | mysql 8.0.12 | 192.168.1.98 | 3006 | 主 |
window server 2008 r2 | mysql 8.0.12 | 192.168.1.97 | 3006 | 從 |
window server 2008 r2 | mysql 8.0.12 | 192.168.1.96 | 3006 | 從 |
1.Master配置
1.需要設置一個唯一的 server-id ,並且設置二進制日志文件 log-bin=[file_name]。
MySQL8.0之前的版本默認log_bin=OFF是關閉日志記錄的,設置了log-bin,就會開啟記錄日志log_bin=ON
編輯master的配置文件my.ini,在[mysqld]下添加如下內容
[mysqld]
server-id=1 #服務器id
log-bin=mysql-bin #二進制日志文件的基名字
#設置需要寫日志的數據庫的名稱,不設置默認所有數據庫。一個配置項只能配置一個數據庫,如果要設置寫多個數據庫,那么需要寫多份配置項,用逗號來分割多個數據庫是無效。
binlog-do-db=test
#binlog-do-db=test1
#binlog-do-db=test2
#設置不需要寫日志的數據庫的名稱,一個配置項只能配置一個數據庫,如果要設置寫多個數據庫,那么需要寫多份配置項,用逗號來分割多個數據庫是無效。
binlog-ignore-db=mysql
#日志記錄格式,默認是ROW行模式。還有STATEMENT語句模式和MIXED混合模式。不同的記錄格式會對binlog-do-db和binlog-ignore-db產生影響
#STATEMENT模式:記錄執行的SQL語句
#Row模式:記錄語句執行后對單個行做的修改,而不是記錄執行的語句
binlog-format=ROW
2、在InnoDB存儲引擎時,為了獲得最大持久性和一致性,需要增加下面兩個配置
#控制寫入二進制日志的頻率。
#0表示mysql服務器依賴與操作系統來把二進制文件寫入到磁盤中,這種情況下性能最好。但是在斷電或者操作系統崩潰時,服務器可能提交了未同步到二進制文件的事務。
#1表示在提交事務前先把二進制文件寫入到磁盤中,可能會對性能有印象
sync_binlog=1
#控制事物提交時ACID的遵守的嚴格性和性能之間的平衡。默認1時,表示每次事務提交時記錄日志的同時馬上寫入磁盤
innodb_flush_log_at_trx_commit=1
3、在master上給slave創建一個擁有復制權限的賬號repl,密碼是123456
CREATE USER 'repl'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
2.Slave配置
1、需要給slave設置一個唯一的 server-id ,值不要和master和其他slave重復。如果需要只復制特定的數據庫或者排除特定的數據庫,可以使用 replicate-do-db 和 replicate-ignore-db 配置。
當啟用slave的log-bin日志記錄,配合log-slave-updates=ON時,slave會在復制master的數據時也記錄到自己的二進制日志中。這樣方便以后的主從切換,數據恢復。甚至可以實現更復雜的多級復制拓撲,比如:master->slave->slave
編輯slave的配置文件my.ini,在[mysqld]下添加如下內容
[mysqld]
server-id=2 #服務器id
log-bin=mysql-bin #二進制日志文件的基名字
#當開啟了log-bin時,並且log-slave-updates=ON時slave復制master的數據時也記錄到自己的二進制日志中,默認值ON
log-slave-updates=ON
#中繼日志的基名稱
relay-log=mysql-relay
#設置需要復制的數據庫的名稱,不設置默認所有數據庫。一個配置項只能配置一個數據庫,如果要設置寫多個數據庫,那么需要寫多份配置項,用逗號來分割多個數據庫是無效,效果同binlog-do-db。
replicate-do-db=test
#設置不需要復制的數據庫的名稱,一個配置項只能配置一個數據庫,如果要設置寫多個數據庫,那么需要寫多份配置項,用逗號來分割多個數據庫是無效,效果同binlog-ignore-db。
replicate-ignore-db=mysql
#告訴slave服務器在啟動時不開啟復制功能,默認值OFF
skip-slave-start=OFF
其他slave服務器配置一樣,只有server-id不同
slave的配置參考
3.配置和開啟復制功能
1、查詢master當前的狀態
因為是InnoDB,首先在master上執行FLUSH TABLES WITH READ LOCK;
語句,關閉所有打開的表,刷新緩存。並且用全局讀鎖鎖住所有的表。
然后在master上執行下面sql獲取binary log的文件名稱和當前寫入的坐標
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 115 | test | mysql |
+------------------+----------+--------------+------------------+
2、復制master庫的數據到slave庫 如果在slave開啟復制之前,master的test庫已經有數據了,那么需要先把master的數據快照dump下來,然后復制到slave服務器。如果是新庫沒有數據要復制,可以跳過此步驟到下一步。 使用mysqldump工具命令如下:
mysqldump -h[IP地址] -P[端口號] -u[用戶名] -p[密碼] --databases test > dump.sql
mysqldump -h192.168.1.98 -P3006 -uroot -p123456 --databases test > dump.sql
3、釋放master上的全局讀鎖
UNLOCK TABLES;
4、導入master的test庫數據到slave服務器,導入第2步中dump.sql文件。如果是新庫沒有數據導入,則跳過此步驟,進行到第5步。
mysql -h[IP地址] -P[端口號] -u[用戶名] -p[密碼] < dump.sql
mysql -h192.168.1.96 -P3006 -uroot -p123456 < dump.sql
5、在slave服務器上配置slave要復制的文件和開始的坐標
CHANGE MASTER TO
MASTER_HOST='192.168.1.98',
MASTER_PORT=3006,
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=115;
MASTER_LOG_FILE=3.配置復制功能第1步查詢出來的File
MASTER_LOG_POS=3.配置復制功能第1步查詢出來的Position
CHANGE MASTER TO參考
6.開啟復制功能
在slave服務器上執行START SLAVE語句,開啟slave的復制功能。
START SLAVE;
7.查看從庫的復制狀態信息
SHOW SLAVE STATUS
Slave_IO_Running和Slave_SQL_Running都=Yes,就表明復制功能正常運行
Slave_IO_Running:從master讀取二進制文件,寫入到slave的中繼日志的I/O線程。yes表示正常
Slave_SQL_Running:從中繼日志中讀取新的命令執行到slave的庫中的SQL線程。yes表示正常
Master_Log_File:表示I/O線程當前正在讀取的master的二進制文件名稱
Read_Master_Log_Pos:表示I/O線程當前正在讀取的master的二進制文件中的位置信息
Relay_Log_File:當前在執行的中繼日志名稱
Relay_Log_Pos:當前在執行的中繼日志中執行到的位置
Last_Errno:最后一次復制失敗的錯誤日志號
Last_Error:最后一次復制失敗的錯誤日志
當slave服務器停止了復制功能,要重新開始時,要從停止前讀取的位置開始繼續復制命令。第5步中MASTER_LOG_FILE=Master_Log_File的值,MASTER_LOG_POS=Read_Master_Log_Pos的值
如果只是Slave_SQL_Running線程執行錯誤,而Slave_IO_Running讀取master的線程是yes,想要重新開始只需要先 stop slave ,再 start slave 即可。不用重新設置要復制的master的文件和坐標
這樣就配置好了一個master->slave的主從復制,多個從庫的配置可以重復【3.配置和開啟復制功能的4-7步】即可。
后記
如果想配置成復雜的多級復制拓撲,比如A->B->C
,那么先配置A作為master,B作為slave,B復制A的數據。然后在配置B作為master,C作為slave,C復制B的數據。