主從複製介紹
- 主從複製基於binlog來實現的
- 主庫發生新的操作,都會記錄到binlog
- 從庫取得主庫的binlog進行“回放”
- 主從複製的過程是異步的
搭建主從複製的前提
- 2個或以上的數據庫實例
- 主庫需要開啓二進制日誌
- server_id要不同,區分不同的節點
- 主庫需要建立專用的複製用戶 (replication slave)
- 從庫應該通過備份主庫,恢復的方法進行"補課"
- 人爲告訴從庫一些複製信息(CHANGE MASTER TO)
- 從庫應該開啓專門的複製線程
主從複製工作過程
- 從庫執行change master to 命令(主庫的連接信息+複製的起點)
- 從庫會將以上信息,記錄到master.info文件
- 從庫執行 start slave 命令,立即開啓IO線程和SQL線程
- 從庫 IO線程,讀取master.info文件中的信息
- 從庫IO線程請求連接主庫,主庫專門提供一個DUMP線程,負責和IO線程交互
- IO線程根據binlog的位置信息(mysql-bin.000004 , 444),請求主庫新的binlog
- 主庫通過DUMP線程將最新的binlog,通過網絡TP給從庫的IO線程
- IO線程接收到新的binlog日誌,存儲到TCP/IP緩存,立即返回ACK給主庫,並更新master.info
- IO線程將TCP/IP緩存中數據,轉儲到磁盤relaylog中.
- SQL線程讀取relay.info中的信息,獲取到上次已經應用過的relaylog的位置信息
- SQL線程會按照上次的位置點回放最新的relaylog,再次更新relay.info信息
- 從庫會自動purge應用過的relay進行定期清理
一旦主從複製構建成功,主庫當中發生了新的變化,都會通過dump線程發送信號給IO線程,增強了主從複製的實時性.
主從複製的作用
- 備份。主庫down了自動切換到從庫
- 在數據庫層面上實現讀寫分離
主從複製搭建
構建MySQL多實例
-
準備多個數據目錄
[root@localhost ~]# mkdir -p /data/3307/data
-
準備配置文件
cat > /data/3307/my.cnf <<EOF [mysqld] basedir=/app/mysql datadir=/data/3307/data socket=/data/3307/mysql.sock log_error=/data/3307/mysql.log port=3307 server_id=7 log_bin=/data/3307/mysql-bin binlog_format=row ----------啓用GTID模式構建主從 gtid-mode=on --啓用gtid類型,否則就是普通的複製架構 enforce-gtid-consistency=true --強制GTID的一致性 log-slave-updates=1 --slave更新是否記入日誌 sync_binlog=1 --每次事務提交都立即刷寫binlog到磁盤 最高安全模式 innodb_flush_log_at_trx_commit=1(0:一秒會發生n多事務,斷電可能會丟失1秒內的所有事務;2(分兩步提交事務,一步只保證刷寫到os buffer。)) Innodb_flush_method=O_DIRECT 最高性能: innodb_flush_log_at_trx_commit=0 innodb_flush_method=fsync EOF
-
初始化數據庫
mv /etc/my.cnf /etc/my.cnf.bak mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/application/mysql
-
設置以systemd的方式啓動數據庫(Centos6省略)
cd /etc/systemd/system cp mysqld.service mysqld3307.service vim mysqld3307.service # 修改爲: ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
-
授權數據目錄
chown -R mysql.mysql /data/*
-
啓動數據庫
systemctl start mysqld3307.service //Centos6啓動方式 mysqld_safe --defaults-file=/data/3307/my.cnf & //Centos6關閉方式 mysqladmin -S /data/3307/mysql.sock shutdown //Centos6設置多實例密碼 mysqladmin -uroot -S /data/3307/mysql.sock password '2'
-
驗證多實例
netstat -lnp|grep 330
-
開啓binlog
log_bin=/data/3307/mysql-bin
-
在主庫創建複製用戶
mysql -uroot -p1 -e "grant replication slave on *.* to repl@'192.168.63.%' identified by '123'"
-
要求數據完全一致則先備份主庫的數據導入從庫
mysqldump -uroot -p2 -p 3306 -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql
-
在從庫導入數據
mysql> source /tmp/full.sql
-
告訴從庫信息
CHANGE MASTER TO MASTER_HOST='192.168.63.128', //主庫IP地址 MASTER_USER='repl', 主庫授權給從庫的用戶名及密碼 MASTER_PASSWORD='123', MASTER_PORT=3306, 主庫端口 #MASTER_LOG_FILE='mysql-bin.000006', vim /tmp/full.sql查看主庫的binlog及pos #MASTER_LOG_POS=1210, 主庫pos MASTER_AUTO_POSITION=1;開啓了GTID模式則不需加以上兩行 #MASTER_AUTO_POSITION=?;如果是導如通過xtrabackup備份的數據應該查看binlog填寫 MASTER_CONNECT_RETRY=10; 重連次數
-
從庫開啓複製線程(IO,SQL)
mysql> start slave;
-
檢查主從複製狀態、排錯
mysql> show slave status \G
主從複製故障
- IO線程故障(connecting)
可能原因:
(1)網絡、防火牆、連接數上限
解決:
stop slave;
reset slave all;
change master to
start slave
(2)請求binlog遇到的問題,比如binlog沒開啓或者損壞
解決:
主庫:reset master
從庫:stop slave;
reset slave all;
change master to
start slave
- SQL線程故障
可能原因:
relay-log損壞
合理解決方法:
把握一個原則,一切以主庫爲準進行解決.
如果出現問題,儘量進行反操作
最直接穩妥辦法,重新構建主從
暴力的解決方法
方法一:
stop slave;
set global sql_slave_skip_counter = 1;
start slave;
#將同步指針向下移動一個,如果多次不同步,可以重複操作。
start slave;
方法二:
/etc/my.cnf
slave-skip-errors = 1032,1062,1007
常見的錯誤代碼:
1007:對象已存在
1032:無法執行DML
1062:主鍵衝突,或約束衝突
爲了很大程度避免SQL線程故障,我們一般配置主從讀寫分離:
從庫只讀:
read_only
super_read_only
使用讀寫分離中間件,比如mycat、atlas、proxySQL、Maxscale
主從延時監控主要原因
(1) binlog寫入不及時
sync_binlog=1
(2) 默認情況下dump_t 是串行傳輸binlog *****
在併發事務量大時或者大事務,由於dump_t 是串行工作的,導致傳送日誌較慢,如何解決問題?
必須啓用GTID,使用Group commit方式.可以支持DUMP_T並行
(3) 主庫極其繁忙
慢語句
鎖等待
從庫個數
網絡延時
從庫方面可能原因:
(1) 傳統複製(Classic)中
如果主庫併發事務量很大,或者出現大事務,由於從庫是單SQL線程,導致不管傳的日誌有多少,只能一次執行一個事務.
5.6 版本,有了GTID,可以實現多SQL線程,但是隻能基於不同庫的事務進行併發回放.(database)
5.7 版本中,有了增強的GTID,增加了seq_no,增加了新型的併發SQL線程模式(logical_clock),MTS技術
(2) 主從硬件差異太大
(3) 主從的參數配置
(4) 從庫和主庫的索引不一致
(5) 版本有差異