MySQL 主從複製
阿新 • • 發佈:2020-07-23
MySQL 主從複製
主從複製前提
- Master 和 Slave 時間同步
- 至少 2 臺以上例項,需要有角色劃分的標識,server_id
- Master 需要開啟 Binlog
- Master 建立專用複製使用者
- Slave 提前錄入Master 的大部分資料
- Slave 確認複製起點
- 開啟專用複製執行緒(主庫 Dump 執行緒;從庫 IO 執行緒,SQL 執行緒)
主從複製原理
文字描述:
主庫配置: # 主庫配置 server_id ,開啟 bin-log (/etc/my.cnf) # 主庫建立授權主從複製使用者(grant replication slave) # 獲取主庫的 binlog 資訊(file,position) # 匯出主庫資料(mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql) 從庫配置: # 從庫配置 server_id # 確認使用主庫的主從複製使用者可以連線主庫 # 匯入主庫資料(mysql < full.sql) # 配置主從(change master to),需要 Master節點 IP,使用者,埠,binlog-file,binlog-pos # binlog 配置資訊可以從 full.sql 中 22 行獲得 工作原理: # 1. Start slave 之後,從庫開啟 IO執行緒 和 SQL執行緒 # 2. 主庫開啟 Dump執行緒 # 3. IO執行緒 向 Dump執行緒 發起詢問,詢問是否有新的資料 # 4. Dump執行緒 被詢問,查詢是否有新資料,若有返回給 IO執行緒 # 5. IO執行緒 拿到資料,寫入TCP快取 # 6. TCP快取拿到資料,寫入relay-log,並返回給 IO執行緒一個 ACK報文 # 7. IO執行緒 收到 ACK報文,會記錄當前位置到 master.info(binlog 位置點) # 8. SQL執行緒 會主動讀取 relay-log,執行主庫執行的sql語句 # 9. 執行後,將執行到的位置點,記錄到 relay-log.info(relay-log 位置點)
涉及的檔案 & 執行緒
Master 主庫
Binlog:主庫執行的 SQL語句
Binlog_Dump 執行緒:用來接收從庫的請求,並投遞 Binlog 給從庫
mysql> show processlist; +----+------+--------------------+------+-------------+------+-----------------------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+--------------------+------+-------------+------+-----------------------------------------------------------------------+------------------+ | 2 | rep | 172.16.1.122:44504 | NULL | Binlog Dump | 282 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL | | 3 | root | localhost | NULL | Query | 0 | init | show processlist | +----+------+--------------------+------+-------------+------+-----------------------------------------------------------------------+------------------+ 2 rows in set (0.00 sec)
Slave 從庫
Relaylog:中繼日誌,記錄從主庫接收的 binlog
master.info:連線主庫的資訊,以及記錄主庫 binlog 資訊,會隨著同步進行更新
relay-log.info:記錄sql執行緒執行到了那裡,下次從哪裡開始執行
I/O 執行緒:連線主庫,請求 Binlog,接收 Binlog,等待主庫傳送 Binlog 事件
SQL 執行緒:讀取執行 Relaylog,等待 I/O 執行緒更新 Relaylog,實質上就是執行從主庫接收的 Binlog 事件(Relaylog 中記錄著 Binlog 事件)
mysql> show processlist; +----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+ | 3 | system user | | NULL | Connect | 1915 | Waiting for master to send event | NULL | | 4 | system user | | NULL | Connect | 1635 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | | 6 | root | localhost | NULL | Query | 0 | init | show processlist | +----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+ 3 rows in set (0.00 sec)
主從複製的搭建
主庫配置
配置 /etc/my.cnf
[root@db03 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/service/mysql/data/mysql-bin
[root@db03 ~]# /etc/init.d/mysqld start
建立專用複製使用者
mysql> grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
Query OK, 0 rows affected (0.03 sec)
檢視 Binlog 資訊
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 326 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
匯出主庫全部資料
[root@db03 data]# mysqldump -uroot -p -A --master-data=2 --single-transaction > /tmp/full.sql
[root@db03 data]# scp /tmp/full.sql 172.16.1.52:/tmp/
從庫配置
配置 /etc/my.cnf
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2
[root@db02 ~]# /etc/init.d/mysqld start
驗證專用複製使用者
[root@db02 ~]# mysql -urep -p -h172.16.1.53
匯入主庫全部資料
[root@db02 ~]# mysql -uroot -p123 < /tmp/full.sql
配置主從資訊
mysql> change master to
-> master_host='172.16.1.121',
-> master_user='rep',
-> master_password='123',
-> master_log_file='mysql-bin.000005',
-> master_log_pos=640;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
開啟從庫執行緒
mysql> start slave;
Query OK, 0 rows affected (0.04 sec)
檢驗是否成功
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
主從資料庫出錯
I/O 執行緒出錯
mysql> show slave status\G
Slave_IO_Running: No
Slave_SQL_Running: Yes
mysql> show slave status\G
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
# 排查思路
1.網路
[root@db02 ~]# ping 172.16.1.53
2.埠
[root@db02 ~]# telnet 172.16.1.53 3306
3.防火牆
4.主從授權的使用者錯誤
5.反向解析
skip-name-resolve
6.UUID或server_id相同
SQL 執行緒出錯
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
# 原因:
1.主庫有的資料,從庫沒有
2.從庫有的資料,主庫沒有
# 處理方式三:正解
重新同步資料,重新做主從