ppt做的模板下载网站有哪些内容,wordpress 4.5.3中,全国企业信息公示官网,大型门户网站建设定制当数据页破坏#xff0c;如何根据实例的健康状况选择不同的策略定位损坏文件并恢复。 作者#xff1a;徐文梁 爱可生 DBA 成员#xff0c;一个执着于技术的数据库工程师#xff0c;主要负责数据库日常运维工作。擅长 MySQL#xff0c;Redis 及其他常见数据库也有涉猎…当数据页破坏如何根据实例的健康状况选择不同的策略定位损坏文件并恢复。 作者徐文梁 爱可生 DBA 成员一个执着于技术的数据库工程师主要负责数据库日常运维工作。擅长 MySQLRedis 及其他常见数据库也有涉猎喜欢垂钓看书看风景结交新朋友。 本文来源原创投稿 爱可生开源社区出品原创内容未经授权不得随意使用转载请联系小编并注明来源。 问题背景
四月份的时候遇到一次实例异常 crash 的问题。当时数据库自动重启未对生产造成影响未做处理但是还是记录了下错误信息错误日志中有如下信息:
InnoDB: End of page dump
InnoDB: Page may be an index page where index id is 8196
2023-04-11T07:57:42.50837108:00 0 [ERROR] [FATAL] InnoDB: Apparent corruption of an index page [page id: space3859, page number842530] to be written to data file. We intentionally crash the server to prevent corrupt data from ending up in data files.
2023-04-11 07:57:42 0x7fe4d42cf080 InnoDB: Assertion failure in thread 140620788985984 in file ut0ut.cc line 921
InnoDB: We intentionally generate a memory trap.
因为当时自动恢复了并未重视这个问题然后六月份的时候实例又 crash 了。查看报错信息报错信息如下
2023-06-23T04:32:36.53838008:00 0 [ERROR] InnoDB: Probable data corruption on page 673268. Original record on that page;
(compact record)2023-06-23T04:32:36.53842608:00 0 [ERROR] InnoDB: Cannot find the dir slot for this record on that page;
(compact record)2023-06-23 04:32:36 0x7fe2bf68f080 InnoDB: Assertion failure in thread 140611850662016 in file page0page.cc line 153
InnoDB: We intentionally generate a memory trap.
两次的报错信息很相似出现一次是偶然两次就值得重视了。虽然之前很幸运未对生产造成影响但是如果后面哪一天异常了导致实例无法启动那不就是妥妥的一个生产故障嘛作为 DBA 要有忧患意思必须要提前准备好应对之策针对此类问题该如何排查以及解决通过查阅资料和向前辈请教也算有所收获想着如果有其他同学遇到类似问题也可作为参考于是有了此文。
问题分析
一般来说数据页损坏错误日志中都会显示具体的 page number其他情况暂不考虑。在此前提下根据实例状态可以将数据页损坏分为以下两种场景
实例能正常启动实例无法正常启动
场景不同处理方法也略有不同下面分别展开详细分析
场景一实例能正常启动
此时借助通过错误日志中的信息可以通过查询元数据表获取数据页所属信息。考虑生产环境信息安全在测试环境建立测试表进行展示。
测试环境表结构如下:
mysql use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql show create table t_user\G;
*************************** 1. row ***************************Table: t_user
Create Table: CREATE TABLE t_user (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL,age tinyint(4) DEFAULT NULL,create_time datetime DEFAULT NULL,update_time datetime DEFAULT NULL,PRIMARY KEY (id),KEY idx_name (name)
) ENGINEInnoDB AUTO_INCREMENT178120 DEFAULT CHARSETutf8
1 row in set (0.00 sec)ERROR:
No query specified
根据错误信息中提示的 page number 信息来查看数据页信息查询方式如下
mysql use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql select * from INNODB_BUFFER_PAGE where PAGE_NUMBER1156 limit 10;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| POOL_ID | BLOCK_ID | SPACE | PAGE_NUMBER | PAGE_TYPE | FLUSH_TYPE | FIX_COUNT | IS_HASHED | NEWEST_MODIFICATION | OLDEST_MODIFICATION | ACCESS_TIME | TABLE_NAME | INDEX_NAME | NUMBER_RECORDS | DATA_SIZE | COMPRESSED_SIZE | PAGE_STATE | IO_FIX | IS_OLD | FREE_PAGE_CLOCK |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | 64 | 126 | 1156 | INDEX | 0 | 0 | NO | 0 | 0 | 0 | test.t_user | idx_name | 515 | 15965 | 0 | FILE_PAGE | IO_NONE | NO | 0 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 row in set (0.18 sec) 注意查询 INNODB_BUFFER_PAGE 系统表 会对性能有影响因此不建议随意在生产环境执行。 另外如果错误日志中有提示 space id 和 index id 相关信息则也可以通过如下方式涉及 INNODB_SYS_INDEXES 和 INNODB_SYS_TABLES 系统表 进行查询
mysql select b.INDEX_ID, a.NAME as TableName, a.SPACE as Space,b.NAME as IndexName from INNODB_SYS_TABLES a,INNODB_SYS_INDEXES b where a.SPACE b.SPACE and a.SPACE126 and b.INDEX_ID225;
-----------------------------------------
| INDEX_ID | TableName | Space | IndexName |
-----------------------------------------
| 225 | test/t_user | 126 | idx_name |
-----------------------------------------
1 row in set (0.01 sec)
根据上面的查询结果确定损坏的页是属于主键还是辅助索引如果属于主键索引因为在 MySQL 中索引即数据则可能会导致数据丢失如果是辅助索引删除索引重建即可。
场景二实例无法正常启动
此时可以通过两种方式尝试拉起实例。
方法一
使用 innodb_force_recovery 参数进行强制拉起 MySQL 实例。
正常情况下可以 innodb_force_force_recovery 值应该设置为 0。当紧急情况下实例无法正常启动时可以尝试将其设置为 0 的值强制拉起实例然后将数据逻辑备份导出进行恢复。innodb_force_recovery 值最高支持设置到 6但是值为 4 或更大可能会永久损坏数据文件。因此当强制 InnoDB 恢复时应始终以 innodb_force_recovery1 开头并仅在必要时递增该值。
方法二
使用 inno_space 工具进行数据文件进行修复。 inno_space 是一个可以直接访问 InnoDB 内部文件的命令行工具可以通过该工具查看 MySQL 数据文件的具体结构修复 corrupt page。更多参考 如果 InnoDB 表文件中的 page 损坏导致实例无法启动可以尝试通过该工具进行修复如果损坏的只是 leaf pageinno_space 可以将 corrupt page 跳过从而保证实例能够启动并且将绝大部分的数据找回。示例
# 假设 MySQL 错误日志中有类似报错如下
[ERROR] [MY-030043] [InnoDB] InnoDB: Corrupt page resides in file: .test/t_user.ibd, offset: 163840, len: 16384
[ERROR] [MY-011906] [InnoDB] Database page corruption on disk or a failed file read of page [page id: space126, page number1158]. You may have to recover from a backup.# 通过如下方式进行修复
# 删除损坏的数据页中损坏部分。
./inno -f /opt/mysql/data/3307/test/t_user.ibd -d 10# 更新损坏的数据页中 checksum 值。
./inno -f /opt/mysql/data/3307/test/t_user.ibd -u 10启动 MySQL 服务。
问题总结
经过前面分析了解数据页损坏场景的处理方式。哪怕极端场景下也可以做到从容不慌尽可能少丢数据甚至能够不丢数据。但是如果是生产环境尤其是金融行业是无法容忍丢失一条数据的比较有可能这一条数据就涉及几个小目标呢因此重要的事情说三遍一定要备份一定要备份一定要备份
更多技术文章请访问https://opensource.actionsky.com/
关于 SQLE
爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者支持多场景审核支持标准化上线流程原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。
SQLE 获取
类型地址版本库https://github.com/actiontech/sqle文档https://actiontech.github.io/sqle-docs/发布信息https://github.com/actiontech/sqle/releases数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse