mysql啓動腳本詳解

mysql啓動腳本詳解

  1 #!/bin/sh
  2 # Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
  3 # This file is public domain and comes with NO WARRANTY of any kind
  4 
  5 # MySQL daemon start/stop script.
  6 
  7 # Usually this is put in /etc/init.d (at least on machines SYSV R4 based
  8 # systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
  9 # When this is done the mysql server will be started when the machine is
 10 # started and shut down when the systems goes down.
 11 
 12 # Comments to support chkconfig on RedHat Linux
 13 # chkconfig: 2345 64 36
 14 # description: A very fast and reliable SQL database engine.
 15 
 16 # Comments to support LSB init script conventions
 17 ### BEGIN INIT INFO
 18 # Provides: mysql
 19 # Required-Start: $local_fs $network $remote_fs
 20 # Should-Start: ypbind nscd ldap ntpd xntpd
 21 # Required-Stop: $local_fs $network $remote_fs
 22 # Default-Start:  2 3 4 5
 23 # Default-Stop: 0 1 6
 24 # Short-Description: start and stop MySQL
 25 # Description: MySQL is a very fast and reliable SQL database engine.
 26 ### END INIT INFO
 27  
 28 # If you install MySQL on some other places than /usr, then you
 29 # have to do one of the following things for this script to work:
 30 #
 31 # - Run this script from within the MySQL installation directory
 32 # - Create a /etc/my.cnf file with the following information:
 33 #   [mysqld]
 34 #   basedir=<path-to-mysql-installation-directory>
 35 # - Add the above to any other configuration file (for example ~/.my.ini)
 36 #   and copy my_print_defaults to /usr/bin
 37 # - Add the path to the mysql-installation-directory to the basedir variable
 38 #   below.
 39 #
 40 # If you want to affect other MySQL variables, you should make your changes
 41 # in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
 42 
 43 # If you change base dir, you must also change datadir. These may get
 44 # overwritten by settings in the MySQL configuration files.
 45 
 46 basedir=            #mysql的安裝目錄
 47 datadir=            #數據存儲路徑
 48 
 49 # Default value, in seconds, afterwhich the script should timeout waiting
 50 # for server start. 
 51 # Value here is overriden by value in my.cnf. 
 52 # 0 means don‘t wait at all
 53 # Negative numbers mean to wait indefinitely
 54 service_startup_timeout=900
 55 
 56 # Lock directory for RedHat / SuSE.
 57 lockdir=‘/var/lock/subsys‘                #mysql進程鎖
 58 lock_file_path="$lockdir/mysql"
 59 
 60 # The following variables are only set for letting mysql.server find things.
 61 
 62 # Set some defaults
 63 mysqld_pid_file_path=
 64 if test -z "$basedir"                     #依次確定$basedir,$datadir,$bindir等路徑
 65 then
 66   basedir=/usr
 67   bindir=/usr/bin
 68   if test -z "$datadir"   
 69   then
 70     datadir=/var/lib/mysql
 71   fi
 72   sbindir=/usr/sbin
 73   libexecdir=/usr/sbin
 74 else
 75   bindir="$basedir/bin"
 76   if test -z "$datadir"
 77   then
 78     datadir="$basedir/data"
 79   fi
 80   sbindir="$basedir/sbin"
 81   libexecdir="$basedir/libexec"
 82 fi
 83 
 84 # datadir_set is used to determine if datadir was set (and so should be
 85 # *not* set inside of the --basedir= handler.)
 86 datadir_set=
 87 
 88 #
 89 # Use LSB init script functions for printing messages, if possible
 90 #
 91 lsb_functions="/lib/lsb/init-functions"   #linux系統腳本,包含打印log函數
 92 if test -f $lsb_functions ; then    #如果存在改文件,將這些函數導入該腳本
 93   . $lsb_functions
 94 else                              #否則使用自定義信息
 95   log_success_msg()
 96   {
 97     echo " SUCCESS! $@"
 98   }
 99   log_failure_msg()
