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=prod或
DB_ENV=dev,代码里读
os.getenv('DB_ENV') 查对应配置段
配置文件分层管理(例如 Python 的 config.py):
class Config:
SQLALCHEMY_ENGINE_OPTIONS = {"pool_pre_ping": True}
<p>class DevelopmentConfig(Config):
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://devuser:devpass@localhost:3306/myapp_dev"</p><p>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:00,
NOW()和
CONVERT_TZ()行为会偏移 最稳妥的做法:在 Docker Compose 或 K8s manifest 中显式指定
environment: - TZ=UTC和
command: [--default-time-zone='+00:00']
实际部署时,最容易被跳过的不是备份策略,而是「开发与生产 SQL mode 的对齐校验」——它不会让你的服务起不来,但会让某条看似简单的 INSERT 在凌晨三点突然开始失败。
