参数 server_id 的潜在重要性
2024-01-12 20:18 abce 阅读(47) 评论(0) 编辑 收藏 举报一般情况下,server_id 被设置为一个随机数字,只是与其他副本上配置的数字不同,而且一旦设置好,以后一般就不会再查看或更改,通常这没什么问题,但如果忽略了 server_id,就可能导致在下面描述的恢复场景中出现不必要的事务跳过。
假设我们有以下拓扑结构:
db2 - primary - server_id = 82 db1 - replica - server_id = 81
一旦主数据库(db1)上的流量被转移,我们就可以开始对其进行维护。在维护过程中,磁盘出现了问题,导致 MySQL 中的数据不一致。别担心,我们有当天早些时候从 db2 上获取的备份,让我们使用它吧
·使用 rsync 将备份从 db2 复制到 db1。 ·使用 xtrabackup 还原数据 ·使用与 db1 崩溃前相同的配置启动 MySQL。(server_id=81)。 ·在设置复制时,可以使用来自 xtrabackup_binlog_info 的复制位置,因为我们需要一致备份是来自 db2 的日志位置。
在备份和还原之间,生成了许多需要应用的 binlog,因此我们预计复制需要一些时间才能完全赶上主系统。
复制配置完成后,却发现 binlog 的进度太快。
假设使用以下位置配置复制:
mysql> CHANGE MASTER TO -> MASTER_HOST='10.10.10.10', -> MASTER_USER='repluser', -> MASTER_PASSWORD='XXXXXXXXXXXXXXXX', -> MASTER_LOG_FILE='mysql-bin.034322', -> MASTER_LOG_POS=375677230; Query OK, 0 rows affected, 2 warnings (0.36 sec)
查看一下复制的状态:
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.10.10 Master_User: repluser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.034324 Read_Master_Log_Pos: 3898727534 Relay_Log_File: mysql-relay-bin.000006 Relay_Log_Pos: 369 Relay_Master_Log_File: mysql-bin.034324 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Exec_Master_Log_Pos: 3898727534 ... 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: 2002 Master_UUID: 94318777-57fe-11ee-a884-b496916f3834 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
注意到奇怪的事情了吗?是的,Seconds_behind_master: 0,即使有大约 40 多个 binlog 需要应用。
它一直以"快节奏"运行;在几分钟内就推进了 40 个 binlog,直到失败:
mysql> show slave statusG *************************** 1. row *************************** Slave_IO_State: Master_Host: 10.10.10.10 Master_User: repluser Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.034372 Read_Master_Log_Pos: 107962899 Relay_Log_File: mysql-relay-bin.000086 Relay_Log_Pos: 6294 Relay_Master_Log_File: mysql-bin.034364 Slave_IO_Running: No 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 test.mysql1; Can't find record in mysql1, Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.034364, end_log_pos 123596930
怎么回事?我们的备份坏了吗?
检查 binlog 后发现,"处理速度过快"由 server_id=81 导致的,而 server_id=81 与当前副本相同(因为这些记录是在 db1 上生成的,备份时 db1 是主服务器)。一旦尝试在具有相同 server_id 的服务器上应用这些记录,就会跳过这些记录。
然后,一旦完成故障转移,binlogs 事件就会以 server_id=82 (db2)生成。这时它开始实际应用事件,但由于它跳过了来自同一 server_id 的多个事件,因此错过了对数据库的许多更新和插入,导致数据库处于不一致状态。在这种情况下,别无他法,只能重试还原,这次要在开始复制前更改还原服务器上的 server_id 值。
除更改 server_id 外,另一种可行的方法是启用选项 replicate-same-server-id。根据文档:"该选项用于复制。默认值为 0(FALSE)。将该选项设置为 1(TRUE)后,副本不会跳过具有自己 server ID 的事件。此设置通常只在罕见配置中有用"。
提醒了我们,在复制环境中执行还原时要检查 server_id。这可以避免令人头疼的问题!
需要提醒的是,除非我们确定自己在做什么,否则不建议使用 "replicate-same-server-id "参数。