首页 > 编程知识 正文

mysql被删库如何恢复,数据库表误删除恢复

时间:2023-05-05 11:40:11 阅读:143014 作者:3906

全部展开

在任何DBA上,是否删除过e 68 a 84 E8 a 2ad 62616964757 a 686964616 f 313343626437日历库? 删除库没有备份吗? 在备份恢复后无法启动服务的情况是什么? 如果无法读取表定义损坏数据该怎么办?

我遇到过一家第一家互联网企业。 由于维护人员不规范的备份恢复操作,系统表空间中的文件被初始化,数万张表无法读取,需要几个小时进行救治。

如果可靠的虾发现无法读取数据,可能不是数据丢失,而是DBMS找不到描述数据的信息。

背景

首先,我们看一下包含部分表定义信息的重要InnoDB数据字典表。 恢复表结构时需要这些。

SYS_TABLES是InnoDB表信息create table ` sys _ tables ` (name ` varchar ) 255 ) NOT NULL DEFAULT )、表名) id`bigint ) 20 int(10 ) DEFAULT NULL,` type`int ) 10 ) unsigned DEFAULT NULL,` mix_id ' bigint ) 20 ) unsigneddefaull,mix _ id ) bbid ` cluster _ name ` varchar ' 255 ) DEFAULT NULL, ` space ` int ' 10 ) unsigner SYS_INDEXES是InnoDB索引信息create table ` sys _ indexes ` (table _ id ` bigint (20 ) unsigned not nut bigint(20 ) unsigned NOT NULL DEFAULT '0),索引id ` name ' varchar ) 120 ) DEFAULT NULL,索引名称` n_fing )。 索引中包含的字段数` type`int(10 ) unsigned DEFAULT NULL,` space`int ) 10 ) unsigned DEFAULT NULL, 要存储索引的表空间id`page_no`int ) 10 ) uno ) unt索引的根页面id主密钥(` table _ id `,` id ` ) engine=innodbdefaultched SYS_COLUMNS描述InnoDB表的字段信息create table ` sys _ columns ` (table _ id ` bigint (20 ) unsigned NOT NULL,sys_tables 字段相对位置` name`varchar(255 ) DEFAULT NULL,字段名` mtype`int ) 10 ) unsigned DEFAULT NULL,字段代码` prtype`int ) 10 字段代码` pr type ` int ' 10 ) unsig字段检查类型` len`int(10 ) unsigned DEFAULT NULL,字段字节长度` prec`int ) 10 ) unsig ` table`id,` SYS_FIELDS是所有索引的字段列create table ` sys _ fields ` (index _ id ` bigint ) 20 ) unsigned NOT NULL, ` pos`int ) 10 ) unsigned )的` col_name`varchar(255 ) DEFAULT NULL,primarykey ) index_id `, POS ` ) engine=innodbdefaultcharset=Latin ng./storage/inno base/include/dict0boot.h文件定义每个词典表的索引id,id

这里需要使用undrop-for-innodb工具恢复数据。 undrop-for-innodb工具读取表空间信息以获取page,然后从page中提取数据。

# wget https://github.com/chab haiya/un drop-for-innodb/archive/master.zip # yum install-ygccflexbison # make # make #

# ./sys_parser读取表结构信息

p>

sys_parser [-h] [-u] [-p] [-d] databases/table

stream_parser 读取 InnoDB page 从 ibdata1 或 ibd 或分区表

# ./stream_parserYou must specify file with -f optionUsage: ./stream_parser -f [-T N:M] [-s size] [-t size] [-V|-g]  Where:    -h         - Print this help    -V or -g   - Print debug information    -s size    - Amount of memory used for disk cache (allowed examples 1G 10M). Default 100M    -T         - retrieves only pages with index id = NM (N - high word, M - low word of id)    -t size    - Size of InnoDB tablespace to scan. Use it only if the parser can't determine it by himself.

c_parser 从 innodb page 中读取记录保存到文件

# ./c_parserError: Usage: ./c_parser -4|-5|-6 [-dDV] -f -t table.sql [-T N:M] [-b ]  Where    -f -- InnoDB page or directory with pages(all pages should have same index_id)    -t -- CREATE statement of a table    -o -- Save dump in this file. Otherwise print to stdout    -l -- Save SQL statements in this file. Otherwise print to stderr    -h  -- Print this help    -d  -- Process only those pages which potentially could have deleted records (default = NO)    -D  -- Recover deleted rows only (default = NO)    -U  -- Recover UNdeleted rows only (default = YES)    -V  -- Verbose mode (lots of debug information)    -4  -- innodb_datafile is in REDUNDANT format    -5  -- innodb_datafile is in COMPACT format    -6  -- innodb_datafile is in MySQL 5.6 format    -T  -- retrieves only pages with index id = NM (N - high word, M - low word of id)    -b

