开发、预生产与生产环境必须严格隔离数据库实例或schema,禁用开发账号的drop/alter权限,仅授予必要dml权限,强制使用固定版本镜像和统一配置,ci流程自动拦截生产库连接串。

开发环境数据库不隔离,线上数据就可能被删光
开发环境和生产环境共用一个数据库实例,哪怕只是执行一条 DELETE FROM users WHERE status = 'test',也可能因为条件没写全、表名拼错、或事务没回滚,直接把生产数据清空。这不是假设——真实事故里,80% 的误删操作都发生在“就改一点点”的开发联调阶段。
MySQL 开发账号必须禁掉 DROP 和 ALTER 权限
开发账号不是为了造环境,而是为了跑逻辑。给 dev_user 授予 GRANT ALL PRIVILEGES 是最常见也最危险的操作。
- 必须显式只授
SELECT、INSERT、UPDATE、DELETE—— 连CREATE都不该默认放开 - 若真需要建表(比如本地跑 Flyway),只允许在
dev_%前缀的库上执行:GRANT CREATE ON `dev_%`.* TO 'dev_user'@'192.168.10.%' - 用
SHOW GRANTS FOR 'dev_user'@'%'检查权限,确认没有USAGE或GRANT OPTION—— 这俩是越权扩散的温床
预生产环境(pre)不能直连生产库
预生产环境常被当成“准上线沙盒”,但只要它连的是生产数据库,就不是沙盒,是雷区。测试 SQL 一跑,UPDATE config SET value = 'debug' 可能立刻让所有用户看到调试界面。
- 强制要求 pre 环境使用独立数据库实例,或至少独立 schema(如
pre_table_name_1) - 用 Liquibase 的
label机制区分变更集:生产只允许打带prod标签的脚本,pre 环境可跑pre和common标签 - 部署前自动校验连接串:CI 流程中加一步
grep -q 'prod-db' ecosystem.config.js && exit 1,防配置误提交
Docker 启动 MySQL 时必须固定版本和配置
开发机上 mysql --version 显示 8.0.33,生产是 8.0.32,看着只差一个小版本,但 JSON_TABLE 行为差异可能让查询直接报错;开发用默认 innodb_buffer_pool_size=128M,生产却要扛百万 QPS —— 配置漂移比代码 bug 更难复现。
- 镜像必须指定完整 tag:
mysql:8.0.32-debian-12,禁用mysql:8这类浮动标签 - 启动时挂载统一配置文件:
-v ./mysql-dev.cnf:/etc/mysql/conf.d/custom.cnf,里面明确写死sql_mode、字符集、日志级别 - 开发容器禁止挂载宿主机
/var/lib/mysql:避免本地残留数据污染下一次启动
最易被忽略的一点:环境隔离不是靠“大家自觉不用生产库”,而是靠权限卡死、连接串硬隔离、CI 自动拦截三重防线。少一环,就等于在生产数据表上裸奔。











