MySQL基於多實例構建主從複製及常見故障排查

主從複製介紹

  • 主從複製基於binlog來實現的
  • 主庫發生新的操作,都會記錄到binlog
  • 從庫取得主庫的binlog進行“回放”
  • 主從複製的過程是異步的

搭建主從複製的前提

  • 2個或以上的數據庫實例
  • 主庫需要開啓二進制日誌
  • server_id要不同,區分不同的節點
  • 主庫需要建立專用的複製用戶 (replication slave)
  • 從庫應該通過備份主庫,恢復的方法進行"補課"
  • 人爲告訴從庫一些複製信息(CHANGE MASTER TO)
  • 從庫應該開啓專門的複製線程

主從複製工作過程

  1. 從庫執行change master to 命令(主庫的連接信息+複製的起點)
  2. 從庫會將以上信息,記錄到master.info文件
  3. 從庫執行 start slave 命令,立即開啓IO線程和SQL線程
  4. 從庫 IO線程,讀取master.info文件中的信息
  5. 從庫IO線程請求連接主庫,主庫專門提供一個DUMP線程,負責和IO線程交互
  6. IO線程根據binlog的位置信息(mysql-bin.000004 , 444),請求主庫新的binlog
  7. 主庫通過DUMP線程將最新的binlog,通過網絡TP給從庫的IO線程
  8. IO線程接收到新的binlog日誌,存儲到TCP/IP緩存,立即返回ACK給主庫,並更新master.info
  9. IO線程將TCP/IP緩存中數據,轉儲到磁盤relaylog中.
  10. SQL線程讀取relay.info中的信息,獲取到上次已經應用過的relaylog的位置信息
  11. SQL線程會按照上次的位置點回放最新的relaylog,再次更新relay.info信息
  12. 從庫會自動purge應用過的relay進行定期清理
    在這裏插入圖片描述
    一旦主從複製構建成功,主庫當中發生了新的變化,都會通過dump線程發送信號給IO線程,增強了主從複製的實時性.

主從複製的作用

  1. 備份。主庫down了自動切換到從庫
  2. 在數據庫層面上實現讀寫分離

主從複製搭建

