引言
MySQL数据库支持从配置文件中读取启动选项,不用每次启动时在命令行输入,方便管理。很多选项都是以纯文本的形式存在,可以用任何的编辑器打开编辑。.mylogin.cnf文件除外,此文件包含了登录路径的选项,使用mysql_config_editor程序去创建的加密文件。
搜索顺序
MySQL默认情况下是按照一定的顺序去搜索具体路径的配置文件,并且在windows和linux的操作顺序不一样。
搜索顺序,按照下面表格中文件名从上往下,如果存在相同的选项,最后一个出现的选项有最高的优先级。参考官网的解释:”Options are processed in order, so if an option is specified multiple times, the last occurrence takes precedence.”
Windows
在windows上,MySQL按照指定的顺序从下表中显示的文件中读取启动选项
文件名 | 描述 |
---|---|
%WINDIR%\my.ini, %WINDIR%\my.cnf | 全局 |
C:\my.ini, C:\my.cnf | 全局 |
BASEDIR\my.ini, BASEDIR\my.cnf | 全局 |
defaults-extra-file | 如果存在—default-extra-file |
%APPDATA%\MySQL.mylogin.cnf | Login选项,仅适用于client |
1 | 其中, |
Linux or Unix
在Linux或Unix等类Unix系统上,MySQL按照指定的顺序从下表中显示的文件中读取启动选项
文件名 | 描述 |
---|---|
/etc/my.cnf | 全局 |
/etc/mysql/my.cnf | 全局 |
SYSCONFDIR/my.cnf | 全局 |
$MYSQL_HOME/my.cnf | 仅适用于server |
defaults-extra-file | 如果存在—default-extra-file |
~/.my.cnf | 用户的选项 |
~/.mylogin.cnf | Login选项,仅适用于client |
1 | 其中, |
实验
生产环境一般多使用linux系统,在单实例和多实例启动时,my.cnf加载的顺序也存在不一样的情况,这里分别进行测试,对结果进行说明
单实例
在不考虑SYSCONDIR,同时BASEDIR为/usr/local/mysql的情况下,从上面的搜索顺序来看,MySQL会依次加载以下的文件:
- /etc/my.cnf
- /etc/mysql/my.cnf
- /usr/local/mysql/my.cnf
- ~/.my.cnf
也就是说MySQL会找/etc/my.cnf这个文件,如果此文件不存在,继续找/etc/mysql/my.cnf这个文件,依此类推,最后是读取–defaults-file加载的文件,如果最后的文件也不存在,通过mysqld的帮助可以看出来:
/etc/my.cnf
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf中只存在/etc/my.cnf时,很明显MySQL是加载的/etc/my.cnf
/etc/my.cnf && /etc/mysql/my.cnf
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf中只存在/etc/my.cnf和/etc/mysql/my.cnf时,很明显MySQL是加载的/etc/mysql/my.cnf
/etc/my.cnf && /etc/mysql/my.cnf && /usr/local/mysql/my.cnf
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf中存在/etc/my.cnf和/etc/mysql/my.cnf和/usr/local/mysql/my.cnf时,很明显MySQL是加载的/usr/local/mysql/my.cnf
/etc/my.cnf && /etc/mysql/my.cnf && /usr/local/mysql/my.cnf && ~/.my.cnf
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,很明显MySQL是加载的~/my.cnf
defaults-file
当指定–defaults-file为/tmp/my.cnf时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,很明显MySQL是加载的/tmp/my.cnf
多实例
多实例的启动通常使用mysqld_multi脚本,此脚本也支持–defaults-file选项。从mysqld_multi的官档上可以看出,mysqld_multi支持[mysqldN]的标签,其中N代表常量数字,此脚本是调用mysqld_safe命令是启动服务,所以支持[mysqld]标签做通用性配置文件,适用于多个实例启动时的通用配置,也可以使用[mysqldN],N代表特定端口做特殊性实例配置。
/etc/my.cnf && [mysqldN]
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在[mysqld]中全部配置innodb_lock_wait_timeout,又在/etc/my.cnf加了一个[mysqld3306]标签,这时候,MySQL是加载的是/etc/my.cnf的[mysqld3306]标签配置文件
/etc/my.cnf && /etc/mysql/my.cnf && [mysqldN]
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在[mysqld]中全部配置innodb_lock_wait_timeout,又在/etc/my.cnf和/etc/mysql/my.cnf加了一个[mysqld3306]标签,这时候,MySQL是加载的是/etc/mysql/my.cnf的[mysqld3306]标签配置文件
/etc/my.cnf && /etc/mysql/my.cnf &&/usr/local/mysql/my.cnf && [mysqldN]
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在[mysqld]中全部配置innodb_lock_wait_timeout,又在/etc/my.cnf和/etc/mysql/my.cnf和/usr/local/mysql/my.cnf加了一个[mysqld3306]标签,这时候,MySQL是加载的还是/etc/my.cnf的[mysqld3306]标签配置文件
/etc/my.cnf && /etc/mysql/my.cnf &&/usr/local/mysql/my.cnf && ~/.mycf && [mysqldN]
当没有指定–defaults-file时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在[mysqld]中全部配置innodb_lock_wait_timeout,又在全部配置了[mysqld3306]标签,这时候,MySQL是加载的是~/my.cnf的[mysqld3306]标签配置文件
defaults-file && [mysqldN]
当指定–defaults-file为/tmp/my.cnf时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在了[mysqld]中全部配置innodb_lock_wait_timeout,又在全部配置了了[mysqld3306]标签,这时候,了MySQL是加载的是/tmp/my.cnf的[mysqld3306]标签配置文件
defaults-file
当指定–defaults-file为/tmp/my.cnf时,而且/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf全部存在时,同时在[mysqld]中全部配置innodb_lock_wait_timeout,全部未配置了[mysqld3306]标签,这时候,MySQL是加载的是~/my.cnf的配置文件而不是加载的/tmp/my.cnf的配置文件,说明mysqld_multi不加载除默认搜索的配置文件外的其他[mysqld]标签
启动方式
MySQL的启动包括多种,包括以下几种:
- /usr/local/mysql/bin/mysqld –defaults-file=/etc/my.cnf –basedir=/usr/local/mysql –datadir=/opt/mysql/data –user=mysql
- /usr/local/mysql/bin/mysqld_safe –defaults-file=/etc/my.cnf –basedir=/usr/local/mysql –datadir=/opt/mysql/data –user=mysql
- /etc/init.d/mysqld start && service mysqld start
- mysqld_multi start
service mysqld start
service mysqld start的启动有一个要注意的地方,它不会加载~/.my.cnf,实验如下,很明显,部service mysqld start启动方式不加载~/.my.cnf的参数
分析
1 | 由于linux的service启动服务的方式是调用的/sbin/service脚本来进行管理的,并且/sbin/service脚本是shell编写的,可以通过debug的模式来查看具体执行过程 |
1
2
3
4
5通过上面的执行过程可以了解到,service mysqld start启动mysql的方式,实际最终调用的命令为:
env -i PATH=/sbin:/usr/sbin:/bin:/usr/bin TERM=linux SYSTEMCTL_IGNORE_DEPENDENCIES= SYSTEMCTL_SKIP_REDIRECT= /etc/init.d/mysqld start
此命令没有包含/home/mysql的环境变量,如果修改为以下命令,则可以加载~/.my.cnf
命令为:
env -i PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/home/mysql TERM=linux SYSTEMCTL_IGNORE_DEPENDENCIES= SYSTEMCTL_SKIP_REDIRECT= /etc/init.d/mysqld start
解决方案
从脚本/sbin/service的最下面部分可以看出,具体的启动命令,如果想修改为让service mysqld start的启动方式也能搜索~/.my.cnf的参数,可以修改具体的脚本,添加了一个if else判断条件,如下:1
2
3
4
5
6
7
8
9将脚本/sbin/service的第81行的原始命令:
env -i PATH="$PATH" TERM="$TERM" SYSTEMCTL_IGNORE_DEPENDENCIES=${SYSTEMCTL_IGNORE_DEPENDENCIES} SYSTEMCTL_SKIP_REDIRECT=${SYSTEMCTL_SKIP_REDIRECT} "${SERVICEDIR}/${SERVICE}" ${ACTION} ${OPTIONS}
修改为
if [ "${SERVICE}" = "mysqld" ]; then
env -i PATH="$PATH" HOME=/home/mysql TERM="$TERM" SYSTEMCTL_IGNORE_DEPENDENCIES=${SYSTEMCTL_IGNORE_DEPENDENCIES} SYSTEMCTL_SKIP_REDIRECT=${SYSTEMCTL_SKIP_REDIREC
T} "${SERVICEDIR}/${SERVICE}" ${ACTION} ${OPTIONS}
else
env -i PATH="$PATH" TERM="$TERM" SYSTEMCTL_IGNORE_DEPENDENCIES=${SYSTEMCTL_IGNORE_DEPENDENCIES} SYSTEMCTL_SKIP_REDIRECT=${SYSTEMCTL_SKIP_REDIRECT} "${SERVICEDIR}/${SERVICE}" ${ACTION} ${OPTIONS}
fi
如下:
修改后的脚本启动一下测试,查看已经满足需求
mysqld_multi start
当mysqld_multi方式指定–defaults-file的参数文件时,不加载除默认搜索顺序以外的[mysqld]标签,也可以做下debug,mysqld_multi是perl脚本,可能通过perl -d script的方式进行调试,这里不再展示。
结论
通过以上的的测试,得出以下结论1
2
3
41. 默认情况前三种启动方式下,[mysqld]标签以按照/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf,--defaults-file搜索顺序加载
2. mysqld_mutli启动方式,[mysqldN]标签也是按照/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf,--defaults-file搜索顺序加载。但是,[mysqld]标签只按照/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf搜索顺序加载,不加载--defaults-file的配置
3. service mysqld start启动方式,默认不加载~/.my.cnf文件,需要修改脚本才能让其支持搜索
4. 当找不到/etc/my.cnf,/etc/mysql/my.cnf,/usr/local/mysql/my.cnf,~/.my.cnf,--defaults-file的配置时,默认编译的mysql,参数是全部其默认值,数据目录保存在BASEDIR下的data目录。比如,BASEDIR为/usr/local/mysql,则DATADIR为/usr/local/mysql/data,上面没有实验这一项