一、mysql複製原理
- 從庫的I/O thread 線程會讀取master info 文件 獲取主庫的 user,password port信息然後還會獲取上次獲取主庫二進制日誌的位置 如3640 就是00003這個文件640這個位置,主庫收到從庫的請求後,會驗證用戶名密碼等的合法性,然後問主庫你有沒有比上次00003文件640這個位置更加新的二進制日誌,然後主庫就會查看自己的binglog日誌,如果發現比640這個新,如已經到達31080這個位置了,主庫就會把00003號文件的640這個位置到1080這個位置的binglog日誌截斷,通過dump(i/o)線程返回給從庫的I/O thread線程,到從庫之後,它會先存到tcp/ip緩存當中(tcp/ip cached),然後從庫會立即發送一個ack給主庫,主庫收到ack後就認爲這個過程已經完成,就可以去幹別的事情了,此時從庫會更新mast info的信息,把binglog的位置信息更新到1080,下次就從1080開始往下找,然後再把tcp/ip緩存的日誌寫入到relaylog當中,最後sql thread線程會讀取relay-log.info,獲取到上次執行binglog日誌的位置信息,比如發現上次以及執行到640這個位置了,sql就會讀取relaylog從640的位置開始執行二進制日誌,當執行完後,最後更新relay-log.info文件,記錄最後執行的位置,最後,relaylog會自動把已經執行過的二進制日誌清理掉這樣一次複製就完成了
-
複製中的線程及文件
2.1、主庫
Dump(IO) thread:在複製過程中,主庫發送二進制日誌的線程
2.2、從庫
IO thread:向主庫請求二進制日誌,並且接受二進制日誌的線程
SQL thread:執行請求過來的二進制的線程
2.3、主庫
binlog文件:主庫的二進制日誌
2.4、從庫
relaylog:中繼日誌,存儲請求過來的二進制日誌
master.info:
1、從庫連接主庫的重要參數(user,passwd,ip,port)
2、上次獲取過的主庫二進制日誌的位置
relay-log.info
存儲從庫SQL線程已經執行過的relaylog日誌位置二、mysql 主從搭建
-
主從複製前提
1、兩臺以上MySQL實例(可以是多臺物理機,也可是mysql實例)
2、主庫要開啓二進制日誌
3、主庫要提供複製相關的用戶需要用到 replication slave一個比較特殊的權限
4、從庫需要將和主庫相差的數據進行追加,一般情況下認爲備份數據庫,恢復到從庫上
5、從庫應該從恢復後的時間點開始自動從主庫獲取二進制日誌開始自動同步主庫數據,我們需要告訴從庫,從哪兒開始複製二進制日誌進行學習 - 主從複製搭建實戰
1、環境準備
兩個MySQL實例
3307:master
3308:slave
2、開啓主庫binlog,從庫開啓relay-log(默認在數據目錄下生成)
vim /data/3307/my.cnf
log-bin=/data/3307/mysql-bin
binlog_format=row
3、server-id不同
[root@db02 data]# cat /data/3307/my.cnf |grep server-id
server-id=3307
[root@db02 data]# cat /data/3308/my.cnf |grep server-id
server-id=3308
4、關閉數據庫自動域名解析(沒個節點實例都加)
skip-name-resolve
5、啓動多實例
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
6、主庫創建複製賬戶連接到主庫
mysql -S /data/3307/mysql.sock
grant replication slave on . to repl@'10.0.0.%' identified by '123';
7、從庫數據追加
(1)不需要追加的情況
主和從同時搭建的新環境,就不需要備份主庫數據,恢復到從庫了,直接從第一個binlog(mysql-bin.000001)開頭位置(120)
(2)如果主庫已經工作了很長時間了,我們一般需要備份主庫數據,恢復到從庫,然後從庫從備份的時間點起自動進行復制
mysqldump -S /data/3307/mysql.sock -A -R --triggers --master-data=2 --single-transaction >/tmp/full.sql
sed -n '22p' /tmp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=325
恢復到從庫:
mysql -S /data/3308/mysql.sock
mysql> set sql_log_bin=0;
mysql> source /tmp/full.sql
8、從庫開啓主庫
mysql -S /data/3308/mysql.sock
help change master to
CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=325;
開啓主從(開啓IO/SOL線程)
start slave
9、查看主從狀態
show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
10、主從重要狀態信息介紹
show slave status\G
Slave_IO_Running: Yes(io線程狀態)
Slave_SQL_Running: Yes(sql線程狀態)
Last_IO_Errno: 0(io線程異常狀態碼)
Last_IO_Error: (io線程異常詳細信息)
Last_SQL_Errno: 0(sql線程狀態碼)
Last_SQL_Error: (sql線程異常詳細信息)
三 、 主從複製常見異常解決思路
- IO線程故障
1、主庫連接不上
檢查user,password,port,IP,網絡,防護牆
stop slave;
reset slave all;(清空配置)
chagen master to
start slave
2、主庫二進制文件丟失或損壞
解決方案;
stop slave;
reset slave all;
從新備份恢復
change master to
start slave;
- SQL線程故障
執行relaylog日誌新新的事件
1、刪除,修改對象的操作時,沒有這個對象
2、創建對象時,對象已存在
3、主鍵衝突
從庫做寫入操作,會導致以上問題出現
處理方法跳過這個錯誤
stop slave;
set global sql_slave_skip_counter=1;
start slave;
/etc/my.cnf
slave-skip-errors=1032,1062,1007
但是,以上操作有的時候時候是有風險的,最安全的方法是從新構建新的主從
如何預防?
修改從庫爲只讀庫
set global read_only=1;
vim /etc/my.cnf
read_only=1(這個參數只能控制普通用戶)
- 主從延時過長
show slave status \G
Seconds_Behind_Master:0
默認的主從複製是異步的過程
主庫原因
1、主庫做修改操作之後,纔會記錄二進制日誌
2、主庫的壓力特別大(大事務,多事物)
3、從庫數量多,導致domp線程繁忙
從庫原因:
1、relay-log寫入慢
2、sql線程慢(主從硬件差異較大)
解決思路
主庫
1、sync_binlog=1(1表示只要主庫做了一次commit,二進制日誌就會立刻刷新到磁盤,如果等於0要根據系統binlog決定)
2、大事物拆分成小事物,多事物進行分離
3、使用多級主從,分庫分表架構
4、將binlog放在ssd或者flash上,高性能存儲
從庫
1、將relay放到ssd或者flash上
2、儘量選擇和主庫一樣的硬件配置