接下来,我们演示场景的几种数据恢复场景。

场景1:drop table

是否启用了 innodb_file_per_table 其恢复方法有所差异,当发生误删表时,应尽快停止MySQL服务,不要启动。若 innodb_file_per_table=ON,最好只读方式重新挂载文件系统,防止其他进程写入数据覆盖之前块设备的数据。

如果评估记录是否被覆盖,可以表中某些记录的作为关键字看是否能从 ibdata1 中筛选出。

# grep WOODYHOFFMAN ibdata1

Binary file ibdata1 matches

也可以使用 bvi(适用于较小文件)或 hexdump -C(适用于较大文件)工具

以表 sakila.actor 为例CREATE TABLE `actor` (`actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,`first_name` varchar(45) NOT NULL,`last_name` varchar(45) NOT NULL,`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`actor_id`),KEY `idx_actor_last_name` (`last_name`)) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8

首先恢复表结构信息1. 解析系统表空间获取 page 信息

./stream_parser -f /var/lib/mysql/ibdata1

2. 新建一个 schema,把系统字典表的 DDL 导入

cat dictionary/SYS_* | mysql recovered

3. 创建恢复目录

mkdir -p dumps/default

4. 解析系统表空间包含的字典表信息,

./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql > dumps/default/SYS_TABLES 2> dumps/default/SYS_TABLES.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000002.page -t dictionary/SYS_COLUMNS.sql > dumps/default/SYS_COLUMNS 2> dumps/default/SYS_COLUMNS.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql > dumps/default/SYS_INDEXES 2> dumps/default/SYS_INDEXES.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000004.page -t dictionary/SYS_FIELDS.sql > dumps/default/SYS_FIELDS 2> dumps/default/SYS_FIELDS.sql

5. 导入恢复的数据字典

cat dumps/default/*.sql | mysql recovered

6. 读取恢复后的表结构信息

./sys_parser -pmsandbox -d recovered sakila/actor

由于 5.x 版本 innodb 引擎并非完整记录表结构信息,会丢失 AUTO_INCREMENT 属性、二级索引和外键约束, DECIMAL 精度等信息。

若是 mysql 5.5 版本 frm 文件被从系统删除,在原目录下 touch 与原表名相同的 frm 文件,还能读取表结构信息和数据。若只有 frm 文件,想要获得表结构信息,可使用 mysqlfrm --diagnostic /path/to/xxx.frm,连接 mysql 会显示字符集信息。

innodb_file_per_table=OFF

因为是共享表空间模式,数据页都存储在 ibdata1,可以从 ibdata1 文件中提取数据。

1. 获取表的 table id,sys_table 存有表的 table id,sys_table 表 index id 是1,所以从0000000000000001.page 获取表 id./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor000000000B28  2A000001430D4D  SYS_TABLES  "sakila/actor"  158  4  1 0   0   ""  0000000000B28  2A000001430D4D  SYS_TABLES  "sakila/actor"  158  4  1 0   0   ""  0

2. 利用 table id 获取表的主键 id,sys_indexes 存有表索引信息,innodb 索引组织表,找到主键 id 即找到数据,sys_indexes 的 index id 是3,所以从0000000000000003.page 获取主键 id

./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158000000000B28    2A000001430BCA  SYS_INDEXES     158     376     "PRIMARY"       1       3       0       4294967295000000000B28    2A000001430C3C  SYS_INDEXES     158     377     "idx_actor_last_name"        1       0       0       4294967295000000000B28    2A000001430BCA  SYS_INDEXES     158     376     "PRIMARY"       1       3       0       4294967295000000000B28    2A000001430C3C  SYS_INDEXES     158     377     "idx_actor_last_name"        1       0       0       4294967295

3. 知道了主键 id,就可以从对应 page 中提取表数据,并生成 sql 文件。

./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t sakila/actor.sql > dumps/default/actor 2> dumps/default/actor_load.sql

4. 最后导入恢复的数据

cat dumps/default/*.sql | mysql sakila

更多详细情况点击

网页链接网页链接

请点击输入图片描述

请点击输入图片描述

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。