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

MySQL 主從複製(下)

延時複製

延時從庫只做備份,不提供任何對外服務

配置延時複製(已經有主從)

1.停止主從
mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)

2.配置延時時間
mysql> change master to master_delay=180;
Query OK, 0 rows affected (0.01 sec)

3.開啟主從
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

配置延時複製(沒有主從)

1.搭建出一臺mysql
2.配置主從
mysql> change master to
    -> master_host='172.16.1.51',
    -> master_user='rep',
    -> master_password='123',
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=424,
    -> master_delay=180;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
3.開啟執行緒
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

關閉延時從庫

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> change master to master_delay=0;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

注意事項

延時從庫恢復資料時不要關閉主庫的binlog,實際上從庫還是會執行主庫執行錯的語句,只不過又執行了重建語句

延時複製例項

#  思考問題:
總資料量級500G,正常備份去恢復需要1.5-2小時
1)配置延時3600秒
mysql>CHANGE MASTER TO MASTER_DELAY = 3600;

2)主庫
drop database db;

3)怎麼利用延時從庫,恢復資料?
提示:
1、從庫relaylog存放在datadir目錄下
2、mysqlbinlog 可以擷取relaylog內容
3、show relay log events in 'db01-relay-bin.000001';

# #處理的思路:
1)停止SQL執行緒
mysql> stop slave sql_thread;

2)擷取relaylog到誤刪除之前點
relay-log.info 獲取到上次執行到的位置點,作為恢復起點
分析relay-log的檔案內容,獲取到誤刪除之前position
模擬故障處:

1)關閉延時
mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_DELAY = 0;
mysql> start slave;

2)模擬資料
mysql -S /data/3307/mysql.sock
source  /root/world.sql
use world;
create table c1 select * from city;
create table c2 select * from city;

3)開啟從庫延時5分鐘
mysql -S /data/3308/mysql.sock
show slave status \G
mysql>stop slave;
mysql>CHANGE MASTER TO MASTER_DELAY = 300;
mysql>start slave;
mysql -S /data/3307/mysql.sock
use world;
create table c3 select * from city;
create table c4 select * from city;

4)破壞,模擬刪庫故障。(以下步驟在5分鐘內操作完成。)
mysql -S /data/3307/mysql.sock
drop database world;

5)從庫,關閉SQL執行緒
mysql -S /data/3308/mysql.sock
stop slave sql_thread;

6)擷取relay-log
起點:
cd /data/3308/data/
cat relay-log.info
./db01-relay-bin.000002
283
終點:
mysql -S /data/3308/mysql.sock
show relaylog events in 'db01-relay-bin.000002'
db01-relay-bin.000002 | 268047 
mysqlbinlog --start-position=283  --stop-position=268047 /data/3308/data/db01-relay-bin.000002 >/tmp/relay.sql 
恢復relay.sql

1)取消從庫身份
mysql> stop slave;
mysql> reset slave all;

2)恢復資料
mysql> set sql_log_bin=0;
mysql> source /tmp/relay.sql
mysql> use world
mysql> show tables;

半同步複製

半同步複製概念

從MYSQL5.5開始,支援半自動複製。之前版本的MySQL Replication都是非同步(asynchronous)的,主庫在執行完一些事務後,是不會管備庫的進度的。如果備庫不幸落後,而更不幸的是主庫此時又出現Crash(例如宕機),這時備庫中的資料就是不完整的。簡而言之,在主庫發生故障的時候,我們無法使用備庫來繼續提供資料一致的服務了。

半同步複製(Semi synchronous Replication)則一定程度上保證提交的事務已經傳給了至少一個備庫。
出發點是保證主從資料一致性問題,安全的考慮。

5.5 出現概念,但是不建議使用,效能太差
5.6 出現group commit 組提交功能,來提升開啟半同步複製的效能
5.7 更加完善了,在group commit基礎上出現了MGR
5.7 的增強半同步複製的新特性:after commit; after sync;

