• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > mysqld_safe启动脚本源码阅读、分析

mysqld_safe启动脚本源码阅读、分析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-11

通过本文主要向大家介绍了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"

  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • mysql基础:mysqld_safe 启动执行流程详解
  • mysql安全启动脚本mysqld_safe详细介绍
  • mysqld_safe启动脚本源码阅读、分析

相关文章

  • 2018-12-05SQL查询入门(中篇)
  • 2018-12-05MySQL 存储过程的基本用法介绍
  • 2017-05-11MySQL-Python安装问题小记
  • 2018-12-05实例学习SQL的Select命令
  • 2018-12-05总结SQL Server中常用函数使用方法
  • 2018-12-05总结关于命令包注意点
  • 2018-12-05Oracle SecureFile的功能第1/4页
  • 2017-05-11PHP之Mysql常用SQL语句示例的深入分析
  • 2018-12-05PHP中mysql和mysqli的区别
  • 2018-12-05MSSQL 首字母替换成大写字母

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • 关于5.0.16的详细介绍
    • 如何授权查询v$视图
    • mysql自动化安装脚本(ubuntu and centos64)
    • MySQL修改账号的IP限制条件的方法详解
    • mysql 截取指定的两个字符串之间的内容
    • Mongodb之(小试牛刀)
    • 在SQL Server Management Studio中可以运行作业但是用T-SQL运行
    • oracle数据库添加或删除一列的sql语句
    • Mongodb的主从复制使用总结
    • 比较详细的完美解决安装sql2000时出现以前的某个程序安装已在安

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有