mysql主從記錄

一,主從的工作原理

master-slave
master-slave
    1. master將改變記錄到二進制日志(binary log)中(這些記錄叫做二進制日志事件,binary log events), Slave根據本機的master.info文件中記錄的Master的日志文件名程和具體位置,通過IO進程連接上Master并請求從指定日志文件的指定位置(或者從最開始的日志)之后的日志內容;
    1. Master接收到來自Slave的IO進程的請求后,通過負責復制的IO進程根據請求信息讀取制定日志指定位置之后的日志信息,返回給Slave 的IO進程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息已經到Master端的bin-log文件的名稱以及bin-log的位置;
    1. slave將master的binary log events拷貝到它的中繼日志(relay log);
    1. slave中的sql進程發現relay-log日志有改動后,根據relay.info中的relay位置,從relay-log的該位置開始重做中繼日志中的事件,將sql語句在本地數據庫執行。
[root@service mysql]# cat relay-log.info
./service-relay-bin.000002
3007731 ------------->代表relay-log文件執行的位置
mysql-bin.000008----->代表遠程master端binlog
338489392----------->執行到遠程master端binlog的具體位置
[root@service mysql]# cat master.info
18
mysql-bin.000008-->代表遠程master端binlog
338493827--------->執行到遠程master端binlog的具體位置
192.168.15.15----->遠程master端ip
username---------->遠程master端mysql的replication用戶名
userpassword----->遠程master端mysql的replication密碼
3306------------->遠程master端mysql端口

二,使用中遇到的問題

  • 公司采用 A:主-> B:從(blackhole)->C:從 架構;
  • 12月1日運維重啟了一下C機,過了一周后12月8號發現,A機的數據已經一周沒有同步到C機了,去C機器一看:
slave status\G
無任何信息
  • 于是想到在C機主動連接B,先登錄B機:
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysql-bin.000008 | 338242604 |              |                  |
+-------------------+----------+--------------+------------------+
  • 然后登錄C
CHANGE MASTER TO MASTER_HOST='B',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='p4ssword',
    -> MASTER_LOG_FILE='mysql-bin.000008',
    -> MASTER_LOG_POS=338242604;
START SLAVE;
  • 原本以為問題解決了,可是又一想從12.1到12.8這7天的數據并沒有同步到C機,但是此時已經過去幾分鐘了,趕快執行
STOP SLAVE
  • 后來仔細回憶主從原理,在C機的master.info文件中會保存最后一次請求B的binlog文件和位置,重啟C后,會在對應目錄自動生成master.info_bak文件,于是查看C機的master.info_bak
[root@service mysql]# cat master.info_bak 
18
mysql-bin.000008
335481914
192.168.15.15
repl
p4ssword
3306

可以看到12.1最后連接B的位置是335481914,而我們剛剛start slave的點是 338242604, 兩個點有差異,本以為在 start slave 到stop slave 之間在A機會有用戶操作產生很多數據, 如果此時在C上從335481914開始請求擔心會和剛剛同步的數據有沖突;

  • 于是想到查看
mysqlbinlog service-relay-bin.000002 > /tmp/relay.sql
cat /tmp/relay.sql
151202 12:02:40 server id 1  end_log_pos 335482146     Query   thread_id=281429        exec_time=4294964863    error_code=0
use ljyun_754_merchant/*!*/;
SET TIMESTAMP=1449028960/*!*/;
INSERT INTO role (role_name, role_leader) VALUES (店長, 0)

可以看到在servicw-relay-bin.000002 中會記錄在C上start slave 和stop slave 之間的所有C機數據庫的操作, 查看對應end_log_pos 335482146到B機的master的位置,根據該文件位置及具體的sql的分析,與master.info文件的對比判斷從start 到 stop之間C機的所有數據庫操作,然后確定只有一條數據產生,原本根據位置的加減判斷有200條數據產生,最后分析binglog中的end_log_pos 335482146 并不是以1為單位累加的,所以不要以binlog中的位置差判斷數據記錄的數量;

  • 最后可以放心的從12.1那天的斷點開始從C上發起請求,登錄C:
mysql> CHANGE MASTER TO MASTER_HOST='B',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='p4ssword',
    -> MASTER_LOG_FILE='mysql-bin.000008',
    -> MASTER_LOG_POS=335481914;
mysql> START SLAVE;
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.15.15
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 0
              Master_Log_File: mysql-bin.000008-->遠程master端binlog文件名
          Read_Master_Log_Pos: 338500476----->執行到master的binlog位置
               Relay_Log_File: service-relay-bin.000002-->relay-log文件名
                Relay_Log_Pos: 3018815-->本地執行到relay-log的位置
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: Yes------------>slave向master發起請求的io進程,正常=Yes 異常=No
            Slave_SQL_Running: Yes---------->slave在本地執行sql的sql進程,正常=Yes 異常=No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: mysql
           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: 338500476
              Relay_Log_Space: 3018973
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: oduct w
           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: 4
1 row in set (0.00 sec)

總結:mysql在賦值的時候,insert語句雖然在binlog中沒有主鍵,但是根據本次事故的觀察,insert操作是在真實數據庫操作的時候,卻與A機保持一致;比如有t1表為空表,則:

  1. 現在斷開同步,在A機上插入表t1一條記錄id=1, 此時在C上t1是空表;
  2. 在從最新點連接同步后,id=1的記錄沒有同步,因為連接的點不是當時的斷點; 此時在A上再次插入表t1一條記錄id=2, 查看C已經同步成功,并且在C上t1表只有一條記錄id=2和A保持一致;
  3. 在C上斷點出連接成功后,查看C上的t1表有兩條記錄,id分別和A上t1表保持一致;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一、什么是Mysql主從復制 MySQL主從復制是其最重要的功能之一。主從復制是指一臺服務器充當主數據庫服務器,另...
    人在碼途閱讀 2,791評論 0 23
  • 又看了一遍惡作劇之吻! 以前看不懂直樹計劃要去服兵役順便留在那個地方當醫生一年多湘琴哭得那么厲害,那么不舍?,F在談...
    靜默等你閱讀 254評論 0 0
  • 感恩今早小寶陪我跑步與吃早餐,回家以后把ip的密碼告訴我,還把我的指紋識別信息輸進去,敞開了心扉的大門,感恩寶貝的...
    今天的心情好閱讀 139評論 0 0
  • 昨天讀到簡書作者傻狍子寫的文章《我所親歷的窮學生思維》。其中,作者寫到一種思維“用時間換錢,不懂得用錢換時間”。很...
    _SSharon閱讀 421評論 0 1
  • 聽了你的話,我仿佛受了審判,無比委屈,又無從分辨,在離開前,我想問,那真的是你的意思嗎? 在自我辯護前,在帶著痛苦...
    點滴輝光閱讀 161評論 0 0