Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL frm ibd恢复表结构和数据

MySQL利用frm文件和ibd文件恢复表结构和表数据

作者:月巴左耳东

当MySQL数据库遭遇崩溃或数据丢失时,利用备份的 .frm 和 .ibd 文件恢复数据是一种有效的解决方案,.frm 文件包含表的结构信息,而 .ibd 文件则存储表的实际数据,本文将提供一个详细的步骤指南,演示如何利用这些文件恢复MySQL表数据和表结构,需要的朋友可以参考下

frm文件和ibd文件简介

frm文件恢复表结构

create table study (id int);

查看日志

grep study mysql.err | grep columns

容器启动的MySQL,直接使用docker restart <容器id>来重启MySQL服务

如果是容器启动的MySQL,可以使用下面的命令在容器外查看日志

docker logs <容器id> | grep study | grep columns
[Warning] InnoDB: Table hello@002dworld/study contains 1 user defined columns in InnoDB, but 5 columns in MySQL. Please check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.
drop table study;
create table study (id1 int,id2 int,id3 int,id4 int,id5 int);
show create table study\G
*************************** 1. row ***************************
       Table: study
Create Table: CREATE TABLE `study` (
  `id1` int(11) DEFAULT NULL,
  `id2` int(11) DEFAULT NULL,
  `id3` int(11) DEFAULT NULL,
  `id4` int(11) DEFAULT NULL,
  `id5` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)
grep 'innodb_force' my.cnf
sed -i '/\[mysqld\]/a\innodb_force_recovery=6' my.cnf
show create table study\G
*************************** 1. row ***************************
       Table: study
Create Table: CREATE TABLE `study` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `time` int(11) DEFAULT NULL,
  `lang` varchar(20) COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)
sed -i '/innodb_force_recovery/s/^\(.*\)$/#\1/g' my.cnf
drop table study;
CREATE TABLE `study` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `time` int(11) DEFAULT NULL,
  `lang` varchar(20) COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

ibd文件恢复表数据

alter table study discard tablespace;
alter table study import tablespace;
select * from study;
+------+------+------+----------+---------+
| id   | name | age  | time     | lang    |
+------+------+------+----------+---------+
|    1 | tom  |   26 | 20211024 | chinese |
+------+------+------+----------+---------+

通过脚本利用ibd文件恢复数据

前提是表结构是存在的
注意自己的数据库是否区分大小写,以及表名称是否有大小写,如果表名称有大小写,新启动的mysql一定要开启大小写[开启大小写参数:lower_case_table_names = 0]
mysql_user变量的值为mysql数据目录的属主和属组
根据实际场景修改mysql_cmd变量的值,修改成自己用户名用户密码主机ip
mysql_data_dir变量的值为mysql数据存储路径
back_data_dir变量的值为备份下来的ibd文件存储路径

#!/bin/bash
base_dir=$(cd `dirname $0`; pwd)
mysql_user='mysql'
mysql_cmd="mysql -N -uroot -proot -h192.168.70.49"
databases_list=($(${mysql_cmd} -e 'SHOW DATABASES;' | egrep -v 'information_schema|mysql|performance_schema|sys'))
mysql_data_dir='/var/lib/mysql'
back_data_dir='/tmp/back-data'

for (( i=0; i<${#databases_list[@]}; i++ ))
do
  tables_list=($(${mysql_cmd} -e "SELECT table_name FROM information_schema.tables WHERE table_schema=\"${databases_list[i]}\";"))
  database_name=${databases_list[i]/-/@002d}

  for (( table=0; table<${#tables_list[@]}; table++ ))
  do
    ${mysql_cmd} -e "alter table \`${databases_list[i]}\`.${tables_list[table]} discard tablespace;"
    rm -f ${mysql_data_dir}/${database_name}/${tables_list[table]}.ibd
    cp ${back_data_dir}/${database_name}/${tables_list[table]}.ibd ${mysql_data_dir}/${database_name}/
    chown -R ${mysql_user}.${mysql_user} ${mysql_data_dir}/${database_name}/
    ${mysql_cmd} -e "alter table \`${databases_list[i]}\`.${tables_list[table]} import tablespace;"
    sleep 5
  done
done

通过shell脚本导出mysql所有库的所有表的表结构

mysql_cmddump_cmd的变量值根据实际环境修改,修改成自己用户名用户密码主机ip
databases_list只排除了mysql的系统库,如果需要排除其他库,可以修改egrep -v后面的值
导出的表结构以库名来命名,并且加入了CREATE DATABASE IF NOT EXISTS语句

#!/bin/bash
base_dir=$(cd `dirname $0`; pwd)
mysql_cmd="mysql -N -uroot -proot -h192.168.70.49"
dump_cmd="mysqldump -uroot -proot -h192.168.70.49"
databases_list=($(${mysql_cmd} -e 'SHOW DATABASES;' | egrep -v 'information_schema|mysql|performance_schema|sys'))

for (( i=0; i<${#databases_list[@]}; i++ ))
do
  tables_list=($(${mysql_cmd} -e "SELECT table_name FROM information_schema.tables WHERE table_schema=\"${databases_list[i]}\";"))

  [[ ! -f "${base_dir}/${databases_list[i]}.sql" ]] || rm -f ${base_dir}/${databases_list[i]}.sql
  echo "CREATE DATABASE IF NOT EXISTS \`${databases_list[i]}\`;" >> ${base_dir}/${databases_list[i]}.sql
  echo "USE \`${databases_list[i]}\`;" >> ${base_dir}/${databases_list[i]}.sql

  for (( table=0; table<${#tables_list[@]}; table++ ))
  do
    ${dump_cmd} -d ${databases_list[i]} ${tables_list[table]} >> ${base_dir}/${databases_list[i]}.sql
  done
done

以上就是MySQL利用frm文件和ibd文件恢复表结构和表数据的详细内容,更多关于MySQL frm ibd恢复表结构和数据的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文