GTID主從復制

GTID主從復制

GTID是對傳統(tǒng)基于binary log的復制進行了增強,在binary log復制方式中,我們必須手動跟蹤主服務器的日志名稱和位置;但在GTID工作方式下面,我們無需跟蹤這兩個值,取而代之的是由MySQL自動跟蹤它們,并使用GTID來標記哪些事務已經(jīng)被處理,哪些還沒有被處理。GTID的一個優(yōu)點是:相同GTID的事務不會被重復處理,好處是可以最大限度地確保數(shù)據(jù)的一致性。

想了解更多gtid和binlog:http://www.itdecent.cn/p/63efedc95822

根據(jù)GTID搭建MySQL主從

比較喜歡docker,所以這次環(huán)境搭建也是用Docker部署

1、使用docker-compose部署兩個mysql

version: '3.6'
services:
  master:
    image: mysql:8.0.25
    restart: always
    container_name: mysql-master
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: root
    command:
      --default-authentication-plugin=mysql_native_password
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
      --max_allowed_packet=128M
      --sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
    ports:
      - 3306:3306
  slaver:
    image: mysql:8.0.25
    restart: always
    container_name: mysql-slaver 
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: root
    command:
      --default-authentication-plugin=mysql_native_password
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
      --max_allowed_packet=128M
      --sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
    ports:
      - 3307:3306 
#Are you trying to mount a directory onto a file or vice-versa 
#docker 掛載只能掛載目錄,不能掛載文件,如果掛載的是文件,則docker會把他當成一個目錄,對于掛載的文件需要先創(chuàng)建
#mysql8默認加密方式cahing_sha2_password,舊版navicate不支持,可以使用mysql5.7的加密方式mysql_native_password
#也可以在mysql中執(zhí)行
#ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; #修改加密規(guī)則 
#ALTER USER 'root'@'%' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; #更新一下用戶的密碼 
#FLUSH PRIVILEGES; #刷新權限 。%表示遠程連接
  

2、修改配置文件

master數(shù)據(jù)庫

# 進入MySQL容器
~ docker exec -it mysql-master bash 
# 編輯mysql配置文件
cat >> /etc/mysql/my.cnf << EOF 
#GTID:
server_id=1   #服務器id
gtid_mode=on                 #開啟gtid模式
enforce_gtid_consistency=on  #強制gtid一致性,開啟后對于特定create table不被支持

#binlog
log_bin=master-binlog
log-slave-updates=1    
binlog_format=row            #強烈建議,其他格式可能造成數(shù)據(jù)不一致

#relay log
skip_slave_start=1
max_connect_errors=1000
#default_authentication_plugin = 'mysql_native_password'
# 結束
EOF

slave數(shù)據(jù)庫

# 進入MySQL容器
~ docker exec -it mysql-slaver bash 
# 編輯mysql配置文件
cat >> /etc/mysql/my.cnf << EOF 
#GTID:
gtid_mode=on
enforce_gtid_consistency=on
server_id=2

#binlog
log-bin=slave-binlog
log-slave-updates=1
binlog_format=row      #強烈建議,其他格式可能造成數(shù)據(jù)不一致

*#relay log*  
skip_slave_start=1
EOF

3、搭建主從復制

主庫執(zhí)行

# 進入數(shù)據(jù)庫
mysql -uroot -proot;
# 創(chuàng)建有復制權限的賬號
create user 'repl'@'%' identified by 'repl';
grant replication slave,replication client on *.* to 'repl'@'%';
# 刷新權限
flush privileges;

從庫執(zhí)行

# 使用前面創(chuàng)建的賬號連接主數(shù)據(jù)庫測試下
# docker中同意網(wǎng)絡中可以只用容器名代替ip,docker會使用自己的dns解析
mysql -urepl -prepl -hmysql-slave -P 3306
# 進入數(shù)據(jù)庫
mysql -uroot -proot;
# 從庫連接主數(shù)據(jù)庫
CHANGE MASTER TO  
      MASTER_HOST='mysql-master',    
      master_user='repl',    
      master_password='repl',    
      master_port=3306,    
      MASTER_AUTO_POSITION = 1;
# 啟動從庫進程
start slave;    

查看從庫啟動狀態(tài),從數(shù)據(jù)庫執(zhí)行 show slave status\G

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.56.101
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-binlog.000002
          Read_Master_Log_Pos: 1135
               Relay_Log_File: mysql-103-relay-bin.000002
                Relay_Log_Pos: 1357
        Relay_Master_Log_File: master-binlog.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1135
              Relay_Log_Space: 1569
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
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: 135
                  Master_UUID: 1c8f7f48-4a7c-11ea-ab18-0800278ffd3d
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 1c8f7f48-4a7c-11ea-ab18-0800278ffd3d:1-4
            Executed_Gtid_Set: 1c8f7f48-4a7c-11ea-ab18-0800278ffd3d:1-4,
846de782-4a7c-11ea-95ab-080027e75c4d:1
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
1 row in set (0.00 sec)

Slave_IO_Running是Yes狀態(tài),Slave_SQL_Running是Yes狀態(tài)則表示成功

查看主從數(shù)據(jù)庫binlog日志復制情況 show master status\G;

*************************** 1. row ***************************
             File: master-binlog.000001
         Position: 475696
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: f0c7abf2-f548-11eb-a45d-0242ac190002:1-1128
1 row in set (0.00 sec)

*************************** 1. row ***************************
             File: slave-binlog.000001
         Position: 475696
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: f0c7abf2-f548-11eb-a45d-0242ac190002:1-1128
1 row in set (0.00 sec)

正常情況下兩邊binlog日志pos是相同的

4、主從不一致解決

方法一:忽略錯誤

# 從數(shù)據(jù)庫關閉復制
stop slave; 
# 表示跳過一步錯誤,后面的數(shù)字可變 
set global sql_slave_skip_counter =1; 
start slave; 
# 查看數(shù)據(jù)庫情況
show slave status\G; 
Slave_IO_Running: Yes 
Slave_SQL_Running: Yes 
則正常

方法二:重新做主從,完全同步

1.先進入主庫,進行鎖表,防止數(shù)據(jù)寫入 
使用命令: 
mysql> flush tables with read lock; 
注意:該處是鎖定為只讀狀態(tài),語句不區(qū)分大小寫 
2.進行數(shù)據(jù)備份 
#把數(shù)據(jù)備份到mysql.bak.sql文件 
[root@server01 mysql]#mysqldump -uroot -proot -hmysql-master > mysql.bak.sql 
這里注意一點:數(shù)據(jù)庫備份一定要定期進行,可以用shell腳本或者python腳本,都比較方便,確保數(shù)據(jù)萬無一失 
3.查看master 狀態(tài) 
mysql> show master status; 
4.把mysql備份文件傳到從庫機器,進行數(shù)據(jù)恢復 
5.停止從庫的狀態(tài) 
mysql> stop slave; 
6.然后到從庫執(zhí)行mysql命令,導入數(shù)據(jù)備份 
mysql> source /mysql.bak.sql 
7.設置從庫同步,注意該處的同步點,就是主庫show master status信息里的| File| Position兩項 
#關閉自動pos
mysql> change master to master_auto_position=0;
# 同步主從數(shù)據(jù)庫pos
mysql> change master to master_host = 'mysql-master', master_user = 'repl', master_port=3306, master_password='repl', master_log_file = 'mysql-master.000001', master_log_pos=411148; 
# 開啟自動pos
mysql> change master to master_auto_position=1;
8.重新開啟從同步 
mysql> start slave; 
9.查看同步狀態(tài) 
mysql> show slave status\G 查看: 
Slave_IO_Running: Yes 
Slave_SQL_Running: Yes 
好了,同步完成啦。
10.同步完成
unlock tables;
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容