主從復(fù)制簡介
主從復(fù)制即將一臺(tái)MySQL實(shí)例(Master)的數(shù)據(jù)復(fù)制到一個(gè)或多個(gè)MySQL實(shí)例(Slave)。默認(rèn)情況下,復(fù)制是異步的;Slave不需要持久連接來接收來自Master的更新。根據(jù)配置,可以自定義復(fù)制的對象是實(shí)例中的所有數(shù)據(jù)庫,或指定的數(shù)據(jù)庫甚至某幾張指定的表。
首先master把數(shù)據(jù)變化作為事件記錄到binlog中,然后slave通過I/O線程讀取master上的binlog,并且把它寫入到slave的中繼日志中,接著SQL線程讀取中繼日志,并且在slave本地庫上重放,從而實(shí)現(xiàn)MySQL復(fù)制。下例介紹是基于主庫binlog的name及應(yīng)用的position來配置的。
配置主庫
主庫必須啟用二進(jìn)制日志并有唯一的server ID,設(shè)置后需要重啟mysql服務(wù)生效。主從數(shù)據(jù)傳輸同步是根據(jù)binlog實(shí)現(xiàn)的,如果未啟用binlog,復(fù)制是不可能的。復(fù)制組內(nèi)每個(gè)服務(wù)器都必須有一個(gè)唯一的server ID,此ID用來標(biāo)識(shí)各個(gè)服務(wù)器,且范圍在1
-power(2,32)-1
之間的整數(shù),如不設(shè)置將如法配置復(fù)制。
[mysqld]
log-bin=mysql-bin
server-id=1
innodb_flush_log_at_trx_commit=1
sync_binlog=1
創(chuàng)建復(fù)制用戶
從庫需要帳號(hào)來連接主庫,帳號(hào)需要具有REPLICATION SLAVE權(quán)限,一般會(huì)單獨(dú)創(chuàng)建一個(gè)僅具有REPLICATION SLAVE權(quán)限的用戶用于復(fù)制。
[master]
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.141.8.174' IDENTIFIED BY 'p4word';
Query OK, 0 rows affected (0.02 sec)
獲取主庫二進(jìn)制日志執(zhí)行位置并同步數(shù)據(jù)
配置復(fù)制需要指定從庫開始執(zhí)行主庫的二進(jìn)制日志的起始執(zhí)行位置,因此當(dāng)從庫同步主庫現(xiàn)有數(shù)據(jù)時(shí),需要停止在主庫上執(zhí)行更新語句,然后獲得主庫的當(dāng)前二進(jìn)制日志坐標(biāo)并基于此位置備份數(shù)據(jù)。如果主庫繼續(xù)執(zhí)行更新操作,可能導(dǎo)致主從數(shù)據(jù)不一致。
獲取主庫二進(jìn)制日志坐標(biāo)的方式:
- 主庫執(zhí)行FLUSH TABLES WITH READ LOCK 語句:
mysql> FLUSH TABLES WITH READ LOCK;
mysql> show master status;
該語句刷新所有表及塊寫入語句,對于InnoDB表還會(huì)阻塞Commit。非正常退出該session,F(xiàn)LUSH TABLES仍會(huì)生效,如使用exit退出該會(huì)話,鎖會(huì)被釋放。
- 獲取主庫數(shù)據(jù)快照
如果新配置的主從復(fù)制可忽略本步驟,如果創(chuàng)建的主庫已存在數(shù)據(jù),需要?jiǎng)?chuàng)建一個(gè)主庫的數(shù)據(jù)快照并在從庫中恢復(fù)。獲取數(shù)據(jù)快照的方式很多,可使用備份工具如:mysqldump、xtrabackup等,也可直接拷貝主庫數(shù)據(jù)文件。
- 釋放讀鎖
備份完成后,釋放主庫鎖定
mysql> UNLOCK TABLES;
如果配置表都是InnoDB等支持事務(wù)的表,可以跳過手工設(shè)定鎖定的操作,mysqldump --single-transaction --master-data
來確保快照一致性。
配置從庫
如果有多個(gè)slave,各從庫也必須有唯一的server ID,不能省略,否則拒絕連接。
[mysqld]
server-id=2
啟動(dòng)生效后,從庫執(zhí)行CHANGE MASTER TO語句,啟動(dòng)復(fù)制,change master 語法。
mysql> change master to master_user='repl',
master_password='p4word',
master_host='10.141.8.173',
master_log_file='mysql-bin.000007',
master_log_pos=120;
Query OK, 0 rows affected, 2 warnings (0.11 sec)
導(dǎo)入主庫快照數(shù)據(jù)后,啟動(dòng)復(fù)制線程,同步主從數(shù)據(jù)
mysql> start slave; ## 啟動(dòng)復(fù)制線程
Query OK, 0 rows affected (0.06 sec)
查看主從復(fù)制狀態(tài)
mysql> show slave status \G;
當(dāng)slave_IO_Running、Slave_SQL_Running
均為Yes,則表示復(fù)制可以正常運(yùn)行。如復(fù)制不能正常進(jìn)行,狀態(tài)及錯(cuò)誤日志將會(huì)出現(xiàn)錯(cuò)誤信息,一般常見的錯(cuò)誤的原因有:操作系統(tǒng)防火墻,Selinux,主庫信息錯(cuò)誤,server_id未設(shè)置或重復(fù),server_uuid重復(fù)及主從數(shù)據(jù)問題。
驗(yàn)證同步效果
[master]
mysql> create table test.sysc (
> id int primary key,
-> name varchar(10)
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> insert into test.sysc values(1001,'1001');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test.sysc values(1002,'1002');
Query OK, 1 row affected (0.03 sec)
[slave]
mysql> use test;
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| sysc |
+----------------+
1 row in set (0.00 sec)
mysql> select * from sysc;
+------+------+
| id | name |
+------+------+
| 1001 | 1001 |
| 1002 | 1002 |
+------+------+
2 rows in set (0.00 sec)
以下幾種狀態(tài)對判斷主從復(fù)制延遲及處理主從復(fù)制故障很重要。
- Master_Log_File & Read_Master_Log_Pos:IO線程讀取的當(dāng)前主庫binlog位置信息。
- Relay_Master_Log_File & Exec_Master_Log_Pos:SQL線程當(dāng)前讀取執(zhí)行的主庫binlog位置信息。
- Relay_Log_File & Relay_Log_Pos:SQL線程當(dāng)前讀取執(zhí)行的中繼日志位置信息。
- Slave_IO_Running & Slave_SQL_Running:當(dāng)前復(fù)制狀態(tài)是否正常