1. 程式人生 > 實用技巧 >MySQL 主從複製

MySQL 主從複製

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.從庫有的資料,主庫沒有

#  處理方式三:正解
重新同步資料,重新做主從