查找默认的配置文件
-r file 如果文件可读,则为真
# # Read defaults file from 'basedir'. If there is no defaults file there # check if it's in the old (depricated) place (datadir) and read it from there # extra_args="" if test -r "$basedir/my.cnf" then extra_args="-e $basedir/my.cnf" else if test -r "$datadir/my.cnf" then extra_args="-e $datadir/my.cnf" fi fi
解析配置文件中的参数
my_print_defaults的用法如下:
my_print_defaults --defaults-file=example.cnf client mysql
即读取配置文件中,client和mysql部分的参数配置,
具体在本脚本中,是读取mysqld,server,mysql_server,mysql.server四个部分的配置参数。
parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
设置pid file的路径
-z string 判断字符串是否为空
如果--pid-file没有在读取到的配置文件中设置或者脚本刚开始的mysqld_pid_file_path参数没有设置,
则pid file默认设置在datadir下,以主机名.pid命名。
如果该参数设置了,还需要进一步判断
如果该参数中带有斜杠,则代表给定的值带有路径,可直接使用。
如果该参数中没带路径,则代表给定的值只是pid的文件名,可将其设在datadir下。
# # Set pid file if not given # if test -z "$mysqld_pid_file_path" then mysqld_pid_file_path=$datadir/`hostname`.pid else case "$mysqld_pid_file_path" in /* ) ;; * ) mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;; esac fi
服务脚本start选项
首先,切换到$basedir中
其次,判断$basedir/bin中的mysqld_safe是否是可执行文件,如果是,则启动mysqld实例,如果不是,则报错退出。
那么,启动流程又是如何实现的呢?
首先,执行$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &命令,启动mysqld实例。
注意到没有,mysqld_safe其实是在basedir中执行的,包括mysql初始化脚本mysql_install_db,也建议在basedir中执行,具体可参考:
分析MariaDB初始化脚本mysql_install_db
然后通过wait_for_pid函数进行判断,具体可见下文对于wait_for_pid函数的分析
判断完毕后,
查看$lockdir目录是否可写,可写的话,则在目录上创建一个文件。
case "$mode" in 'start') # Start daemon # Safeguard (relative paths, core dumps..) cd $basedir echo $echo_n "Starting MySQL" if test -x $bindir/mysqld_safe then # Give extra arguments to mysqld with the my.cnf file. This script # may be overwritten at next upgrade. $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$? # Make lock for RedHat / SuSE if test -w "$lockdir" then touch "$lock_file_path" fi exit $return_value else log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)" fi ;;
wait_for_pid函数
在利用mysqld_safe启动mysql实例后,会调用该参数
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
其中$!在shell中用于获取最后运行的后台Process的PID,具体在本例中,是mysqld_safe进程的pid。
因为第一个参数是created,所以会执行test -s "$pid_file_path" && i='' && break命令。
-s file 如果文件的长度不为零,则为真
该命令的意思是如果pid文件存在,则将变量i设置为空,并退出while循环。
然后执行如下判断,
if test -z "$i" ; then log_success_msg return 0 else log_failure_msg return 1 fi
如果$i为空,则打印成功日志,并退出脚本,很显然,在pid文件存在的情况下,会将变量i设置为空。
再来看看pid文件不存在的情况
首先,会判断$pid是否不为空(即if test -n "$pid")
如果不为空,则代表在执行完mysqld_safe后,已经捕捉到了该进程的pid。
在这种情况下,进一步通过kill -0 "$pid"确认该进程是否存在。
kill -0就是不发送任何信号,但是系统会进行错误检查,所以经常用来检查一个进程是否存在,当进程不存在时, kill -0 pid会返回错误
如果该进程存在,则不执行任何操作,直接跳到如下操作
echo $echo_n ".$echo_c" i=`expr $i + 1` sleep 1
将变量i加1,并sleep 1s。
然后,继续while循环,之所以这样做,是考虑到mysqld_safe已经执行,但是mysqld实例还在启动过程中,还没创建好pid文件。
一直到$1达到$service_startup_timeout定义的时长。
如果在while循环的过程中,通过kill -0 "$pid"判断到进程已经不存在了,
则会再判断一次,如果这次判断的结果依旧是pid file不存在,且进程不存在,则会执行
log_failure_msg "The server quit without updating PID file ($pid_file_path)."
这就是大名鼎鼎的“The server quit without updating PID file”的由来。
wait_for_pid () { verb="$1" # created (北联网教程,专业提供视频软件下载)
第1页 第2页 第3页 第4页 第5页 第6页 第7页 第8页 第9页 第10页 第11页 第12页 第13页 第14页 第15页 第16页 第17页 第18页 第19页 第20页 第21页 第22页 第23页 第24页 第25页 第26页 第27页 第28页 第29页 第30页……