# 缺點:
1.效能差,影響主庫效率
2.半同步複製,有一個超時時間,超過這個時間恢復主從複製

主庫配置

# 登入資料庫
[root@db01 ~]#  mysql -uroot -p123
# 檢視是否有動態支援
mysql> show global variables like 'have_dynamic_loading';
# 安裝自帶外掛
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
# 啟動外掛
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
# 設定超時
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;
# 修改配置檔案
[root@db01 ~]#  vim /etc/my.cnf
# 在[mysqld]標籤下新增如下內容(不用重啟庫)
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000
檢查安裝:
mysql> show variables like'rpl%';
mysql> show global status like 'rpl_semi%';

從庫配置

# 登入資料庫
[root@mysql-db02 ~]#  mysql -uroot -poldboy123
# 安裝slave半同步外掛
mysql>  INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
# 啟動外掛
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
# 重啟io執行緒使其生效
mysql> stop slave io_thread;
mysql> start slave io_thread;
# 編輯配置檔案(不需要重啟資料庫)
[root@mysql-db02 ~]#  vim /etc/my.cnf
# 在[mysqld]標籤下新增如下內容
[mysqld]
rpl_semi_sync_slave_enabled =1

額外引數

rpl_semi_sync_master_timeout=milliseconds
設定此引數值(ms),為了防止半同步複製在沒有收到確認的情況下發生堵塞,如果Master在超時之前沒有收到任何確認,將恢復到正常的非同步複製,並繼續執行沒有半同步的複製操作。

rpl_semi_sync_master_wait_no_slave={ON|OFF}
如果一個事務被提交,但Master沒有任何Slave的連線,這時不可能將事務傳送到其它地方保護起來。預設情況下,Master會在時間限制範圍內繼續等待Slave的連線,並確認該事務已經被正確的寫到磁碟上。
可以使用此引數選項關閉這種行為,在這種情況下,如果沒有Slave連線,Master就會恢復到非同步複製。

過濾複製

過濾複製的方式

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      305 |   白名單      |    黑名單        |                   |
+------------------+----------+--------------+------------------+-------------------+

白名單

# 從庫
replicate-do-db=test
replicate-do-table=test.t1
replicate-wild-do-table=test.t*
# 主庫
binlog-do-db=test
binlog-do-table=test.t1
binlog-wild-do-table=test.t*

黑名單

# 從庫
replicate-ignore-db=test
replicate-ignore-table=test.t1
replicate-wild-ignore-table=test.t*
# 主庫
binlog-ignore-db=test
binlog-ignore-table=test.t1
binlog-wild-ignore-table=test.t*

配置過濾複製(一個從庫)

主庫建立兩個庫

mysql> create database wzry;
Query OK, 1 row affected (1.00 sec)

mysql> create database lol;
Query OK, 1 row affected (0.00 sec)

第一臺從庫配置

[root@db02 data]#  vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=wzry

[root@db02 data]#  systemctl restart mysqld

# 檢視主從狀態
mysql> show slave status\G
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: wzry

配置第二臺從庫

[root@db03 ~]#  vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=lol

[root@db03 ~]#  systemctl restart mysqld

# 檢視主從狀態
mysql> show slave status\G
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: lol

驗證過濾複製

# 1.主庫操作
mysql> use wzry
Database changed

mysql> create table cikexintiao(id int);
Query OK, 0 rows affected (0.26 sec)

mysql> use lol
Database changed

mysql> create table fuleierzhuode(id int);
Query OK, 0 rows affected (0.01 sec)

# 第一臺從庫檢視
mysql> use wzry
Database changed

mysql> show tables;
+----------------+
| Tables_in_wzry |
+----------------+
| cikexintiao    |
+----------------+
1 row in set (0.00 sec)

mysql> use lol
Database changed

mysql> show tables;
Empty set (0.00 sec)

