mysql权限不能直接写入git,因其存储在系统表而非文本文件;应将授权意图转化为标准化grant/revoke语句,显式指定对象、兼容旧版、单行格式、分目录管理,并经dba审批后执行,配合规范commit message、sql注释及审计日志实现可追溯。

MySQL权限变更为什么不能直接写进Git
MySQL的用户权限存在数据库系统表里(比如 mysql.user、mysql.db),不是文本文件,没法像SQL建表语句那样直接提交到Git。硬把 SELECT * FROM mysql.user 导出成CSV再塞进仓库,既没操作语义,又容易因哈希字段(如 authentication_string)导致每次diff全是噪音。
真正可追溯的做法,是把「人执行了什么授权动作」这个意图固化为可读、可审、可重放的SQL语句,并纳入版本控制。
怎么生成可Git管理的权限SQL语句
用 SHOW GRANTS FOR 'user'@'host' 只能查当前结果,不反映变更过程;而 mysqldump --no-data --skip-triggers --routines 也不导权限。必须手动或脚本化生成标准化的 GRANT / REVOKE 语句:
- 所有语句显式指定
ON database.table,避免模糊的ON *.* - 用
IDENTIFIED BY而非IDENTIFIED WITH ... AS,兼容旧版本MySQL且语义清晰 - 每个语句独占一行,方便Git diff识别增删行
- 按角色/环境分目录存放,例如:
git/perms/prod/app_reader.sql、git/perms/staging/ci_deployer.sql
示例(真实可用):
GRANT SELECT ON `orders`.* TO 'reporting_user'@'10.20.%'; GRANT INSERT, UPDATE ON `logs`.`events` TO 'ingest_app'@'%';
谁来执行这些SQL?DBA还是CI流水线
权限变更必须走审批流,不能由开发直接提交SQL并自动执行。Git只是存凭证,不是执行引擎。
- 开发/运维提交
*_perms.sql到特定分支(如perms/main),触发PR流程 - DBA审查语句合理性:是否越权、是否遗漏
WITH GRANT OPTION、是否匹配最小权限原则 - 通过后,由DBA在目标实例上手动执行(或用带人工确认环节的Ansible Playbook)
- 执行成功后,记录
mysql -e "SHOW GRANTS FOR ..."输出到变更日志表,与Git commit hash 关联
跳过人工审核直接CI执行 GRANT,等于把root密码放进GitHub Actions secrets——技术上可行,安全上已失守。
审计时怎么快速定位某次权限变动
Git本身不存执行时间、执行人、影响实例等上下文,靠commit message和配套机制补全:
- 强制commit message格式:
[PERM] add read access to analytics_db for bi_team (ref: JIRA-123) - 在SQL文件头部加注释块,说明变更原因、生效环境、回滚方式
- 搭配MySQL的
general_log或企业版Audit Log,把实际执行的语句和操作者IP、时间戳对上 - 避免用
FLUSH PRIVILEGES——它不记binlog,也不进audit log,纯属黑盒刷新
最常被忽略的一点:MySQL 8.0+ 的角色(CREATE ROLE)虽支持复用,但角色赋权语句仍需进Git;且角色名本身要遵循命名规范(如 role__data_analyst_v1),否则重命名时Git无法体现语义变更。











