在MySQL中,它是按什么顺序或规律去读取my.cnf配置文件的呢?其实只要你花一点功夫,实验测试一下就能弄清楚,下面的实验环境为5.7.21 MySQL Community Server。其它版本如有不同,请以实际情况为准。

其实,MySQL是按照下面这个顺序来读取my.cnf:

1: /etc/my.cnf

2: /etc/mysql/my.cnf

3: /usr/etc/my.cnf

4: ~/.my.cnf

也就是说首先它会找/etc/my.cnf 这个文件, 如果这个文件不存在,那么它接下来去找/etc/mysql/my.cnf这个文件,依此类推(这个实验很简单,在此略过,不浪费篇幅),如果最后一个文件~/.my.cnf 也不存在,那么会怎么样呢?

[root@gettestlnx02 ~]# mysql --help | grep my.cnf

                      order of preference, my.cnf, $MYSQL_TCP_PORT,

/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf 

[root@gettestlnx02 ~]# ls /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

ls: cannot access /etc/mysql/my.cnf: No such file or directory

ls: cannot access /usr/etc/my.cnf: No such file or directory

ls: cannot access /root/.my.cnf: No such file or directory

/etc/my.cnf

[root@gettestlnx02 ~]# 

如上所示,其实MySQL安装完成后,只生成了/etc/my.cnf这个配置文件。其它路径的my.cnf文件是不存在的。我们先来测试一下,将配置文件移走。在这之前,我们先查看一下log_error的位置。如下所示:

mysql> show variables like '%log_error%';

+---------------------+---------------------+

| Variable_name       | Value               |

+---------------------+---------------------+

| binlog_error_action | ABORT_SERVER        |

| log_error           | /var/log/mysqld.log |

| log_error_verbosity | 3                   |

+---------------------+---------------------+

3 rows in set (0.00 sec)

 

mysql> exit

Bye

[root@gettestlnx02 ~]# mv /etc/my.cnf  /tmp/my.cnf

[root@gettestlnx02 ~]# ls -lrt /etc/my.cnf

ls: cannot access /etc/my.cnf: No such file or directory

[root@gettestlnx02 ~]# service mysqld stop

Stopping mysqld:  [  OK  ]

[root@gettestlnx02 ~]# service mysqld start

Starting mysqld:  [  OK  ]

[root@gettestlnx02 ~]# 

如上所示,即使没了my.cnf配置文件,MySQL服务依然可以启动,那么这个是怎么回事呢? 我们知道service mysqld start启动MySQL,其实是运行/etc/init.d/mysqld这个脚本。下面是脚本获取给变量datadir、socketfile、errlogifle赋值的部分脚本,如下所示:

# Extract value of a MySQL option from config files

# Usage: get_mysql_option OPTION DEFAULT SECTION1 SECTION2 SECTIONN

# Result is returned in $result

# We use my_print_defaults which prints all options from multiple files,

# with the more specific ones later; hence take the last match.

get_mysql_option () {

    option=$1

    default=$2

    shift 2  #移动到第3个参数,详情见下面调试。

    result=$(/usr/bin/my_print_defaults "$@" | sed -n "s/^--${option}=//p" | tail -n 1)

    if [ -z "$result" ]; then

        # not found, use default

        result="${default}"

    fi

}

 

get_mysql_option datadir "/var/lib/mysql" mysqld

datadir="$result"

get_mysql_option socket "$datadir/mysql.sock" mysqld

socketfile="$result"

get_mysql_option log-error "/var/log/mysqld.log" mysqld mysqld_safe

errlogfile="$result"

get_mysql_option pid-file "/var/run/mysqld/mysqld.pid" mysqld mysqld_safe

mypidfile="$result"

