Docker中MariaDB挂载的自定义.cnf配置未生效问题排查
MariaDB Docker容器自定义配置不生效排查方案
问题背景
需要自定义wait_timeout等MariaDB服务端参数,参照官方镜像说明,在宿主机/config/mariadb目录下创建两个.cnf配置文件,通过如下volumes配置挂载到容器内:
volumes: - /config/mariadb:/etc/mysql/conf.d:ro - /config/mariadb:/etc/mysql/mariadb.conf.d:ro
宿主机目录下文件列表:
root@server:~# ls -l /config/mariadb total 12 -rwxrwx--- 1 root root 263 Jun 8 13:43 mariadb-finetuning.cnf -rwxrwx--- 1 root root 367 Jun 8 13:43 mariadb-inno.cnf
两个配置文件内容:
mariadb-inno.cnf
[mysqld] # * InnoDB # # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. # Read the manual for more InnoDB related options. There are many! # default_storage_engine = InnoDB # innodb_buffer_pool_size = 256M # innodb_log_buffer_size = 8M # innodb_file_per_table = 1 # innodb_open_files = 400 # innodb_io_capacity = 400 innodb_flush_method = fsync
mariadb-finetuning.cnf
[mysqld] # * Fine Tuning # # max_connections = 100 # connect_timeout = 5 wait_timeout = 3600 # max_allowed_packet = 16M # thread_cache_size = 128 # sort_buffer_size = 4M # bulk_insert_buffer_size = 16M # tmp_table_size = 32M # max_heap_table_size = 32M
异常表现
配置未实际生效,数据库内查询参数返回结果:
show variables where variable_name = 'innodb_flush_method' # Variable_name Value # innodb_flush_method O_DIRECT
已确认两个现象:
- 手动修改容器内
my.cnf写入配置可以生效,但该方式无法持久化,不符合使用需求 - 容器内用root身份执行
mysqld --print-defaults可以正常输出... --innodb_flush_method=fsync配置内容,怀疑配置未生效和入口脚本/docker-entrypoint.sh有关
排查步骤
按优先级从高到低逐一排查即可:
- 先检查配置文件权限:当前宿主机配置文件权限为
770,属主属组均为root,其他用户无任何读写权限。MariaDB容器内服务默认以uid=999的mysql用户启动,该用户属于other用户组,根本没有读取你挂载的配置文件的权限。你之前用root执行mysqld --print-defaults能读到配置,不代表运行服务的mysql用户能读到。可以在容器内执行如下命令验证:
如果执行后输出没有你自定义的参数,直接把宿主机上两个.cnf文件权限改为su mysql -s /bin/bash -c "mysqld --print-defaults"644,保证所有用户可读,重启容器即可。这是这类配置不生效问题最常见的原因。 - 检查配置加载顺序是否被覆盖:在容器内执行如下命令,可以查看mysqld启动时读取配置文件的完整顺序:
输出会按加载先后顺序列出所有会读取的.cnf文件,排在后面的文件内的同参数配置会覆盖前面的配置。MariaDB镜像默认自带的mysqld --verbose --help | grep -A 1 'Default options'/etc/mysql/mariadb.conf.d/50-server.cnf里默认就配置了innodb_flush_method = O_DIRECT,如果你的配置文件排序在这个文件之前,就会被默认值覆盖。这种情况把你的自定义配置文件改名为99-custom.cnf这类大序号开头的文件名,保证它最后被加载即可。 - 检查入口脚本是否注入了启动参数:部分版本的MariaDB官方镜像入口脚本会根据运行环境、预设环境变量自动拼接启动参数,这类命令行传入的参数优先级高于所有配置文件。可以执行如下命令临时启动容器,打印入口脚本的完整执行流程,看最终启动mysqld的命令是否带了覆盖参数:
如果最终执行的mysqld命令带了docker run -it --rm -v /config/mariadb:/etc/mysql/conf.d:ro -v /config/mariadb:/etc/mysql/mariadb.conf.d:ro 你的MariaDB镜像名:版本号 bash -x /docker-entrypoint.sh mysqld--innodb_flush_method=O_DIRECT参数,要么对应调整触发该设置的环境变量,要么直接在容器启动命令里显式传入你需要的参数值即可。 - 验证挂载有效性:进入容器后分别查看
/etc/mysql/conf.d、/etc/mysql/mariadb.conf.d两个目录下的文件,确认你的两个.cnf文件确实存在、内容和宿主机一致,排除SELinux等安全策略限制导致容器内无法读取挂载文件的情况。
补充:你当前将同一个宿主机目录同时挂载到容器内两个配置目录的操作没有功能性问题,但如果排查后确认是加载顺序问题,仅保留挂载到
/etc/mysql/mariadb.conf.d的映射即可,避免重复加载同一份配置。
内容的提问来源于stack exchange,提问作者FabianTe
相关产品推荐
相关产品推荐

