避免误操作的关键,在于从权限设计源头切断越权可能,而不是依赖人工谨慎或事后补救。MySQL 的权限隔离不是“能用就行”,而是要让每个账号只拥有完成其职责的最小权限,并在逻辑、库表、甚至行和列层面做分层控制。
按角色划分账号,禁用通用高权账号
生产环境不应存在长期使用的 root 或 super 权限账号。所有运维、开发、应用连接都应使用专用账号,权限严格绑定角色:
应用账号:仅授予对应数据库的 SELECT/INSERT/UPDATE/DELETE,且限定到具体表(如app_user.orders),不给
GRANT OPTION和 DDL 权限 运维账号:可执行
SHOW PROCESSLIST、
RELOAD、
REPLICATION CLIENT等监控类权限,但禁止直接操作业务表 DBA 账号:保留高权,但必须通过跳板机+双因素认证访问,且操作需审计留痕
库级与表级权限分离,避免跨库误写
默认禁止跨库访问。例如订单服务只需访问
shop_db,就不要赋予
user_db或
sys_db的任何权限。建库时统一前缀(如
prod_shop_),再用
GRANT ... ON `prod_shop_%`.* TO 'shop_app'@'%'实现模糊授权,既灵活又防越界。
对敏感表(如
users、
finance_log)单独收回 UPDATE/DELETE,或改用存储过程封装变更逻辑,强制走审批流。
用视图 + 列权限限制敏感字段暴露
开发查日志时不需要看到用户手机号明文,可创建视图屏蔽:
CREATE VIEW user_safe AS
SELECT id, username, created_at,
CASE WHEN is_admin THEN 'YES' ELSE 'NO' END AS role_flag
FROM users;再授予开发账号对该视图的 SELECT 权限,同时收回对原表的访问权。也可用列级权限精确控制:
GRANT SELECT(id,username,email) ON prod_db.users TO 'dev_read'@'%';
REVOKE SELECT(phone,identity_no) ON prod_db.users FROM 'dev_read'@'%';
启用 SQL 审计与只读实例分流高危操作
在 MySQL 8.0+ 启用 audit log plugin,记录所有 DROP、TRUNCATE、ALTER TABLE 等高危语句来源账号与时间;对核心库部署只读从库供 BI、导出、排查使用,主库禁止执行 SELECT * FROM huge_table 这类低效查询,从源头减少锁表与误删风险。
定期用
SELECT user, host, privilege_type, is_grantable FROM role_edges JOIN role_column_grants USING (role) WHERE ...梳理权限继承链,及时清理废弃角色与冗余授权。
