• Mysql8.0~gh-ost~default_authentication_plugin导致ddl卡住


    一、引言

            最近线上有个表要加几个字段,提交db单之后执行了一天都没有结束,这个表的容量不大不应该这样。因此作者与DBA进行了深入沟通,了解了集团使用gh-ost更新表结构的过程,问题出在交换表名的过程中。

    二、分析

            看的ddl单据卡住了之后,作者看了一下日志,循环播放取消gh-ost的限速设置成功,怎么看都是代码走到死循环里面去了,毕竟我们这边执行ddl的系统是自研的。

             因此作者只能和dba沟通一下了,因为不了解集团这个db系统后台是怎么玩的。

            沟通之后了解到这个系统拿到ddl语句之后会使用gh-ost进行表结构修改,gh-ost是一个开源工具,用于执行DDL(数据定义语言)操作。它可以在不中断服务的情况下执行表结构的更改,例如添加、修改或删除列、索引等。gh-ost使用一种称为"online schema change"的方法,通过复制表并在副本上执行DDL操作,然后将更改应用到主表上,以减少对生产环境的影响。

            首先分析一下这个表结构更新的过程,接下来才能分析问题出在什么地方

    1、表结构更新过程

            1、改表结构对于大表来说是非常长的过程,锁表时间很久,所以gh-ost会在主节点建立一个临时副本,把a表里面所有的数据复制过去并且在这个过程中追加a更新的数据,gh-ost会使用MySQL的复制机制将主库上的binlog事件复制到副本上,以确保临时表中的数据与主表中的数据保持一致。

            从库不用管,主库的变化都会从binlog被感知。

            这个过程不是绝对安全的,gh-ost是通过MySQL的复制机制来实现数据的复制和追加的,它无法实时感知到原表的更新操作,为了解决这个问题,gh-ost在复制数据之前会记录原表的binlog位置,并在复制完成后再次检查这个位置。如果原表在复制过程中被更新了,gh-ost会重新执行复制过程,确保副本上的临时表与原表的数据保持一致。

            所以还是要在业务低峰期操作表结构变更。

             2、副本数据一致的时候加锁,Ghost lock是一种特殊的表级别锁,它会锁定主表,基于MySQL的表级别锁机制实现。在执行DDL操作之前,会使用ALTER TABLE语句对主表进行加锁。这个ALTER TABLE语句中使用的锁模式是`LOCK=EXCLUSIVE`,它会锁定整个表,阻止其他会话对表进行写入或修改。

            3、这一步是关键的,交换表名,可以按照下面这个sql理解下,由于已经被锁不会有数据影响

    1. ALTER TABLE `temp_a` RENAME TO `temp_b`,
    2. `a` RENAME TO `temp_a`,
    3. `temp_b` RENAME TO `a`;

            最后在把副本删除就可以了

    2、MYSQL Error: this authentication plugin is not supported

            其实真正报的错是这个,这个错是当连接到MySQL Docker时,应用程序一直报告错误:这个身份验证插件不受支持。

            查到是default_authentication_plugin配置的身份插件有问题,又碰到这个db实例在阿里云上面,而新版本的MySQL(8.0或以上)将root用户使用的插件更新为caching_sha2_password。种种巧合才触发了这个问题。这个问题是在交换表名的阶段发生的。

    解决方案如下:
    (1)降级并使用较旧版本的MySQL。
    (2)将插件更改为mysql_native_password。

    3、为什么交换表名的时候会因为身份验证插件是`caching_sha2_password`,导致一直ddl失败,gh-ost创建副本同步数据就不会发生这个问题?

            爱思考的同学一定想到了,为什么是在交换表名的时候因为身份验证失败,再次之前gh-ost又是创建副本又同步数据又查log的,为什么这些操作没有导致身份验证失败?

            gh-ost创建副本同步数据时不会出现这个问题,是因为在创建副本时,MySQL会将副本的身份验证插件设置为与主库相同的插件。因此,在副本上执行DDL操作时,身份验证插件与主库相同,不会出现身份验证失败的情况。

            而在交换表名时,由于gh-ost需要在主库上执行DDL操作,因此需要使用主库的身份验证插件进行身份验证。如果主库的身份验证插件是`caching_sha2_password`,而gh-ost使用的是旧版本的MySQL客户端,那么就可能会出现身份验证失败的情况。

    三、总结

            在使用mysql8.0的时候要注意default_authentication_plugin插件的设置。以上是作者交流和阅读相关资料的总结,有不同想法欢迎讨论。

  • 相关阅读:
    docker 安装 mysql 5.7 主从实战 (1主1从)
    解释Java虚拟机(JVM)的工作原理
    区块链技术的应用场景和优势
    数据库管理-第110期 Oracle Exadata 01(20231016)
    云小课|基于华为云WAF的日志运维分析,构筑设备安全的城墙
    算法leetcode|19. 删除链表的倒数第 N 个结点(rust重拳出击)
    R统计绘图-线性混合效应模型详解(理论、模型构建、检验、选择、方差分解及结果可视化)
    Nautilus无法创建下列所需的文件夹:/home/user/Desktop 报错解决
    JAVA Stream流
    VSCode Python运行环境配置
  • 原文地址:https://blog.csdn.net/m0_69270256/article/details/133750687