簡(jiǎn)介
通常數(shù)據(jù)庫(kù)的主從同步可用作數(shù)據(jù)備份,也可以用來(lái)解決數(shù)據(jù)庫(kù)訪問(wèn)的熱點(diǎn)問(wèn)題。通過(guò)讀寫(xiě)分離(主庫(kù)寫(xiě)推捐,從庫(kù)讀)的方式對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)進(jìn)行分壓。
MySQL 的主從同步既可以是單向的侧啼,也可以是雙向的互為主從牛柒。一個(gè)主庫(kù)可以有多個(gè)從庫(kù),而從庫(kù)也可以通過(guò)級(jí)聯(lián)的方式作為其他從庫(kù)的主庫(kù)痊乾。
原理
MySQL 的主從同步是一個(gè)異步復(fù)制的過(guò)程皮壁。其原理如下
- Master 在執(zhí)行完SQL 語(yǔ)句后,將相關(guān)的語(yǔ)句記錄到binlog 文件中哪审。
- Slave 從Master 獲取binlog 文件蛾魄,并存于本地relay-log 文件中,然后讀取master.info 文件湿滓,從上次同步時(shí)的position 位置開(kāi)始執(zhí)行SQL 語(yǔ)句滴须。
整個(gè)過(guò)程如下,主要由Master I/O 線程叽奥、Slave I/O 線程和Slave SQL 線程參與完成扔水。
- 在Slave 上執(zhí)行start slave,開(kāi)啟主從同步朝氓。
- Slave I/O 線程通過(guò)Master 上的授權(quán)用戶連接Master魔市,并請(qǐng)求從指定的binlog 文件及位置開(kāi)始的日志內(nèi)容。
- Master 接收到請(qǐng)求后赵哲,通過(guò)Master I/O 線程讀取指定的binlog 內(nèi)容并返回給Slave I/O 線程待德。同時(shí)返回本次讀取的binlog 文件名及位置。
- Slave I/O 線程將binlog 內(nèi)容依次寫(xiě)入本地的relay-log 文件枫夺,并更新master.info 文件中的binlog 文件名和位置磅网。
- Slave SQL 線程實(shí)時(shí)檢測(cè)本地relay-log 中新增的內(nèi)容,解析成SQL 語(yǔ)句后在Slave 上順序執(zhí)行筷屡。
- 由此完成了從Master 到Slave 的基于SQL 執(zhí)行語(yǔ)句的數(shù)據(jù)同步,確保數(shù)據(jù)的一致性簸喂。
步驟
Step 1. 修改Master 上的my.cnf 文件毙死,開(kāi)啟binlog 功能。
[mysqld]
server-id=1
log-bin=/var/lib/mysql/mysql-bin.log
binlog-ignore-db=mysql
binlog-do-db=demo
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=3
- server-id 用于唯一標(biāo)識(shí)數(shù)據(jù)庫(kù)喻鳄,可用來(lái)避免互為主從同步的情況下的循環(huán)復(fù)制問(wèn)題
- log-bin 指定binlog 的文件路徑扼倘,該目錄需要有mysql 的用戶權(quán)限
- binlog-do-db 指定需要同步的數(shù)據(jù)庫(kù);binlog-ignore-db 指定不需要同步的數(shù)據(jù)庫(kù)
Step 2. 在Master 上創(chuàng)建用于復(fù)制的用戶并授權(quán)
> grant replication slave on *.* to 'repl'@'10.1.1.%' identified by 'password';
> flush privileges;
Step 3. Master 鎖表
鎖表是為了防止由于新數(shù)據(jù)的寫(xiě)入而導(dǎo)致binlog 文件名和位置發(fā)生變化。也可以通過(guò)暫停其他服務(wù)來(lái)保證沒(méi)有新數(shù)據(jù)寫(xiě)入再菊。
> flush tables with read lock;
在鎖表期間不要關(guān)閉該窗口爪喘。
Step 4. 記錄Master 的binlog 文件名和位置信息
> show master status;
Step 5. 導(dǎo)出數(shù)據(jù)庫(kù)
如果要同步的數(shù)據(jù)庫(kù)數(shù)據(jù)量比較大,可以先從Master 上導(dǎo)出該數(shù)據(jù)庫(kù)纠拔,然后在Slave 上導(dǎo)入秉剑,以此減少需要同步的數(shù)據(jù)量。
# master
> mysqldump -ureadonly -ppassword -S /var/run/mysqld/mysql.sock --databases demo | gzip > demo.sql.gz
# slave
> gzip -d demo.sql.gz
> mysql -uroot -ppassword -S /var/run/mysqld/mysql.sock < demo.sql
Step 6. Master 解鎖稠诲,恢復(fù)可寫(xiě)
> unlock tables;
Step 7. 修改Slave 上的my.cnf
[mysqld]
server-id=2
relay-log=/var/lib/mysql/mysql-relay-bin
relay-log-index=/var/lib/mysql/mysql-relay-bin.index
read-only=1
- relay-log 和relay-log-index 指定relay-log 的文件路徑和索引
- read-only 表明對(duì)于非臨時(shí)表進(jìn)行只讀控制侦鹏,replication threads 和擁有super 權(quán)限的用戶不受此控制。
- replicate-do-db 指定需要同步的數(shù)據(jù)庫(kù)
如果該slave 同時(shí)要作為其他從庫(kù)的主庫(kù)臀叙,則需要添加bin-log 配置略水,同時(shí)log_slave_updates=1。
Step 8. Slave 上開(kāi)啟同步
> change master to master_host='10.1.1.1',master_port=3306,master_user='repl',master_password='password',master_log_file='mysql-bin.000001',master_log_pos=10;
> start slave;
使用以下命令查看Slave 的同步狀態(tài)劝萤,如果出現(xiàn)Slave_IO_Running: Yes 和Slave_SQL_Running: Yes渊涝,則說(shuō)明同步正常。
> show slave status\G
可以通過(guò)以下腳本讀取該值來(lái)監(jiān)控主從同步床嫌。
> mysql -h 127.0.0.1 --port=3306 -u root -ppassword -e "show slave status\G" | grep Slave_SQL_Running | awk -F: '{print $2}'
Step 9. 關(guān)閉主從同步
在Slave 上停止主從同步
> stop slave;
重置Slave 信息
> reset slave; # 清除binlog 文件名及位置
> reset slave all; # 清除slave 的連接配置信息