1. 程式人生 > 實用技巧 >NOI2020訓練題4 A 解放

NOI2020訓練題4 A 解放

mysql主從複製(非同步複製)

配置主從的條件

1.一臺帶有資料的主庫
2.一臺嶄新的從庫,或者初始化之後的

#初始化
cd /usr/local/mysql/scripts/ && rm -rf ../data && ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

1.主庫操作

1.主庫配置server_id
2.主庫開啟binlog
3.主庫授權連線的使用者
4.檢視binlog資訊(之後不能再有重新整理binlog的操作) -------------
5.匯出資料(mysqldump)
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql

#檢視binlog資訊之後,不能再有重新整理binlog的操作
#主從資料的同步,是為了建立或刪除的某些時候不報錯
#主從配置的過程中,可以寫入資料,因為change master to的時候已經記錄了那個位置點,所以同步的時候只需要指定那個位置點就好,那麼這樣從庫就可以同步到主庫的所有的資料了

2.從庫操作

1.從庫配置server_id(從庫不需要配置binlog,因為只配置主從複製的話,從庫不會寫入binlog,寫入中繼日誌)
2.確認主庫授權的使用者可以連線從庫(ssh)
3.匯入主庫資料
4.配置主庫資訊(change master to)(連線,會自動同步位置點之後的資料)
5.開啟slave(IO執行緒 dump執行緒)


#從庫不需要開啟binlog,因為從庫從主庫獲取的binlog存放到了中繼日誌(relay-log),中繼日誌就相當於從庫的binlog
#當資料量很大的時候,主從複製不是實時的情況將會很突出(中繼日誌裡面的SQL語句SQL執行緒執行)
#主從複製實際上是非同步複製

3.主從複製原理

1)圖解

2)文字描述

1.主庫配置server_id和開啟binlog
	[mysqld]
	server_id=1
	log_bin=/usr/local/mysql/data/mysql-bin
2.主庫授權從庫連線的使用者
	grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
3.主庫檢視binlog資訊,與伺服器資訊
	show master status;
3.5 主庫匯出所有資料(不會記錄在SQL)
mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
head -22 /tmp/full.sql | tail -1
	
4.從庫配置跟主庫'不一致'server_id,沒有binlog不能show master status;
	[mysqld]
	server_id=2
5.配置主從,通過change master to指定'從庫主庫的資訊':ip、使用者、密碼、埠、binlog位置點(b不加引號)、binlog名字(#埠 位置點不能加引號)
change master to
master_host='172.16.1.53',
master_user='rep',
master_port=3306,
master_password='123',
master_log_file='mysql-bin.000003',
master_log_pos=120;
6.從庫開啟IO執行緒(連線主庫)和sql執行緒(獲取主庫資訊)
start slave;
7.從庫連線主庫以後,'IO執行緒'會向主庫的'dump執行緒'發起詢問,詢問是否有新資料
8.dump執行緒被詢問,去'查詢新資料',並將新資料'返回給IO執行緒'
9.'IO執行緒'拿到資料先寫入'TCP快取')(三次握手,四次揮手)
10.'TCP快取'將資料寫入'中繼日誌relay-log',並返回給IO執行緒一個'ACK'
11.'IO執行緒'收到ACK會記錄當前位置點到'master.info'
12.'sql執行緒'會讀取relay-log,'執行'從主庫獲取的sql語句
13.執行完以後將執行到的'位置點,記錄'到relay-log.info

#binlog中的位置點放到中繼日誌relay-log中,位置點數值會發生變化(但是之間的資料不變)
#主從使用者的授權必須是*.*
grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
#使用過濾複製,可以使從庫只同步主庫的某一個庫,因此一個從庫可以同步不同的主庫
#主從複製,從庫會同步主庫位置點之後的資料變化(之前的並不會同步)

4.主從中涉及到的檔案或者執行緒

1)主庫

1.binlog:主庫執行的sql語句
2.dump執行緒:'對比'binlog是否更新,'獲取'新的binlog

2)從庫

1.IO執行緒:連線主庫,詢問新資料,'dump執行緒'獲取新資料
2.SQL執行緒:'執行'從主庫拿來的sql語句
3.relay-log:中繼日誌,'記錄'從主庫拿過來的binlog
4.master.info:'記錄'主庫binlog資訊,會隨著同步進行更新
5.relay-log.info:'記錄'sql執行緒執行到了哪裡,下次從哪裡開始'執行'

主從複製的搭建

1.主庫操作

1)配置

[root@db03 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
log_bin=/service/mysql/data/mysql-bin

[root@db03 ~]# /etc/init.d/mysqld restart

2)授權一個使用者

mysql> grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
Query OK, 0 rows affected (0.03 sec)

3)檢視binlog資訊

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      326 |   只同步           |  不同步                |                   |
自己去找binlog,然後同步
1 row in set (0.00 sec)

4)匯出所有資料

[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/

2.從庫操作

1)配置

[root@db02 ~]# vim /etc/my.cnf
[mysqld]
server_id=2

[root@db02 ~]# /etc/init.d/mysqld start

2)驗證主庫使用者

[root@db02 ~]# mysql -urep -p -h172.16.1.52

3)同步資料

[root@db02 ~]# mysql -uroot -p123 < /tmp/full.sql

4)配置主從

change master to
master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000018',
master_log_pos=120;

5)開啟執行緒

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

6)檢視主從

mysql> show slave status\G
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            
#如果IO執行緒和SQL執行緒都為no,那麼就是slave沒有開啟

主從資料庫出錯

1)IO執行緒出錯

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.防火牆(Connecting)
4.主從授權的使用者錯誤
5.反向解析
	skip-name-resolve
6.UUID或server_id相同

2)SQL執行緒出錯

mysql> show slave status\G
             Slave_IO_Running: Yes
            Slave_SQL_Running: No

#原因:
1.主庫有的資料,從庫沒有
2.從庫有的資料,主庫沒有
總而言之就是主從才能夠資料不一致,create drop insert 導致SQL執行緒斷開連線

#處理方式一:自欺欺人
1.臨時停止同步
mysql> stop slave;
2.將同步指標向下移動一個(需要重複操作,斷一次跳一次)
mysql> set global sql_slave_skip_counter=1;
3.開啟同步
mysql> start slave;

#處理方式二:掩耳盜鈴
1.編輯配置檔案
[root@db01 ~]# vim /etc/my.cnf
#在[mysqld]標籤下新增以下引數
slave-skip-errors=1032,1062,1007

#處理方式三:正解
重新同步資料,重新做主從(重新獲取binlog位置點即可)

# mysql主從複製的意義就是主庫和從庫資料的一致,如果配置好主從之後,主從資料還不一致,那麼主從就失去意義了


一、主從複製(步驟)(非同步複製)

1.主庫操作

1.配置server_id,開啟binlog
2.主庫授權使用者
grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
3.檢視binlog資訊
mysql> show master status;
4.匯出資料庫資料
[root@db03 mysql]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql

#主庫不要change自己,不然要 stop slave;reset slave;

2.從庫操作

1.配置server_id
2.配置主從
change master to
master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000003',
master_log_pos=120;
Query OK, 0 rows affected, 2 warnings (2.94 sec)
3.匯入資料
mysql> source /tmp/full.sql;
4.開啟執行緒
start slave;
5.檢視

二、延時複製

延時從庫只做'備份',不提供任何對外服務
#即便不配置主庫延時配置,從庫SQL執行緒執行的SQL語句在大資料的情況下,'來不及'執行,仍然會有延遲

#解決主庫從庫延時複製
1.讀寫分離,多做幾個從庫,那個快讀哪個
2.拆庫拆表
3.基於GTID的主從複製,開啟多個SQL執行緒

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

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

2.配置延時時間(reset slave all;)
change master to
master_delay=180;

master_host='172.16.1.52',
master_user='rep',
master_password='123',
master_log_file='mysql-bin.000018',
master_log_pos=120,

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

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.1.52 #被用於連線主伺服器的當前ip
                  Master_User: rep		#被用於連線主伺服器的當前使用者
                  Master_Port: 3306
                Connect_Retry: 60	#–master-connect-retry選項的當前值
                
              Master_Log_File: mysql-bin.000001 #I/O執行緒當前正在讀取的主伺服器二進位制日誌檔案的名稱
          Read_Master_Log_Pos: 468 --------------------
#在當前的主伺服器二進位制日誌中,I/O執行緒已經讀取的位置。
          
               Relay_Log_File: db03-relay-bin.000002	#中繼日誌
                Relay_Log_Pos: 283	--------------------		
