my.cnf 增加一个配置项,MySQL 不能启动了


外向笑小鸭子
外向笑小鸭子 2024-01-02 11:16:11 51162
分类专栏: 资讯

有一天,同事问了我一个来自客户的问题:
在 my.cnf 中增加系统变量 foreign_key_checks 之后,MySQL 就启动不了了

我们尝试通过 SET 命令修改 foreign_key_checks,成功了。查看官方文档,明明也是有这个系统变量的:

为什么把 foreign_key_checks 加到配置文件里就不行了呢?

这就触及到我的盲区了,同时也勾起了我的好奇心,搞清楚这个问题势在必行。

研究一番之后,发现并不是只有 foreign_key_checks 存在这种情况,还有一些系统变量也是这样的,不能加到配置文件里,只能通过 SET 命令修改。

如果你也对这个问题感到好奇,我们就一起来探个究竟吧。

本文基于 MySQL 8.0.32 源码。

目录

  • 1. 问题复现

  • 2. 原理介绍

  • 3. 简单的分辨方法

  • 4. 总结

 

正文

1. 问题复现

在 my.cnf 中增加系统变量:

foreign_key_checks = 0

然后,启动 MySQL,结果:启动失败。查看 error.log,能看到如下错误信息:

unknown variable 'foreign_key_checks = 0'

官方文档里说 MySQL 支持这个系统变量,MySQL 说我不认识它,是不是有点奇怪?

不过,不管怎样,我们已经复现了这个问题,接下来,继续追根溯源。

2. 原理介绍

MySQL 中,每个系统变量都会在代码里定义,foreign_key_checks 定义如下:

图片

我最开始怀疑是 SESSION_VAR 的问题,调试了一遍,发现 SESSION_VAR 是无辜的,它并不是导致 MySQL 无法识别配置文件中 foreign_key_checks 的元凶。

调试过程中,发现了另一个疑似凶手,就是红框里的 NO_CMD_LINE

为了验证我的推测,又在代码中搜索了其它带有 NO_CMD_LINE 标志的系统变量,在其中发现了一个比较眼熟的家伙(autocommit):

图片

为了确认 autocommit 是否也会导致 MySQL 启动失败,修改了配置文件:

# foreign_key_checks = 0
autocommit = 0

注释掉配置文件中的 foreign_key_checks,加上了 autocommit,结果 MySQL 启动成功了。

完了,NO_CMD_LINE 看起来也不像凶手,探索之路就此进入了尴尬的局面。

又经过一番漫长的东调西试,发现了 autocommit 的秘密:autocommit 有两处定义,上面截图是 sql/sys_vars.cc 里的定义,还有一处位于 sql/mysqld.cc 文件

图片

为了验证 MySQL 能识别配置文件中的 autocommit,是因为 my_long_options 中增加了 autocommit 的定义,我把 my_long_options 中的 autocommit 删掉了,然后启动 MySQL,结果失败。

不过,遗憾的是,并没有报 unknown variable 错误,而是触发了一个断言错误,和配置文件无关,这条路径验证失败。

为了继续验证我的推测,在 sql/sys_vars.cc 中增加了一个带有 NO_CMD_LINE 标志的自定义系统变量,并加到配置文件中,然后,启动 MySQL,结果:启动失败,报错:unknown variable xxx

接着,我又在 sql/mysqld.cc 的 my_long_options 中增加了这个自定义的系统变量,然后,启动 MySQL,结果:启动成功

这就证明了我的推测:
sql/sys_vars.cc 中定义的系统变量,如果包含了 NO_CMD_LINE,MySQL 启动过程中不能识别。

这种系统变量加入 sql/mysqld.cc 的 my_long_options 数组之后,MySQL 启动过程中就能识别了,autocommit 就是这么干的。

另外,调试过程中还有另一个发现:sql/mysqld.cc 的 my_long_early_options 数组,也具有和 my_long_options 一样的功能。

概括来说,NO_CMD_LINE 是一扇门,my_long_optionsmy_long_early_options 是两扇窗,某个系统变量被 NO_CMD_LINE 关起来闭门思过之后,如果开了其中一扇窗,这个系统变量就可以从窗户上逃出来了。

3. 简单的分辨方法

有些系统变量能在配置文件中配置,有些变量又不能,我们想知道哪些变量能,哪些变量不能,除了撸代码还有别的方法吗?

当然是有的,用这个命令就可以:

/path/mysqld --verbose --help | grep "xxx"

例如,查看 foreign_key_checks 是否能通过配置文件配置:

./mysqld --verbose --help | grep "foreign-key-checks"

执行命令没有任何输出,说明 foreign_key_checks 不能通过配置文件配置。

查看 autocommit 是否能通过配置文件配置:

./mysqld --verbose --help | grep "autocommit"

# 输出如下
--autocommit Set default value for autocommit (0 or 1)
            (Defaults to on; use --skip-autocommit to disable.)

输出结果中有 --autocommit balabala,说明 autocommit 能通过配置文件配置。

注意:grep 后面系统变量名中的下划线需要替换为中划线,例如 foreign-key-checks。

4. 总结

对于官方文档里说明 MySQL 支持的系统变量,如果我们在配置文件(my.cnf)中增加了一个系统变量,MySQL 启动时报 unknown variable xxx 错误,说明这个系统变量不支持通过配置文件配置。

另一种分辨方法是执行 /path/mysqld --verbose --help | grep "xxx" 命令,如果输出结果中没有 --xxx balabala 这样的信息,也可以说明这个系统变量不支持通过配置文件配置。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=34131
赞同 0
评论 0 条
外向笑小鸭子L0
粉丝 0 发表 622 + 关注 私信
上周热门
如何使用 StarRocks 管理和优化数据湖中的数据?  2944
【软件正版化】软件正版化工作要点  2863
统信UOS试玩黑神话:悟空  2823
信刻光盘安全隔离与信息交换系统  2717
镜舟科技与中启乘数科技达成战略合作,共筑数据服务新生态  1251
grub引导程序无法找到指定设备和分区  1217
华为全联接大会2024丨软通动力分论坛精彩议程抢先看!  163
点击报名 | 京东2025校招进校行程预告  162
2024海洋能源产业融合发展论坛暨博览会同期活动-海洋能源与数字化智能化论坛成功举办  160
华为纯血鸿蒙正式版9月底见!但Mate 70的内情还得接着挖...  157
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

加入交流群

请使用微信扫一扫!