这个错误是 InnoDB 存储引擎的内部断言失败,通常与 InnoDB 数据页的一致性问题相关。下面是具体分析和解决思路:

错误含义

btr0pcur.cc 是 InnoDB 引擎中负责 B-tree 游标操作 的源代码文件,断言 page_is_comp(next_page) == page_is_comp(page) 的含义是:
下一个数据页(next_page)的压缩状态必须与当前数据页(page)的压缩状态一致(要么都压缩,要么都不压缩)。

当这个断言失败时,说明 InnoDB 在遍历 B-tree 页面时,发现相邻页面的压缩状态不匹配,违反了 InnoDB 内部的数据结构一致性规则。

可能的原因

  1. 数据文件损坏
    最常见的原因是 InnoDB 数据文件(.ibd 或共享表空间 ibdata1)损坏,可能由以下情况导致:

    • 意外断电、服务器崩溃导致的未完成写操作;
    • 磁盘错误(坏道)或文件系统损坏;
    • 第三方工具(如备份软件)误操作修改了数据文件。
  2. InnoDB 引擎 Bug
    特定版本的 MySQL/MariaDB 中,InnoDB 处理压缩表(ROW_FORMAT=COMPRESSED)时可能存在逻辑缺陷,导致页面状态不一致。

  3. 硬件问题
    内存损坏(导致数据在内存中被篡改)或磁盘控制器故障,可能导致写入的数据页状态异常。

解决步骤

设置 innodb_force_recovery

innodb_force_recovery是MySQL中InnoDB存储引擎的一个重要参数,用于在数据库出现损坏等特殊情况下强制启动InnoDB存储引擎,以便尽可能地恢复数据。以下是关于它的详细介绍:

  • 参数概述innodb_force_recovery的默认值为0,表示正常启动InnoDB,不进行强制恢复。该参数的取值范围是1到6,取值越大,恢复的力度越强,但风险也越高,只有在紧急情况下才应将其设置为大于0的值。
  • 各取值的作用
    • 1(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的损坏页,让服务器可以继续运行,尝试使SELECT * FROM语句跳过损坏的索引记录和页面,有助于导出表数据。
    • 2(SRV_FORCE_NO_BACKGROUND):阻止主线程和任何清理线程运行,防止因清理操作(如full purge操作)导致的崩溃。
    • 3(SRV_FORCE_NO_TRX_UNDO):在崩溃恢复后不执行事务回滚操作,可避免因长时间回滚大表而带来的问题。
    • 4(SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作,也不计算表统计信息,可能会永久损坏数据文件,使用后需要删除并重新创建所有二级索引。
    • 5(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB会将未提交的事务视为已提交,此操作可能会永久损坏数据文件,并将InnoDB设置为只读模式。
    • 6(SRV_FORCE_NO_LOG_REDO):不执行前滚操作,会使数据库页面处于过时状态,可能会对B树和其他数据库结构造成更多破坏,同样会将InnoDB设置为只读模式。
  • 使用方法:首先要确保对数据库进行了备份,然后编辑MySQL的配置文件(通常是my.cnfmy.ini),在[mysqld]部分添加innodb_force_recovery = X``(X为1到6之间的某个值),保存配置文件后重启MySQL服务,使配置生效。数据恢复完成后,应将该参数的值重置为0,并再次重启MySQL服务。
  • 注意事项:设置innodb_force_recovery为4或更大的值时要格外小心,因为这可能会导致数据文件永久损坏。在生产环境中使用该设置之前,应先在数据库的单独物理副本上进行测试。当强制InnoDB恢复时,应始终从innodb_force_recovery = 1开始,必要时再逐步增加其值。
全备+binlog 恢复
通过 frm 和 ibd 文件尽可能恢复数据和表结构
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