DBA账号不应拥有SUPER权限,因其在MySQL 8.0+中已被弃用且风险极高;应改用SYSTEM_VARIABLES_ADMIN、CONNECTION_ADMIN等动态权限替代,并限制登录来源、精简root@localhost权限、设置资源配额以防范误操作与提权风险。

DBA账号不该有 SUPER 权限
MySQL 8.0+ 中 SUPER 已被标记为弃用,且它是一把“万能钥匙”:能绕过所有限制、修改全局变量、杀掉任意连接、甚至跳过二进制日志写入。真实事故里,90% 的误删/误改都源于这个权限被滥用。
替代方案是按需授予动态权限(Dynamic Privileges),例如:
-
SYSTEM_VARIABLES_ADMIN—— 允许调用SET PERSIST修改持久化变量,但不能动max_connections以外的敏感项 -
CONNECTION_ADMIN—— 可执行KILL,但无法KILL QUERY或影响其他用户会话状态 -
BACKUP_ADMIN—— 支持LOCK INSTANCE FOR BACKUP和物理备份操作,不带FILE权限,杜绝写 shell 风险 -
REPLICATION_SLAVE_ADMIN—— 管理复制链路,但不能CHANGE MASTER TO指向恶意源
检查当前 DBA 账号是否还在用 SUPER:
SELECT User, Host, Super_priv FROM mysql.user WHERE User = 'dba_admin';
若返回 Y,立刻迁移:
REVOKE SUPER ON *.* FROM 'dba_admin'@'192.168.10.%';<br>GRANT SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, BACKUP_ADMIN, REPLICATION_SLAVE_ADMIN ON *.* TO 'dba_admin'@'192.168.10.%';
root@localhost 也要收窄权限
很多团队以为 root@localhost 安全就放任不管,其实它默认拥有 FILE、PROCESS、SHUTDOWN 等高危权限,而日常运维根本用不到。
典型场景对比:
- 用
mysqldump备份?只需SELECT+LOCK TABLES+RELOAD,不需要FILE - 查慢查询日志?
SELECT权限查performance_schema.events_statements_summary_by_digest就够了,不需要PROCESS - 重启服务?那是操作系统层的事,DBA 不该在 SQL 层有
SHUTDOWN
精简命令示例:
REVOKE FILE, PROCESS, SHUTDOWN, SUPER ON *.* FROM 'root'@'localhost';<br>GRANT SELECT, LOCK TABLES, RELOAD, SHOW DATABASES ON *.* TO 'root'@'localhost';
执行后记得 FLUSH PRIVILEGES,但注意:MySQL 8.0+ 的权限变更会自动生效,FLUSH PRIVILEGES 仅对部分旧式缓存有效,不是必须步骤。
限制登录来源比设强密码更重要
一个复杂密码挡不住开放的 root@'%'。MySQL 8.0 默认创建了这个账号,它是远程提权的第一入口。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
立即执行:
DROP USER 'root'@'%';
再为 DBA 创建专用账号,绑定网络段和认证方式:
CREATE USER 'dba_admin'@'192.168.10.0/24' IDENTIFIED BY 'StrongPwd!2026' REQUIRE X509;<br>GRANT ... /* 上面精简后的动态权限 */ ... ON *.* TO 'dba_admin'@'192.168.10.0/24';
关键点:
- 用 CIDR 表达式(如
192.168.10.0/24)代替%,避免 IP 欺骗 -
REQUIRE X509强制客户端提供有效证书,比密码更难伪造 - 配合 MySQL 配置项
bind-address = 127.0.0.1,让root@localhost只能走 socket 连接,彻底切断 TCP 通道
资源限制防止误操作雪崩
DBA 执行一条没加 WHERE 的 UPDATE,可能锁住整张表几小时;跑一个全表 SELECT,可能吃光内存。靠自觉不如靠限制。
给 DBA 账号加每小时操作上限:
ALTER USER 'dba_admin'@'192.168.10.0/24'<br> WITH MAX_QUERIES_PER_HOUR 120<br> MAX_UPDATES_PER_HOUR 30<br> MAX_CONNECTIONS_PER_HOUR 10<br> MAX_USER_CONNECTIONS 3;
说明:
-
MAX_QUERIES_PER_HOUR 120:一小时内最多发 120 条语句(含SELECT、SHOW等) -
MAX_UPDATES_PER_HOUR 30:只统计修改类语句(INSERT/UPDATE/DELETE/REPLACE) -
MAX_USER_CONNECTIONS 3:同一账号最多保持 3 个活跃连接,防多开窗口误操作
这些限制写在 mysql.user 表的对应字段中,重启不失效,也不依赖插件状态。
真正难的是权限边界的持续校验——比如某天加了个新监控工具,它悄悄需要 INFORMATION_SCHEMA.PROCESSLIST 权限,而你没意识到这等价于开了 PROCESS。这类隐性依赖,得靠定期跑 SELECT user, host, authentication_string FROM mysql.user WHERE Super_priv='Y' OR Grant_priv='Y' 来兜底。

