構建MySQL多實例

  • 準備多個數據目錄

    [root@localhost ~]# mkdir -p /data/3307/data
    
  • 準備配置文件

    cat > /data/3307/my.cnf <<EOF
    [mysqld]
    basedir=/app/mysql
    datadir=/data/3307/data
    socket=/data/3307/mysql.sock
    log_error=/data/3307/mysql.log
    port=3307
    server_id=7
    log_bin=/data/3307/mysql-bin
    binlog_format=row
    ----------啓用GTID模式構建主從 
    gtid-mode=on                                --啓用gtid類型,否則就是普通的複製架構
    enforce-gtid-consistency=true          --強制GTID的一致性
    log-slave-updates=1 					--slave更新是否記入日誌
    sync_binlog=1	 --每次事務提交都立即刷寫binlog到磁盤
    最高安全模式
    innodb_flush_log_at_trx_commit=1(0:一秒會發生n多事務,斷電可能會丟失1秒內的所有事務;2(分兩步提交事務,一步只保證刷寫到os buffer。))
    Innodb_flush_method=O_DIRECT
    最高性能:
    innodb_flush_log_at_trx_commit=0
    innodb_flush_method=fsync
    EOF
    
  • 初始化數據庫

    mv /etc/my.cnf /etc/my.cnf.bak
    mysqld --initialize-insecure  --user=mysql --datadir=/data/3307/data --basedir=/application/mysql
    
  • 設置以systemd的方式啓動數據庫(Centos6省略)

    cd /etc/systemd/system
    cp mysqld.service mysqld3307.service
    vim mysqld3307.service
    # 修改爲:
    ExecStart=/application/mysql/bin/mysqld  --defaults-file=/data/3307/my.cnf
    
  • 授權數據目錄

    chown -R mysql.mysql /data/*
    
  • 啓動數據庫

    systemctl start mysqld3307.service
    //Centos6啓動方式
    mysqld_safe --defaults-file=/data/3307/my.cnf &
    //Centos6關閉方式
    mysqladmin -S /data/3307/mysql.sock shutdown
    //Centos6設置多實例密碼
    mysqladmin -uroot -S /data/3307/mysql.sock password '2'
    
  • 驗證多實例

    netstat -lnp|grep 330
    
  • 開啓binlog

    log_bin=/data/3307/mysql-bin
    
  • 在主庫創建複製用戶

    mysql -uroot -p1   -e "grant replication slave on *.* to repl@'192.168.63.%' identified by '123'"
    
  • 要求數據完全一致則先備份主庫的數據導入從庫

     mysqldump -uroot -p2 -p 3306 -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql
    
  • 在從庫導入數據

     mysql> source  /tmp/full.sql
    
  • 告訴從庫信息

     CHANGE MASTER TO 
     MASTER_HOST='192.168.63.128', //主庫IP地址
     MASTER_USER='repl', 主庫授權給從庫的用戶名及密碼
     MASTER_PASSWORD='123',
     MASTER_PORT=3306,  主庫端口
     #MASTER_LOG_FILE='mysql-bin.000006',  vim /tmp/full.sql查看主庫的binlog及pos
     #MASTER_LOG_POS=1210,     主庫pos
     MASTER_AUTO_POSITION=1;開啓了GTID模式則不需加以上兩行
     #MASTER_AUTO_POSITION=?;如果是導如通過xtrabackup備份的數據應該查看binlog填寫
     MASTER_CONNECT_RETRY=10;   重連次數
    
  • 從庫開啓複製線程(IO,SQL)

     mysql> start slave;
    
  • 檢查主從複製狀態、排錯

     mysql> show slave status \G
    

主從複製故障

  • IO線程故障(connecting)
    可能原因:
    (1)網絡、防火牆、連接數上限
    解決:

stop slave;
reset slave all;
change master to
start slave

(2)請求binlog遇到的問題,比如binlog沒開啓或者損壞

解決:
主庫:reset master
從庫:stop slave;
reset slave all;
change master to
start slave

  • SQL線程故障
    可能原因:
    relay-log損壞

合理解決方法:
把握一個原則,一切以主庫爲準進行解決.
如果出現問題,儘量進行反操作
最直接穩妥辦法,重新構建主從

暴力的解決方法
方法一:
stop slave;
set global sql_slave_skip_counter = 1;
start slave;
#將同步指針向下移動一個,如果多次不同步,可以重複操作。
start slave;
方法二:
/etc/my.cnf
slave-skip-errors = 1032,1062,1007

常見的錯誤代碼:
1007:對象已存在
1032:無法執行DML
1062:主鍵衝突,或約束衝突

爲了很大程度避免SQL線程故障,我們一般配置主從讀寫分離:
從庫只讀:

read_only
super_read_only

使用讀寫分離中間件,比如mycat、atlas、proxySQL、Maxscale

主從延時監控主要原因

(1) binlog寫入不及時
sync_binlog=1
(2) 默認情況下dump_t 是串行傳輸binlog *****
在併發事務量大時或者大事務,由於dump_t 是串行工作的,導致傳送日誌較慢,如何解決問題?
必須啓用GTID,使用Group commit方式.可以支持DUMP_T並行
(3) 主庫極其繁忙
慢語句
鎖等待
從庫個數
網絡延時
從庫方面可能原因:
(1) 傳統複製(Classic)中
如果主庫併發事務量很大,或者出現大事務,由於從庫是單SQL線程,導致不管傳的日誌有多少,只能一次執行一個事務.
5.6 版本,有了GTID,可以實現多SQL線程,但是隻能基於不同庫的事務進行併發回放.(database)
5.7 版本中,有了增強的GTID,增加了seq_no,增加了新型的併發SQL線程模式(logical_clock),MTS技術
(2) 主從硬件差異太大
(3) 主從的參數配置
(4) 從庫和主庫的索引不一致
(5) 版本有差異

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章