#中繼日誌位置點
#在主伺服器的二進位制日誌中的(Relay_Master_Log_File, Exec_Master_Log_Pos)對應於在中繼日誌中的(Relay_Log_File,Relay_Log_Pos)。
        Relay_Master_Log_File: mysql-bin.000001	#主庫binlog
        
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            
              Replicate_Do_DB: 	
#使用–replicate-do-db和–replicate-ignore-db選項指定的資料庫清單。(過濾庫複製白名單)
          Replicate_Ignore_DB: (過濾庫複製黑名單)
          
           Replicate_Do_Table: 
#使用–replicate-do-table,–replicate-ignore-table,–replicate-wild-do-table和–replicate-wild-ignore_table選項指定的表清單。
       Replicate_Ignore_Table:  #(過濾表複製白名單)
      Replicate_Wild_Do_Table:  #(過濾表複製黑名單,支援正則)
  Replicate_Wild_Ignore_Table: 
  
                   Last_Errno: 0 #主從資料不一致導致的錯誤訊息數
                   Last_Error: 
                   
                 Skip_Counter: 0  
#最近被使用的用於SQL_SLAVE_SKIP_COUNTER的值
          Exec_Master_Log_Pos: 468 -------------------------
#來自主伺服器的二進位制日誌的由SQL執行緒執行的上一個時間的位置
              Relay_Log_Space: 455  
#所有原有的中繼日誌結合起來的總大小
              
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
Until_Condition具有以下值:
o 如果沒有指定'UNTIL'子句,則沒有值
o 如果從屬伺服器正在讀取,直到達到主伺服器的二進位制日誌的'給定位置'為止,則值為Master
o 如果從屬伺服器正在讀取,直到達到其中繼日誌的'給定位置'為止,則值為Relay
Until_Log_File和Until_Log_Pos用於指示日誌檔名和位置值。日誌檔名和位置值定義了'SQL執行緒在哪個點中止執行'。
                
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
#這些欄位顯示了被從屬伺服器使用的引數。這些引數用於連線主伺服器。
Master_SSL_Allowed具有以下值:
o 如果允許對主伺服器進行SSL連線,則值為Yes
o 如果不允許對主伺服器進行SSL連線,則值為No
o 如果允許SSL連線,但是從屬伺服器沒有讓SSL支援被啟用,則值為Ignored。
與SSL有關的欄位的值對應於–master-ca,–master-capath,–master-cert,–master-cipher和–master-key選項的值
               
        Seconds_Behind_Master: 0 
#本欄位測量從屬伺服器SQL執行緒和從屬伺服器I/O執行緒之間的時間差距,單位以秒計
##延時的SQL語句距離在從庫執行的已過去時間
        
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
  
             Master_Server_Id: 1 #主
                  Master_UUID: ebc5b10d-cf5f-11ea-b071-000c299d6beb
             Master_Info_File: /service/mysql-5.6.46-linux-glibc2.12-x86_64/data/master.info
             #master_info_file
                    SQL_Delay: 180
                    #sql執行緒延時180秒
          SQL_Remaining_Delay: NULL
          #延時的SQL語句距離在從庫執行的剩餘時間(xx秒後執行)
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
                
#延時複製中,延時的SQL語句儲存在只能中繼日誌
[root@db03 data]# ll
total 110668
-rw-rw---- 1 mysql mysql       56 Jul 27 00:49 auto.cnf
-rw-rw---- 1 mysql mysql    37295 Jul 27 01:27 db03.err
-rw-rw---- 1 mysql mysql        5 Jul 27 01:17 db03.pid
-rw-rw---- 1 mysql mysql      172 Jul 27 01:27 db03-relay-bin.000001
-rw-rw---- 1 mysql mysql      374 Jul 27 02:04 db03-relay-bin.000002
-rw-rw---- 1 mysql mysql       48 Jul 27 01:27 db03-relay-bin.index
#延時複製的作用是:做備份,MHA
#當發現主從資料不一致的時候,stop slave;同步主庫資料,重新做主從
#同步主庫資料,最好重新mysqldump 一下,以免漏資料(別人重新整理了binlog)
#reset slave;重新整理從庫binlog(清空)
#如果沒有做主從複製,可以關閉主庫的binlog來達到’避免binlog內臟資料的記錄‘,

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

