老师找学生做网站是什么心态,google网站地图格式,企业网站的缺点,免费制作企业小程序在MySQL中#xff0c;它是按什么顺序或规律去读取my.cnf配置文件的呢#xff1f;其实只要你花一点功夫#xff0c;实验测试一下就能弄清楚#xff0c;下面的实验环境为5.7.21 MySQL Community Server。其它版本如有不同#xff0c;请以实际情况为准。 其实#xff0c;MyS…在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 也不存在那么会怎么样呢 [rootgettestlnx02 ~]# 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 [rootgettestlnx02 ~]# ls /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnfls: cannot access /etc/mysql/my.cnf: No such file or directoryls: cannot access /usr/etc/my.cnf: No such file or directoryls: cannot access /root/.my.cnf: No such file or directory/etc/my.cnf[rootgettestlnx02 ~]# 如上所示其实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 exitBye [rootgettestlnx02 ~]# mv /etc/my.cnf /tmp/my.cnf[rootgettestlnx02 ~]# ls -lrt /etc/my.cnfls: cannot access /etc/my.cnf: No such file or directory[rootgettestlnx02 ~]# service mysqld stopStopping mysqld: [ OK ][rootgettestlnx02 ~]# service mysqld startStarting mysqld: [ OK ][rootgettestlnx02 ~]# 如上所示即使没了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 mysqlddatadir$resultget_mysql_option socket $datadir/mysql.sock mysqldsocketfile$resultget_mysql_option log-error /var/log/mysqld.log mysqld mysqld_safeerrlogfile$resultget_mysql_option pid-file /var/run/mysqld/mysqld.pid mysqld mysqld_safemypidfile$result 如果你对shell很熟那么可以忽略下面步骤如果不熟悉那么我们可以手工调试一下# sh -x mysqld看看它是如何获取相关变量的值的呢 [rootgettestlnx02 ~]# 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[rootgettestlnx02 ~]# /usr/bin/my_print_defaults mysqld[rootgettestlnx02 ~]# 如上所示因为/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是没有输出结果的 [rootgettestlnx02 ~]# ls /tmp/my.cnf/tmp/my.cnf[rootgettestlnx02 ~]# /usr/bin/my_print_defaults mysqld[rootgettestlnx02 ~]# mv /tmp/my.cnf /etc/my.cnf[rootgettestlnx02 ~]# /usr/bin/my_print_defaults mysqld--datadir/var/lib/mysql--socket/var/lib/mysql/mysql.sock--symbolic-links0--log-error/var/log/mysqld.log--pid-file/var/run/mysqld/mysqld.pid 接下来我们将配置文件my.cnf挪回原位/etc/my.cnf然后更改数据库数据存储目录从/var/lib/mysql挪动到/data/mysqldata/mysql 步骤从略然后我们再做下面测试 [rootgettestlnx02 ~]# service mysqld stopStopping mysqld: [ OK ][rootgettestlnx02 ~]# mv /etc/my.cnf /tmp/my.cnf[rootgettestlnx02 ~]# service mysqld startInitializing 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, LSN457902018-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 rootlocalhost: O;kZmIj.6jf[ OK ]Logging to /var/lib/mysql/gettestlnx02.err.Starting mysqld: [ OK ] MySQL服务居然也启动了它初始化了数据库数据文件位于/var/lib/mysql。这个确实让我吃了一惊原本预测如果更改数据库数据存储目录MySQL又没有my.cnf配置文件MySQL服务应该启动不了。当然这个启动也没有什么意义因为你的数据和一些账号权限配置都没有了有点类似于SQL Server里面的重建系统数据库 [rootgettestlnx02 mysql]# cd /var/lib/mysql[rootgettestlnx02 mysql]# ls -lrttotal 122948-rw-r-----. 1 mysql mysql 50331648 Mar 16 09:26 ib_logfile1-rw-r-----. 1 mysql mysql 56 Mar 16 09:26 auto.cnfdrwxr-x---. 2 mysql mysql 4096 Mar 16 09:26 performance_schemadrwxr-x---. 2 mysql mysql 4096 Mar 16 09:26 mysqldrwxr-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.locksrwxrwxrwx. 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[rootgettestlnx02 mysql]# 测试、折腾过程发现并不是所有情况下都会成功初始化数据库如果当/var/lib/mysql下存在一些文件时初始化会报错“initialize specified but the data directory has files in it. Aborting.”此时只要你清空 /var/lib/mysql下文件就能成功初始化。 [rootgettestlnx02 ~]# service mysqld stop [rootgettestlnx02 ~]# mv /etc/my.cnf /tmp/my.cnf [rootgettestlnx02 ~]# 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] [rootgettestlnx02 ~]# 其实只要稍微花费一点心思查看一下/etc/init.d/mysqld的代码就会发现start函数里面在条件满足的情况就会初始化数据库。 start(){ [ -x $exec ] || exit 5 # check to see if its already running RESPONSE$(/usr/bin/mysqladmin --no-defaults --socket$adminsocket --userUNKNOWN_MYSQL_USER ping 21) if [ $? 0 ]; then # already running, do nothing action $Starting $prog: /bin/true ret0 elif echo $RESPONSE | grep -q Access denied for user then # already running, do nothing action $Starting $prog: /bin/true ret0 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 21 /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 --usermysql --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 --uidmysql /dev/null 21 fi 另外在多实例情况下多实例有两种方案 1、基于mysqld_multi: 多个实例共用同一个my.cnf配置文件中利用[mysqld1]、[mysqld2]、[mysqld*]标签实现不同实例的差异化配置 2、基于多配置文件每一个实例单独一个my.cnf配置文件 多实例启动时都会指定对应的my.cnf所以虽然这里没有详细测试其实大致的原理也跟单实例是差不多的。当你有疑问或不解的时候动手实践是检验真理的唯一标准。