Mysql slave是否能夠update ?

最近平臺要作遷移,因爲業務遷移過程需求,但願slave在平臺遷移過程當中,既能保證master的數據同步到slave,可是也但願slave能夠update.
這個需求,做爲DBA,單單從數據庫層面,基本能夠判斷,是不可行的.可是,實際測試,纔有說服力.用數據/實驗結果說話。mysql

開始着手搭建一個測試的主從,進行slave的update測試.sql

  1. 將slave的read_only設置爲on,讓slave是能夠更改的.這裏須要注意.read_only這個參數.對於root或者擁有(.) 全instance權限的用戶,是不生效的.
  2. 主庫建立一個測試表test2
  3. 在slave上,能夠看到test2已經同步過來
    查詢錶行數數據庫

    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 23502 |
    +----------+
    1 row in set (0.01 sec)
  4. 刪除10行npm

    mysql> delete from test2 where id<10;
    Query OK, 9 rows affected (0.04 sec)
  5. 再次查詢錶行數
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 23493 |
    +----------+
    1 row in set (0.01 sec)
  6. 在主庫,修改表數據
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 23502 |
    +----------+
    1 row in set (0.01 sec)
  7. 刪除5行數據
    mysql> delete from test2 where id<5;
    Query OK, 4 rows affected (0.04 sec)
  8. 查詢行數
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 23498 |
    +----------+
    1 row in set (0.01 sec)
  9. 再到備庫,查看同步狀態json

    mysql> show slave status\G
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    Master_Host: 10.27.20.4
    Master_User: envision
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mysql-bin.000043
    Read_Master_Log_Pos: 57380204
    Relay_Log_File: replay-bin.000003
    Relay_Log_Pos: 320
    Relay_Master_Log_File: mysql-bin.000043
    Slave_IO_Running: Yes
    Slave_SQL_Running: No
    Replicate_Do_DB:
    Replicate_Ignore_DB:
    Replicate_Do_Table:
    Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
    Last_Errno: 1032
    Last_Error: Could not execute Delete_rows event on table cnpmjs.test2; Can't find record in 'test2', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000043, end_log_pos 57380173
    Skip_Counter: 0
    Exec_Master_Log_Pos: 57375790
    Relay_Log_Space: 13539720
    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: NULL
    Master_SSL_Verify_Server_Cert: No
    Last_IO_Errno: 0
    Last_IO_Error:
    Last_SQL_Errno: 1032
    Last_SQL_Error: Could not execute Delete_rows event on table cnpmjs.test2; Can't find record in 'test2', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000043, end_log_pos 57380173
    Replicate_Ignore_Server_Ids:
    Master_Server_Id: 102
    Master_UUID: b095e989-7dcf-11e8-83a2-0017fa032e39
    Master_Info_File: /var/lib/mysql/master.info
    SQL_Delay: 0
    SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State:
    Master_Retry_Count: 86400
    Master_Bind:
    Last_IO_Error_Timestamp:
    Last_SQL_Error_Timestamp: 180702 14:54:00
    Master_SSL_Crl:
    Master_SSL_Crlpath:
    Retrieved_Gtid_Set:
    Executed_Gtid_Set:
    Auto_Position: 0
    Replicate_Rewrite_DB:
    Channel_Name:
    Master_TLS_Version:
    1 row in set (0.00 sec)

    上面錯誤,已經說明,主從的數據已經不一致,沒法繼續同步app

  10. 在slave上修復數據,插入缺乏的10行
    mysql> insert into test2 select * from user where id<10;
    Query OK, 9 rows affected (0.01 sec)
    Records: 9 Duplicates: 0 Warnings: 0
  11. 修改完成以後,重啓slave進程
    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
  12. 再次查詢,能夠看到,slave又繼續同步了.
    mysql> show slave status\G
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    Master_Host: 10.27.20.4
    Master_User: envision
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mysql-bin.000043
    Read_Master_Log_Pos: 57380204
    Relay_Log_File: replay-bin.000005
    Relay_Log_Pos: 320
    Relay_Master_Log_File: mysql-bin.000043
    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: 57380204
    Relay_Log_Space: 688
    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: 102
    Master_UUID: b095e989-7dcf-11e8-83a2-0017fa032e39
    Master_Info_File: /var/lib/mysql/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:
    Executed_Gtid_Set:
    Auto_Position: 0
    Replicate_Rewrite_DB:
    Channel_Name:
    Master_TLS_Version:
    1 row in set (0.00 sec)
  13. 查詢數據,也是主庫刪除5條以後的信息.
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 23498 |
    +----------+
    1 row in set (0.01 sec)
  14. 再次更新master,看主從同步狀況
    mysql> insert into test2 select * from test2;
    Query OK, 23498 rows affected (1.01 sec)
    Records: 23498 Duplicates: 0 Warnings: 0
  15. 查詢主庫表的行數
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 46996 |
    +----------+
    1 row in set (0.02 sec)
  16. 從庫查詢,同步正常執行.
    mysql> select count(*) from test2;
    +----------+
    | count(*) |
    +----------+
    | 46996 |
    +----------+
    1 row in set (0.02 sec)

    前面測試的是delete,如今測試update是否可行ide

  17. 在備庫,修改數據
    mysql> update test2 set json=0 where id=5;
    Query OK, 2 rows affected (0.08 sec)
    Rows matched: 2 Changed: 2 Warnings: 0
    mysql> select * from test2 where id=5\G;
    *************************** 1. row ***************************
    id: 5
    gmt_create: 2016-02-23 12:28:51
    gmt_modified: 2016-02-23 12:28:51
    name: m_gol
    salt: 0
    password_sha: 0
    ip: 0
    roles: []
    rev: 2-379c3d7dfc06312105072ec0ccf84b4a
    email: m.goleb@gmail.com
    json: 0
    npm_user: 1
  18. 在主庫,修改數據
    mysql> update test2 set json=1000 where id=5;
    Query OK, 0 rows affected (0.07 sec)
    Rows matched: 2 Changed: 0 Warnings: 0
    mysql> select * from test2 where id=5\G;
    *************************** 1. row ***************************
    id: 5
    gmt_create: 2016-02-23 12:28:51
    gmt_modified: 2016-02-23 12:28:51
    name: m_gol
    salt: 0
    password_sha: 0
    ip: 0
    roles: []
    rev: 2-379c3d7dfc06312105072ec0ccf84b4a
    email: m.goleb@gmail.com
    json: 1000
    npm_user: 1
  19. 在備庫查詢slave同步狀態
    mysql> show slave status\G
    *************************** 1. row ***************************
    Slave_IO_State: Waiting for master to send event
    Master_Host: 10.27.20.4
    Master_User: envision
    Master_Port: 3306
    Connect_Retry: 60
    Master_Log_File: mysql-bin.000043
    Read_Master_Log_Pos: 70913715
    Relay_Log_File: replay-bin.000005
    Relay_Log_Pos: 13529969
    Relay_Master_Log_File: mysql-bin.000043
    Slave_IO_Running: Yes
    Slave_SQL_Running: No
    Replicate_Do_DB:
    Replicate_Ignore_DB:
    Replicate_Do_Table:
    Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
    Last_Errno: 1032
    Last_Error: Could not execute Update_rows event on table cnpmjs.test2; Can't find record in 'test2', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000043, end_log_pos 70912987
    Skip_Counter: 0
    Exec_Master_Log_Pos: 70909853
    Relay_Log_Space: 13534935
    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: NULL
    Master_SSL_Verify_Server_Cert: No
    Last_IO_Errno: 0
    Last_IO_Error:
    Last_SQL_Errno: 1032
    Last_SQL_Error: Could not execute Update_rows event on table cnpmjs.test2; Can't find record in 'test2', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql-bin.000043, end_log_pos 70912987
    Replicate_Ignore_Server_Ids:
    Master_Server_Id: 102
    Master_UUID: b095e989-7dcf-11e8-83a2-0017fa032e39
    Master_Info_File: /var/lib/mysql/master.info
    SQL_Delay: 0
    SQL_Remaining_Delay: NULL
    Slave_SQL_Running_State:
    Master_Retry_Count: 86400
    Master_Bind:
    Last_IO_Error_Timestamp:
    Last_SQL_Error_Timestamp: 180702 15:23:42
    Master_SSL_Crl:
    Master_SSL_Crlpath:
    Retrieved_Gtid_Set:
    Executed_Gtid_Set:
    Auto_Position: 0
    Replicate_Rewrite_DB:
    Channel_Name:
    Master_TLS_Version:
    1 row in set (0.00 sec)

    總結, slave是不能修改的,尤爲是在相同的表,和相同的行,若是出現查找的行不存在.就會致使同步失敗.
    即便,不是delete,只是update,也是不能夠的.
    因此slave仍是須要以read_only的形式存在. 才能保證組從一直正常同步.測試

