Docker下MariaDB entrypoint脚本无法创建数据库,如何解决?
解决MariaDB初始化脚本连接失败的问题
问题原因
挂载到/docker-entrypoint-initdb.d/的.sh脚本会被MariaDB的entrypoint脚本直接source执行,此时MariaDB服务还未完全启动,无法通过TCP连接(mariadb主机名)访问。而默认的mysql命令如果不指定连接方式,会尝试用TCP连接,导致出现ERROR 2002错误。
解决方法
方法1:使用Unix socket连接
修改你的create-test-db.sh脚本,在mysql命令中指定本地socket路径,绕开TCP连接:
#!/bin/bash set -e ADDITIONAL_DB_NAME="test_${MYSQL_DATABASE}" echo "Creating additional database: $ADDITIONAL_DB_NAME" # 指定Unix socket路径连接本地MariaDB mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -S /var/run/mysqld/mysqld.sock <<-EOSQL CREATE DATABASE IF NOT EXISTS \`$ADDITIONAL_DB_NAME\`; CREATE USER IF NOT EXISTS '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD'; GRANT ALL PRIVILEGES ON \`$ADDITIONAL_DB_NAME\`.* TO '$MYSQL_USER'@'%'; FLUSH PRIVILEGES; EOSQL
方法2:改用SQL脚本文件(推荐)
MariaDB的entrypoint会自动在服务启动后执行/docker-entrypoint-initdb.d/下的.sql文件,无需手动处理连接:
- 创建
provision/mariadb/create-test-db.sql文件,内容如下:
CREATE DATABASE IF NOT EXISTS `test_${MYSQL_DATABASE}`; CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}'; GRANT ALL PRIVILEGES ON `test_${MYSQL_DATABASE}`.* TO '${MYSQL_USER}'@'%'; FLUSH PRIVILEGES;
- 修改
docker-compose.yaml中的挂载配置:
volumes: - ./volumes/db:/var/lib/mysql - ./provision/mariadb/create-test-db.sql:/docker-entrypoint-initdb.d/create-test-db.sql
entrypoint会自动替换SQL文件中的环境变量并执行,无需额外脚本。
方法3:在脚本中等待服务启动
如果必须使用shell脚本,可以添加循环等待逻辑,直到MariaDB服务可连接:
#!/bin/bash set -e ADDITIONAL_DB_NAME="test_${MYSQL_DATABASE}" # 等待MariaDB服务启动 until mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1"; do echo "Waiting for MariaDB to start..." sleep 2 done echo "Creating additional database: $ADDITIONAL_DB_NAME" mysql -uroot -p"$MYSQL_ROOT_PASSWORD" <<-EOSQL CREATE DATABASE IF NOT EXISTS \`$ADDITIONAL_DB_NAME\`; CREATE USER IF NOT EXISTS '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD'; GRANT ALL PRIVILEGES ON \`$ADDITIONAL_DB_NAME\`.* TO '$MYSQL_USER'@'%'; FLUSH PRIVILEGES; EOSQL
这种方式会不断尝试连接,直到成功后再执行创建逻辑。
内容的提问来源于stack exchange,提问作者Dimitrios Desyllas
相关产品推荐
相关产品推荐

