在 Linux 下的 MySQL(包括 8.0 版本)中,/etc/mysql/my.cnf 文件里的这两行代码:
!includedir /etc/mysql/conf.d/!includedir /etc/mysql/mysql.conf.d/
是 MySQL 配置文件的包含指令(Include Directive)。下面为你详细解释它的含义和作用:
1. 核心含义:!includedir 是什么?
!includedir 是 MySQL 读取配置文件时的一个特殊指令,意思是:
“在读取当前配置文件(my.cnf)的过程中,顺带去读取指定目录下所有以
.cnf为后缀的配置文件,并将它们的内容合并到当前配置中。”
也就是说,MySQL 启动时会按以下顺序“拼接”配置:
- 先读取
/etc/mysql/my.cnf本身的内容。 - 遇到
!includedir /etc/mysql/conf.d/时,按字母顺序读取该目录下所有.cnf文件。 - 遇到
!includedir /etc/mysql/mysql.conf.d/时,同样按字母顺序读取该目录下所有.cnf文件。
2. 为什么要这样设计?(模块化配置)
这种设计主要是为了配置管理的模块化和安全性:
- 解耦与清晰:不用把所有配置都堆在一个
my.cnf文件里,不同的功能(如主服务、客户端、自定义调优)可以分开放在不同的文件里。 - 避免升级冲突:通过包管理器(如
apt或yum)升级 MySQL 时,主配置文件my.cnf可能会被更新覆盖。如果你把自定义配置放在子目录(如conf.d)里,升级就不会影响你的配置。 - 方便软件包管理:不同的 MySQL 相关软件包(如
mysql-server,mysql-client)可以只往这些目录里丢自己的配置文件,互不干扰。
3. 这两个目录通常有什么区别?
在 Debian/Ubuntu 等 Linux 发行版中,这两个目录的分工通常是:
/etc/mysql/conf.d/:- 通常用于存放用户自定义的通用配置,或者一些可选的插件配置。
- 你可以自己在这里新建一个
.cnf文件来覆盖默认设置(比如调大连接数)。
/etc/mysql/mysql.conf.d/:- 通常用于存放 MySQL 服务器核心运行参数(最重要的
[mysqld]段落)。 - 比如 Ubuntu 上安装 MySQL 后,主要的服务器配置(数据目录
datadir、端口、socket、日志路径等)通常位于该目录下的mysqld.cnf文件中。
- 通常用于存放 MySQL 服务器核心运行参数(最重要的
4. 配置的优先级与覆盖规则
- 后加载的覆盖先加载的:如果多个配置文件里设置了同一个参数(例如都设置了
max_connections),那么字母排序靠后的文件,或者后一个!includedir目录中的配置会生效。 - 目录内的读取顺序:同一个目录下,MySQL 会按照文件名的字母顺序依次读取。例如
00-default.cnf会先于zz-custom.cnf被读取,因此zz-custom.cnf里的配置可以覆盖前者。
5. 使用注意事项
- 只认
.cnf后缀:目录下如果不是以.cnf结尾的文件(比如备份文件mysqld.cnf.bak),MySQL 会直接忽略。 - 修改后需重启/重载:修改了这些目录下的任何配置文件后,需要执行
systemctl restart mysql(或mysqld)才能使配置生效。 - 语法正确:确保你新建的
.cnf文件格式正确(如包含[mysqld]等段名),否则可能导致 MySQL 启动失败。
在 Linux 的 MySQL 8.0 中,配置 sql_mode 推荐修改以下两个位置之一(效果相同,取决于你的管理习惯):
1. 推荐方案:修改主服务配置文件
直接编辑 MySQL 服务端的主配置文件:
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
在文件末尾(或找到 [mysqld] 区块)添加如下内容:
[mysqld]sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
说明:
/etc/mysql/mysql.conf.d/mysqld.cnf是 Ubuntu/Debian 系发行版中 MySQL 服务器核心参数的默认存放位置,优先级较高。
2. 自定义方案:在 conf.d 目录下新建文件(防升级覆盖)
如果你希望配置与系统默认文件完全解耦(升级 MySQL 时不会被覆盖),可以在 /etc/mysql/conf.d/ 目录下新建一个自定义的 .cnf 文件:
sudo vim /etc/mysql/conf.d/sql-mode.cnf
写入以下内容(必须包含 [mysqld] 段名):
[mysqld]sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
文件名随意,但必须以 .cnf 结尾,建议以 z_ 开头(如 z_sql_mode.cnf)以保证最后加载、覆盖其他配置。
3. 常见 sql_mode 配置示例
- MySQL 8.0 默认模式(严格、安全):
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
- 去掉
ONLY_FULL_GROUP_BY(解决常见的 GROUP BY 报错):sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
- 彻底放宽模式(不推荐生产环境使用):
sql_mode=''
4. 修改后必须执行的操作
保存文件后,重启 MySQL 服务使配置生效:
sudo systemctl restart mysql# 或者sudo service mysql restart
5. 验证是否生效
登录 MySQL 命令行,执行:
SELECT @@sql_mode;
如果输出结果中包含你刚设置的模式,说明配置成功。
💡 补充:临时修改(无需重启,重启后失效)
如果你只是想临时测试,可以登录 MySQL 后执行:
-- 全局生效(当前 MySQL 实例运行期间有效)SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';-- 当前会话生效SET SESSION sql_mode='STRICT_TRANS_TABLEES,NO_ENGINE_SUBSTITUTION';
