前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Shell恢复MySQL .frm和.ibd文件

使用Shell恢复MySQL .frm和.ibd文件

作者头像
jeanron100
发布2019-03-14 15:36:58
2.6K0
发布2019-03-14 15:36:58
举报

这是学习笔记的第 1901篇文章

MySQL里面对于表的默认的配置是每个表都有独立的文件.ibd和.frm文件对应,对于数据恢复来说,会提供很大的便利。

其中.frm文件存储了表结构定义信息,而.ibd文件存储了真正的数据。如果某种特殊情况下,你只有.frm文件和.ibd文件,能不能单独恢复出来数据呢,答案是肯定的,当然这个过程不是一个命令搞定,而是需要一些方法和技巧。

比如.frm文件,我们拿到这个二进制文件的时候,其实我们也不知道里面到底有多少字段,怎么把DDL结构解析出来呢,这是第一个问题,而这个问题解决了之后,后续的问题其实就迎刃而解,我们可以完全使用迁移表空间的方式来处理。

所以在恢复.frm和.ibd文件的时候,难点在于如何解析得到建表的DDL语句。

在这里我们要做个小把戏,需要预创建一个同名的表,然后通过交换frm文件来变相得到DDL语句。这个脚本为了支撑后续的灵活性,我是单独创建了一个数据库test_recover,可以作为你的一个专用恢复数据库,可以在上面做大量的恢复测试,来充分验证方案的可行性。

所以对于test_recover我们可以默认设置一些基本的配置。

解析得到DDL的脚本get_tab_ddl.sh如下:

代码语言:javascript
复制
SOURCE_DUMP_PATH='/tmp'
RECOVER_TABLE_NAME='userscore_255'
MYSQL_DATA_DIR=/data/mysql_5727/data
MYSQL_LOG_DIR=/data/mysql_5727/log/mysql.err
MYSQL_CONN_STR="/usr/local/mysql/bin/mysql --socket=/data/mysql_5727/tmp/mysql.sock --port=5727 -Ne"
MYSQL_RECOVER_DB=test_recover
MYSQL_CON_FILE=/data/mysql_5727/my.cnf
SHUTDOWN_MYSQL="mysqladmin shutdown --socket=/data/mysql_5727/tmp/mysql.sock --port=5727"
STARTUP_MYSQL="/bin/sh /usr/local/Percona-Server-5.7.16-10-Linux.x86_64.ssl101/bin/mysqld_safe --defaults-file=/data/mysql_5727/my.cnf "

ls -l ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}

${MYSQL_CONN_STR}  "select now()"
${MYSQL_CONN_STR}  "create database if not exists  ${MYSQL_RECOVER_DB} ; use ${MYSQL_RECOVER_DB};create table if not exists ${RECOVER_TABLE_NAME}(id int);"

ls -l ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}

rm -f ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm  ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.ibd
#mv ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm  ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm.bak
#mv ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.ibd  ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.ibd.bak

/bin/cp ${SOURCE_DUMP_PATH}/${RECOVER_TABLE_NAME}.frm ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm 

chown -R mysql:mysql ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm

${MYSQL_CONN_STR}  " flush tables;use ${MYSQL_RECOVER_DB};show create table ${RECOVER_TABLE_NAME}\G"

COLUMN_NUM=`tail -5000 $MYSQL_LOG_DIR |grep "contains 1 user defined columns in InnoDB, but" |tail -1|awk  -F, '{print $2}'|awk '{print $2}'`
echo 'Generate dynamic columns...'$COLUMN_NUM
echo  "create table ${MYSQL_RECOVER_DB}.${RECOVER_TABLE_NAME} ("  > $SOURCE_DUMP_PATH/ddl_${RECOVER_TABLE_NAME}.sql
for ((i=1; i < COLUMN_NUM; i++))
do
 echo "id${i} int," >> $SOURCE_DUMP_PATH/ddl_${RECOVER_TABLE_NAME}.sql
done
echo "id$COLUMN_NUM int);" >> $SOURCE_DUMP_PATH/ddl_${RECOVER_TABLE_NAME}.sql

${MYSQL_CONN_STR}  "use ${MYSQL_RECOVER_DB};drop table ${RECOVER_TABLE_NAME};"
${MYSQL_CONN_STR}  "source $SOURCE_DUMP_PATH/ddl_${RECOVER_TABLE_NAME}.sql"

#create table ${RECOVER_TABLE_NAME}(id1 int,id2 int,id3 int,id4 int,id5 int,id6 int,id7 int)"


 /bin/cp -f ${SOURCE_DUMP_PATH}/${RECOVER_TABLE_NAME}.frm ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm
 chown -R mysql:mysql ${MYSQL_DATA_DIR}/${MYSQL_RECOVER_DB}/${RECOVER_TABLE_NAME}.frm