1.搭建出一臺mysql
同步資料mysqldump
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;
3.開啟執行緒
mysql> start slave;

#可以自由選擇主庫位置點

3.關閉延時從庫

mysql> stop slave;
mysql> change master to master_delay=0;
mysql> start slave;

4.注意:

#如果做了主從,就不能關閉主庫的binlog了,因為主庫執行的drop在中級日誌中已經記錄,從庫早晚都會執行(刪庫),
	所以把主庫的binlog'一直開啟',這樣從庫的中繼日誌就可以通過主庫的恢復來恢復,'但是從庫的slave要關閉'(實際上從庫還是會執行主庫執行錯的語句,只不過又執行了重建語句)
	如果'關閉'了主庫的binlog,那麼從庫將不能恢復,主從資料不一致,主從複製失敗

#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內容(#relaylog就是binlog)
3、show relay log events in 'db01-relay-bin.000001'; (#看drop之前)


#處理的思路:
1)停止SQL執行緒(#防止從庫執行drop語句損壞'備份'資料)
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
stop slave;
CHANGE MASTER TO MASTER_DELAY = 300;	#延時同步
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;  #只關閉SQL執行緒

6)擷取relay-log
#備份起點:
cd /data/3308/data/
cat relay-log.info
./db01-relay-bin.000002	
283
#終點:(drop之前)
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恢復從庫到drop之前,恢復了之後,也可以通過Mysqldump -d匯出指定庫的SQL語句,再匯入到主庫,主庫恢復
1)取消從庫身份
mysql> stop io_thread;
mysql> reset slave all;

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


三、半同步複製(實時同步)

1.半同步複製概念

從'MYSQL5.5'開始,支援半自動複製。
之前版本的MySQL Replication都是'非同步'(asynchronous)的,(dump執行緒和IO執行緒之間沒有延遲,IO 執行緒和SQL執行緒在'大量訪問'的時候即便不配置延時複製,仍然會有'延遲')

主庫在執行完一些事務後,是'不會管'備庫的進度的。
如果備庫不幸落後,而更不幸的是主庫此時又出現Crash(例如宕機),
這時'備庫中的資料就是不完整的'。簡而言之,在主庫發生故障的時候,我們無法使用備庫來繼續提供資料一致的服務了。
'半同步複製'(Semi synchronous Replication)則一定程度上保證提交的事務已經傳給了至少一個備庫。出發點是保證主從資料一致性問題,安全的考慮。

5.5 出現概念,但是不建議使用,效能太差(#IO執行緒阻止主庫SQL語句的執行)
5.6 出現group commit 組提交功能,來提升開啟半同步複製的效能
5.7 更加完善了,在group commit基礎上出現了MGR(#主庫高可用)
5.7 的增強半同步複製的新特性:after commit; after sync;

#缺點:
1.效能差,影響主庫效率
2.半同步複製,有一個超時時間(IO執行緒等待SQL執行緒時間),超過這個時間'恢復主從複製'
3.當資料量很大的時候,SQL執行緒的語句還沒有執行的話,會組織主庫資料的寫入
4.#小的訪問量可以做半同步複製

#半同步複製是在主從複製的基礎上做的

2.配置半同步

1)主庫操作

#登入資料庫
[root@db01 ~]# mysql -uroot -p123
#檢視是否有動態支援
mysql> show global variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| have_dynamic_loading | YES   |
+----------------------+-------+
#安裝自帶外掛
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;

#修改配置檔案,在[mysqld]標籤下新增如下內容(不用重啟庫)
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000

檢查安裝:
mysql> show variables like'rpl%';
+------------------------------------+----------+
| Variable_name                      | Value    |
+------------------------------------+----------+
| rpl_semi_sync_master_enabled       | ON       |	#
| rpl_semi_sync_master_timeout       | 10000    |
| rpl_semi_sync_master_trace_level   | 32       |
| rpl_semi_sync_master_wait_no_slave | ON       |	#
| rpl_stop_slave_timeout             | 31536000 |	#停止主從的時間
+------------------------------------+----------+
mysql> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     | #有幾個客戶端
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     | #

#資料庫自帶的未安裝的外掛(.so)
[root@db02 ~]# ll /service/mysql/lib/plugin/
total 3484
-rwxr-xr-x 1 7161 31415  16581 Sep 27  2019 adt_null.so
-rwxr-xr-x 1 7161 31415 426219 Sep 27  2019 semisync_master.so  #
-rwxr-xr-x 1 7161 31415 249327 Sep 27  2019 semisync_slave.so   #
-rwxr-xr-x 1 7161 31415  14173 Sep 27  2019 test_udf_services.so
-rwxr-xr-x 1 7161 31415  99629 Sep 27  2019 udf_example.so
-rwxr-xr-x 1 7161 31415 193667 Sep 27  2019 validate_password.so

2)從庫操作

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