# 第二臺從庫檢視
mysql> use wzry
Database changed

mysql> show tables;
Empty set (0.00 sec)

mysql> use lol
Database changed

mysql> show tables;
+---------------+
| Tables_in_lol |
+---------------+
| fuleierzhuode |
+---------------+
1 row in set (0.00 sec)

配置過濾複製(多個從庫)

[root@db02 data]#  vim /etc/my.cnf
[mysqld]
server_id=2
replicate-do-db=wzry,lol

過濾複製配置在主庫

1.配置
[root@db01 ~]#  vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin
binlog-do-db=wzry

2.檢視主庫狀態
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      120 | wzry         |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3.在主庫的wzry庫和lol庫新增資料

4.從庫檢視資料,只能看到wzry庫的資料

過濾複製總結

# 配置在從庫時
1.配置白名單:IO執行緒將主庫的資料拿到了relay-log,但是sql執行緒只執行白名單配置的資料庫相關語句
1.配置黑名單:IO執行緒將主庫的資料拿到了relay-log,但是sql執行緒只不執行黑名單配置的資料庫相關語句

# 配置在主庫時
1.配置白名單:binlog只記錄白名單相關的sql語句
2.配置黑名單:binlog只不記錄黑名單相關的sql語句

GTID 主從複製

什麼是 GTID

1.全域性事務識別符號
2.組成:UUID + TID    
	   f03a53e0-cd46-11ea-a2c4-000c292c767e:1

GTID 主從複製的優點

1.GTID同步時開啟多個SQL執行緒,每一個庫同步時開啟一個執行緒
2.binlog在rows模式下,binlog內容比尋常的主從更加簡潔
3.GTID主從複製會記錄主從資訊,不需要手動配置binlog和位置點

GTID 主從複製的缺點

1.備份時更加麻煩,需要額外加一個引數 --set-gtid=on
2.主從複製出現錯誤,沒有辦法跳過錯誤

搭建 GTID 主從複製

配置三臺資料庫

# 配置第一臺主庫
[root@db01 ~]#  vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin

# 配置第一臺從庫
[root@db02 ~]#  vim /etc/my.cnf
[mysqld]
server_id=2

# 配置第二臺從庫
[root@db03 ~]#  vim /etc/my.cnf
[mysqld]
server_id=3

檢視是否開啟 GTID

mysql> show variables like '%gtid%';
+---------------------------------+-----------+
| Variable_name                   | Value     |
+---------------------------------+-----------+
| binlog_gtid_simple_recovery     | OFF       |
| enforce_gtid_consistency        | OFF       |
| gtid_executed                   |           |
| gtid_mode                       | OFF       |
| gtid_next                       | AUTOMATIC |
| gtid_owned                      |           |
| gtid_purged                     |           |
| simplified_binlog_gtid_recovery | OFF       |
+---------------------------------+-----------+
8 rows in set (0.00 sec)

開啟 GTID

# 主庫配置
[root@db01 ~]#  vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates

# 從庫1的配置
[root@db02 ~]#  vim /etc/my.cnf
[mysqld]
server_id=2
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates

# 從庫2的配置
[root@db02 ~]#  vim /etc/my.cnf
[mysqld]
server_id=3
log_bin=/usr/local/mysql/data/mysql-bin
gtid_mode=on
enforce_gtid_consistency
log-slave-updates

需要用 log-slave-updates 的場景

# 配置log-slave-updates引數的場景
1.基於GTID的主從複製
2.雙主架構+keepalived
3.級聯複製
4.MHA

主庫建立使用者

mysql> grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';

主庫資料同步到從庫

mysqldump -uroot -p -R --triggers --master-data=2 --single-transaction -A > /tmp/full.sql
scp
mysql < full.sql

從庫配置主從資訊

mysql> change master to
    -> master_host='172.16.1.51',
    -> master_user='rep',
    -> master_password='123',
    -> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.03 sec)