sed -i "s/^innodb_force_recovery=6/#innodb_force_recovery=6/g" $MYSQL_CON_FILE

${SHUTDOWN_MYSQL}
sleep 10;
$STARTUP_MYSQL &

第二个脚本是加载数据的脚本,原理相对简单,就是传输表空间。脚本为load_data.sh

代码语言:javascript
复制
SOURCE_DUMP_PATH = '/tmp'
RECOVER_TABLE_NAME = 'userscore_255'
MYSQL_DATA_DIR = / data / mysql_5727 / data
MYSQL_LOG_DIR = / data / mysql_5727 / log / mysql.err
MYSQL_CONN_STR = "/usr/local/mysql/bin/mysql --socket=/data/mysql_5727/tmp/mysql.sock --port=5727 -Ne"
MYSQL_RECOVER_DB = test_recover
MYSQL_CON_FILE = / data / mysql_5727 / my.cnf
SHUTDOWN_MYSQL = "mysqladmin shutdown --socket=/data/mysql_5727/tmp/mysql.sock --port=5727"
STARTUP_MYSQL = "/bin/sh /usr/local/Percona-Server-5.7.16-10-Linux.x86_64.ssl101/bin/mysqld_safe --defaults-file=/data/mysql_5727/my.cnf "

${MYSQL_CONN_STR}
"show create table ${MYSQL_RECOVER_DB}.${RECOVER_TABLE_NAME} \G" | grep - v
"\*" >$SOURCE_DUMP_PATH / ddl_${RECOVER_TABLE_NAME}.sql
sed - i
'1d' $SOURCE_DUMP_PATH / ddl_${RECOVER_TABLE_NAME}.sql
${MYSQL_CONN_STR}
"use ${MYSQL_RECOVER_DB};drop table ${RECOVER_TABLE_NAME};"
${MYSQL_CONN_STR}
"use ${MYSQL_RECOVER_DB};source $SOURCE_DUMP_PATH/ddl_${RECOVER_TABLE_NAME}.sql;"

${MYSQL_CONN_STR}
"use ${MYSQL_RECOVER_DB};alter table ${RECOVER_TABLE_NAME}  discard tablespace;"

/ bin / cp ${SOURCE_DUMP_PATH} /${RECOVER_TABLE_NAME}.ibd ${MYSQL_DATA_DIR} /${MYSQL_RECOVER_DB} /${
RECOVER_TABLE_NAME}.ibd
chown - R
mysql:mysql ${MYSQL_DATA_DIR} /${MYSQL_RECOVER_DB} /${RECOVER_TABLE_NAME}.ibd

${MYSQL_CONN_STR}
"use ${MYSQL_RECOVER_DB};alter table  ${RECOVER_TABLE_NAME} import tablespace;"

${MYSQL_CONN_STR}
"use ${MYSQL_RECOVER_DB};select count(*)from  ${RECOVER_TABLE_NAME} ;"

输出的日志如下:

sh get_tab_ddl.sh

total 11280

-rw-r----- 1 mysql mysql 61 Feb 25 14:49 db.opt

-rw-r----- 1 mysql mysql 8754 Feb 25 23:34 userscore_255.frm

-rw-r----- 1 mysql mysql 11534336 Feb 25 23:34 userscore_255.ibd

+---------------------+

| 2019-02-25 23:34:27 |

+---------------------+

total 11280

-rw-r----- 1 mysql mysql 61 Feb 25 14:49 db.opt

-rw-r----- 1 mysql mysql 8754 Feb 25 23:34 userscore_255.frm

-rw-r----- 1 mysql mysql 11534336 Feb 25 23:34 userscore_255.ibd

*************************** 1. row ***************************

userscore_255

CREATE TABLE `userscore_255` (

`PID` int(11) NOT NULL,

`Score` int(11) DEFAULT NULL,

`Master` int(11) DEFAULT NULL,

`MCount` int(11) DEFAULT NULL,

`MTime` int(11) DEFAULT NULL,

`UDate` int(11) DEFAULT NULL,

`CDate` int(11) DEFAULT NULL,

PRIMARY KEY (`PID`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

Generate dynamic columns...7

2019-02-25T15:34:32.593762Z mysqld_safe mysqld from pid file /data/mysql_5727/tmp/mysql.pid ended

sh load_data.sh

+-------+

| 33213 |

+-------+

只要能够正常读取,我们是mysqldump导出还是做其他的数据流转,都是手到擒来的事情。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档