MySQL-lesson08-主從復制基礎(chǔ)

1、主從復制準備

1.1 前提

  1. 準備2個以上地mysql實例,一主一從。
  2. 每臺實例server_id不同
  3. 主庫方面創(chuàng)建專用地復制用戶
  4. 主庫必須開啟二進制日志
  5. 從庫需要初始化數(shù)據(jù),保證和主庫數(shù)據(jù)在一個時間點上一致

1.2 準備

  1. 3307配置文件添加binlog配置
    vim /data/3307/my.cnf
    log_bin=/data/3307/data/mysql-bin
    binlog_format=row

  2. 啟動多實例
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3307/my.cnf &
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3308/my.cnf &
    /application/mysql/bin/mysqld_safe --defaults-file=/data/3309/my.cnf &

  3. 驗證
    netstat -lnp|grep 330

  4. 主庫創(chuàng)建復制用戶
    mysql -uroot -S /data/3307/mysql.sock
    grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

  5. 全備主庫數(shù)據(jù),恢復到從庫
    mysqldump -S /data/3307/mysql.sock -A -R --triggers --master-data=2 --single-transaction >/tmp/full.sql

  6. 查看binlog文件和位置點
    vim /tmp/full.sql
    -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=325;

  7. 全備導入從庫
    mysql -uroot -S /data/3308/mysql.sock
    set sql_log_bin=0;
    source /tmp/full.sql

  8. 開啟主從復制
    mysql -uroot -S /data/3308/mysql.sock

CHANGE MASTER TO
MASTER_HOST='10.0.0.51', ---->主庫IP
MASTER_USER='repl', ---->主庫復制用戶
MASTER_PASSWORD='123', ---->主庫復制用戶密碼
MASTER_PORT=3307, ----->主庫端口
MASTER_LOG_FILE='master2-bin.000001', ----->需要復制的二進制日志名
MASTER_LOG_POS=325, ---->需要復制的二進制日志復制起點
MASTER_CONNECT_RETRY=10; ---->重連重試次數(shù)

啟動復制線程
start slave;

查看主從狀態(tài)
show slave status\G
slave_IO_Running:yes
slave_SQL_Running:yes

2、主從復制介紹

2.1 什么是主從復制?

基于主庫二進制日志實時恢復到從庫

2.2 主從復制存在的原因

  1. 輔助備份:解決物理損壞
  2. 演變高可用架構(gòu):在主庫發(fā)生故障時,自動進行故障轉(zhuǎn)移,對應用透明

2.3 主從復制原理

  • 主從復制前提
  1. 多臺節(jié)點
  2. server_id要不同
  3. 主庫開啟binlog
  4. 主庫提供專門的復制用戶
  5. 主庫備份導入從庫,跟上主庫的數(shù)據(jù)位置
  6. 通知從庫:復制用戶、密碼、IP、port、復制文件和起點
  7. 開啟復制
  • 文件
  1. Master:
    binlog:記錄主庫的數(shù)據(jù)變化
  2. Slave:
    relaylog:中繼日志,存儲從主庫請求過來的二進制日志的存儲位置
    master.info:存儲用戶,密碼,IP,port,記錄上次請求過的binlog位置
    relay-log.info:記錄了上次SQL線程執(zhí)行過的relaylog的位置點
  • 線程:
  1. Master:
    dump線程:主庫發(fā)送二進制日志給從庫的線程
  2. Slave:
    IO線程:請求binlog,并接收binlog的線程
    SQL線程:執(zhí)行relaylog日志的線程

主從復制原理

image.png

  1. 從庫IO線程,查看master.info信息,獲取IP,port,user,password,file,position位置點
  2. 通過IP,port,user,password,連接到主庫
  3. 拿著 file(mysql-bin.000003),pos(120),請求主庫
  4. 主庫判斷如果有新的binlog(mysql-bin.000003,800),通過Dump線程從3號文件的120開始發(fā)送二進制日志事件
  5. 從庫IO線程,接收binlog日志
  6. 接收到的binlog日志存到TCP/IP緩存
  7. IO線程回復一個ACK確認給dump線程,主庫收到后,主庫此次復制工作就完成了
  8. IO線程通知更新master.info文件,file,position被更新為最新請求的值
  9. 同時TCP/IP的緩存數(shù)據(jù),寫入relay-log中
  10. SQL線程,讀取relay-log.info,獲取到上次已經(jīng)執(zhí)行過的位置信息
  11. SQL執(zhí)行最新的relay-log日志內(nèi)容,數(shù)據(jù)重做
  12. 再次更新relay-log.info
  13. 已經(jīng)復制過的relay-log,會被自動清理

簡單來說就是三個步驟:
1、master將改變記錄到二進制日志(binary log),這些記錄過程叫做二進制日志事件(binary log events);
2、slave將master 的binary log events 拷貝到它的中繼日志( relay log);
3、slave重做中繼日志中的事件,將改變應用到自己的數(shù)據(jù)庫中。mysql復制是異步的且串行化的

