我们知道mysql.server,mysqld_safe和mysqld都是可以用来启动mysql服务的,但他们之间是有些区别的

Note:Mysql.server指的是 /etc/init.d/mysql

这三个命令中,其中mysql.server和mysqld_safe 是shell 脚本写的,我们可以打开来查看里面的内容。

   打开mysql.server 脚本,大致看了一下,这个脚本的主要作用就是为了方便启动和关闭mysql服务,这个脚本中需要调用的是 mysqld_safe 这个脚本

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 

     ;;

在调用 mysqld_safe 的时候我要把 –datadir ,–pid-file,$other_args 这些参数值传入到mysqld_safe 脚本,那怎么来确定这些参数呢?    首先得知道 my_print_defaults 这个命令,这个命令就是从配置文件中读取mysql的参数值,具体可以通过  my_print_defaults  --help 查看: 默认情况下 my_print_defaults 会从 /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf 这些文件中读取配置信息,当然也可以通过 –e 参数选项来指定配置信息;

parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`

这行代码中parse_server_arguments 是个函数,是用来处理my_print_defaults 输出的一些参数,$print_defaults 就是指 my_print_defaults 命令的路径, $extra_args 是指要读取的配置文件, mysqld server mysql_server mysql.server 这些就是确定读配置信息的那几部分内容.   再查看parse_server_arguments 这个函数,就可以发现,其实只需要读取—basedir,--datadir,--pid-file这些参数

parse_server_arguments() { 
     for arg do 
     case "$arg" in 
     --basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` 
     bindir="$basedir/bin" 
     if test -z "$datadir_set"; then 
     datadir="$basedir/data" 
     fi 
     sbindir="$basedir/sbin" 
     libexecdir="$basedir/libexec" 
     ;; 
     --datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'` 
     datadir_set=1 
     ;; 
     --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; 
     --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; 
     esac 
     done 
     }



那最后$other_args 参数是什么?继续看脚本:

[ $# -ge 1 ] && shift

other_args="$*"

这里就可以看出 other_args 就是 除去$1 变量之后的所有变量

比如启动的时候用 ./mysql  start  --log-bin=/var/lib/mysql –performance-schema 那么

Other_args 变量就是等于 --log-bin=/var/lib/mysql –performance-schema,但一般我们启动的时候 就是./mysql start 所有一般other_args 是为空的。

   总结一下:mysql.server 这个脚本就是为了方便启动和关闭mysql 服务,但真正启动mysql服务的不是它.

(function(w, d, g, J) { var e = J.stringify || J.encode; d[g] = d[g] || {}; d[g]['showValidImages'] = d[g]['showValidImages'] || function() { w.postMessage(e({'msg': {'g': g, 'm':'s'}}), location.href); } })(window, document, '__huaban', JSON);



当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  的原因了!


 --------------------觉得后面写的有点凌乱了,真觉得自己的表达能力还需加强

(function(w, d, g, J) { var e = J.stringify || J.encode; d[g] = d[g] || {}; d[g]['showValidImages'] = d[g]['showValidImages'] || function() { w.postMessage(e({'msg': {'g': g, 'm':'s'}}), location.href); } })(window, document, '__huaban', JSON);