事务操作本身不依赖特殊权限,但底层语句需要对应权限
MySQL 中
BEGIN、
COMMIT、
ROLLBACK这些事务控制语句本身不需要额外授权,它们只是会话级语法糖。真正起作用的是事务里执行的 DML(如
INSERT、
UPDATE、
DELETE)或 DDL(如
CREATE TABLE)语句——这些操作所需的权限(如
INSERT_PRIV、
UPDATE_PRIV)必须已授予用户。
常见误解是给用户加了
PROCESS或
SUPER就能任意事务控制,其实没用;反而容易因权限过大埋下风险。 事务中执行
UPDATE orders SET status='paid' WHERE id=123,用户必须对
orders表有
UPDATE权限 若事务内含
DROP TABLE temp_log,则需
DROP权限,且该权限需作用于具体库表,不能只靠全局
GRANT OPTION使用
SET autocommit = 0同样不校验权限,但后续语句仍受常规权限约束
自定义函数(FUNCTION)必须显式授权,且有严格创建限制
MySQL 对存储函数权限管理比存储过程更苛刻:不仅调用时要授权,创建时就卡得死。
创建函数前必须满足两个硬性条件:
log_bin_trust_function_creators = ON(否则报错
ERROR 1418),或用户拥有
SUPER权限(5.7 及以前)/
SYSTEM_VARIABLES_ADMIN+
ROUTINE_ADMIN(8.0+)。这两个条件缺一不可。 函数调用权限通过
GRANT EXECUTE ON FUNCTION db_name.func_name TO 'user'@'host'单独授予,不随表权限自动继承
EXECUTE权限只允许调用,不能查看函数定义(查定义需
SELECT权限在
mysql.proc或
information_schema.ROUTINES) 若函数体内含 SQL(比如
SELECT ... INTO),其内部查询所涉表仍需对应
SELECT权限,函数不会“越权代查”
高危权限组合要拆分,避免用 SUPER 或 ALL PRIVILEGES
SUPER是 MySQL 里最危险的权限之一,它能绕过很多安全机制:终止任意线程、修改全局变量、跳过 binlog 写入、甚至覆盖函数创建限制。生产环境应彻底禁用。
替代方案是按最小权限原则精准授权:
需要动态修改max_connections?授
SYSTEM_VARIABLES_ADMIN而非
SUPER需要杀慢查询?授
CONNECTION_ADMIN(8.0+)或
PROCESS+
RELOAD(旧版),并配合监控脚本限制目标线程 需要创建函数?明确授
ROUTINE_ADMIN+
CREATE ROUTINE,再单独
GRANT EXECUTE给调用者 用
ALL PRIVILEGES ON db.*代替
ALL PRIVILEGES全局授权,防止误操作跨库
权限变更后必须 FLUSH PRIVILEGES,但注意生效时机差异
手动修改
mysql.user或
mysql.db表后,必须执行
FLUSH PRIVILEGES才能让新权限加载进内存。但通过
GRANT/
REVOKE语句授予权限时,MySQL 会自动刷新,无需再执行该命令。
特别要注意:权限变更对**已存在连接不立即生效**,只影响新建立的连接。这意味着你改完权限后,原用户只要不重连,仍可能用旧权限继续操作。
线上紧急回收某账号的UPDATE权限?除了
REVOKE UPDATE ON db.tbl FROM 'u'@'h',还得主动 KILL 对应连接(
KILL CONNECTION id)才能立刻阻断写入 函数权限变更(如
GRANT EXECUTE ON FUNCTION f1 TO u)同样遵循此规则:已有连接调用失败会报
ERROR 1449(The user specified as a definer does not exist),但不是权限问题,而是缓存未更新导致的 definer 解析失败 权限粒度越细,运维越清晰;但函数和事务相关的权限边界容易被忽略——尤其是
log_bin_trust_function_creators这种开关型配置,既不在 GRANT 体系内,又直接影响函数能否创建,上线前务必核对。
