对于商业数据库来说,数据库升级是重中之重。有版本升级路线图,对应的补丁,以及计划的一系列演练。硬仗。在MySQL的方向上,升级这件事被淡化了很多,好像只能证明它的存在一样。当然,也正是因为这种不重视,才让我今天走了很多弯路。一般来说,升级MySQL有两种可行方案。一种是直接升级数据字典,在本地完成。整个过程将离线操作,这会中断业务。二是通过高可用切换实现平滑实施。原理就是建立从低版本到高版本的数据复制关系。该方案优势明显,对业务的侵入性小,可以提前验证,甚至可以实现平滑回滚。当然,第二种方案需要做很多准备工作。我们今天处理的环境使用第一种方法,基于存储和持续时间等因素。整个过程如下:1)mysqldump备份数据库,备份文件约120G2)停止MySQL5.5数据库3)修改数据库端口,重启数据库,例如从4308调整为4318,这样避免迁移过程中其他业务连接的影响,验证无误后停止数据库4)修改mysql_base路径为5.7版本,修改/usr/bin/mysql等环境变量配置5)将配置文件替换为5.7版本,以5.7模式启动数据库6)使用upgrade模式升级数据字典,命令如下:mysql_upgrade--socket=/data/mysql_4306/tmp/mysql.sock--port=4308-uroot-pxxxx7)检查回顾整个过程看起来还可以,实际操作起来漏洞百出。1)mysqldump备份数据库,备份文件约120G。mysqldump用于在线快速备份,但是异常情况下的恢复效率有硬伤,所以这里不推荐使用mysqldump备份,建议使用物理备份,即使条件允许,直接使用冷备模式2)停止MySQL5.5数据库3)修改数据库端口,重启数据库,例如从4308调整为4318,以免迁移过程中影响其他业务连接,验证无误后停止数据库4)修改mysql_basepath对于5.7版本,修改/usr/bin/mysql等环境变量配置5)将配置文件替换为5.7版本,以5.7模式启动数据库。我这里没有注意ibdata的配置。运气不好,遇到了一个奇怪的配置,如下:innodb_data_file_path=ibdata1:1000M;ibdata2:100M:autoextend原来规范配置是一个ibdata文件,如下:innodb_data_file_path=ibdata1:1G:autoextend,导致报错的时候数据库启动,提示ibdata文件已损坏。6)使用升级方式升级数据字典,命令如下:mysql_upgrade--socket=/data/mysql_4306/tmp/mysql.sock--port=4308-uroot-pxxxxupgrade该命令的执行提示不是够友好,丢了很多的错误,不过最后还是安慰我说升级成功了。问题到了这个阶段,其实很难结束,因为数据字典文件损坏,导致无法升级数据字典。现在数据库甚至无法描述其中的表。7)检查复查,很简单原来叫出来的验证工作,现在变成了紧急修复。后续第一波补救措施如下:8)使用凌晨固定的现有物理备份恢复数据,耗时约1小时。mysqldumprestore果断放弃,印象中至少需要6个小时。9)使用物理备份方式备份当前数据库10)重新升级数据库,特别注意ibdata的配置,如果升级失败,使用物理备份快速回滚11)升级过程再次阻塞,这次是sql_mode,系统数据字典升级成功,但是在数据库的表检测中,很多数据表的格式校验失败,主要是sql_mode的数据格式校验,以及altertabletest等重构操作.xxxxx强制需要执行。12)恢复过程中由于不明原因,InnoDB的redolog也受到影响,日志开始抛错。因此,即使字典升级成功,当前恢复的数据库本身也存在一些缺陷。后续第二波补救措施如下:13)使用mysqldump备份当前数据库,只备份指定的数据库,不要使用all-databases选项,单独导出权限。14)部署一个MySQL5.7实例,不同端口,比如4390端口15)sql_mode与5.5版本通配,修改其他参数等16)导入mysqldump数据到4390的5.7实例17)建立主从复制关系18)切换数据库端口,让新的5.7版本服务生效的整个过程也是一波三折。看到窍门后发现想走捷径,最后发现一个坑都没拉下来。这也给我上了深刻的一课。不要掉以轻心。以试一试的态度解决问题。
