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

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

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

 

1. case "$mode" in 
2. 'start') 
3. # Start daemon 
4. # Safeguard (relative paths, core dumps..) 
5. cd $basedir 
6. echo $echo_n "Starting MySQL" 
7. if test -x $bindir/mysqld_safe 
8. then 
9. # Give extra arguments to mysqld with the my.cnf file. This script 
10. # may be overwritten at next upgrade. 
11. $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &
12. wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$? 
13. # Make lock for RedHat / SuSE 
14. if test -w "$lockdir" 
15. then 
16. touch "$lock_file_path" 
17. fi 
18. exit $return_value 
19. else 
20. log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)" 
21. fi 
22. ;;


 

在调用 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 参数选项来指定配置信息;

  1. 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这些参数

1. parse_server_arguments() { 
2. for arg do 
3. case "$arg" in 
4. --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
5. bindir="$basedir/bin" 
6. if test -z "$datadir_set"; then 
7. datadir="$basedir/data" 
8. fi 
9. sbindir="$basedir/sbin" 
10. libexecdir="$basedir/libexec" 
11. ;; 
12. --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
13. datadir_set=1 
14. ;; 
15. --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
16. --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
17. esac 
18. done 
19. }


那最后$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服务的不是它.

 

************************************************************************

当mysql.server 调用mysqld_safe的时候并把一些必要的参数传给mysqld_safe,它就开始运行了。

查看了一下mysqld_safe的代码,有831行(包括注释 )


    1. [root@media bin]# wc -l mysqld_safe 
    2. 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() 代码

     

    1. parse_arguments() { 
    2. # We only need to pass arguments through to the server if we don't 
    3. # handle them here. So, we collect unrecognized options (passed on 
    4. # the command line) into the args variable. 
    5. pick_args=1 
    6. if test "$1" = PICK-ARGS-FROM-ARGV 
    7. then 
    8. pick_args=1 
    9. shift 
    10. fi 
    11. for arg do 
    12. # the parameter after "=", or the whole $arg if no match 
    13. val=`echo "$arg" | sed -e 's;^--[^=]*=;;'` 
    14. # what's before "=", or the whole $arg if no match 
    15. optname=`echo "$arg" | sed -e 's/^\(--[^=]*\)=.*$/\1/'` 
    16. # replace "_" by "-" ; mysqld_safe must accept "_" like mysqld does. 
    17. optname_subst=`echo "$optname" | sed 's/_/-/g'` 
    18. arg=`echo $arg | sed "s/^$optname/$optname_subst/"` 
    19. case "$arg" in 
    20. # these get passed explicitly to mysqld 
    21. --basedir=*) MY_BASEDIR_VERSION="$val" ;; 
    22. --datadir=*) DATADIR="$val" ;; 
    23. --pid-file=*) pid_file="$val" ;; 
    24. --plugin-dir=*) PLUGIN_DIR="$val" ;; 
    25. --user=*) user="$val"; SET_USER=1 ;; 
    26. # these might have been set in a [mysqld_safe] section of my.cnf 
    27. # they are added to mysqld command line to override settings from my.cnf 
    28. --log-error=*) err_log="$val" ;; 
    29. --port=*) mysql_tcp_port="$val" ;; 
    30. --socket=*) mysql_unix_port="$val" ;; 
    31. # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])! 
    32. --core-file-size=*) core_file_size="$val" ;; 
    33. --ledir=*) ledir="$val" ;; 
    34. --malloc-lib=*) set_malloc_lib "$val" ;; 
    35. --mysqld=*) MYSQLD="$val" ;; 
    36. --mysqld-version=*) 
    37. if test -n "$val" 
    38. then 
    39. MYSQLD="mysqld-$val" 
    40. PLUGIN_VARIANT="/$val" 
    41. Else 
    42. MYSQLD="mysqld" 
    43. fi 
    44. ;; 
    45. --nice=*) niceness="$val" ;; 
    46. --open-files-limit=*) open_files="$val" ;; 
    47. --open_files_limit=*) open_files="$val" ;; 
    48. --skip-kill-mysqld*) KILL_MYSQLD=0 ;; 
    49. --syslog) want_syslog=1 ;; 
    50. --skip-syslog) want_syslog=0 ;; 
    51. --syslog-tag=*) syslog_tag="$val" ;; 
    52. --timezone=*) TZ="$val"; export TZ; ;; 
    53. --help) usage ;; 
    54. *) 
    55. if test -n "$pick_args" 
    56. then 
    57. append_arg_to_args "$arg" 
    58. fi 
    59. ;; 
    60. esac 
    61. done 
    62. }


    这里可以比较清楚的看出这个函数的功能是把一些参数解析出来并赋予给某个变量,把解析不了的参数追加到 $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参数和两个系统内核参数:open_files_limits和core_files_limits

    在确定了启动参数以后,就需要把mysqld命令和所需要的参数链接到一起:

     

    1. cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" 
    2. for i in  "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \ 
    3. "--datadir=$DATADIR" "--plugin-dir=$plugin_dir" "$USER_OPTION" 
    4. do 
    5. cmd="$cmd "`shell_quote_string "$i"` 
    6. done 
    7. cmd="$cmd $args" 
    8. # Avoid 'nohup: ignoring input' warning 
    9. test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null"


    二、mysql 启动和监控

    启动mysql的代码如下


      1. eval_log_error "$cmd"


       

      看下eval_log_error 这个函数  

      1. eval_log_error () { 
      2. cmd="$1" 
      3. case $logging in 
      4. file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;; 
      5. syslog) 
      6. # mysqld often prefixes its messages with a timestamp, which is 
      7. # redundant when logging to syslog (which adds its own timestamp) 
      8. # However, we don't strip the timestamp with sed here, because 
      9. # sed buffers output (only GNU sed supports a -u (unbuffered) option) 
      10. # which means that messages may not get sent to syslog until the 
      11. # mysqld process quits. 
      12. cmd="$cmd 2>&1 | logger -t '$syslog_tag_mysqld' -p daemon.error" 
      13. ;; 
      14. *) 
      15. echo "Internal program error (non-fatal):" \ 
      16. " unknown logging method '$logging'" >&2 
      17. ;; 
      18. esac 
      19. #echo "Running mysqld: [$cmd]" 
      20. eval "$cmd" 
      21. }

       

      eval "$cmd"

       

      mysql 监控主要体现在当mysql宕掉的时候或者hang住的时候mysqld_safe会自动重启mysql服务,用了一个while true的一个循环来实现的,或许这就是为什么叫mysql_safe  的原因了!

              

       综上所述:mysql.server就是存放在/etc/init.d/下的mysql或者myqld文件,它其实就是一个调用mysqld_safe的脚本,只不过在调用mysqld_safe的同时加上了一些 参数,mysqld_safe也是一个脚本,它调用mysqld,并且它还有监控mysqld的功能,在mysqld宕掉的时候或者hang住的时候重启mysqld服务