我随便写写,你们随便看看

环境背景:在docker中部署mysql镜像,通过portainer管理docker容器

简单说下过程:docker里mysql的时区没有设置,导致相差8小时,通过增加TZ=Asiz/Shanghai环境变量,然后重启容器来生效。结果重启的时候始终无法启动起来,后来发现是自动升级了mysql镜像版本,导致启动失败。

最终解决办法:创建旧版本的mysql容器,通过binlog恢复数据

在portainer中增加环境变量之后,启动的时候报错:[ERROR] [MY-013171] [InnoDB] Cannot boot server version 80027 on data directory built by version 80031. Downgrade is not supported
mysqld: Can't open file: 'mysql.ibd' (errno: 0 - )

提示:不能打开mysql.ibd文件,第一次遇到,通过错误提示知道和版本有关系。80031版本不支持80027版本的文件。

当时的第一反应就是,怎么会自动升级的?怎么滚回去?

自动升级的原因:在于在portainer创建容器的时候,使用的镜像没设置正确:

当时创建容器的时候,就看了一眼,没想到会有自动升级的问题。先把这里改回旧版本的镜像mysql:8.0.27,然后把环境变量里的两个版本变量更改一下: 

 更改之后,重新启动,依然无法启动,报同样的错。。。

尝试把mysql.ibd删除,然后再重新启动,依然报错。。

创建新的mysql容器,使用8.0.31版本的镜像,然后把mysql.ibd文件复制过去,依然无法正常启动。。

最后想了下,最可能的原因就是使用8.0.31版本启动的时候,已经把mysql.ibd文件进行了更改,即使使用8.0.27版本启动也无法使用高版本的文件,导致目前的文件在两个版本都无法使用。也许会还有其他可能。。

在查找mysql.ibd文件的时候,发现了binlog文件,就想只能通过binlog恢复数据的方式恢复数据了。 放弃了原来的容器,把几个binlog文件导出来。

创建新容器,恢复数据

创建新容器,使用旧的镜像版本8.0.27,然后相关的环境变量和配置项都设置好,通过navicat连接保持畅通。

先说正常恢复数据的方法:我把几个binlog文件cp到新容器里面之后,在新容器里执行命令:

mysqlbinlog --no-defaults binlog.000001 | mysql-u root -p

其中binlog.000001为binlog文件,如果有多个文件的话,要多次按照顺序执行。

可以增加 --database=xxx 来指定数据库,我由于是全量恢复,就没指定。

执行完了之后,所有的数据都已恢复,至此一场惊险落幕。

在此期间尝试的其他方法:

1、将旧的binlog文件复制到新容器下,妄图通过新容器重启自动加载进去,也失败了。

2、将binlog文件转化成sql语句再通过sql导入,也失败了。转化后的sql语句要进行二次处理。数据量太大,时间又紧,就没继续。。

血与泪的教训

1、使用docker容器的时候,一定要指定镜像image的版本号,不能使用latest,防止因为重启自动升级版本导致无法启动。

2、数据库一定要做定时备份,平时用不到,用到了就能发挥大作用。即使是测试环境也要做,当然看情况。

也许还有其他的解决方案,望多多指教。

恢复数据的参考地址:MySQL通过Binlog恢复数据_撸码社区的博客-CSDN博客_binlog恢复数据

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