MySQL 主从复制遇到 1590 报错
作者通过一个主从复制过程中 1590 的错误,说明了 MySQL 8.0 在创建用户授权过程中的注意事项。
作者:王祥
爱可生 DBA 团队成员,主要负责 MySQL 故障处理和性能优化。对技术执着,为客户负责。
本文来源:原创投稿
- 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
故障描述
DMP 收到告警:从库的 SQL 线程停止工作,MySQL 版本为 5.7.32,登录到从库查看复制信息报错如下:
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event …… Last_Errno: 1590 Last_Error: The incident LOST_EVENTS occured on the master. Message: REVOKE/GRANT failed while granting/revoking privileges in databases. Skip_Counter: 0 Exec_Master_Log_Pos: 12531 Relay_Log_Space: 69304 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1590 Last_SQL_Error: The incident LOST_EVENTS occured on the master. Message: REVOKE/GRANT failed while granting/revoking privileges in databases. ……
从库错误日志信息如下:
[ERROR] Slave SQL for channel '': The incident LOST_EVENTS occured on the master. Message: REVOKE/GRANT failed while granting/revoking privileges in databases. Error_code: 1590 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000003' position 12531.
解析对应 Binlog 信息如下:
# Incident: LOST_EVENTS RELOAD DATABASE; # Shall generate syntax error
主库错误信息如下:
[ERROR] REVOKE/GRANT failed while granting/revoking privileges in databases. An incident event has been written to the binary log which will stop the slaves.
客户反馈执行了一些授权操作然后复制就出现报错,执行的语句如下:
mysql> create user test@'%',app@'%' identified by 'Root@123'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements mysql> grant all on test.* to test@'%',app@'%'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
故障分析
根据以上报错信息可知:在做权限变更时发生了错误,主库在 binlog 里写一条 INCIDENT_EVENT,备库在解析到 INCIDENT_EVENT 就直接报错。
那在什么情况下执行授权语句会导致主库在 binlog 写 INCIDENT_EVENT 呢?
当权限变更操作只处理了一部分并发生错误时,主库会在 binlog 里写一条 INCIDENT_EVENT。
那什么情况下会发生权限变更只处理一部分而有一部分没处理完呢?
下面举例说明两种相关场景。
MySQL 5.7 的问题
在 MySQL 5.7 里使用 GRANT 语句新建用户,其中有部分权限有问题。
使用 GRANT 创建 test
用户(MySQL 8.0 版本已经不支持使用 GRANT 创建用户):
mysql> grant select,insert,file on test.* to test@'%' identified by 'Q1w2e3E$'; ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES mysql> select user,host from mysql.user where user='test' and host='%'; +------+--------+ | user | host | +------+--------+ | test | % | +------+--------+ 1 row in set (0.00 sec) mysql> show grants for test@'%'; +--------------------------------------------+ | Grants for test@% | +--------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' | +---------------------------------------------+ 1 row in set (0.00 sec)
在创建用户时对 test
库授予 SELECT、INSERT、FILE 权限,因 FILE 权限不能授予某个数据库而导致语句执行失败。但最终结果是:test@'%'
创建成功,授权部分失败。从上面的测试可知,使用 GRANT 创建用户其实是分为两个步骤:创建用户和授权。权限有问题并不影响用户的创建,上述语句会导致主库在 binlog 写 INCIDENT_EVENT,从而导致主从复制报错。
GRANT 对两个用户同时授权
使用一条 GRANT 语句,同时给 test@'10.186.63.5'
与 test@'10.186.63.29'
用户授权,其中 test@'10.186.63.5'
用户存在,而 test@'10.186.63.29'
不存在。
mysql> create user test@'10.186.63.5' identified by '123'; Query OK, 0 rows affected (0.00 sec) mysql> grant all on test.* to test@'10.186.63.5',test@'10.186.63.29'; ERROR 1133 (42000): Can't find any matching row in the user table mysql> show grants for test@'10.186.63.5'; +----------------------------------------------------------+ | Grants for test@10.186.63.5 | +----------------------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'10.186.63.5' | | GRANT ALL PRIVILEGES ON `test`.* TO 'test'@'10.186.63.5' | +----------------------------------------------------------+ 2 rows in set (0.00 sec)
根据上面的实验可知:test@'10.186.63.5'
用户存在故授权成功,而 test@'10.186.63.29'
用户不存在授权失败。上述语句也会导致主库在 binlog 写 INCIDENT_EVENT,从而导致主从复制报错。
但以上两种情况似乎都不符合客户执行语句情况,从报错来看是因为密码复杂度不够而导致创建用户失败了,那到底是什么原因导致从库出现 1590 错误呢?下面我们来看看在使用了密码复杂度插件后使用create语句同时创建两个用户会有什么问题。
mysql> show global variables like '%validate%'; +--------------------------------------+--------+ | Variable_name | Value | +--------------------------------------+--------+ | query_cache_wlock_invalidate | OFF | | validate_password_check_user_name | OFF | | validate_password_dictionary_file | | | validate_password_length | 8 | | validate_password_mixed_case_count | 1 | | validate_password_number_count | 1 | | validate_password_policy | MEDIUM | | validate_password_special_char_count | 1 | +--------------------------------------+--------+ mysql> select user,host from mysql.user; +---------------+-----------+ | user | host | +---------------+-----------+ | universe_op | % | | root | 127.0.0.1 | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+-----------+ 5 rows in set (0.00 sec) mysql> create user test@'%',app@'%' identified by 'Root@123'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements mysql> select user,host from mysql.user;(app@'%'创建成功,test@'%'创建失败) +---------------+-----------+ | user | host | +---------------+-----------+ | app | % | | universe_op | % | | root | 127.0.0.1 | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+-----------+ 6 rows in set (0.00 sec)
上述测试使用 CREATE USER 同时创建 test@'%'
、app@'%'
。但因为密码复杂度不合符要求而失败报错(多次测试发现并不是密码复杂度不够,只要同时创建两个用户都会报密码复杂度不符合要求。在未使用密码复杂度插件时是可以同时创建两个用户),正常的话这两个用户应该都会创建失败。但实际上 app@'%'
用户创建成功了。
到这里我们就明白文章开始描述故障的触发原因:数据库实例开启了密码复杂度插件,使用 CREATE USER 同时创建两个用户,因为密码复杂度不符合要求而报错,但 app@'%'
是已经创建了, test@'%'
用户未创建,紧接着又执行了 GRANT 语句给两个用户同时授权,此时因为 test@'%'
用户不存在,而导致 GRANT 语句部分执行的问题,最终导致了主从复制报错。
故障解决
当主从复制出现 1590 报错时,可以先解析 binlog,找到 INCIDENT_EVENT(搜索关键字 LOST_EVENTS)和对应的 GTID,然后通过跳过这个 GTID 的方式来恢复主从复制。在跳过 GTID 之前还需要先将数据补全,因为主库有一个用户是已经授权成功从库这部分授权是没有执行的。具体操作如下(在从库执行):
mysql>set global super_read_only=0; mysql>set sql_log_bin=0; mysql>grant all on test.* to test@'10.186.63.5';
跳过报错对应的 GTID,具体操作如下:
解析 binlog 找到 INCIDENT_EVENT。
mysqlbinlog --no-defaults -vv --base64-output=decode-rows mysql-bin.000016 > /root/bin.log
跳过 LOST_EVENTS
对应的 GTID(在从库执行):
stop slave sql_thread; set gtid_next='9d2e7089-2774-11ee-99d6-02000aba3f05:4198564'; begin;commit; set gtid_next='automatic'; start slave sql_thread;
总结
- 权限变更操作只处理了一部分并发生错误时,会导致 binlog 写一条 INCIDENT_EVENT,从而导致主从复制报错。
- 在使用密码复杂度插件时,使用 CREATE 语句同时创建两个用户,会出现一个用户创建成功另外一个用户创建失败的情况。
建议
- 使用了密码复杂度插件,创建用户时一条 CREATE 语句只创建一个用户。
- 授权时一条 GRANT 语句只对一个用户授权,防止因权限错误导致部分授权成功的问题。 更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。
SQLE 获取
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
阿里云故障洞察提效 50%,全栈可观测建设有哪些技术要点?
#一分钟精华速览 # 全栈可观测是一种更全面、更综合和更深入的观测能力,能协助全面了解和监测系统的各个层面和组件,它不仅仅是一个技术上的概念,更多地是技术与业务的结合。在“以业务为导向”的大前提下,全栈可观测正在成为趋势。 本文分享了阿里云可观测平台服务作为全球分布的超大业务系统,同时也作为服务全球企业用户的可观测平台提供方,在故障洞察提效中遇到的业务挑战,以及 6 个关键技术点和 2 个应用案例。 背景 全栈可观测是一个技术和业务相结合的领域,单从技术维度理解,可观测包含了基础设施、应用服务、客户端等等,而是更广义的维度则关注这项技术如何支撑企业的业务,提供跨越各个层面的数据收集、分析和可视化,帮助企业更好地理解和管理其系统和应用。从技术开源到各类头部厂商的产品,再到国内外多个业务组织的落地,都可以看出全栈可观测已经成为一种技术趋势。 Gartner 报告显示,落地可观测性具有相当高的战略价值 这一观点也在 Gartner 的报告中得到印证,根据 Gartner 的预测,到 2026 年,成功应用可观测性的 70% 组织将能够实现更短的决策响应时间,从而为目标业务或 IT 流程带来竞...
- 下一篇
使用 OpenTelemetry 构建可观测性 01 - 介绍
毫无疑问,在过去几年里,你可能已经多次听到过可观测性这个词。对于很多人来说,很难理解这个词的真正含义。对许多人来说,他们错误地将其等同于"监控"。虽然可观测性的根本定义以及它所包含的一切都不在本系列博文的讨论范围之内,但我强烈建议您购买一本由 Charity Majors (twitter)、Liz Fong-Jones (twitter) 和 George Miranda (twitter) 合著的《可观测性工程》(Observability Engineering)一书。 不过,本系列博文将介绍使用 OpenTelemetry 实现可观测性的完整示例和说明,OpenTelemetry 是 CNCF 的一个项目,致力于让可观测性变得更简单。 什么是 OpenTelemetry? OpenTelemetry 是几年前 OpenCensus 和 OpenTracing 合并的产物。从那时起,OpenTelemetry(也简称为 "OTel")就很好地将自己定位为在现代软件世界中获取遥测数据且厂商中立的方法。很多人会说 OpenTelemetry 是可观测性的未来,根据我的经验和接触,我倾...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- 2048小游戏-低调大师作品
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16