展开全部

自动备份,另一种方法请看

每个 DBA 是不是都有过删库的经历?删库了没有备份怎么办?备份恢复后无法启动服务什32313133353236313431303231363533e78988e69d8331333433626437么情况?表定义损坏数据无法读取怎么办?

我曾遇到某初创互联网企业,因维护人员不规范的备份恢复操作,导致系统表空间文件被初始化,上万张表无法读取,花了数小时才抢救回来。

当你发现数据无法读取时,也许并非数据丢失了,可能是 DBMS 找不到描述数据的信息。

背景

先来了解下几张关键的 InnoDB 数据字典表,它们保存了部分表定义信息,在我们恢复表结构时需要用到。

SYS_TABLES 描述 InnoDB 表信息CREATE TABLE `SYS_TABLES` (`NAME` varchar(255) NOT NULL DEFAULT '',  表名`ID` bigint(20) unsigned NOT NULL DEFAULT '0',  表id`N_COLS` int(10) DEFAULT NULL,`TYPE` int(10) unsigned DEFAULT NULL,`MIX_ID` bigint(20) unsigned DEFAULT NULL,`MIX_LEN` int(10) unsigned DEFAULT NULL,`CLUSTER_NAME` varchar(255) DEFAULT NULL,`SPACE` int(10) unsigned DEFAULT NULL,   表空间idPRIMARY KEY (`NAME`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_INDEXES 描述 InnoDB 索引信息CREATE TABLE `SYS_INDEXES` (  `TABLE_ID` bigint(20) unsigned NOT NULL DEFAULT '0', 与sys_tables的id对应  `ID` bigint(20) unsigned NOT NULL DEFAULT '0',  索引id  `NAME` varchar(120) DEFAULT NULL,         索引名称  `N_FIELDS` int(10) unsigned DEFAULT NULL, 索引包含字段的个数  `TYPE` int(10) unsigned DEFAULT NULL,  `SPACE` int(10) unsigned DEFAULT NULL,  存储索引的表空间id  `PAGE_NO` int(10) unsigned DEFAULT NULL,  索引的root page id  PRIMARY KEY (`TABLE_ID`,`ID`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_COLUMNS 描述 InnoDB 表的字段信息CREATE TABLE `SYS_COLUMNS` (  `TABLE_ID` bigint(20) unsigned NOT NULL, 与sys_tables的id对应  `POS` int(10) unsigned NOT NULL,     字段相对位置  `NAME` varchar(255) DEFAULT NULL,    字段名称  `MTYPE` int(10) unsigned DEFAULT NULL,  字段编码  `PRTYPE` int(10) unsigned DEFAULT NULL, 字段校验类型  `LEN` int(10) unsigned DEFAULT NULL,  字段字节长度  `PREC` int(10) unsigned DEFAULT NULL, 字段精度  PRIMARY KEY (`TABLE_ID`,`POS`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_FIELDS 描述全部索引的字段列CREATE TABLE `SYS_FIELDS` (  `INDEX_ID` bigint(20) unsigned NOT NULL,  `POS` int(10) unsigned NOT NULL,  `COL_NAME` varchar(255) DEFAULT NULL,  PRIMARY KEY (`INDEX_ID`,`POS`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;./storage/innobase/include/dict0boot.h 文件定义了每个字典表的 index id,对应 id 的 page 中存储着字典表的数据。

这里我们需要借助 undrop-for-innodb 工具恢复数据,它能读取表空间信息得到 page,将数据从 page 中提取出来。

# wget https://github.com/chhabhaiya/undrop-for-innodb/archive/master.zip# yum install -y gcc flex bison# make# make sys_parser

# ./sys_parser 读取表结构信息

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

更多详细情况点击网页链接

请点击输入图片描述

mysql数控不小心被删_mysql 数据库信息不小心被删除了, 请问能恢复么相关推荐

  1. mysql全表重命名备份_Mysql数据库和表的常用操作以及数据备份恢复

    数据库 查看所有数据库 show databases; 使用数据库 use 数据库名; 查看当前使用的数据库 select database(); 创建数据库 create database 数据库名 ...

  2. mysql r和n的区别_mysql数据库 r n

    mysql集群的备份与还原 应用场景 当使用mysql集群数据库的时候,有时候会误删一些数据,那么数据就缺失了完整性,现在需要将数据进行备份,将误删的数据还原出来,这样保证数据的完整性. 操作步骤 注 ...

  3. mysql四列数据表代码_MySQL数据库常用代码

    MySQL数据库常用代码启动数据库服务:[ net Start MySQL ] 使用命令登录:[ Mysql -h localhost -u root -p] 关闭数据库服务: [net stop m ...

  4. mysql 修改库的校对集_mysql数据库的基本操作(增删改查、字符集、校对集)

    MySQL数据库概述 MySQL数据库是经典的关系型数据库管理系统,MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Dat ...

  5. mysql的网址是什么意思_Mysql数据库地址是什么怎么填写

    Mysql数据库地址:C:\ProgramData\MySQL\MySQL Server 5.5\data. 具体情况: 一.Mysql数据使用MyISAM存储引擎,数据库文件类型就包括.frm..M ...

  6. mysql从一台电脑迁移_mysql数据库迁移到另一台电脑上

    解决办法 mysql要转换到另一台机器上面,最重要的要考虑以下几个问题 1.数据库使用什么存储引擎,如果是myisam的话,可以把data目录复制移走.但如果是innodb的话,千万不要用这种方法,会 ...

  7. mysql怎么加载bak文件_MySQL数据库(表)的导入导出(备份和还原)

    一)在同一个数据库服务器上面进行数据表间的数据导入导出: 1. 如果表tb1和tb2的结构是完全一样的,则使用以下的命令就可以将表tb1中的数据导入到表tb2中: insert into db2.tb ...

  8. mysql数据库不小心删除文件_mysql数据库被删除了,怎么恢復吗

    MySQL 5.1以后版本中有 Event ,这是类似Oracle中的job 可以通过创建Event,然后在里面调用删除过期记录的存储过程即可实现 定时每天备份mysql并定时删除上月记录(脚本) o ...

  9. mysql将查到的数据删除_MySQL数据库的基本操作——增、删、改、查

    一.数据库查询SELECT SELECT语句查询数据表中的一列或多列数据.使用集合函数显示查询结果.连接查询.子查询以及使用正则表达式查询等. SELECT语句的基本格式是: SELECT id,na ...

最新文章

  1. python urllib.request 爬虫 数据处理-python爬虫1--urllib请求库之request模块
  2. 个人信息安全 不能止于“打补丁”
  3. dedecms arclist中截取字符串的方法
  4. AI:2020年6月24日北京智源大会演讲分享之机器学习前沿青年科学家专题论坛——10:40-11:10金驰《Near-Optimal Reinforcement Learning with Sel》
  5. android 自定义 进度条 旋转,Android_Android ProgressBar进度条使用详解,ProgressBar进度条,分为旋转进 - phpStudy...
  6. SAP OData $batch processing
  7. Qt简单实现UDP通信
  8. 免费OFD在线阅读器,可以二次开发
  9. 手机点餐APP开发需求分析
  10. 计算机课件制作总结,课件制作比赛活动总结范文
  11. magicbookpro做php开发,荣耀MagicBook Pro测评:全面屏专业生产力工具
  12. 10分钟教你搭建一个好玩的Python全文搜索引擎
  13. 网页外链微信公众号文章里的图片显示未经许可无法显示的解决办法
  14. Keil(C51)安装与注册
  15. 9-《电子入门趣谈》第一章_一切从单片机开始-1.3.6串口通信
  16. 桁架机器人立柱_麻城大型桁架式机械手,桁架式机器人结构
  17. 本人机械专业研究生,研一暑假开始正式接触深度学习相关内容,想通过写文章记录以及分享下学习的历程,让大家可以避免坑以及记录下自己成长的过程。今天是第一天,安装opencv包出现的问题。
  18. wav C语言音频切割器 非常详细、400行代码搞定!!
  19. pycharm运行虚拟环境Django项目报错
  20. 标称电阻值(转) 常用的5%和1%精度电阻的标称值

热门文章

  1. 在Android上将ONNX神经网络模型与TensorFlow Lite结合使用
  2. 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用ApplicationPart动态加载控制器和视图
  3. linux编译c 自动化,Linux江湖06:感悟GNU C以及将Vim打造成C/C++的半自动化IDE
  4. java数组移除对象_如何从Java数组中删除对象?
  5. c语言函数man,Linux下C语言编程有困难找man
  6. long 雪花算法_雪花算法(snowflake)
  7. 列注释_技术贴 | 宏基因组分箱 (Binning)第四课——COG EC RNA注释统计
  8. expandablelistview 折叠动画_这个机械手到底有几个自由度,31个机械原理、设计动画来了。。。...
  9. char* 去除后面几个字符_【算法打卡】去除重复字母
  10. 使用vue-cli初始化项目时运行‘npm run dev’报错