緣由是,binglog中,是記錄行信息的上下文的,若是上下文對不上了(在slave端被修改過),接下來的binglog的recover就不能正確找到須要繼續還原的信息,也就不能成功執行recover,進而致使slave同步失敗。3d

參考下面一段binlog的截取信息:code

mysqlbinlog mysql-bin.000005 >> test.log
#181126  9:53:49 server id 101  end_log_pos 8342676 CRC32 0x928e28de    Anonymous_GTID  last_committed=2436 sequence_number=2437    rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 8342676
#181126  9:53:49 server id 101  end_log_pos 8342758 CRC32 0x1068a385    Query   thread_id=58717 exec_time=0 error_code=0
SET TIMESTAMP=1543226029/*!*/;
BEGIN
/*!*/;
# at 8342758
#181126  9:53:49 server id 101  end_log_pos 8342849 CRC32 0x2ee04d35    Table_map: `test`.`app_purchases` mapped to number 290
# at 8342849
#181126  9:53:49 server id 101  end_log_pos 8343168 CRC32 0x598ec3d0    Update_rows: table id 290 flags: STMT_END_F

BINLOG '
rcL7WxNlAAAAWwAAAEFNfwAAACIBAAAAAAEADmVvc19wb3J0YWxfd2ViAA1hcHBfcHVyY2hhc2Vz
AAsPDw8PAQ8SEhESAQ7AAMAAwADAAP0CAAAAAPgHNU3gLg==
rcL7Wx9lAAAAPwEAAIBOfwAAACIBAAAAAAEAAgAL/////2D7JDBlM2FmNzJkLWIxNDctNGQ3My1h
ZjY5LTBhNDQxZmZmMTdiMSQzN2Q2ZDJjZS1hZGU2LTRhNzEtOTEzYS1lNDJhMTQ5NmQxMDAPbzE1
NDI1MjM2NjI4NDcxJDM3ZDZkMmNlLWFkZTYtNGE3MWQ5ZDc1NWUyLWJmYTQtNDA3ZgKZoXSdawBg
+CQwZTNhZjcyZC1iMTQ3LTRkNzMtYWY2OS0wYTQ0MWZmZjE3YjEkMzdkNmQyY2UtYWRlNi00YTcx
LTkxM2EtZTQyYTE0OTZkMTAwD28xNTQyNTIzNjYyODQ3MSQzN2Q2ZDJjZS1hZGU2LTRhNzFkOWQ3
NTVlMi1iZmE0LTQwN2YCmaF0nWtb+8KtmaF0nXEB0MOOWQ==
'/*!*/;
# at 8343168
#181126  9:53:49 server id 101  end_log_pos 8343199 CRC32 0xcb9106dc    Xid = 400668
COMMIT/*!*/;
# at 8343199
相關文章
相關標籤/搜索