2.4 主從復制監(jiān)控

  1. 主庫:
    show master status; //主庫和從庫的文件和位置信息應該是一致
    show processlist;

  2. 從庫:

show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.0.0.51
                  Master_User: repl
                  Master_Port: 3307
                Connect_Retry: 10
              Master_Log_File: master-bin.000004      //主庫的binlog日志文件
          Read_Master_Log_Pos: 918                      //binlog日志文件位置點
               Relay_Log_File: db01-relay-bin.000001       //relay log 文件
                Relay_Log_Pos: 4                                      //relay  log 位置點
        Relay_Master_Log_File: master-bin.000004      //relaylog 日志文件對應的主庫的binlog文件名
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

  1. 啟動關(guān)閉線程
    stop slave;
    start slave;
    stop slave io_thread; //單獨關(guān)閉IO線程
    stop slave sql_thread; //單獨關(guān)閉sql線程

  2. 監(jiān)控線程具體報錯信息

                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
               Last_SQL_Errno: 0
               Last_SQL_Error: 

2.5 主從復制故障

  1. IO線程故障
  • 連接master故障
    user,password,IP,port,網(wǎng)絡不通,防火墻,master沒啟動,master連接數(shù)到達上限,反向解析(skip-name-resolve)
# 用戶密碼錯誤,嘗試登錄主庫
mysql -urepl -p123 -h 10.0.0.51 -P3307

# 解決方法:
show slave status\G   //查看故障點的binlog位置
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 918 

# 停止復制
stop slave;         
reset slave all;    //清除之前的復制

# 修改信息重新復制
CHANGE MASTER TO
MASTER_HOST='10.0.0.51', 
MASTER_USER='repl',   
MASTER_PASSWORD='123', 
MASTER_PORT=3307, 
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=918,      //從故障時間點的位置開始復制主庫
MASTER_CONNECT_RETRY=10;

start slave;
show slave status\G
  • 接收binlog故障
    binlog日志文件找不到、損壞、與主庫斷節(jié)
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
               Last_SQL_Errno: 0
               Last_SQL_Error: 

reset master //二進制日志從頭開始。禁用

解決方法:

# 從庫停庫
stop slave;
reset slave all;

# 使用備份恢復,重新初始化數(shù)據(jù);如果主庫數(shù)據(jù)沒有變化,則不用
set sql_log_bin=0;
source /tmp/full.sql

# 重新復制
CHANGE MASTER TO
MASTER_HOST='10.0.0.51', 
MASTER_USER='repl',   
MASTER_PASSWORD='123', 
MASTER_PORT=3307, 
MASTER_LOG_FILE='mysql-bin.000001',    //從頭開始復制
MASTER_LOG_POS=120,
MASTER_CONNECT_RETRY=10; 

start slave;
  1. SQL線程故障
    (1)讀寫relay log.info
    (2)relay log 損壞,斷節(jié),找不到
    (3)接收到的SQL無法執(zhí)行;根本原因是從庫有寫入操作,從庫所有的數(shù)據(jù)都應該來自于主庫。

解決方法:
1、寫入操作撤回
2、跳過錯誤的方法是有風險的,最安全的方法重新構(gòu)建主從。
3、徹底解決方法是將從庫設置為只讀庫

從庫設置只讀權(quán)限

# 會話級別設置:
set global read_only=1;

# 永久設置:
vim /etc/my.cnf
[mysqld]
read_only=1

# 以上兩條只對普通用戶生效

# 設置管理員只讀權(quán)限
vim /etc/my.cnf
[mysqld]
innodb_read_only=1
會話級別無法設置,只能重啟生效
  1. 主從復制延時過高

定義:主庫做了一個操作,從庫很久都沒有追上

  • 原因1 主庫寫binlog不及時

解決方法:控制binlog從內(nèi)存寫入到磁盤的控制參數(shù):

  1. 每次事務提交會立即刷新binlog到磁盤(雙一標準的其中一個)
    sync_binlog=1

  2. 每次事務提交不立即寫入磁盤,靠操作系統(tǒng)判斷什么時候?qū)懭?br> sync_binlog=0

  • 原因2 dump線程壓力大

  • 原因3 IO線程阻塞
    大事務------->拆成多個小事務
    事務量大------->group commit,5.6以后的參數(shù),可以同時提交

  • 原因4 SQL線程慢

  1. 默認只有一個SQL線程,從庫中的事務都是一個一個來執(zhí)行的
  2. 如果主庫的并發(fā)事務數(shù)很多,大事務,都會造成從庫延時
    5.6 多線程復制(多SQL線程),有局限性,針對不同庫的事務進行并發(fā);
    大事務只能在主庫拆成小事務。
  • 查看從庫延時時間
    show slave status\G
    Seconds_Behind_Master:8888
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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