mysql 8.0中lock tables权限必须按库显式授权(如grant lock tables on myapp_db.*),不可用on *.*,否则不生效;同时必须搭配backup_admin、reload、replication client等最小权限集,并执行flush privileges;xtrabackup需用--check-privileges提前验证。

GRANT 语句必须避开 MySQL 8.0 的 LOCK TABLES 权限陷阱
MySQL 8.0+ 中 LOCK TABLES 已被降级为数据库级权限,GRANT ... ON *.* 写法看似成功,实际不生效。一旦 XtraBackup 遇到 MyISAM 表或 fallback 场景(如长事务导致 --single-transaction 失效),就会报 Access denied; you need LOCK TABLES —— 而你查权限时还显示“已授权”。
正确做法是显式按库授权,库名必须用反引号包裹:
GRANT RELOAD, LOCK TABLES ON `myapp_db`.* TO 'bkpuser'@'localhost';- 若需备份多个库,逐个授权:
GRANT RELOAD, LOCK TABLES ON `log_db`.* TO 'bkpuser'@'localhost'; -
REPLICATION CLIENT可跨库授(ON *.*),因为它仍是全局权限 - 执行完务必
FLUSH PRIVILEGES;,否则权限不加载
xtrabackup --check-privileges 不是摆设,它能提前暴露权限缺口
XtraBackup 自带的 --check-privileges 参数不是装饰,它会真实连接并验证账号是否具备所有必需权限。很多团队跳过这步,直到备份失败才去翻日志,而错误信息常模糊(比如只报 Failed to connect 或 Can't lock tables),实际根源是缺 BACKUP_ADMIN 或 RELOAD。
运行前先校验:
xtrabackup --user=bkpuser --password=xxx --check-privileges --target-dir=/tmp/test- 它会明确列出缺失项,例如:
Missing privilege: BACKUP_ADMIN或Missing privilege: REPLICATION CLIENT - 注意:该命令不写盘、不耗时,但要求
--target-dir存在且可写
MySQL 8.0 必须加 BACKUP_ADMIN,否则 FLUSH TABLES WITH READ LOCK 失败
MySQL 8.0 移除了 SUPER 权限,FLUSH TABLES WITH READ LOCK(XtraBackup 在某些场景下仍会触发)现在依赖 BACKUP_ADMIN + LOCK TABLES 组合。只给 LOCK TABLES 不够,会卡在准备阶段并报错 Access denied; you need BACKUP_ADMIN。
最小权限集应包含:
-
SELECT:读取表结构和数据(含.frm、.ibd等) -
RELOAD:用于FLUSH LOGS、FLUSH TABLES等操作 -
LOCK TABLES:按库授权,不可省略 -
REPLICATION CLIENT:获取 binlog 位点(时间点恢复必需) -
BACKUP_ADMIN:MySQL 8.0+ 强制要求,替代旧版SUPER
不要授予 PROCESS 或 SHOW DATABASES——XtraBackup 不需要它们;也不要用 ALL PRIVILEGES,这是最常见也最危险的越权操作。
备份账号不能访问 mysql 系统库,除非你真要 dump 权限表
默认情况下,XtraBackup 不读取 mysql 库。但如果你用了 --flush-privileges(少见),或误配了 GRANT ... ON *.* 并希望备份系统库,则必须额外授权:GRANT SELECT ON mysql.* TO 'bkpuser'@'localhost';
但绝大多数生产环境不需要。漏掉它不会影响备份主流程;加了反而扩大攻击面——mysql.user 表泄露等于密码策略和账号体系裸奔。
更安全的做法是彻底隔离:
– 创建账号时限定 HOST(如 'localhost' 或具体内网 IP)
– 不授权任何系统库
– 定期用 SELECT user, host FROM mysql.user WHERE user = 'bkpuser'; 核对是否存在多余记录