100   {
101     echo " ERROR! $@"
102   }
103 fi
104 
105 PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"           #添加$basrdir到系統環境變量
106 export PATH
107 
108 mode=$1    # start or Stop        #傳入啓動腳本的第1個參數
109 
110 [ $# -ge 1 ] && shift      #如果參數個數大於等於1個,shift刪掉第一個參數,將剩餘參數傳給$other_args
111 
112 
113 other_args="$*"   # uncommon, but needed when called from an RPM upgrade action
114            # Expected: "--skip-networking --skip-grant-tables"
115            # They are not checked here, intentionally, as it is the resposibility
116            # of the "spec" file author to give correct arguments only.
117 
118 case `echo "testing\c"`,`echo -n testing`     #echo_c和echo_n的定義;\c不加換行符,-n不換行
119     *c*,-n*) echo_n=   echo_c=     ;;
120     *c*,*)   echo_n=-n echo_c=     ;;
121     *)       echo_n=   echo_c=‘\c‘ ;;
122 esac
123 
124 
125 parse_server_arguments() {                 #該函數將my_print_defaults 命令分析出得參數賦值給相應的變量
126   for arg do 
127     case "$arg" in
128       --basedir=*)  basedir=`echo "$arg" | sed -e ‘s/^[^=]*=//‘`    #利用正則表達式獲取
129                     bindir="$basedir/bin"
130             if test -z "$datadir_set"; then  
131               datadir="$basedir/data"
132             fi
133             sbindir="$basedir/sbin"
134             libexecdir="$basedir/libexec"
135         ;;
136       --datadir=*)  datadir=`echo "$arg" | sed -e ‘s/^[^=]*=//‘`
137             datadir_set=1
138     ;;
139       --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e ‘s/^[^=]*=//‘` ;;
140       --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e ‘s/^[^=]*=//‘` ;;
141     esac
142   done
143 }
144 
145 
146 
147 wait_for_pid () {                        #該函數在啓動和停止mysql服務時用於等待pid的生成
148   verb="$1"           # created | removed
149   pid="$2"            # process ID of the program operating on the pid-file
150   pid_file_path="$3" # path to the PID file.
151 
152   i=0
153   avoid_race_condition="by checking again"
154 
155   while test $i -ne $service_startup_timeout ; do    
156 
157     case "$verb" in                                  #處理第1個參數,created或removed
158       ‘created‘)
159         # wait for a PID-file to pop into existence.
160         test -s "$pid_file_path" && i=‘‘ && break
161         ;;
162       ‘removed‘)
163         # wait for this PID-file to disappear
164         test ! -s "$pid_file_path" && i=‘‘ && break
165         ;;
166       *)
167         echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
168         exit 1
169         ;;
170     esac
171 
172     # if server isn‘t running, then pid-file will never be updated
173     if test -n "$pid"; then                 #如果pid非空
174       if kill -0 "$pid" 2>/dev/null; then   #kill -0發送一個無效信號,可檢查進程是否存在,存在返回0,反之則1
175         :  # the server still runs
176       else
177         # The server may have exited between the last pid-file check and now.  
178         if test -n "$avoid_race_condition"; then
179           avoid_race_condition=""
180           continue  # Check again.
181         fi
182 
183         # there‘s nothing that will affect the file.
184         log_failure_msg "The server quit without updating PID file ($pid_file_path)."
185         return 1  # not waiting any more.
186       fi
187     fi
188 
189     echo $echo_n ".$echo_c"    
190     i=`expr $i + 1`
191     sleep 1                   #睡眠1秒
192 
193   done
194 
195   if test -z "$i" ; then   #如果i長度爲0
196     log_success_msg
197     return 0
198   else
199     log_failure_msg
200     return 1
201   fi
202 }
203 
204 
205 # Get arguments from the my.cnf file,
206 # the only group, which is read from now on is [mysqld]
207 if test -x ./bin/my_print_defaults          #找到print_defaults的路徑
208 then
209   print_defaults="./bin/my_print_defaults"
210 elif test -x $bindir/my_print_defaults
211 then
212   print_defaults="$bindir/my_print_defaults"
213 elif test -x $bindir/mysql_print_defaults
214 then
215   print_defaults="$bindir/mysql_print_defaults"
216 else
217   # Try to find basedir in /etc/my.cnf
218   conf=/etc/my.cnf
219   print_defaults=
220   if test -r $conf                         #如果可讀,從配置文件$conf讀取
221   then
222     subpat=‘^[^=]*basedir[^=]*=\(.*\)$‘
223     dirs=`sed -e "/$subpat/!d" -e ‘s//\1/‘ $conf`
224     for d in $dirs
225     do
226       d=`echo $d | sed -e ‘s/[     ]//g‘`
227       if test -x "$d/bin/my_print_defaults"
228       then
229         print_defaults="$d/bin/my_print_defaults"
230         break
231       fi
232       if test -x "$d/bin/mysql_print_defaults"
233       then
234         print_defaults="$d/bin/mysql_print_defaults"
235         break
236       fi
237     done
238   fi
239 
240   # Hope it‘s in the PATH ... but I doubt it
241   test -z "$print_defaults" && print_defaults="my_print_defaults"     #還是不行,就用my_print_defaults
242 fi
243 
244 #
245 # Read defaults file from ‘basedir‘.   If there is no defaults file there
246 # check if it‘s in the old (depricated) place (datadir) and read it from there
247 #
248 
249 #配置文件的目錄,先從basedir讀取,不行再讀取datadir的
250 extra_args=""
251 if test -r "$basedir/my.cnf"
252 then
253   extra_args="-e $basedir/my.cnf"
254 else
255   if test -r "$datadir/my.cnf"
256   then
257     extra_args="-e $datadir/my.cnf"
258   fi
259 fi
260 
261 #使用parse_server_arguments函數和my_print_defaults 從my.cnf 中獲取相應的參數並付給相應的變量
262 parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
263 
264 #
265 # Set pid file if not given
266 #指定mysql啓動時進程文件的位置
267 if test -z "$mysqld_pid_file_path"
268 then
269   mysqld_pid_file_path=$datadir/`hostname`.pid
270 else
271   case "$mysqld_pid_file_path" in
272     /* ) ;;
273     * )  mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
274   esac
275 fi
276 
277 case "$mode" in
278   ‘start‘)
279     # Start daemon
280 
281     # Safeguard (relative paths, core dumps..)
282     cd $basedir
283 
284     echo $echo_n "Starting MySQL"
285     if test -x $bindir/mysqld_safe  #如果mysqld_safe存在且可執行
286     then
287       # Give extra arguments to mysqld with the my.cnf file. This script
288       # may be overwritten at next upgrade.
289       #關鍵語句,啓動mysqld_safe,傳入3個參數:datadir,pid-file,other_args;將輸出丟棄到系統黑洞/dev/null
290       $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &
291       wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
292 
293       # Make lock for RedHat / SuSE          #mysql鎖的檢測和創建
294       if test -w "$lockdir"       #如果存在且可寫
295       then
296         touch "$lock_file_path"
297       fi
298 
299       exit $return_value
300     else
301       log_failure_msg "Couldn‘t find MySQL server ($bindir/mysqld_safe)"
302     fi
303     ;;
304 
305   ‘stop‘)
306     # Stop daemon. We use a signal here to avoid having to know the
307     # root password.
308 
309     if test -s "$mysqld_pid_file_path"    #如果非空
310     then
311       mysqld_pid=`cat "$mysqld_pid_file_path"`      #獲取mysqld進程
312 
313       if (kill -0 $mysqld_pid 2>/dev/null)
314       then
315         echo $echo_n "Shutting down MySQL"
316         kill $mysqld_pid                             #殺死
317         # mysqld should remove the pid file when it exits, so wait for it.
318         wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
319       else
320         log_failure_msg "MySQL server process #$mysqld_pid is not running!"
321         rm "$mysqld_pid_file_path"
322       fi
323 
324       # Delete lock for RedHat / SuSE
325       if test -f "$lock_file_path"    #如果存在鎖,需要移除
326       then
327         rm -f "$lock_file_path"
328       fi
329       exit $return_value
330     else
331       log_failure_msg "MySQL server PID file could not be found!"
332     fi
333     ;;
334 
335   ‘restart‘)                    
336     # Stop the service and regardless of whether it was          #重啓mysql
337     # running or not, start it again.
338     if $0 stop  $other_args; then
339       $0 start $other_args
340     else
341       log_failure_msg "Failed to stop running server, so refusing to try to start."
342       exit 1
343     fi
344     ;;
345 
346   ‘reload‘|‘force-reload‘)                        #重載mysql
347     if test -s "$mysqld_pid_file_path" ; then
348       read mysqld_pid <  "$mysqld_pid_file_path"
349       kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
350       touch "$mysqld_pid_file_path"
351     else
352       log_failure_msg "MySQL PID file could not be found!"
353       exit 1
354     fi
355     ;;
356   ‘status‘)               
357     # First, check to see if pid file exists           #mysql的狀態           
358     if test -s "$mysqld_pid_file_path" ; then 
359       read mysqld_pid < "$mysqld_pid_file_path"
360       if kill -0 $mysqld_pid 2>/dev/null ; then 
361         log_success_msg "MySQL running ($mysqld_pid)"
362         exit 0
363       else
364         log_failure_msg "MySQL is not running, but PID file exists"
365         exit 1
366       fi
367     else
368       # Try to find appropriate mysqld process                             
369       mysqld_pid=`pidof $libexecdir/mysqld`
370 
371       # test if multiple pids exist
372       pid_count=`echo $mysqld_pid | wc -w`
373       if test $pid_count -gt 1 ; then
374         log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
375         exit 5
376       elif test -z $mysqld_pid ; then 
377         if test -f "$lock_file_path" ; then 
378           log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"
379           exit 2
380         fi 
381         log_failure_msg "MySQL is not running"
382         exit 3
383       else
384         log_failure_msg "MySQL is running but PID file could not be found"
385         exit 4
386       fi
387     fi
388     ;;
389     *)
390       # usage            #輸出用法的提示
391       basename=`basename "$0"`
392       echo "Usage: $basename  {start|stop|restart|reload|force-reload|status}  [ MySQL server options ]"
393       exit 1
394     ;;
395 esac
396 
397 exit 0

選自:
http://www.bubuko.com/infodetail-529751.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章