You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Docker Compose配置MySQL初始化与数据持久化时,已挂载初始化SQL文件未自动执行

核心原因

MySQL 官方镜像的初始化脚本自动执行逻辑有硬限制:

  • 仅当容器内 /var/lib/mysql 目录完全为空(即数据库实例从未完成首次初始化)时,才会遍历执行 /docker-entrypoint-initdb.d 下的脚本文件
  • 你当前挂载的 db-data 命名卷已经存储了历史数据(从你执行show databases看到的example库可以确认),容器启动时检测到数据目录非空,会直接跳过全量初始化阶段,根本不会扫描、执行挂载进去的init.sql

你提供的启动日志可以完全印证这个判断:正常首次初始化时,日志会输出类似[Entrypoint]: Running /docker-entrypoint-initdb.d/init.sql的记录,而你的日志从入口脚本启动直接跳到MySQL服务就绪状态,完全跳过了初始化脚本执行环节。

解决步骤
  1. 清空历史持久化卷,触发自动初始化流程
    这是实现「首次启动自动执行初始化SQL、后续数据持久化」的标准操作,注意该操作会删除旧卷中存储的所有历史数据库数据:

    # 停止当前compose编排的所有服务
    docker-compose down
    # 查看遗留的db-data命名卷(命名规则为<项目目录名>_db-data)
    docker volume ls | grep db-data
    # 删除对应旧卷
    docker volume rm <上一步查到的完整卷名>
    # 重新启动服务,触发MySQL首次初始化
    docker-compose up -d
    

    这次启动时,MySQL会检测到空的/var/lib/mysql目录,自动执行挂载的init.sql,启动日志中可以看到明确的脚本执行记录。初始化完成后,所有写入的数据都会被持久化到新建的db-data卷中,后续容器重启不会重复执行初始化脚本。

  2. 需保留现有数据的补救方案
    如果你需要保留db-data卷里的现有数据,无法触发自动初始化,可以手动执行挂载进去的SQL文件:

    # 进入运行中的db容器
    docker exec -it <你的db容器名称> bash
    # 手动执行init.sql(密码为你配置的MYSQL_ROOT_PASSWORD值)
    mysql -u root -ppassword < /docker-entrypoint-initdb.d/init.sql
    
配置校验注意事项

你的docker-compose.yml本身没有语法或配置错误,只需要确认几个细节避免后续踩坑:

  • 确保./db/init.sql文件没有SQL语法错误,脚本内操作的数据库、表权限和配置的root用户匹配
  • 初始化目录的只读挂载配置ro是正确的,不会影响脚本的读取和执行
  • 一旦卷完成首次初始化,后续修改init.sql、重启容器都不会重新执行脚本——这类场景下的数据库结构变更应该通过正式的迁移流程处理,不能依赖容器的初始化逻辑

内容的提问来源于stack exchange,提问作者Damiano C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 05:36:08