#
mysql> create database sssss;
Query OK, 1 row affected (0.01 sec)

mysql>  show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |  #主庫半同步複製有幾個客戶端
| Rpl_semi_sync_master_net_avg_wait_time     | 1812  |
| Rpl_semi_sync_master_net_wait_time         | 1812  |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    | #主庫是否開啟半同步
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 2273  |
| Rpl_semi_sync_master_tx_wait_time          | 2273  |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     | #從庫執行半同步的SQL語句
+--------------------------------------------+-------+

3)額外引數

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

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

1.開發環境	
	2臺
2.測試環境 (沙盒環境一般遊戲公司做)
	2臺
	測試併發等
	部署環境與生產一樣
3.灰度釋出(不刪檔內測)
4.生產環境
	20臺機子
	
#除了開發環境,別的環境都需要運維維護

四、過濾複製

1.過濾複製的方式

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

1)白名單

#從庫
只過濾庫
replicate-do-db=test
只過濾庫下表
replicate-do-table=test.t1
只過濾庫下以t開頭的表
replicate-wild-do-table=test.t*
#主庫
binlog-do-db=test
binlog-do-table=test.t1
binlog-wild-do-table=test.t*

2)黑名單

#從庫
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*

2.從庫配置過濾複製

1)主庫建立兩個庫

create database wzry;
create database lol;

#過濾複製只在配置了之後才會'過濾'並複製該庫以後的內容
#不管是主從複製,延時複製,半同步複製,過濾複製,都要先同步資料,再做主從複製

2)第一臺從庫配置

[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  #從庫配置檔案中指定要同步的庫

3)配置第二臺從庫

[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 #從庫要同步主庫的庫

4)驗證過濾複製

#1.主庫操作
use wzry
create table cikexintiao(id int);
use lol
create table fuleierzhuode(id int);

#第一臺從庫檢視
mysql> use wzry
mysql> show tables;
+----------------+
| Tables_in_wzry |
+----------------+
| cikexintiao    |
+----------------+
mysql> use lol
mysql> show tables;

#第二臺從庫檢視
mysql> use wzry
mysql> show tables;
mysql> use lol
mysql> show tables;
+---------------+
| Tables_in_lol |
+---------------+
| fuleierzhuode |
+---------------+

3.配置過濾多個庫

1)方法一:

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

2)方法二:

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

4.過濾複製配置在主庫

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庫的資料

5.過濾複製總結

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

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

#所以過濾複製一般配置在從庫,因為如果配置在了主庫,那麼binlog將部分記錄

五、基於GTID的主從複製

1.什麼是GTID

1.'全域性事務識別符號'
2.組成:UUID + TID    #資料庫的id+事務的id(依次遞增)
	   f03a53e0-cd46-11ea-a2c4-000c292c767e:1
#UUID
[root@db02 ~]# cat /service/mysql/data/auto.cnf 
[auto]
server-uuid=ebc5b10d-cf5f-11ea-b071-000c299d6beb

#停止主從
stop slave;
reset slave all;

2.GTID主從複製的優點

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

3.GTID主從複製的缺點

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

4.搭建GTID主從複製

1)配置三臺資料庫

#配置第一臺主庫
[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

2)檢視是否開啟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)

3)開啟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


4)擴充套件

#配置log-slave-updates引數的場景(主庫的binlog在寫入中繼日誌的同時,也寫入從庫的binlog)
1.基於GTID的主從複製(報錯)
2.雙主架構,mysql+keepalived
3.級聯複製
4.MHA

5)主庫建立使用者

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

6)主庫資料同步到從庫

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

7)從庫配置主從

change master to
master_host='172.16.1.51',
master_user='rep',
master_password='123',
master_auto_position=1;

#自動連線主庫位置點(當前binlog 120)
master_auto_position=1