适用于:

MySQL服务器版本4.1到5.6 [发行版4.1到5.6]

本文信息适用于所有平台。

目标

如何使用undropforinnodb从损坏的表中提取数据

解决方案

使用工具有时可能从无法用innodb_force_recovery读取的表中恢复数据。

Undrop工具用于不被使用或不被启用的DB服务器使用的ibdata文件。

通常,该工具从整个(多个)ibdata文件且/或独立的InnoDB tablespace文件 (innodb_file_per_table在使用中的.ibd文件)提取索引页。Blob页被提取到可应用的另外的子目录

一旦数据被提取到索引页,下一步就是从数据目录恢复主键或一般聚类索引ID,然后将数据提取到适于使用LOAD DATA INFILE的文件。

如果可以的话,以要恢复的(多个)数据库的至少一个schema dump启动,需要时使用innodb_force_recovery。即使一个过时的备份也好过什么都没有。虽然UnDROP有时能从ibdata文件中提取一个有效表定义,它不擅于处理所有列类型。如果你完全没有备份,.frm文件能被用于重建表定义。如果你没有任何备份或.frm文件,那么最后一招就是UnDROP 能从idbata提取的表定义能尝试至少恢复一些数据。

UnDROP工具如下,以它们被用于提取数据的顺序排列:

stream_parser

stream_parser是用于从ibdata提取页的工具。它的使用很简单:

./stream_parser f

页会被默认提取到”pages-”。索引页被储存在子目录

FIL_PAGE_INDEX,且blob页被储存在子目录FIL_PAGE_TYPE_BLOB。

要提取表的所有数据,有必要识别表的主键的数据目录索引ID (在没有主键时的一般索引)。这能通过使用UnDROP工具的”recover_dictionary.sh”脚本,将从被提取的索引页提取的字典数据放到在运行服务器的’test’ schema,像这样:

$ ./recover_dictionary.sh

Generating dictionary tables dumps... OK

Creating test database ... OK

Creating dictionary tables in database test:

SYS_TABLES ... OK

SYS_COLUMNS ... OK

SYS_INDEXES ... OK

SYS_FIELDS ... OK

All OK

Loading dictionary tables data:

SYS_TABLES ... 1845 recs OK

SYS_COLUMNS ... 22029 recs OK

SYS_INDEXES ... 4994 recs OK

SYS_FIELDS ... 6070 recs OK

All OK

现在字典能被查询来找出索引相对于任何给定表的索引ID。

给出的示例是对于在moodle2 schema中的表mdl2_user:

mysql> SELECT SYS_TABLES.NAME TABLE_NAME, SYS_TABLES.ID TABLE_ID,

SYS_INDEXES.NAME INDEX_NAME, SYS_INDEXES.ID INDEX_ID FROM SYS_TABLES LEFT JOIN

SYS_INDEXES ON SYS_TABLES.ID = SYS_INDEXES.TABLE_ID WHERE SYS_INDEXES.NAME LIKE '%PRIMARY%' AND SYS_TABLES.NAME LIKE 'moodle2/mdl2_user' AND SYS_INDEXES.NAME IN ('PRIMARY', 'GENERAL_CLUSTERED_INDEX');

+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐ ‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+

| TABLE_NAME | TABLE_ID | INDEX_NAME | INDEX_ID |

+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐ ‐‐‐‐‐‐+

| moodle2/mdl2_user | 646 | PRIMARY | 1867 |

+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐ +‐‐‐‐‐‐‐‐‐‐+

1 row in set (0.00 sec)

INDEX_ID返回与名称1相应的提取的页文件:

