mysql如何搭建开发环境和生产环境_mysql多环境配置方案

13次阅读

快速配好 MySQL 开发环境需用 docker run 启动轻量实例,关闭严格模式和 binlog,创建专用账号;生产环境须开启 binlog、设 innodb_flush_log_at_trx_commit=1、限制 secure_file_priv、禁用远程 root;代码通过环境变量自动切换数据库配置;dev 与 prod 需对齐 SQL mode、字符集及时区。

mysql 如何搭建开发环境和生产环境_mysql 多环境配置方案

MySQL 开发环境 怎么快速配好?

开发环境的核心诉求是「改得快、查得清、崩了不心疼」,不需要高可用或强安全,但必须方便本地调试和 CI 流水线接入。

  • docker run 启一个轻量实例最省事:
    docker run -d --name mysql-dev -p 3306:3306    -e MYSQL_ROOT_PASSWORD=dev123    -e MYSQL_DATABASE=myapp_dev    -v $(pwd)/mysql-dev-data:/var/lib/mysql    -v $(pwd)/my-dev.cnf:/etc/mysql/conf.d/my.cnf    -d mysql:8.0
  • my-dev.cnf 里关掉严格模式和 binlog(除非你真要测主从):
    [mysqld] sql_mode = "" skip-log-bin innodb_flush_log_at_trx_commit = 2
  • 别用 root 连应用代码——建个专用账号:CREATE USER 'devuser'@'%' IDENTIFIED BY 'devpass'; GRANT ALL ON myapp_dev.* TO 'devuser'@'%';

生产环境 MySQL 必须关掉哪些默认配置?

MySQL 8.0 默认配置是为「单机演示」设计的,直接上生产等于埋雷。重点不是加功能,而是关掉危险默认项。

  • skip-log-bin 必须删掉,否则无法做主从或 PITR(按时间点恢复);但记得开 binlog_format = ROW,语句级日志在多表更新时容易主从不一致
  • innodb_flush_log_at_trx_commit = 1 不能动,这是 ACID 的底线;设成 2 或 0 会导致断电丢事务
  • 关掉 symbolic-links = 0(已默认禁用),但检查 secure_file_priv 是否为空——为空意味着 LOAD DATA INFILE 可读任意路径,生产必须设为具体目录如 /var/lib/mysql-files/
  • 禁止远程 root 登录:DELETE FROM mysql.user WHERE User='root' AND Host!='localhost'; FLUSH PRIVILEGES;

如何让同一套代码自动连不同环境的 MySQL?

靠硬 编码 或手动改 配置文件,迟早出错。关键是在连接初始化阶段根据运行上下文选配置,而不是靠 if-else 切换 host/port。

  • 环境变量 驱动:应用启动前设 DB_ENV=prodDB_ENV=dev,代码里读 os.getenv('DB_ENV') 查对应配置段
  • 配置文件分层管理(例如 Python 的 config.py):
    class Config:     SQLALCHEMY_ENGINE_OPTIONS = {"pool_pre_ping": True} 

    class DevelopmentConfig(Config): SQLALCHEMY_DATABASE_URI = "mysql+pymysql://devuser:devpass@localhost:3306/myapp_dev"

    class ProductionConfig(Config): SQLALCHEMY_DATABASE_URI = "mysql+pymysql://appuser:xxx@db-prod-01:3306/myapp_prod"

  • 别把密码写进代码或 Git —— 生产密钥走 secrets manager 或挂载的 /run/secrets/db_password(Docker Swarm)或 Secrets Store CSI Driver(K8s)

为什么 dev 和 prod 用同一个 MySQL 版本还会出兼容问题?

版本号一样,不代表行为一致。MySQL 的隐式行为受 SQL mode、字符集、时区、甚至系统库版本影响,开发没报错,上线就挂。

  • 检查两边的 SELECT @@sql_mode; —— 开发常是空或宽松值(NO_ENGINE_SUBSTITUTION),而生产开了 STRICT_TRANS_TABLES,导致 INSERT INTO t(a) VALUES ('') 在 dev 成功、prod 报错
  • 确认 SELECT @@character_set_database, @@collation_database; 一致,尤其注意 utf8mb4_0900_as_cs(8.0 默认)和旧版 utf8mb4_general_ci 对排序结果的影响
  • 开发机时区可能是 SYSTEM(即宿主机本地时间),而生产数据库统一设为 +00:00NOW()CONVERT_TZ() 行为会偏移
  • 最稳妥的做法:在 Docker Compose 或 K8s manifest 中显式指定 environment: - TZ=UTCcommand: [--default-time-zone='+00:00']

实际部署时,最容易被跳过的不是备份策略,而是「开发与生产 SQL mode 的对齐校验」——它不会让你的服务起不来,但会让某条看似简单的 INSERT 在凌晨三点突然开始失败。

text=ZqhQzanResources