暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

浅谈升级MySQL 8.0

DBA入坑指南 2021-05-24
1931


点击上方蓝字关注我们



一、为什么要升级到MySQL 8.0

 

  1. 快速加列,腾讯互娱提供的一个很好的MySQL特性,使用PT工具变更大表DBA仍然很痛苦,变更百G以上大表风险极高(大表后续需要拆分),不仅时间很长而且变更期间占用大量磁盘IO,并且容易导致业务报错,比如大量出现锁等待和死锁等,对于核心业务还是很难接受,严重甚至会导致MySQL主从切换。


  2. 支持自增值持久化,解决MySQL 8.0之前版本重启后可能会导致依赖自增值的业务或者归档数据可能报错等问题。


  3. 解决了使用replace into语句导致的问题,MySQL 8.0之前版本主从切换后可能会出现自增值冲突的问题(现象:一个repalce操作,主中表主键中的auto_increment会累加1,但是从中表主键却不会累加,主从切换后,就可能会出现自增id回溯导致的主键冲突问题),如果表有使用自增值的话,无论什么版本,笔者建议业务优先使用insert into on duplicate key update语句,而不是replace into语句 ,因为replace into操作如果没有写全字段,很容易导致字段值被覆盖的问题(使用自增值在MySQL 8.0之前版本还是有不少隐藏的坑,在分布式环境下,禁止使用自增值字段作为主键,可以考虑使用雪花算法生成主键id或者使用uuid等,在单表下使用自增id不能跟业务藕合),在执行replace into后,系统返回了所影响的行数,如果返回1,说明在表中并没有重复的记录,如果返回2,说明有一条重复记录,系统自动先调用了 DELETE删除这条记录,然后再记录用INSERT来插入这条记录。如果返回的值大于2,那说明有多个唯一索引,有多条记录被删除和插入,另外在binlog row格式下,无论执行replace into还是insert into on duplicate key update语句解析binlog看到的都是update语句,而不是delete + insert语句,如下所示

      mysql> replace into user_info(id,username) values (1,'lusi');
      Query OK, 2 rows affected (0.00 sec)
      复制


    •  JSON功能增强,如果之前有使用json数据类型的话,可以体验到更丰富的函数和同步性能提升等。


    • 更好的MGR使用体验。


    • 其他一些业务迫切需要的功能和特性,比如窗口函数、公共表表达式等。


    • 遇到低版本没有彻底解决的BUG等。



    二、升级MySQL 8.0注意事项


    1. 验证插件改为default_authentication_plugin=mysql_native_password。


    2. sql_mode、lower_case_table_names、character_set_server、default_collation_for_utf8mb4等变量保持一致,MySQL 8.0 校对集由原来默认的utf8mb4_general_ci改为utf8mb4_0900_ai_ci,实际生产并没有什么影响,你可以认为utf8mb4_0900_ai_ci是utf8mb4_general_ci的超集。


    3. 注意MySQL 8.0 Group by默认不排序,无论什么版本都建议业务显示加上order by,MySQL 8.0之前版本默认会排序,切换后可能会导致业务返回的结果不对。


    4. Datetime类型字段的值,不能等于空字符串,否则直接报错,有些老业务可能会出现这种问题,比如之前由于使用宽松的SQL模式,不过无论从数据库层面还是业务层面来说,这样子使用都是没意义的,如果不做好相关兼容性测试,切换后程序报错会导致DBA回退,因为开发需要时间进行修复并发布后才能恢复。


    5. 不建议直接使用MySQL 8.0二进制文件替换的方式进行直接升级,①升级风险较高,因为数据库升级后无法降级,即便升级过程中报错了也可能已经损坏了部分数据文件②回滚难度大,会导致业务影响面放大。建议使用DTS进行新旧版本SET间数据同步,一旦发生问题,DBA回退的代价相对较小,DBA只需要解析新写入MySQL 8.0的binlog导入旧SET,不建议使用mysqlbinlog工具解析binlog进行数据导入,可以优先考虑使用binlog2sql/lightning解析sql出来导入即可,不过需要注意的是如果切换完成后,业务已经跑了一段时间后报错(比如已经运行了2个小时),那么回滚代价将会相当高,这时如果不是出现无法修复的BUG或者问题,那么不建议回退。

      注:也可以将MySQL 8.0作为从库使用原生主从同步机制来同步数据,建议测试下,当然如果不是比较核心业务的话也可以考虑原地升级,比如一些游戏场景,升级前先做好备份,万一升级失败后直接使用备份快速恢复到升级前的状态即可。


    6. 做好数据同步校验,云数据库虽然做得已经比较好了,我们可以站在巨人的肩膀上做事,但是还是建议不要完全信任云数据库或者完全丢给云去做,这其实是不合理的,而且是软件就有可能出现不可预料的BUG,如果可以请自己掌控“方向盘”,或者至少可以”踩刹车”。

    7. 最最最重要的一点是在测试环境先做好兼容性测试,避免业务存在使用了一些MySQL 8.0移除的函数、关键字或者语法等,可以在测试环境一段时间,没问题后在进一步考虑升级,举例PASSWORD函数在8.0.11版本移除了,可以使用如下函数

        mysql> SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('xxxxxxxxxx')))));
        +-----------------------------------------------------+
        | CONCAT('*', UPPER(SHA1(UNHEX(SHA1('xxxxxxxxxx'))))) |
        +-----------------------------------------------------+
        | *6FB96B0760E8A04F88398A145B323ED8D67C6792 |
        +-----------------------------------------------------+
        1 row in set (0.00 sec)
        mysql> select authentication_string from mysql.user where user= 'test_user';
        +-------------------------------------------+
        | authentication_string |
        +-------------------------------------------+
        | *6FB96B0760E8A04F88398A145B323ED8D67C6792 |
        +-------------------------------------------+


        复制


      • 另外如果不是因为MySQL 8.0.23及之后版本修复了8.0.23之前版本出现的严重BUG之外,那么笔者暂不建议使用或者升级到MySQL 8.0.23,要是8.0.23的主从同步语法发生了变化,相关周边配套软件和工具可能还没有完全跟上。


      • ETL流程要做好兼容MySQL 8.0。


      • 程序驱动不兼容部分已经移除或者改名的变量,需升级驱动,如程序连接报错,如报'unknown system variable query_cache_size' 或'unknown system variable tx_isolation'。


      • MySQL报错MySQL "java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3",升级驱动或尝试在连接串中添加&serverTimezone=Asia/Shanghai



      三、总结


      上面只是列举了大概,可能并不全,DBA可以根据公司业务的实际情况进行添加或者删减,升级数据库版本可能会有各种原因,但升级的前提一定要做到未雨绸缪,尽量减少对业务的影响。





      扫描二维码获取

      更多精彩

      DBA入坑指南








      点个在看 你最好看



      文章转载自DBA入坑指南,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论