$ ls pages‐ibdata1/FIL_PAGE_INDEX/*1867.page

pages‐ibdata1/FIL_PAGE_INDEX/0000000000001867.page

c_parser

此时有了已知的表定义,数据能被c_parser恢复,像这样,其中mdl2_user.sql 包含表定义:

$ ./c_parser ‐b "./pages‐ibdata1/FIL_PAGE_TYPE_BLOB" ‐p "dumps/moodle2" ‐l

dumps/moodle/mdl2_user.load ‐5f pagesibdata1/

FIL_PAGE_INDEX/0000000000001867.page ‐t mdl2_user.sql

对每个schema使用以下脚本和在转储目录中的给定表定义,所有在数据目录找到的表能被提取到适合LOAD DATA INFILE的文件,以及分开的.load文件来加载它们。如果原始表定义不能被提供或从.frm文件被提取,反注释sys_parser行只作为最后方法。如果原始表defs能被提供,它们应该被作为分开的sql文件储存在dumps//

#!/bin/bash

RECOVERY_DB="test"

USER="root"

PASS="somepass"

DUMPS="dumps"

# Create schema

echo > ${DUMPS}/schema.sql

for DB in `mysql ‐‐user=${USER} ‐‐password=${PASS} ‐NBe "select name from

${RECOVERY_DB}.sys_tables" | sed ‐r "s/^(.*)\/.*$/\1/" | grep ‐v SYS_ | sort ‐u `

do

mkdir ‐p ${DUMPS}/${DB}

echo "Creating schema for $DB..."

echo >> ${DUMPS}/schema.sql

echo "CREATE DATABASE IF NOT EXISTS $DB;" >> ${DUMPS}/schema.sql

for TABLE in `mysql ${RECOVERY_DB} ‐‐user=${USER} ‐‐password=${PASS} ‐NBe

"SELECT NAME FROM SYS_TABLES WHERE NAME LIKE '${DB}/%'"`

do

echo $TABLE

# ./sys_parser ‐u${USER} ‐p${PASS} ‐d ${RECOVERY_DB} ${TABLE} | tee

${DUMPS}/${TABLE}.sql >> ${DUMPS}/schema.sql

PKEY=`mysql ${RECOVERY_DB} ‐BNe "SELECT SYS_INDEXES.ID FROM SYS_TABLES

LEFT JOIN SYS_INDEXES ON (SYS_TABLES.ID = SYS_INDEXES.TABLE_ID) WHERE

SYS_TABLES.NAME = \"${TABLE}\" AND SYS_INDEXES.NAME=\"PRIMARY\""`

echo "pkey = $PKEY"

PAGE="pages‐ibdata1/FIL_PAGE_INDEX/`printf '%016u' ${PKEY}`.page"

echo "PAGE = $PAGE"

./c_parser ‐b "./pages‐ibdata1/FIL_PAGE_TYPE_BLOB" ‐p "./${DUMPS}/${DB}" ‐

l ${DUMPS}/${TABLE}.load ‐5f ${PAGE} ‐t ${DUMPS}/${TABLE}.sql > ${DUMPS}/${TABLE}

done

done

sys_parser

像之前所说的,sys_parser能被用于从ibdata文件提取表定义,但它仅应当作为最后手段。可能需要一些猜测,而且如果不能提供有效的表定义,从ibdata完整提取可用数据就不太可能了。

从.frm文件提取有效表定义

使用MySQL Utilities包的mysqlfrm从未损坏的.frm文件提取有效定义是可能的。要注意的是在诊断模式下使用mysqlfrm可能遇到与使用sys_parser从ibdata提取数据相同的问题。所以使用mysqlfrm与服务器标识是很重要的。输出必须被调整来与c_parser运作,因为如果命令行,警告,或默认字符集信息在表定义中被找到,c_parser会终止。这里是提取表定义和单个schema.sql被用于从在给定目录中找到的所有.frm文件创建schema(s)的方式:

#!/bin/bash

for FRM in `find ../datadir/ ‐type f ‐wholename "*frm" | sort`

do

mysqlfrm ‐‐server=root:somepass@localhost:../datadir/mysql.sock ‐‐port=33307

$FRM | extract_schema.pl

if [ ${PIPESTATUS[0]} ‐ne 0 ]; then

echo "$FRM is corrupt"

fi

done

extract_schema.pl像这样:

!/usr/bin/perl

open (SCHEMAFILE, '>>', "schema.sql") or die "Can not write to schema.sql $!";

$schema = "";

$table = "";

while () {

$origline = $ _;

chomp;

if (/^ CREATE TABLE.*$/) {

m/.*CREATE TABLE \`(. *)\`\.\`(.*)\`[[:space:]]\(/;

$schema = $1;

$table = $2;

print "Creat ing $schema.$table\n";

unless (‐e $schema or mkdir $schem a) {

die "Unable to create dir for sche ma $schema";

}

p rint SCHEMAFILE "CREATE DATABASE IF NOT EXISTS $schema;\n";

print SCHEMAFILE "USE $schema;\n";

print SCHEMAFILE "$origline";

open (TABLEFILE, '>', "$schem a/$table.sql") or die "Can not write to

$schema/$table.sql";

print TABLEF ILE "CREATE TABLE $table (\n";

} else {

s/ENGINE=(.*?)[[:space:]].*/ENGINE=\1;/;

s/`PRIMARY`//;

s/^#.*$//;

s/^WARNING.*$//;

$origline =~ s/(.*ENGINE.*$)/\1;/;

$origline =~ s/^#.*$//;

$origline =~ s/^WARNING.*$//;

print SCHEMAFILE "$origline" if (!/^\s*$/);

print TABLEFILE "$_\n" if (!/^\s*$/);

}

}

尽管UnDROP 可用令人高兴,但遇到必须使用它的情况是非常糟糕的。当数据库损坏时,它不能保证任何数据能被恢复。避免陷入这种情况的方法就是使用MySQL Enterprise Backup来定期创建可用的备份,以及至少一个复制slave。关心数据安全的聪明管理员会在远程创建一个复制slave,将服务器的定期备份作为灾难恢复的准备。

