某次强制重启后电脑上docker的全部容器和镜像都不见了,不过数据都还在,重新拉取镜像并且恢复,记录一下过程。
-
拉取Mysql镜像,并创建数据卷,创建容器并挂载到数据卷
拉取的镜像版本要跟原来的版本一样,我的是5.7,略微差异可能也不影响
//拉取镜像
docker pull mysql:5.7
//创建数据卷
docker volume create mysql5data
//创建容器并挂载
docker run -d -p 3337:3306 -v mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=12345678 --name mysql5 mysql:5.7
-
恢复数据
创建跟原本数据库一样的数据库(我的是PersonalForum),然后把全部表创建一遍,表格式任意。
//比如原来的表是abc(id int,ad varchar, ... ),建表只需要表名称是abc就可以
Create tables abc(id int);
然后把镜像内的数据库文件夹下的所有.frm文件用原本的文件覆盖。
我的路径是:\\wsl$\docker-desktop-data\data\docker\volumes\mysql5data\_data\PersonalForum
数据卷位置
- For Docker version 20.10.+ :
\\wsl$\docker-desktop-data\data\docker\volumes
- For Docker Engine v19.03:
\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\
覆盖完成后重启容器,查看日志,
2024-02-06 15:47:08 2024-02-06T07:47:08.793954Z 2 [Warning] InnoDB: Table PersonalForum/admin contains 1 user defined columns in InnoDB, but 2 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.
2024-02-06 15:47:08 2024-02-06T07:47:08.793986Z 2 [Warning] InnoDB: Cannot open table PersonalForum/admin from the internal data dictionary of InnoDB though the .frm file for the table exists. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.
...
可以知道应该要有两个字段,我们创建表只有一个,那么把表admin删除,并把创建语句改为CREATE TABLE admin(id int,id2 int); 重新创建。
其他的表同理。然后我们进入 docker 修改 mysql 配置文件,添加一行
C:\Users\Administrator>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dea9d8fb4b9e mysql:5.7 "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 33060/tcp, 0.0.0.0:3337->3306/tcp mysql5
C:\Users\Administrator>docker container exec -it dea9d8fb4b9e /bin/bash
修改配置文件,保存后关闭容器
vim /etc/my.cnf
//添加一行 innodb_force_recovery=6 到 [mysqld] 下并保存退出
//my.cnf位置可能不同,没有 vim 就安装:yum install -y vim
再次复制原来的结构文件.frm到数据卷覆盖,然后重新启动容器。
此时使用查询语句我们可以查询到原始表的创建结构了。
show create table admin;
//得到
CREATE TABLE `admin` (
`uid` bigint(11) NOT NULL,
`admin` enum('y','n') NOT NULL DEFAULT 'n',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
接下来就是把所有的表按照我们查询出的语句进程重新创建即可,创建前需要把在配置文件中添加的那一行注释掉并重启容器。
接下来我们恢复数据,以表admin为例,依次执行
#flush table admin for export; #我执行的时候不需要这一步,如果第2步报错则执行1,3步
alter table admin discard tablespace;
#unlock tables;
然后将原.idb文件拷贝到数据卷文件夹中覆盖,然后执行以下指令即可。
alter table admin import tablespace;
我执行上面那条指令需要先注释掉配置文件的 innodb_force_recovery=6 ,否则会报 当前只读模式 的错。改完后执行恢复还是报错了,一会报表已经存在,删除了也不行,一会又报锁出错,索性恢复,反正是测试数据,以后找到原因再回来记录。