如何通过docker-compose将sakila数据库完整导入MySQL并即时生效?
问题根源
你给phpmyadmin加的MAX_EXECUTION_TIME=0完全不影响MySQL的数据导入过程——数据导入是在MySQL容器内部执行的,这个配置根本碰不到导入逻辑。数据不全的核心原因大概率是:MySQL还没完全启动就绪,导入脚本就提前执行了;或者MySQL默认配置限制了大文件/大数据量的导入;也可能是导入脚本的执行顺序、挂载方式有问题。
具体修复方案
1. 确保MySQL完全就绪后再执行导入
Docker Compose的depends_on只保证容器启动顺序,不确保MySQL服务已经能接受连接。给MySQL服务加上健康检查,让导入逻辑等MySQL真正就绪后再运行:
mysql: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: your-root-pass MYSQL_DATABASE: sakila healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] timeout: 20s retries: 10 volumes: - ./sakila-schema.sql:/docker-entrypoint-initdb.d/01-sakila-schema.sql - ./sakila-data.sql:/docker-entrypoint-initdb.d/02-sakila-data.sql
MySQL容器会通过mysqladmin ping检查自身状态,只有服务正常响应后,才会标记为healthy。如果你的导入是通过单独容器执行,记得在该容器的depends_on里指定依赖MySQL的健康状态:
data-import: image: mysql:8.0 depends_on: mysql: condition: service_healthy command: > sh -c "mysql -h mysql -u root -p${MYSQL_ROOT_PASSWORD} sakila < /sakila-data.sql" volumes: - ./sakila-data.sql:/sakila-data.sql
2. 调整MySQL配置,解除导入限制
Sakila的导入数据可能包含大字段,默认的max_allowed_packet太小会导致插入失败。直接在MySQL服务的command里添加配置:
mysql: # 其他配置保持不变 command: --max_allowed_packet=64M
如果需要更多自定义配置,可以挂载my.cnf文件:
mysql: # 其他配置保持不变 volumes: - ./my.cnf:/etc/mysql/my.cnf
my.cnf示例内容:
[mysqld] max_allowed_packet=64M wait_timeout=3600 interactive_timeout=3600
3. 规范导入脚本的挂载顺序
MySQL会按文件名顺序执行/docker-entrypoint-initdb.d/下的脚本,必须给schema和data脚本加前缀保证执行顺序:
- 把建表脚本命名为
01-sakila-schema.sql - 把数据插入脚本命名为
02-sakila-data.sql
挂载到MySQL容器对应目录后,启动时会自动先建表、再插入数据。
4. 查看日志定位具体错误
执行以下命令查看MySQL容器的日志,就能找到导入失败的具体原因:
sudo docker logs <你的mysql容器名称>
比如日志里出现Table 'sakila.xxx' doesn't exist,就是脚本顺序错了;出现Packet for query is too large,就是max_allowed_packet配置不够。
验证方法
容器启动完成后,直接进入MySQL容器查询数据是否完整:
sudo docker exec -it <mysql容器名称> mysql -u root -p sakila # 进入后执行查询验证,比如查看actor表数据量 SELECT COUNT(*) FROM actor; # 正常结果应该是200条
内容的提问来源于stack exchange,提问作者amachree tamunoemi

