当mysql.server 调用mysqld_safe的时候并把一些必要的参数传给mysqld_safe,它就开始运行了。
查看了一下mysqld_safe的代码,有831行(包括注释
点击(此处)折叠或打开
- [root@media bin]# wc -l mysqld_safe
- 831 mysqld_safe
仔细看了一下这个脚本,主要分为4部分
1:函数,后面需要调用这些函数
2:确定参数,把这个参数传入到mysqld 命令中去
3:启动mysql服务
4:监控mysql服务
一:函数和参数值
在mysqld_safe这个脚本中,定义了不少函数
my_which();
log_generic ();
log_error ();
log_notice ();
eval_log_error ();
shell_quote_string();
parse_arguments();
add_mysqld_ld_preload();
mysqld_ld_preload_text();
get_mysql_config();
set_malloc_lib();
append_arg_to_args();
其中parse_arguments() 和append_arg_to_args() 这2个函数比较重要,一个是用来解析参数的,一个是用来把参数链接起来.
parse_arguments `$print_defaults $defaults --loose-verbose mysqld server`
就是把 my.cnf 配置文件里的参数解析出来。
下面来查看一下 parse_arguments() 代码
点击(此处)折叠或打开
- parse_arguments() {
- # We only need to pass arguments through to the server if we don't
- # handle them here. So, we collect unrecognized options (passed on
- # the command line) into the args variable.
- pick_args=1
- if test "$1" = PICK-ARGS-FROM-ARGV
- then
- pick_args=1
- shift
- fi
- for arg do
- # the parameter after "=", or the whole $arg if no match
- val=`echo "$arg" | sed -e 's;^--[^=]*=;;'`
- # what's before "=", or the whole $arg if no match
- optname=`echo "$arg" | sed -e 's/^\(--[^=]*\)=.*$/\1/'`
- # replace "_" by "-" ; mysqld_safe must accept "_" like mysqld does.
- optname_subst=`echo "$optname" | sed 's/_/-/g'`
- arg=`echo $arg | sed "s/^$optname/$optname_subst/"`
- case "$arg" in
- # these get passed explicitly to mysqld
- --basedir=*) MY_BASEDIR_VERSION="$val" ;;
- --datadir=*) DATADIR="$val" ;;
- --pid-file=*) pid_file="$val" ;;
- --plugin-dir=*) PLUGIN_DIR="$val" ;;
- --user=*) user="$val"; SET_USER=1 ;;
- # these might have been set in a [mysqld_safe] section of my.cnf
- # they are added to mysqld command line to override settings from my.cnf
- --log-error=*) err_log="$val" ;;
- --port=*) mysql_tcp_port="$val" ;;
- --socket=*) mysql_unix_port="$val" ;;
- # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
- --core-file-size=*) core_file_size="$val" ;;
- --ledir=*) ledir="$val" ;;
- --malloc-lib=*) set_malloc_lib "$val" ;;
- --mysqld=*) MYSQLD="$val" ;;
- --mysqld-version=*)
- if test -n "$val"
- then
- MYSQLD="mysqld-$val"
- PLUGIN_VARIANT="/$val"
- Else
- MYSQLD="mysqld"
- fi
- ;;
- --nice=*) niceness="$val" ;;
- --open-files-limit=*) open_files="$val" ;;
- --open_files_limit=*) open_files="$val" ;;
- --skip-kill-mysqld*) KILL_MYSQLD=0 ;;
- --syslog) want_syslog=1 ;;
- --skip-syslog) want_syslog=0 ;;
- --syslog-tag=*) syslog_tag="$val" ;;
- --timezone=*) TZ="$val"; export TZ; ;;
- --help) usage ;;
- *)
- if test -n "$pick_args"
- then
- append_arg_to_args "$arg"
- fi
- ;;
- esac
- done
- }
这里可以比较清楚的看出这个函数的功能是把一些参数解析出来并赋予给某个变量,把解析不了的参数追加到 $arg 变量中,但前提是pick_args 参数不为0。
Note:这里不能解析的变量指的是 除去以下参数的其他参数
--no-defaults
--defaults-file=FILE
--defaults-extra-file=FILE
--ledir=DIRECTORY
--open-files-limit=LIMIT
--core-file-size=LIMIT
--timezone=TZ
--malloc-lib=LIB
--mysqld=FILE
--mysqld-version=VERSION
--nice=NICE
--plugin-dir=DIR
--skip-kill-mysqld
--syslog
--skip-syslog
--syslog-tag=TAG
在这个函数中,pick_args这个参数初始值是为空,就是说如果是不能解析的参数,是不会追加到$arg变量中的,这会导致当你把启动mysql的参数都写到my.cnf配置文件中,他只会读取能解析的那几个参数,另外的都忽略了。解决的办法:1)写上—defaults-extra-file 的参数值2)修改函数中pick_args变量值,修改为一个非空值即可。
另外在启动mysql服务之前,还有设定一些参数,主要是设定一些启动mysql时候所产生的错误日志(err.log)和系统日志(syslog),可方便mysql错误的时候可以方便检查,还是就是pid_file,另外还有2个系统内核参数,open_files_limits和core_files_limits。
在确定了启动参数以后,就需要把mysqld命令和所需要的参数链接到一起:
点击(此处)折叠或打开
- cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"
- for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \
- "--datadir=$DATADIR" "--plugin-dir=$plugin_dir" "$USER_OPTION"
- do
- cmd="$cmd "`shell_quote_string "$i"`
- done
- cmd="$cmd $args"
- # Avoid 'nohup: ignoring input' warning
- test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null"
二:mysql 启动和监控
启动mysql的代码如下:
点击(此处)折叠或打开
- eval_log_error "$cmd"
看下eval_log_error 这个函数
点击(此处)折叠或打开
- eval_log_error () {
- cmd="$1"
- case $logging in
- file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;;
- syslog)
- # mysqld often prefixes its messages with a timestamp, which is
- # redundant when logging to syslog (which adds its own timestamp)
- # However, we don't strip the timestamp with sed here, because
- # sed buffers output (only GNU sed supports a -u (unbuffered) option)
- # which means that messages may not get sent to syslog until the
- # mysqld process quits.
- cmd="$cmd 2>&1 | logger -t '$syslog_tag_mysqld' -p daemon.error"
- ;;
- *)
- echo "Internal program error (non-fatal):" \
- " unknown logging method '$logging'" >&2
- ;;
- esac
- #echo "Running mysqld: [$cmd]"
- eval "$cmd"
- }
eval "$cmd" 这一行才是真正启动mysq服务的命令l
mysql 监控主要体现在当mysql宕掉的时候或者hang住的时候会自动重启mysql服务,用了一个while true的一个循环来实现的。或许这就是为什么叫mysql_safe 的原因了!
--------------------觉得后面写的有点凌乱了,真觉得自己的表达能力还需加强