通过本文主要向大家介绍了mysqld safe,linux mysqld safe,mysqld safe 启动,没有mysqld safe,mysqld safe error等相关知识,希望本文的分享对您有所帮助
前几天读了下mysqld_safe脚本,个人感觉还是收获蛮大的,其中细致的交代了MySQL数据库的启动流程,包括查找MySQL相关目录,解析配置文件以及最后如何调用mysqld程序来启动实例等,有着不错的参考价值;与此同时,脚本中涉及了很多shell编程中的小技巧,像变量解析,sed替换转义,进程优先级的判断以及无处不在test结构等等,当作Linux shell的学习素材还是非常合适的,下面是我的环境:
数据库版本: MySQL 5.1.45
操作系统版本: Red Hat Enterprise Linux AS release 4 (Nahant Update 3)
MySQL基目录: /usr/local/mysql3306
配置文件目录: /usr/local/mysql3306/etc
数据库是安装好了的,代码如下:
#!/bin/sh # 一些状态变量的定义 KILL_MYSQLD=1; # 试图kill多余的mysqld_safe程序,1表示需要kill MYSQLD= # mysqld二进制可执行文件的名称 niceness=0 # 进程的调度优先级标识 # 下面的变量主要用于标识不使用错误日志和syslog logging=init # 日志记录状态,init代表初始化 want_syslog=0 # 标识是否要使用syslog syslog_tag= user='mysql' # --user选项值 pid_file= # pid文件的路径 err_log= # 错误日志的路径 # 这两个都是定义的syslog中标志位,在后面需要写入日志到syslog中时使用 syslog_tag_mysqld=mysqld syslog_tag_mysqld_safe=mysqld_safe trap '' 1 2 3 15 # 不允许程序在终端上被人打断(包括挂起,中断,退出,系统终止的情形) umask 007 # 默认权限770,其他组用户对该程序创建的文件没有任何权限 # defaults变量记载使用的配置文件的信息 defaults= case "$1" in --no-defaults|--defaults-file=*|--defaults-extra-file=*) defaults="$1"; shift ;; esac # usage()函数:使用--help选项时输出的使用帮助信息 usage () { cat <<EOF Usage: $0 [OPTIONS] --no-defaults Don't read the system defaults file --defaults-file=FILE Use the specified defaults file --defaults-extra-file=FILE Also use defaults from the specified file --ledir=DIRECTORY Look for mysqld in the specified directory --open-files-limit=LIMIT Limit the number of open files --core-file-size=LIMIT Limit core files to the specified size --timezone=TZ Set the system timezone --mysqld=FILE Use the specified file as mysqld --mysqld-version=VERSION Use "mysqld-VERSION" as mysqld --nice=NICE Set the scheduling priority of mysqld --skip-kill-mysqld Don't try to kill stray mysqld processes --syslog Log messages to syslog with 'logger' --skip-syslog Log messages to error log (default) --syslog-tag=TAG Pass -t "mysqld-TAG" to 'logger' All other options are passed to the mysqld program. EOF exit 1 } # my_which的作用相当于which,通过检索$PATH中的路径,打印出命令的全路径 # 这个函数就在后面一个地方用到了,就是my_which logger,意思等同于转换logger为/usr/bin/logger my_which () { save_ifs="${IFS-UNSET}" # 保存当前的内建分隔符,用于后面重置IFS IFS=: # 使用 : 来分割PATH中的路径 ret=0 for file # 这种写法等同于for file in &* do for dir in $PATH do if [ -f "$dir/$file" ] then echo "$dir/$file" continue 2 # continue 第 2 层, 这里就是跳出外层循环了 fi done ret=1 # signal an error break done # 将设置过的IFS重置回去 if [ "$save_ifs" = UNSET ] then unset IFS else IFS="$save_ifs" fi return $ret # Success } # 日志输出函数,这是个原型,后面被log_error和log_notice函数引用 log_generic () { # priority 代表日志信息的分类,从后面的两个函数可知有:daemon.error和daemon.notice两种类别 priority="$1" shift # 日志中记录的msg前缀格式: 时间 + mysqld_safe ,类似于系统日志的记录格式 msg="`date +'%y%m%d %H:%M:%S'` mysqld_safe $*" echo "$msg" case $logging in init) ;; # 初始化状态时,只在命令行输出msg信息,不记录日志 file) echo "$msg" >> "$err_log" ;; # 记录到err_log中 syslog) logger -t "$syslog_tag_mysqld_safe" -p "$priority" "$*" ;; # 使用logger记录到系统日志中 *) echo "Internal program error (non-fatal):" \ " unknown logging method '$logging'" >&2 ;; esac } # 下面两个函数是对log_generic函数中不同分类的引用 log_error () { log_generic daemon.error "$@" >&2 } log_notice () { log_generic daemon.notice "$@" } # 后面就是用它启动的mysqld,通过logging变量区分记录日志的类型,分错误日志和系统日志syslog两种 # 最后的eval命令会解析 $cmd 中的值并执行命令 eval_log_error () { cmd="$1" case $logging in file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;; syslog) 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" } # 转义函数,用于在非"a-z","A-Z","09",'/','_','.','=','-'的特殊字符前加上一个"\" # sed中的\1代表引用前面\(\)中匹配的值 shell_quote_string() { echo "$1" | sed -e 's,\([^a-zA-Z0-9/_.=-]\),\\\1,g' } # 该函数用于解析配置文件中的选项,并赋值给相应的变量 parse_arguments() { pick_args= if test "$1" = PICK-ARGS-FROM-ARGV then pick_args=1 shift fi for arg do # 取出参数值,比如 --port=3306 结果为: val = 3306 注意这里sed中使用;来分割,等同于/ val=`echo "$arg" | sed -e "s;--[^=]*=;;"` case "$arg" in # 将参数值传递给对应的变量 --basedir=*) MY_BASEDIR_VERSION="$val" ;; --datadir=*) DATADIR="$val" ;; --pid-file=*) pid_file="$val" ;; --user=*) user="$val"; SET_USER=1 ;; # 有些值可能已经在my.cnf配置文件的[mysqld_safe]组下设置了 # 某些值会被命令行上指定的选项值覆盖 --log-error=*) err_log="$val" ;; --port=*) mysql_tcp_port="$val" ;; --socket=*) mysql_unix_port="$val" ;; # 接下来这几个特殊的选项在配置文件的[mysqld_safe]组中是必须设置的 # 我没配置这个组,所以就用不到了(使用mysqld中的默认) --core-file-size=*) core_file_size="$val" ;; --ledir=*) ledir="$val" ;; --mysqld=*) MYSQLD="$val" ;; --mysqld-version=*) if test -n "$val" then MYSQLD="mysqld-$val" else MYSQLD="mysqld" fi ;; --nice=*) niceness="$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 ;; # 调用了usage函数,输出帮助信息 *) if test -n "$pick_args" then # 将其他命令行参数值附加到$arg的后面 append_arg_to_args "$arg" fi ;; esac done } ######################################## # 正式工作开始了!! ######################################## # # 下面两段是在寻找基目录和mysqld所在目录 # # 找到/usr/local/mysql3306/share/mysql目录,使用relpkgdata来记录相对路径和绝对路径 # 这个grep其实应该是想判断一下share/mysql是不是显示的绝对路径,不知道这么写的意义在哪里。 if echo '/usr/local/mysql3306/share/mysql' | grep '^/usr/local/mysql3306' > /dev/null then # 一口气用了三个替换,分别为: # 第一步:将/usr/local/mysql3306转换为空 # 第二步:将/share/mysql开头的/转换为空 # 第三步:在share/mysql开头加上./,结果即:./share/mysql relpkgdata=`echo '/usr/local/mysql3306/share/mysql' | sed -e 's,^/usr/local/mysql3306,,' -e 's,^/,,' -e 's,^,./,'` else relpkgdata='/usr/local/mysql3306/share/mysql' fi # 这一段都是在找mysqld文件,分别判断了libexec和bin目录 # 找不到就使用编译时的默认值 MY_PWD=`pwd` if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION" then if test -x "$MY_BASEDIR_VERSION/libexec/mysqld" then ledir="$MY_BASEDIR_VERSION/libexec" else ledir="$MY_BASEDIR_VERSION/bin" fi # 这里对errmsg.sys文件进行了判断,个人认为这是为了确认当前目录为一个mysql安装基目录 elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/bin/mysqld" then MY_BASEDIR_VERSION="$MY_PWD" ledir="$MY_PWD/bin" elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/libexec/mysqld" then MY_BASEDIR_VERSION="$MY_PWD" ledir="$MY_PWD/libexec"