如果你对shell很熟,那么可以忽略下面步骤,如果不熟悉,那么我们可以手工调试一下(# sh -x mysqld),看看它是如何获取相关变量的值的呢?

[root@gettestlnx02 ~]# file /usr/bin/my_print_defaults

/usr/bin/my_print_defaults: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld

[root@gettestlnx02 ~]# 

如上所示,因为/usr/bin/my_print_defaults mysqld输出为空,所以result为空值, 所以result被授予${default}的值,而defualt=$2,其实就是第二个变量,如下所示,第二个变量被标记为红色。

get_mysql_option datadir "/var/lib/mysql" mysqld

datadir="$result"

另外,my.cnf的位置是会影响脚本输出结果的。如下所示:(不在几个默认路径的话,my_print_defaults是没有输出结果的)

[root@gettestlnx02 ~]# ls /tmp/my.cnf

/tmp/my.cnf

[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld

[root@gettestlnx02 ~]# mv /tmp/my.cnf  /etc/my.cnf

[root@gettestlnx02 ~]# /usr/bin/my_print_defaults mysqld

--datadir=/var/lib/mysql

--socket=/var/lib/mysql/mysql.sock

--symbolic-links=0

--log-error=/var/log/mysqld.log

--pid-file=/var/run/mysqld/mysqld.pid

接下来,我们将配置文件my.cnf挪回原位(/etc/my.cnf),然后更改数据库数据存储目录(从/var/lib/mysql挪动到/data/mysqldata/mysql 步骤从略),然后我们再做下面测试:

[root@gettestlnx02 ~]# service mysqld stop

Stopping mysqld:  [  OK  ]

[root@gettestlnx02 ~]# mv /etc/my.cnf  /tmp/my.cnf

[root@gettestlnx02 ~]# service mysqld start

Initializing MySQL database:  2018-03-16T01:26:19.589182Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

2018-03-16T01:26:20.034494Z 0 [Warning] InnoDB: New log files created, LSN=45790

2018-03-16T01:26:20.132219Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.

2018-03-16T01:26:20.193504Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 07ee8c42-28b9-11e8-a04a-005056b3ebdf.

2018-03-16T01:26:20.208662Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.

2018-03-16T01:26:20.209919Z 1 [Note] A temporary password is generated for root@localhost: O;kZmIj+.6jf

[  OK  ]

Logging to '/var/lib/mysql/gettestlnx02.err'.

Starting mysqld:  [  OK  ]

MySQL服务居然也启动了,它初始化了数据库,数据文件位于/var/lib/mysql。这个确实让我吃了一惊,原本预测,如果更改数据库数据存储目录,MySQL又没有my.cnf配置文件,MySQL服务应该启动不了。当然这个启动也没有什么意义,因为你的数据和一些账号权限配置都没有了(有点类似于SQL Server里面的重建系统数据库)

[root@gettestlnx02 mysql]# cd /var/lib/mysql

[root@gettestlnx02 mysql]# ls -lrt

total 122948

-rw-r-----. 1 mysql mysql 50331648 Mar 16 09:26 ib_logfile1

-rw-r-----. 1 mysql mysql       56 Mar 16 09:26 auto.cnf

drwxr-x---. 2 mysql mysql     4096 Mar 16 09:26 performance_schema

drwxr-x---. 2 mysql mysql     4096 Mar 16 09:26 mysql

drwxr-x---. 2 mysql mysql    12288 Mar 16 09:26 sys

-rw-r-----. 1 mysql mysql      420 Mar 16 09:26 ib_buffer_pool

-rw-------. 1 mysql mysql     1679 Mar 16 09:26 ca-key.pem

-rw-r--r--. 1 mysql mysql     1107 Mar 16 09:26 ca.pem

-rw-------. 1 mysql mysql     1675 Mar 16 09:26 server-key.pem

-rw-r--r--. 1 mysql mysql     1107 Mar 16 09:26 server-cert.pem

-rw-------. 1 mysql mysql     1675 Mar 16 09:26 client-key.pem

-rw-r--r--. 1 mysql mysql     1107 Mar 16 09:26 client-cert.pem

-rw-------. 1 mysql mysql     1675 Mar 16 09:26 private_key.pem

-rw-r--r--. 1 mysql mysql      451 Mar 16 09:26 public_key.pem

-rw-------. 1 mysql mysql        6 Mar 16 09:26 mysql.sock.lock

srwxrwxrwx. 1 mysql mysql        0 Mar 16 09:26 mysql.sock

-rw-r-----. 1 mysql mysql 12582912 Mar 16 09:26 ibtmp1

-rw-r-----. 1 mysql mysql 12582912 Mar 16 09:26 ibdata1

-rw-r-----. 1 mysql mysql 50331648 Mar 16 09:26 ib_logfile0

-rw-r-----. 1 mysql mysql     3277 Mar 16 09:27 gettestlnx02.err

[root@gettestlnx02 mysql]# 

测试、折腾过程发现并不是所有情况下都会成功初始化数据库,如果当/var/lib/mysql下存在一些文件时,初始化会报错“initialize specified but the data directory has files in it. Aborting.”此时,只要你清空

/var/lib/mysql下文件,就能成功初始化。

[root@gettestlnx02 ~]# service mysqld stop

[root@gettestlnx02 ~]# mv /etc/my.cnf  /tmp/my.cnf

[root@gettestlnx02 ~]# service mysqld start

Initializing MySQL database:  2018-03-16T03:49:45.190114Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

2018-03-16T03:49:45.192215Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.

2018-03-16T03:49:45.192246Z 0 [ERROR] Aborting

[FAILED]

[root@gettestlnx02 ~]#

其实只要稍微花费一点心思,查看一下/etc/init.d/mysqld的代码,就会发现start函数里面在条件满足的情况就会初始化数据库。

start(){

    [ -x $exec ] || exit 5

    # check to see if it's already running

    RESPONSE=$(/usr/bin/mysqladmin --no-defaults --socket="$adminsocket" --user=UNKNOWN_MYSQL_USER ping 2>&1)

    if [ $? = 0 ]; then

        # already running, do nothing

        action $"Starting $prog: " /bin/true

        ret=0

    elif echo "$RESPONSE" | grep -q "Access denied for user"

    then

        # already running, do nothing

        action $"Starting $prog: " /bin/true

        ret=0

    else

        # prepare for start

        if [ ! -e "$errlogfile" -a ! -h "$errlogfile" -a "x$(dirname "$errlogfile")" = "x/var/log" ]; then

            install /dev/null -m0640 -omysql -gmysql "$errlogfile"

        fi

        [ -x /sbin/restorecon ] && /sbin/restorecon "$errlogfile"

        if [ ! -d "$datadir/mysql" ] ; then

            # First, make sure $datadir is there with correct permissions

            if [ ! -d "$datadir" -a ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then

                install -d -m0751 -omysql -gmysql "$datadir" || exit 1

            fi

            if [ ! -h "$datadir" -a "x$(dirname "$datadir")" = "x/var/lib" ]; then

                chown mysql:mysql "$datadir"

                chmod 0751 "$datadir"

            fi

            if [ -x /sbin/restorecon ]; then

                /sbin/restorecon "$datadir"

                for dir in /var/lib/mysql-files /var/lib/mysql-keyring ; do

                    if [ -x /usr/sbin/semanage -a -d /var/lib/mysql -a -d $dir ] ; then

                        /usr/sbin/semanage fcontext -a -e /var/lib/mysql $dir >/dev/null 2>&1

                        /sbin/restorecon -r $dir

                    fi

                done

            fi

            # Now create the database

            initfile="$(install_validate_password_sql_file)"

            action $"Initializing MySQL database: " /usr/sbin/mysqld --initialize --datadir="$datadir" --user=mysql --init-file="$initfile"

            ret=$?

            rm -f "$initfile"

            [ $ret -ne 0 ] && return $ret

            # Generate certs if needed

            if [ -x /usr/bin/mysql_ssl_rsa_setup -a ! -e "${datadir}/server-key.pem" ] ; then

                /usr/bin/mysql_ssl_rsa_setup --datadir="$datadir" --uid=mysql >/dev/null 2>&1

            fi

另外,在多实例情况下,多实例有两种方案:

1、基于mysqld_multi: 多个实例共用同一个my.cnf配置文件中,利用[mysqld1]、[mysqld2]、[mysqld*]标签实现不同实例的差异化配置;

2、基于多配置文件:每一个实例单独一个my.cnf配置文件

多实例启动时都会指定对应的my.cnf,所以虽然这里没有详细测试,其实大致的原理也跟单实例是差不多的。当你有疑问或不解的时候,动手实践是检验真理的唯一标准。

MySQL服务读取参数文件my.cnf的规律研究探索的更多相关文章

  1. MYSQL数据库的参数文件

    参数文件:告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还会介绍各种参数的类型. 参数文件 当MySQL实例启动时,MySQL会先去 ...

  2. Ubuntu下面MySQL的参数文件my.cnf浅析

    前几天刚接手一个MySQL数据,操作系统为Ubuntu 16.04.5 LTS,  数据库版本为5.7.23-0ubuntu0.16.04.1(APT方式安装的MySQL).这个操作系统下的MySQL ...

  3. 一个生产可用的mysql参数文件my.cnf

    [client]#客户端选项设置#设置客户端和连接字符集default_character_set = utf8port = 3306socket = /opt/mysql-5.6.24/tmp/my ...

  4. MySQL服务优化参数设置参考

    l 通用类: key_buffer_size 含义:用于索引块的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写). 影响:对于MyISAM表的影响不是很大,MyISAM会使用系统的缓存来存储 ...

  5. Mysql任意读取客户端文件复现

    本机执行 python rogue_mysql_server.py 目标机器上连接本机数据库 mysql -u root -p -h 本机IP mysql -h 192.168.250.132 -ur ...

  6. MySQL 5.6.20-enterprise-commercial的参数文件位置问题

    今天在折腾MySQL的参数文件时,突然发现MySQL 5.6.20-enterprise-commercial-advanced-log这个版本数据库的参数文件my.cnf的位置有点奇怪,如下所示: ...

  7. mysql 优化配置参数(my.cnf)

    max_connections:允许客户端并发连接的最大数量,默认值是151,一般将该参数设置为500-2000max_connect_errors:如果客户端尝试连接的错误数量超过这个参数设置的值, ...

  8. MySQL体系结构之物理文件

    一.MySQL日志文件 mysql日志文件及功能: 日志文件 功能 错误日志 记录启动.停止.运行过程中mysqld时出现的问题 通用日志 记录建立客户端连接和执行的语句 二进制日志 记录更改数据的所 ...

  9. MySQL体系结构以及各种文件类型学习

    1,mysql体系结构 由数据库和数据库实例组成,是单进场多线程架构. 数据库:物理操作系统文件或者其它文件的集合,在mysql中,数据库文件可以是frm.myd.myi.ibd等结尾的文件,当使用n ...

随机推荐

  1. EntityFrameWork连接多Db配置

    如题所示,EF作为微软主推的ORM工具,最新版本已经是7,说明有很多人在使用它做项目.在使用过程中,可能会连接不同的数据库,本文介绍的是连接SqlServer,MySql和SQLite三种,并且可以互 ...

  2. .NET平台开源项目速览(19)Power BI神器DAX Studio

    PowerBI更新频繁,已经有点更不上的节奏,一直在关注和学习中,基本的一些操作大概是没问题,更重要的是注重Power Query,M函数,以及DAX的使用,这才是核心.   上个月研究了DAX的一些 ...

  3. 对于JDBC数据库的初始化操作

    package com.bluesky.connection; import java.sql.Connection; import java.sql.DriverManager; import ja ...

  4. Java架构工程师知识图,你都知道么?

    1.工程化专题 (团队大于3个人之后,你需要去考虑团队合作,科学管理)  2.源码分析专题 (好的程序员,一行代码一个设计就能看出来,源码分析带你品味代码,感受架构)  大家可以点击加入群:69757 ...

  5. 业余草分享 Spring Boot 2.0 正式发布的新特性

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  6. Centos7下,简单DOCKER 使用.映射SSH端口到宿主主机.

    其实使用docker完全没有必要ssh,初学的时候,可以这样熟悉以下操作. 参考这哥们的文章:http://www.jianshu.com/p/d2dd936863ec 获取镜像 docker pul ...

  7. SIFT解析(二)特征点位置确定

    最近微博上有人发起投票那篇论文是自己最受益匪浅的论文,不少人说是lowe的这篇介绍SIFT的论文.确实,在图像特征识别领域,SIFT的出现是具有重大意义的,SIFT特征以其稳定的存在,较高的区分度推进 ...

  8. PhpStorm如何下载github上的代码到本地

    1.看着菜单栏有一个VCS(Virus Capture Scripter)集群服务器的选项,选择其下面的Checkout from Version Control,然后 (1)选择GIT:输入git的 ...

  9. Unity引擎与C#脚本简介

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 由 QQ会员技术团队 发布在云+社区 1. Unity编辑器基础 从原理上讲,游戏开发就是将一系列变动的场景呈现在玩家面前,并根据玩家的输入 ...

  10. css动画--元素上下跳动

    在H5场景动画时,常常会用到着一样一个效果,箭头持续上下跳动来引导用户上下滑动整个页面 <!DOCTYPE html > <html> <head> <met ...