MySQL 8.0 中恢复误删用户需确保 binlog_format=ROW 且 log_bin=ON,定位 DELETE FROM mysql.user 事件,提取字段值构造 INSERT 语句,执行前设 SET sql_log_bin=0,最后必须 FLUSH PRIVILEGES 生效。

确认 binlog 是否记录了权限变更操作
MySQL 8.0 默认使用 ROW 格式记录 DML(如 INSERT/UPDATE/DELETE),但对 DDL(如 CREATE USER、GRANT、DROP USER)和权限表(mysql.user、mysql.db 等)的修改,binlog_format 必须为 ROW 才能完整捕获行级变更。如果配置是 MIXED 或 STATEMENT,GRANT 类语句可能只记为原始 SQL,而无法还原被删用户的字段值。
检查方式:
-
SHOW VARIABLES LIKE 'binlog_format';—— 必须返回ROW -
SHOW VARIABLES LIKE 'log_bin';—— 必须为ON -
SELECT * FROM performance_schema.replication_applier_status_by_coordinator;(可选)验证复制通道是否正常,避免日志被意外截断
定位误删用户操作在 binlog 中的位置
权限数据存在 mysql.user 表中,误删用户本质是执行了 DELETE FROM mysql.user WHERE User='xxx' AND Host='yyy'。但直接用 grep 搜 DELETE FROM mysql.user 很容易漏掉——因为 mysqlbinlog 输出中,该操作会被编码为 ### DELETE FROM `mysql`.`user`,且紧跟多行 ### @1=... 字段快照。
推荐做法:
- 先用
mysqlbinlog --base64-output=DECODE-ROWS -vv /var/lib/mysql/binlog.0000xx | less浏览最近几个 binlog 文件 - 搜索关键词:
### DELETE FROM `mysql`.`user`或### UPDATE `mysql`.`user`(权限被清空也可能表现为 UPDATE 将authentication_string设为空) - 注意时间窗口:用
--start-datetime和--stop-datetime缩小范围,避免解析整文件耗时过长
从 binlog 提取并反转成 INSERT 语句
binlog 的 ROW 模式会记录被删行的完整字段值,但不会自动生成可执行的 INSERT。你需要手动或脚本化提取:
- 找到目标
DELETE事件后,向下看### @1=...到### @N=...这些行 —— 它们就是被删用户的各列原始值 - 按
mysql.user表结构顺序拼成INSERT INTO mysql.user (...) VALUES (...);特别注意:authentication_string是哈希值(如$A$...<code>),不能用明文密码替代 - 权限字段(如
Select_priv、Insert_priv)必须设为'Y'或'N',不能留空或 NULL - 执行前务必加
SET sql_log_bin = 0;,否则恢复操作本身又写入 binlog,造成循环或干扰
示例片段(还原一个被删的 admin@localhost):
SET sql_log_bin = 0;
INSERT INTO mysql.user (Host, User, authentication_string, Select_priv, Insert_priv, Update_priv, Delete_priv)
VALUES ('localhost', 'admin', '$A$abc123...', 'Y', 'Y', 'Y', 'Y');
FLUSH PRIVILEGES;执行恢复后必须 FLUSH PRIVILEGES
MySQL 不会自动重载 mysql.user 表的内存缓存。即使你成功插入了用户记录,新用户也无法登录,老用户权限也不会生效——除非显式执行 FLUSH PRIVILEGES;。
常见疏漏点:
- 忘记关
sql_log_bin,导致恢复语句又被记录进 binlog,下次再恢复时重复插入报错1396 - 没执行
FLUSH PRIVILEGES,以为恢复完成,实则权限未加载 - 用普通账号执行恢复,缺乏对
mysql库的INSERT权限,需用root或具备SYSTEM_USER权限的账户 - MySQL 8.0+ 的
caching_sha2_password插件要求authentication_string必须是有效哈希,直接填空字符串或明文会登录失败
最易被忽略的是:权限恢复不是“插入就完事”,它依赖服务端缓存刷新这个显式动作。不执行 FLUSH PRIVILEGES,所有操作都停留在磁盘,对运行中的连接完全无效。


















