MySQL 中 GRANT 操作会引起复制中断吗?
一个案例讲清楚 GRANT 操作的生效过程。
作者:杨彩琳,爱可生华东交付部 DBA,主要负责 MySQL 日常问题处理及 DMP 产品支持。爱好跳舞,追剧。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1100 字,预计阅读需要 3 分钟。
问题背景
客户反馈,某业务测试环境的数据库主从同步断开。
登录到从库,执行 show slave status\G
,发现 sql 线程没有工作了,具体报错为:
LAST_ERROR_MUMBER: 1410 LAST_ERROR_MESSAGE: Worker 1 failed executing transaction 'c593bdc6-cd10-11ec-ac44-0050568a0cc2:2003275' at master log mysql-bin.00187, end_log_post 142 'You are not allowed to create a user with GRANT' on query. Default database: 'mysql'. Query: 'GRANT ALL PRIVILIEGES ON *.* TO 'p-dms-all'@100.104.%''
从提示可以看出是 GRANT 操作失败导致 sql 线程断开了。
经过与其他运维同事的沟通,了解到客户执行了创建用户并授权的操作。由于数据库中本身有一个未使用的用户,所以选择直接对 mysql.user
表的用户数据做 UPDATE 操作实现授权,从 MySQL 操作日志记录也可以看到如下操作:
尝试执行 start slave
,从库的 sql 线程就已经正常工作了。GRANT 的操作也已经正常回放了。
也许你好奇这个过程中到底发生了什么,下面通过复现验证并解释该现象。
本地复现
现有一套 MySQL 8.0 的主从,数据库中已存在只读用户 test@'10.186.%'
。
mysql> show grants for test@'10.186.%'; +------------------------------------------+ | Grants for test@10.186.% | +------------------------------------------+ | GRANT SELECT ON *.* TO `test`@`10.186.%` | +------------------------------------------+ 1 row in set (0.00 sec)
主库更改 test@'10.186.%'
用户的 host
并进行授权操作。
mysql> update mysql.user set host='%' where user='test'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> grant all on *.* to test@'%'; ERROR 1410 (42000): You are not allowed to create a user with GRANT mysql> grant all on *.* to test@'%'; Query OK, 0 rows affected (0.00 sec)
可以看到第一次 GRANT 操作失败了,再执行第二次可以成功。此时查看从库的复制状态,从库的 sql 线程已断开,稳定复现该问题。
mysql> show slave status\G *************************** 1. row *************************** Last_Errno: 1410 Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '59c87cdc-9a47-11ee-b06e-02000aba394f:149931' at master log mysql-bin.000001, end_log_pos 68067966. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any. mysql> select * from performance_schema.replication_applier_status_by_worker limit 1\G *************************** 1. row *************************** LAST_ERROR_MESSAGE: Worker 1 failed executing transaction '59c87cdc-9a47-11ee-b06e-02000aba394f:149931' at master log mysql-bin.000001, end_log_pos 68067966; Error 'You are not allowed to create a user with GRANT' on query. Default database: ''. Query: 'GRANT ALL PRIVILEGES ON *.* TO 'test'@'%''
官方说明
- 如果使用账户管理语句更改授权表,服务器会注意到这些更改并立即将授权表加载到内存中。例如
GRANT,REVOKE,SET PASSWORD,RENAME USER
等操作。 - 如果使用
INSERT
,UPDATE
或DELETE
等语句直接修改授权表(不推荐),这些更改并不会加载到内存,除非告诉服务器重新加载授权表或者重启数据库。 flush-privileges
操作可以让服务器重新加载授权表。
官方文档的这段描述可以解释为什么在 UPDATE 操作之后,执行两次 GRANT 才能成功。
分析过程
UPDATE 操作之后并未将授权表的更改加载到内存,此时内存中并没有 test@'%'
用户,所以第一次 GRANT 操作失败了。
虽然返回执行失败了,但是第一次 GRANT 执行实际有将 UPDATE 的变更加载到内存(可以理解是隐式执行了 flush privileges
,不过 flush privileges
并没有记录到 binlog
日志中),所以第二次 GRANT 执行成功,从库回放到 GRANT 时复制中断重新启动复制即可恢复也是这个逻辑。
GRANT 操作是不是原子性?
那么问题来了,从复现的现象来看,第一个 GRANT 操作虽然执行返回错误,但是实际上已进行了重载授权表的操作。所以,GRANT 操作失败后并没有完全回滚,看来 GRANT 操作不是一个原子性操作,可以来验证一下。
实验验证
总结
- GRANT 操作并不是一个原子性操作,不管执行成功与否,都会触发一个隐式重载授权表的行为。
- 在生产环境中需要规范用户创建及授权的操作,不推荐使用 DML 语句去直接变更
mysql.user
表,可能会引发其他的问题,若使用了 DML 语句进行变更,需要手工执行flush privileges
。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
淘宝互动游戏之我养的鸡要旅行
游戏的开发区别于传统前端,本文记录了作者慢慢摸索该互动游戏项目过程中遇到的问题和解决的思路。 背景 近期PD找到我,说我们的特价版小鸡送好礼要进行大改版,要让小鸡在地图上自由的走动起来,期间会遇到各种随机事件、玩法,从而提高趣味性和业务指标。交互图如下: 作为一个半吊子游戏开发选手首先想到的就是: 小鸡如何行走,是否需要前、后、左、右、左上、左下、右上、右下八个动画; 遇到建筑物、河流如何处理; 交互稿子上有景深的效果、有道路,小鸡如何做到在道路上走、和远景房子等融合。 行走 和设计一起看了一些人物扮演游戏,自己也想了一下DNF、三国这些2D游戏,没我们想得那么复杂需要八个方向不同的动画,不区分奔跑的话就两种动画,左下和右下就能满足大部分场景。 设计师: 提供小鸡形象的spine骨骼动画是什么,包含行走(左、右)、奔跑(左、右)。 开发同学: 通过补间动画,将小鸡从当前位置移动到目标位置,配合spine动画一起循环播放。 行走的效果: 行走 奔跑 路径计算 ▐方案一:基于射线投射的寻路算法 这是我一开始想到的思路,但存在不少问题。 具体的路径计算步骤为: 从起点发射一条射线到目...
- 下一篇
Semi Design v2.62.0 发布,抖音企业级 UI 库
Semi Design 是现代、全面、灵活的设计系统和 UI 库,由字节跳动抖音前端与 UED 团队设计、开发并维护,是一款包含设计语言、React 组件、主题等开箱即用的中后台解决方案,可用于快速搭建美观的 React 应用。 Semi Design v2.62.0 现已发布,此版本带来如下更新内容: 【Fix】 Carousel 仅有一个 children 且 autoPlay 为 true 时不执行任何切换操作#2334 修复 Modal 在 getPopupContainer 中如果返回 document.body 异常的问题#2335 修复 Table 在 dataSource 为空时,存在非预期的 borderRadius 的问题#2337 【Chore】 Table Column jsx 写法支持传入 RecordType 泛型#2314#2320 更新说明:https://github.com/DouyinFE/semi-design/releases/tag/v2.62.0
相关文章
文章评论
共有0条评论来说两句吧...