mysql数据库innodb恢复命令_MySQL 如何对InnoDB使用Undrop来恢复InnoDB数据相关推荐

  1. mysql数据库用doc命令_MySQl数据库常用的DOS命令

    MySQl数据库常用的DOS命令.. 这是第一部分.. 数据库的连接信息: jdbc:mysql://localhost:3306/shxt com.mysql.jdbc.Driver /* jdbc ...

  2. mysql数据库没启动命令_mysql数据库服务启动和停止命令介绍(转载)

    mysql数据库启动与停止我这里给大家介绍在windows系统与linux内核的各种系统中的操作命令,希望对大家会有所帮助哦. MySQL在windows.Linux的启动.停止的方法 一.windo ...

  3. mysql数据库计算全部女生_mysql数据库基础操作大全(小白必看)

    一.概念: 数据: data 数据库: DB 数据库管理系统:DBMS 数据库系统:DBS MySQL:数据库 mysql:客户端命令(用来连接服务或发送sql指令) SQL:结构化查询语言 ,其中M ...

  4. mysql带c的命令_mysql命令整理

    一.总结一下: 1.linux下启动mysql的命令: mysqladmin start /etc/init.d/mysql start (前面为mysql的安装路径) 2.linux下重启mysql ...

  5. 查看MySQL数据库表的命令介绍

    如果需要查看MySQL数据库中都有哪些MySQL数据库表,应该如何实现呢?下面就为您介绍查看MySQL数据库表的命令,供您参考. 进入MySQL Command line client下 查看当前使用 ...

  6. mysql怎么命令查看表的数据_查看MySQL数据库表的命令介绍

    如果需要查看MySQL数据库中都有哪些MySQL数据库表,应该如何实现呢?下面就为您介绍查看MySQL数据库表的命令,供您参考. 进入MySQL Command line client下 查看当前使用 ...

  7. MySQL数据库备份的命令

    MySQL数据库备份的命令 1.备份db1数据库中所有表(包括表结构和数据,不包括创建db1数据库的语句) mysqldump -h192.168.1.10 -uroot -p db1 > xx ...

  8. MySQL数据库select查询命令大全

    MySQL数据库select查询命令大全 --数据库操作前的准备 -- 创建数据库 -- create database python_test_1 charset=utf8; -- 使用数据库 -- ...

  9. mysql数据库,当数据类型是float时,查询居然查询不出数据来

    mysql数据库,当数据类型是float时,查询居然查询不出数据来,类似如下: 以后mysql数据库不用float类型,而double类型可以查得出来. 转载于:https://www.cnblogs ...

最新文章

  1. visual studio code(vs code)如何更换颜色背景
  2. 设计模式-扩展-父类对子类的要求
  3. mingw64 下 java,如何安装MinGW-w64和MSYS2?
  4. .NET Core 的Generic Host 之Generic Host Builder
  5. 查看oracle的块大小,查看操作系统块大小
  6. 如何在Python中建立和训练K最近邻和K-Means集群ML模型
  7. 10大开源文档管理系统_开源文档的5大趋势
  8. Rasa课程、Rasa培训、Rasa面试系列之:Rasa客户案例Dialogue公司
  9. 禧龙字王 v1.0 beta 4 服务器版 是什么
  10. 中职计算机创新杯说课比赛课件,2017年全国中等职业学校“创新杯”  教师信息化教学说课大赛总结...
  11. 如何改变python的背景颜色_怎样使用python改变背景颜色
  12. 跨考计算机者艰难的2019自白
  13. 【Python实战】爬取5K分辨率超清唯美壁纸
  14. vue实现tagsview多页签导航功能
  15. 鸿蒙是什么动物,悟空是猴,八戒是猪,沙和尚是什么动物?乌巢禅师一句话说出答案...
  16. 给自己的android扫盲文 - 1
  17. 瞬时频率函数matlab,瞬时频率估计的相位建模法及Matlab的实现
  18. 使用adb的时候出现 adb不是内部或者外部命令如何解决
  19. Digital Roots
  20. 联想笔记本ubuntu系统下的背光调节

热门文章

  1. 微软开始测试自己的Google Base
  2. android p 游戏调节器,游戏调节器(Game Tuner)
  3. mysql 判断 字母大写_MySQL中查询时对字母大小写的区分
  4. python进程与线程_Python进程与线程知识
  5. 女生学计算机专业报考浙大,2021浙大适合女生的最好的专业
  6. linux下载python的地址_Linux下Python获取IP地址的代码
  7. UI图标设计素材|风格多样的图标
  8. 不可小觑汽车广告海报,设计感分分钟爆棚!
  9. 炫彩渐变流体元素PSD分层海报模板,耍酷就选它做背景!
  10. UI设计素材|正确使用浮动按钮