记一次线上mysql出错:由于docker自动拉取最新mysql镜像导致mysql容器无法启动
修改mysql容器的环境变量后无法启动,最后通过创建旧版本的mysql容器,通过binlog恢复数据。
我随便写写,你们随便看看
环境背景:在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、数据库一定要做定时备份,平时用不到,用到了就能发挥大作用。即使是测试环境也要做,当然看情况。
也许还有其他的解决方案,望多多指教。
更多推荐
所有评论(0)