AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 24350
Accepted
dabest1
dabest1
Asked: 2012-09-15 11:50:16 +0800 CST2012-09-15 11:50:16 +0800 CST 2012-09-15 11:50:16 +0800 CST

寻找一种有效的方法来修复“无法解析中继日志事件条目...”错误

  • 772

我在 MySQL 5.0 中有一个损坏的中继日志,正在寻找修复复制的步骤,而不必再次重新处理来自主服务器的所有二进制日志。

如果您好奇,这里是完整的错误消息:
无法解析中继日志事件条目。可能的原因是:主服务器的二进制日志已损坏(您可以通过在二进制日志上运行“mysqlbinlog”来检查),从服务器的中继日志已损坏(您可以通过在中继日志上运行“mysqlbinlog”来检查),a网络问题,或者主从的 MySQL 代码中的错误。如果你想检查主服务器的二进制日志或从服务器的中继日志,你可以通过在这个从服务器上发出“SHOW SLAVE STATUS”来知道它们的名字。

正常的修复非常简单,您只需从 show slave status 中获取正确的二进制日志名称和位置,然后运行 ​​change master 命令。但这不是我想做的。

我想只重新处理来自主服务器的一个或几个二进制日志以恢复损坏的中继日志,然后继续使用已经创建的中继日志。我正在寻找过去有这样做经验的人,因为以这种方式进行恢复可能会失败。

从概念上讲,我认为可能需要以下步骤(也许其中一些是可选的):

  1. 停止从服务器上的复制。
  2. 关闭从属实例。
  3. 将中继日志移至安全位置。
  4. 查看是否需要手动更新 relay-log.info 或 master.info 文件。
  5. 启动从属实例。
  6. 运行 change master 命令并从失败的位置重新处理二进制日志。
  7. 等到创建下一个中继日志。
  8. 停止从服务器上的复制。
  9. 关闭从属实例。
  10. 弄清楚如何用安全位置的中继日志文件替换第二个中继日志文件并将它们移入。
  11. 查看是否需要手动更新 relay-log.info 或 master.info 文件。
  12. 启动从属实例。
  13. 希望最好的。

我正在考虑另一种方法来做到这一点,这似乎更简单:

  1. 停止从服务器上的复制。
  2. 关闭从属实例。
  3. 将中继日志移至安全位置。
  4. 启动从属实例。
  5. 运行 change master 命令并从失败的位置重新处理二进制日志。
  6. 等到创建下一个中继日志。
  7. 停止从服务器上的复制。
  8. 使用 mysqlbinlog 通过管道到 mysql 客户端来处理位于安全位置的中继日志。确定从哪个文件和位置开始。(潜在的问题,除非在第一个错误时中止处理)。
  9. 在读取的主日志文件/位置设置从属从主复制。
mysql replication
  • 2 2 个回答
  • 3755 Views

