蝴蝶效应关于一次Mac中mysql非自愿升级到8.0的数据找回
其实解决方法网上已经有不少,这里把自己的处理记录下,完全是作为提示给自己预警
事件起因:#
因为在Mac上用homebrew安装一个插件,其关联的软件在本机过老,所以自动更新,更新过程中发现关联的软件需要两外的软件也过老,一并更新,接下来就像瀑布一样一片更新。好不容更新完成,因为当时mysql5.7还在打开可以正常使用以致就做后续设计并未注意。等第二天重新开机时发现mysql无法启动。
开始处理:#
排除端口侵占等其他原因后,感觉应该是mysql的data文件夹内容是老5.7的,对于8.0不兼容。到此其实很简单只要初始化mysql的数据文件夹就可以,但要找回之前的数据。
找回数据:#
因为8.0的数据兼容性,所以不能用5.7的文件直接恢复,这里我采用docker
/youdir:docker挂载目录
/usr/local/var/mysql:原本机5.7数据文件夹
- 在一个位置新建一个文件夹作为 docker 中 mysql 挂载数据文件夹的位置(此位置需要加入到 docker 的 Resources File sharing 中否则会出现挂载失败)
- 下载一个 docker 镜像(最好和本机之前 mysql 版本相同),启动执行 这里把映射端口改到 3307,为不占用主机的端口,也可以为稍后数据导入 8.0 做准备
docker run --name mysql-test -v /yourdir:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.32
- 看到 /yourdir 这个文件夹下有 mysql 启动文件后,停止 docker 中的 mysql,将 mac 里之前 /usr/local/var/mysql 中的一个数据库的文件夹复制到 /yourdir 后启动 docker 中 mysql,发现复制的数据库出现,但打开后不见表结构(由于 innodb 内部对于每个表结构都有唯一 id,而当前库内表结构和 mysql 不一致)
- 停掉 docker 中 mysql,将 /usr/local/var/mysql 中的 ibdata1(存有 innodb 的元数据,包括 id 计数)复制到 /yourdir 下,再次启动 docker 的 mysql,此时发现加入的库中的表可以正常打开了。依照第三步把剩下的库文件夹都复制到 /yourdir 下。
到这里基本是可以对之前数据做导出备份了,但还要要让8.0的mysql启动
mysql8.0 的启动部分#
- 1. 打包备份 /usr/local/var/mysql 这个文件夹原有数据,清空 /usr/local/var/mysql 文件夹并确认此文件夹权限,确保 mac 内 mysql 没有进程在启动(ps 出来直接杀掉),还要查看一下 mac 中 mysql 的 my.cnf 是 8.0(以防万一)
- 2. 执行 (以下二选一)对目录进行初始化
##初始化过程中会现实root账户的初始密码 mysqld --initialize ##初始一个无密码的root账户 mysqld --initialize-insecure
- 3. 修改 root 密码
#对于root有密码的账户登陆 mysql -u root -p #对于root无密码账户登陆 mysql -u root --skip-password #修改root密码 ALTER USER 'root'@'localhost' IDENTIFIED BY 'root-password';
- 4. 从 docker 中的 mysql 导入数据到本机 mysql8.0
由于 8.0 在内部引擎和字段调整有些数据格式不再适用(比如 MYISAM 分区),所以在转移数据时,之前的导出整库 sql 再执行导入容易出现问题,提前检查下格式,校验转换,也可以少量多次。
对于 mysql5.7 的 root 密码找回方法不适用 8.0 版本了,我试了几个方法之后放弃直接从官方文档入手,如果有其他方法也可以提出来
mysqld –initialize 这个是初始化数据目录操作,执行前一定确保数据备份好
到这里还有些写在结尾,这次 brew 及联更新,导致从 nginx,python,php 基本都更新了,每个更新完都要从新调整配置,尤其涉及到插件的,都要重新编译导入,所以各位使用 homebrew 做安装更新时需要小心。
mysql8 文档:dev.mysql.com/doc/refman/8.0/en/de...
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: