Docker部署MySQL8执行initdb.d大SQL初始化极慢如何优化?
问题根因
MySQL官方镜像的默认入口脚本执行/docker-entrypoint-initdb.d下的SQL时,默认启用了全量安全校验、事务自动提交、日志同步刷盘等策略,没有做批量导入优化,所以大文件导入速度极慢。而Navicat导入时会默认关闭非必要校验、批量提交事务,因此速度差异极大。
优化方案
临时调整MySQL启动参数
在docker-compose的mysql服务command字段中添加以下临时优化参数,测试环境可长期保留,生产环境初始化完成后可移除:command: [ "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci", "--lower_case_table_names=1", # 新增优化参数 "--innodb_flush_log_at_trx_commit=0", "--sync_binlog=0", "--innodb_buffer_pool_size=2G", # 可调整为服务器可用内存的50% "--innodb_log_file_size=1G" ]修改SQL文件添加优化开关
在SQL文件最开头添加以下配置,关闭非必要校验和自动提交,文件末尾再恢复配置:-- 开头添加 SET AUTOCOMMIT = 0; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0; -- 原有SQL内容 ... -- 末尾添加 SET FOREIGN_KEY_CHECKS = 1; SET UNIQUE_CHECKS = 1; COMMIT; SET AUTOCOMMIT = 1;替换初始化逻辑,容器启动后再导入
放弃使用镜像自带的entrypoint初始化机制,先启动MySQL容器,等健康检查通过后,执行命令直接导入SQL,速度和Navicat导入基本一致:docker exec -i mysql-service-name mysql -uroot -p123456 db_name < ./initdb.d/db.sql可以直接把这个步骤集成到你的Jenkins流水线中。
测试环境可使用内存挂载数据目录
如果是测试环境不需要持久化数据,可在docker-compose的mysql服务中添加tmpfs配置,把数据目录挂载到内存,IO性能拉满:tmpfs: - /var/lib/mysql优化挂载性能
不要用bind mount挂载SQL文件到initdb.d,可把SQL文件提前打包到自定义MySQL镜像中,避免宿主机挂载带来的IO损耗。
内容的提问来源于stack exchange,提问作者marcos
相关产品推荐
相关产品推荐

