返回文章列表

文章

docker-entrypoint-initdb.d初始化脚本的执行顺序

在 MySQL 官方镜像里,容器在首次启动时会把挂载到 /docker-entrypoint-initdb.d 目录下的所有脚本(后缀为 .sh、.sql、.sql.gz)一次性按 字母序(即“lexicographical order”)来执行

在 MySQL 官方镜像里,容器在首次启动时会把挂载到 /docker-entrypoint-initdb.d 目录下的所有脚本(后缀为 .sh.sql.sql.gz)一次性按 字母序(即“lexicographical order”)来执行,具体流程大致是这样的:

  1. Shell 通配符展开 入口脚本里有类似下面的循环(简化示意):

for f in /docker-entrypoint-initdb.d/*; do case "f"in.sh)echo"runningf" in *.sh) echo "running f"in.sh)echo"runningf"; . "f";;.sql)echo"importingf" ;; *.sql) echo "importing f";;.sql)echo"importingf"; mysql < "f";;.sql.gz)echo"gunzipandimportf" ;; *.sql.gz) echo "gunzip and import f";;.sql.gz)echo"gunzipandimportf"; gunzip -c "f"mysql;;)echo"ignoringf" | mysql ;; *) echo "ignoring f"∣mysql;;)echo"ignoringf" ;; esac done ``` 这里的 for f in /…/* 会由 shell 根据当前 locale 的排序规则,将匹配到的文件名按字母序排列后一次性展开并依次执行。(reddit.com) 2. 文件名决定执行顺序 - 如果你想精确控制顺序,只需要给脚本文件名前加数字前缀,比如 01_init.sql02_schema.sql03_data.sql,这样就能保证它们按你设计的数字顺序依次跑。 - 注意:子目录内的脚本默认不会被递归执行,只有直接位于 /docker-entrypoint-initdb.d 根目录下的文件才会被处理。(hub.docker.com) 3. 扩展名的影响 在同一个字母序列里,后缀并不影响排序——比如 10-a.sql 会在 2-b.sql 之前执行,因为 '1' < '2';要避免这类问题,更推荐使用两位或三位数字前缀(01-…02-…10-…)。#

小结:脚本的执行顺序完全由 文件名的字母(字节)序 决定,给脚本加上有序的数字前缀即可控制执行顺序。

📎 参考文章#