【法器篇】天啦噜,库崩了没备份(天啦噜是什么意思?)
bigegpt 2025-06-03 20:22 8 浏览
背景
数据库没有做备份,一天突然由于断电或其他原因导致无法启动了,且设置了innodb_force_recovery=6都无法启动,里面的数据怎么才能恢复出来?
本例采用解析建表语句+表空间传输的方式进行恢复。
环境
本案例基于下面版本进行的测试验证
- 5.7.44
- 8.0.40
- ibd2sql v1.10+
- 编写的一键恢复脚本
- 10.10.2.12【源端-故障实例】
- 10.10.2.13【目标端-恢复实例】
恢复演示
这边解析演示为单个表,入了需要某个库下的表或多个库下表,可使用下面脚本执行
1.创建测试数据
在已有数据库上创建测试库表
create database yqtest;
create table yqtest.tt01(id int primary key,vname varchar(20));
insert into yqtest.tt01 values (1,'张飞'),(2,'关羽'),(3,'刘备');
create table yqtest.tt02(id int auto_increment primary key,vname varchar(20));
insert into yqtest.tt02(vname) values ('洪七公'),('欧阳锋'),('黄药师');
-- 分区表
CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE,PRIMARY KEY (id,purchased))
PARTITION BY RANGE(YEAR(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (1995),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (2005),
PARTITION p4 VALUES LESS THAN (2010),
PARTITION p5 VALUES LESS THAN (2015)
);
INSERT INTO tr VALUES
(1, 'desk organiser', '2003-10-15'),
(2, 'alarm clock', '1997-11-05'),
(3, 'chair', '2009-03-10'),
(4, 'bookcase', '1989-01-10'),
(5, 'exercise bike', '2014-05-09'),
(6, 'sofa', '1987-06-05'),
(7, 'espresso maker', '2011-11-22'),
(8, 'aquarium', '1992-08-04'),
(9, 'study desk', '2006-09-16'),
(10, 'lava lamp', '1998-12-25');
create database abc;
create table abc.td01(id varchar(20),va varchar(10),vb int);
insert into abc.td01 values('a','张三',20),('b','李四',18);
2.拷贝数据目录
假设当前源端的MySQL已无法启动,但数据文件还是存留着的,需要基于这些数据文件进行数据恢复
-- 将数据文件拷贝到目标端去
scp -r /data/mysql3310/data 10.10.2.13:/root/data_back
3.目标端新建一个同版本的MySQL实例
4.在目标实例下载安装ibd2sql
-- 安装python3
yum install -y python3
-- 下载ibd2sql
wget wget https://github.com/ddcw/ibd2sql/archive/refs/heads/main.zip
unzip main.zip
cd ibd2sql-main
5.解析建表语句并创建表
解析表结构
[root@test13 ~]# python3 /opt/ibd2sql-main/main.py /root/data_back/abc/td01.ibd --ddl
CREATE TABLE IF NOT EXISTS `abc`.`td01`(
`my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT,
`id` varchar(20) NULL,
`va` varchar(10) NULL,
`vb` int NULL,
PRIMARY KEY (`my_row_id` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
目标库创建表
[root@mysql.sock][abc]> CREATE TABLE IF NOT EXISTS `abc`.`td01`(
-> `my_row_id` bigint unsigned NOT NULL AUTO_INCREMENT,
-> `id` varchar(20) NULL,
-> `va` varchar(10) NULL,
-> `vb` int NULL,
-> PRIMARY KEY (`my_row_id` )
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;
Query OK, 0 rows affected (0.03 sec)
6.丢弃表空间
执行丢弃表空间,此表的所有数据都会丢失
[root@mysql.sock][abc]> ALTER TABLE td01 DISCARD TABLESPACE;
Query OK, 0 rows affected (0.00 sec)
7.拷贝文件到目标目录下
[root@test13 ~]# cp /root/data_back/abc/td01.ibd /data/mysql3310/data/abc/
[root@test13 ~]# chown mysql:mysql /data/mysql3310/data/abc/td01.ibd
8.导入表空间
导入表空间,可发现数据已加载恢复
[root@mysql.sock][abc]> ALTER TABLE td01 IMPORT TABLESPACE;
Query OK, 0 rows affected, 1 warning (0.03 sec)
[root@mysql.sock][abc]> select * from td01;
+-----------+------+--------+------+
| my_row_id | id | va | vb |
+-----------+------+--------+------+
| 1 | a | 张三 | 20 |
| 2 | b | 李四 | 18 |
+-----------+------+--------+------+
2 rows in set (0.00 sec)
一键脚本恢复
- 对于单库或多库的恢复,会有需要表,因此使用脚本恢复,以下脚本遍历指定库下的ibd文件后执行恢复
- 使用脚本一键解析指定库的表结构,暂时不支持分区表,分区表需要手动解析恢复
[root@test13 ~]# cat ibd2sql_recover.sh
#!/bin/bash
set -eo pipefail
# 配置参数
DATABASES=("abc" "yqtest") # 需要恢复的数据库列表
BACKUP_DIR="/root/data_back" # 备份文件根目录
MYSQL_BIN="/usr/local/mysql80/bin/mysql"
MYSQL_USER="super_user" # MySQL用户
MYSQL_PASSWORD='s123456' # MySQL密码
MYSQL_HOST="127.0.0.1" # MySQL主机
MYSQL_PORT="3310" # MySQL端口
MYSQL_DATA_DIR="/data/mysql3310/data" # MySQL数据目录
IBD2SQL_SCRIPT="/opt/ibd2sql-main/main.py" # ibd2sql脚本路径
# 安全凭证文件处理
cleanup() {
rm -f "${TMP_CNF_FILE}"
exit 1
}
trap cleanup EXIT TERM INT
TMP_CNF_FILE=$(mktemp)
cat > "${TMP_CNF_FILE}" <<EOF
[client]
user = "${MYSQL_USER}"
password = "${MYSQL_PASSWORD}"
host = "${MYSQL_HOST}"
port = "${MYSQL_PORT}"
EOF
chmod 600 "${TMP_CNF_FILE}"
# 检查必要命令
command -v $MYSQL_BIN >/dev/null || { echo "mysql客户端未安装"; exit 1; }
command -v python3 >/dev/null || { echo "python3未安装"; exit 1; }
# 遍历数据库
for DB in "${DATABASES[@]}"; do
echo "▌▌▌ 正在处理数据库: $DB"
$MYSQL_BIN --defaults-extra-file="${TMP_CNF_FILE}" \
-e "CREATE DATABASE IF NOT EXISTS \`$DB\` CHARACTER SET utf8mb4;" || exit $?
IBDPATH="$BACKUP_DIR/$DB"
[[ -d "$IBDPATH" ]] || { echo "▌! 目录 $IBDPATH 不存在,跳过"; continue; }
# 遍历.ibd文件(排除分区文件)
find "$IBDPATH" -name '*.ibd' -print0 | while IFS= read -r -d '' IBD_FILE; do
# 过滤分区文件(匹配 #p# 或 #P# 模式)
if [[ $(basename "$IBD_FILE") =~ [#][pP][#] ]]; then
echo "▌! 跳过分区文件: $(basename "$IBD_FILE")"
continue
fi
# 提取表名(处理可能的特殊字符)
TABLE=$(basename "$IBD_FILE" .ibd | sed 's/#[^#]*$//') # 处理含#的非分区表
echo "▌▌▌→ 正在处理表: $TABLE"
# 解析建表语句
echo "▌→ 解析表结构..."
DDL=$(python3 "$IBD2SQL_SCRIPT" "$IBD_FILE" --ddl) || {
echo "▌! 解析失败: $IBD_FILE";
continue # 跳过失败文件继续后续流程
}
# 创建表结构
echo "▌→ 创建表结构..."
$MYSQL_BIN --defaults-extra-file="${TMP_CNF_FILE}" "$DB" \
-e "DROP TABLE IF EXISTS \`${TABLE}\`; $DDL" || {
echo "▌! 创建表失败: $DB.$TABLE";
continue
}
# 表空间操作
echo "▌→ 丢弃表空间..."
$MYSQL_BIN --defaults-extra-file="${TMP_CNF_FILE}" "$DB" \
-e "ALTER TABLE \`${TABLE}\` DISCARD TABLESPACE;" || continue
# 复制文件
TARGET_IBD="${MYSQL_DATA_DIR}/${DB}/${TABLE}.ibd"
echo "▌→ 复制文件到: $TARGET_IBD"
cp -v "$IBD_FILE" "$TARGET_IBD" || continue
chown -v mysql:mysql "$TARGET_IBD" || continue
# 导入表空间
echo "▌→ 导入表空间..."
$MYSQL_BIN --defaults-extra-file="${TMP_CNF_FILE}" "$DB" \
-e "ALTER TABLE \`${TABLE}\` IMPORT TABLESPACE;" || continue
echo "▌√ 表 $DB.$TABLE 恢复完成"
done
done
echo "所有数据库恢复操作已完成"
[root@test13 ~]# sh ibd2sql_recover.sh
▌▌▌ 正在处理数据库: abc
▌▌▌→ 正在处理表: td01
▌→ 解析表结构...
▌→ 创建表结构...
▌→ 丢弃表空间...
▌→ 复制文件到: /data/mysql3310/data/abc/td01.ibd
'/root/data_back/abc/td01.ibd' -> '/data/mysql3310/data/abc/td01.ibd'
'/data/mysql3310/data/abc/td01.ibd' 的所有者已从 root:root 更改为 mysql:mysql
▌→ 导入表空间...
▌√ 表 abc.td01 恢复完成
▌▌▌ 正在处理数据库: yqtest
▌▌▌→ 正在处理表: tt01
▌→ 解析表结构...
▌→ 创建表结构...
▌→ 丢弃表空间...
▌→ 复制文件到: /data/mysql3310/data/yqtest/tt01.ibd
'/root/data_back/yqtest/tt01.ibd' -> '/data/mysql3310/data/yqtest/tt01.ibd'
'/data/mysql3310/data/yqtest/tt01.ibd' 的所有者已从 root:root 更改为 mysql:mysql
▌→ 导入表空间...
▌√ 表 yqtest.tt01 恢复完成
▌▌▌→ 正在处理表: tt02
▌→ 解析表结构...
▌→ 创建表结构...
▌→ 丢弃表空间...
▌→ 复制文件到: /data/mysql3310/data/yqtest/tt02.ibd
'/root/data_back/yqtest/tt02.ibd' -> '/data/mysql3310/data/yqtest/tt02.ibd'
'/data/mysql3310/data/yqtest/tt02.ibd' 的所有者已从 root:root 更改为 mysql:mysql
▌→ 导入表空间...
▌√ 表 yqtest.tt02 恢复完成
所有数据库恢复操作已完成
相关推荐
- 【Docker 新手入门指南】第十章:Dockerfile
-
Dockerfile是Docker镜像构建的核心配置文件,通过预定义的指令集实现镜像的自动化构建。以下从核心概念、指令详解、最佳实践三方面展开说明,帮助你系统掌握Dockerfile的使用逻...
- Windows下最简单的ESP8266_ROTS_ESP-IDF环境搭建与腾讯云SDK编译
-
前言其实也没啥可说的,只是我感觉ESP-IDF对新手来说很不友好,很容易踩坑,尤其是对业余DIY爱好者搭建环境非常困难,即使有官方文档,或者网上的其他文档,但是还是很容易踩坑,多研究,记住两点就行了,...
- python虚拟环境迁移(python虚拟环境conda)
-
主机A的虚拟环境向主机B迁移。前提条件:主机A和主机B已经安装了virtualenv1.主机A操作如下虚拟环境目录:venv进入虚拟环境:sourcevenv/bin/active(1)记录虚拟环...
- Python爬虫进阶教程(二):线程、协程
-
简介线程线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能...
- 基于网络安全的Docker逃逸(docker)
-
如何判断当前机器是否为Docker容器环境Metasploit中的checkcontainer模块、(判断是否为虚拟机,checkvm模块)搭配学习教程1.检查根目录下是否存在.dockerenv文...
- Python编程语言被纳入浙江高考,小学生都开始学了
-
今年9月份开始的新学期,浙江省三到九年级信息技术课将同步替换新教材。其中,新初二将新增Python编程课程内容。新高一信息技术编程语言由VB替换为Python,大数据、人工智能、程序设计与算法按照教材...
- CentOS 7下安装Python 3.10的完整过程
-
1.安装相应的编译工具yum-ygroupinstall"Developmenttools"yum-yinstallzlib-develbzip2-develope...
- 如何在Ubuntu 20.04上部署Odoo 14
-
Odoo是世界上最受欢迎的多合一商务软件。它提供了一系列业务应用程序,包括CRM,网站,电子商务,计费,会计,制造,仓库,项目管理,库存等等,所有这些都无缝集成在一起。Odoo可以通过几种不同的方式进...
- Ubuntu 系统安装 PyTorch 全流程指南
-
当前环境:Ubuntu22.04,显卡为GeForceRTX3080Ti1、下载显卡驱动驱动网站:https://www.nvidia.com/en-us/drivers/根据自己的显卡型号和...
- spark+python环境搭建(python 环境搭建)
-
最近项目需要用到spark大数据相关技术,周末有空spark环境搭起来...目标spark,python运行环境部署在linux服务器个人通过vscode开发通过远程python解释器执行代码准备...
- centos7.9安装最新python-3.11.1(centos安装python环境)
-
centos7.9安装最新python-3.11.1centos7.9默认安装的是python-2.7.5版本,安全扫描时会有很多漏洞,比如:Python命令注入漏洞(CVE-2015-2010...
- Linux系统下,五大步骤安装Python
-
一、下载Python包网上教程大多是通过官方地址进行下载Python的,但由于国内网络环境问题,会导致下载很慢,所以这里建议通过国内镜像进行下载例如:淘宝镜像http://npm.taobao.or...
- centos7上安装python3(centos7安装python3.7.2一键脚本)
-
centos7上默认安装的是python2,要使用python3则需要自行下载源码编译安装。1.安装依赖yum-ygroupinstall"Developmenttools"...
- 利用本地数据通过微调方式训练 本地DeepSeek-R1 蒸馏模型
-
网络上相应的教程基本都基于LLaMA-Factory进行,本文章主要顺着相应的教程一步步实现大模型的微调和训练。训练环境:可自行定义,mac、linux或者window之类的均可以,本文以ma...
- 【法器篇】天啦噜,库崩了没备份(天啦噜是什么意思?)
-
背景数据库没有做备份,一天突然由于断电或其他原因导致无法启动了,且设置了innodb_force_recovery=6都无法启动,里面的数据怎么才能恢复出来?本例采用解析建表语句+表空间传输的方式进行...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- skip-name-resolve (63)
- linuxlink (65)
- pythonwget (67)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)