2 个回答

  • Voted
  1. RolandoMySQLDBA
    2012-09-15T12:18:19+08:002012-09-15T12:18:19+08:00

    您可以尝试更稳定的方法

    这是要记住的事情

    每当您运行CHANGE MASTER TO时,它都会清除您拥有的所有中继日志。您不想保留尚未执行任何 SQL 的命令的中继日志

    以下是我在 2012 年 2 月 3 日发表的一篇文章的摘录:如何通过主从复制解决 mysql 中的主服务器关闭/不可用问题:

    请注意,Master 有两组复制坐标

    • (Master_Log_File,Read_Master_Log_Pos)
    • (Relay_Master_Log_File,Exec_Master_Log_Pos)

    它们之间有很大的区别

    • (Master_Log_File,Read_Master_Log_Pos)告诉您从 Master 的日志文件中的最后一个 binlog 语句以及 Slave 从 Master 读取并放置在其 Relay Logs 中的日志位置。
    • (Relay_Master_Log_File,Exec_Master_Log_Pos)告诉您从 Master 的日志文件中的最后一个 binlog 语句以及 Slave 从 Master 读取并放置在其 Relay Logs 中的最后一个 binlog 语句THAT IS NEXT TO BE EXECUTED ON THE SLAVE。

    你想要的是两件事:

    1. 擦除您拥有的所有二进制日志
    2. 开始从您成功执行的最后一个 SQL 收集二进制日志条目。

    在您的情况下,您必须使用第二组复制坐标

    • Relay_Master_Log_File
    • Exec_Master_Log_Pos

    如错误消息所示,很容易不信任损坏的中继日志。最痛苦的是损坏的主日志。如果是这样的话,你将不得不跳过篮球。另一方面,如果其他情况之一是中继日志损坏的原因,那么最简单和最简洁的方法就是我所说的。

    为了确保无论报告什么Relay_Master_Log_File,如果该特定二进制日志仍然存在于 Master 上,请对其执行 mysqlbinlog。如果它完全转储而没有损坏字符,请继续使用第二组复制坐标。

    从我之前的同一篇文章中

    mysql> show slave status\G
    *************************** 1. row ***************************
                 Slave_IO_State: Waiting for master to send event
                    Master_Host: 10.48.20.253
                    Master_User: replicant
                    Master_Port: 3306
                  Connect_Retry: 60
                Master_Log_File: mysql-bin.000254
            Read_Master_Log_Pos: 858190247
                 Relay_Log_File: relay-bin.066069
                  Relay_Log_Pos: 873918
          Relay_Master_Log_File: mysql-bin.000254
               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: 858190247
                Relay_Log_Space: 873772
                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
    1 row in set (0.00 sec)
    

    请注意,SHOW SLAVE STATUS\G上次执行的复制坐标是(mysql-bin.000254,858190247). 在这种情况下,CHANGE MASTER TO命令将是:

    CHANGE MASTER TO master_log_file='mysql-bin.000254',master_log_pos=858190247;
    

    试试看 !!!

    更新 2012-09-14 16:38 EDT

    如果您担心存储中继日志,只需限制中继日志。在SHOW SLAVE STATUS\G中,有一个字段叫做Relay_Log_Space。这为您提供了所有中继大小的总和(以字节为单位)。你知道你可以限制这个数字吗?

    该选项称为relay_log_space_limit。

    例如,如果要将总字节数限制为 10G,请执行以下操作

    步骤 01) 将此添加到从站上的 /etc/my.cnf

    [mysqld]
    relay_log_space_limit = 10G
    

    STEP 02)service mysql restart在从机上运行

    就是这样!

    当最旧的中继处理完所有条目后,将删除它并创建新的中继日志。在所有中继日志加起来达到 10G 之前,它会被填满。这是控制失控的中继日志空间问题的唯一方法。

    更新 2012-09-14 18:10 EDT

    建议:如果您在每个午夜对从站上的数据进行 mysqldump 备份,您可以设置以下内容来限制拥有 1TB 的二进制日志:

    步骤 01) 将此添加到主服务器上的 /etc/my.cnf

    [mysqld]
    expire_logs_days = 14
    

    步骤 02) 在主服务器上运行此查询

    mysql> PURGE BINARY LOGS BEFORE DATE(NOW()) - INTERVAL 14 DAY;
    

    STEP 03)service mysql restart在Master上

    STEP 04) 将 mysqldump 备份脚本添加到 Slave 上的 crontab

    这将使 Slave 更有用,并且可以控制多余的二进制日志来担心

    • 6
  2. Best Answer
    dabest1
    2012-09-27T17:16:39+08:002012-09-27T17:16:39+08:00

    为了解决 master 上二进制日志的磁盘空间不足问题,我将二进制日志移动到另一个磁盘挂载,然后创建指向它们的符号链接,以便 master 知道在哪里可以找到它们。可以使用“ln -s”或“cp -s”创建符号链接。
    例子:

    cd /disk1/mysql/binlogs/
    ls /disk2/binlogs | xargs -l1 -i cp -s /disk2/binlogs/{} ./
    

    在slave上,为了防止网络资源的浪费,我使用了Rolando建议的设置——relay_log_space_limit。这派上用场了,因为在从服务器最终赶上主服务器上的大量事务之前,中继日志多次损坏。

    我使用了一种不同的方法来解决问题,然后我最初进行了探索。我正在探索的解决方案似乎很复杂,并且存在丢失数据的风险。虽然,后来我确实发现使用 CHANGE MASTER 命令读取服务器自己的中继或二进制日志支持我试图实现的一些步骤。但这只是拼图的一部分。由于 MySQL 5.5 具有复制校验和和其他功能,如果我升级到 5.5,也许我不需要弄清楚这一点。

    http://dev.mysql.com/doc/refman/5.0/en/change-master-to.html上的 MySQL 手册说:

    下一个示例显示了一个不太常用的操作。当从属具有由于某种原因您希望它再次执行的中继日志文件时使用它。为此,不需要可访问主节点。您只需要使用 CHANGE MASTER TO 并启动 SQL 线程 (START SLAVE SQL_THREAD):

    将 MASTER 更改为 RELAY_LOG_FILE='slave-relay-bin.006',
    RELAY_LOG_POS=4025;

    您甚至可以在具有独立、非从属服务器的非复制设置中使用第二个操作,以便在崩溃后进行恢复。假设您的服务器已崩溃并且您已从备份中恢复它。您想要重放服务器自己的二进制日志文件(不是中继日志文件,而是常规二进制日志文件),名为(例如)myhost-bin.*。首先,在某个安全的地方制作这些二进制日志文件的备份副本,以防您没有完全按照下面的步骤操作,不小心让服务器清除了二进制日志。使用 SET GLOBAL relay_log_purge=0 以获得额外的安全性。然后不带 --log-bin 选项启动服务器,而是使用 --replicate-same-server-id, --relay-log=myhost-bin (让服务器相信这些常规二进制日志文件是中继日志文件)和 --skip-slave-start 选项。

    将 MASTER 更改为 RELAY_LOG_FILE='myhost-bin.153',
    RELAY_LOG_POS=410,MASTER_HOST='some_dummy_string';开始从 SQL_THREAD;

    服务器读取并执行自己的二进制日志文件,从而实现崩溃恢复。恢复完成后,运行 STOP SLAVE,关闭服务器,删除 master.info 和 relay-log.info 文件,然后使用其原始选项重新启动服务器。

    需要指定 MASTER_HOST 选项(即使使用虚拟值)以使服务器认为它是从站。

    以下方法理论上应该有效,主要问题是正确地确定从新创建的中继日志的哪个位置停止处理以及从保存的中继日志的哪个位置开始处理。另一个问题是如果有更多损坏的中继日志,则从主服务器识别要使用的日志/位置。

    1. 停止从服务器上的复制。
    2. 记录 Master_Log_File / Read_Master_Log_Pos。
    3. 关闭从属实例。
    4. 将中继日志移至安全位置。
    5. 启动从属实例。
    6. 运行 change master 命令并从失败的位置重新处理二进制日志。
    7. 等到创建下一个或几个中继日志。
    8. 停止从服务器上的复制。
    9. 使用 CHANGE MASTER 命令处理位于安全位置的中继日志。确定从哪个文件和位置开始。
    10. 在步骤 2 中记录的读取主日志文件/位置设置从属从主复制。
    • 0

相关问题

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve