关闭mysql的几种方式和区别

      关闭mysql的方式大致有下面几种:

      kill `pidof mysqld`

      kill -9 `pidof mysqld`

      mysqladmin -uroot shutdown

      其中kill `pidof mysqld`是通过信号量SIGTERM(15),结束进程,这个同mysqladmin -uroot shutdown的方式一样 -- mysqladmin关闭mysqld也是通过SIGTERM信号量结束mysqld的。通过这2种方式关闭mysql,mysql的error日志显示的都是normal shutdown;而kill -9则是OS层强制关闭mysqld,error日志则不会有日志(异常crash),重启后则会显示Crash recovery。因此从mysql的错误日志中可以简单地判断mysql是crash还是正常关闭。正常情况下推荐通过mysqladmin 关闭mysql,如果出现异常再考虑使用kill -9的方式关闭。

正常mysqld关闭的过程如下:

1、初始化shutdown process。

2、server端创建一个shutdown thread(非必须)。

3、server拒绝新的连接进来。

4、server停止当前的活动。

5、server shutdown,关闭存储引擎。

6、server退出。

 

下面是具体的一些实现逻辑:

//mysqladmin的调用逻辑:(mysqladmin.cc)
int main(int argc,char *argv[])
{
...
if ((error= execute_commands(&mysql,argc,commands)))
...
}
static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
  for (; argc > 0 ; argv++,argc--)
  {
    switch (find_type(argv[0],&command_typelib,2)) {
...
    case ADMIN_SHUTDOWN:
    {
..
        if (mysql_shutdown(mysql, SHUTDOWN_DEFAULT))
...
    }
   }
}
...

int STDCALL
mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level)
{
  uchar level[1];
  DBUG_ENTER("mysql_shutdown");
  level[0]= (uchar) shutdown_level;
  DBUG_RETURN(simple_command(mysql, COM_SHUTDOWN, level, 1, 0));
}

 

//COM_SHUTDOWN的调用逻辑:
    general_log_print(thd, command, NullS);
    my_eof(thd);
    close_thread_tables(thd);			// Free before kill
    kill_mysql();
...
void kill_mysql(void)
{
  DBUG_ENTER("kill_mysql");

#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
  abort_loop=1;					// Break connection loops
  close_server_sock();				// Force accept to wake up
#endif

#if defined(__WIN__)
#if !defined(EMBEDDED_LIBRARY)
  {
    if (!SetEvent(hEventShutdown))
    {
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
    }
    /*
      or:
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
      SetEvent(hEventShutdown);
      CloseHandle(hEvent);
    */
  }
#endif
#elif defined(HAVE_PTHREAD_KILL)
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
  {
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  }
#elif !defined(SIGNALS_DONT_BREAK_READ)
  kill(current_pid, MYSQL_KILL_SIGNAL);//调用kill函数,发送SIG_TERM信号给mysqld
#endif
  DBUG_PRINT("quit",("After pthread_kill"));
  shutdown_in_progress=1;			// Safety if kill didn't work
#ifdef SIGNALS_DONT_BREAK_READ
  if (!kill_in_progress)
  {
    pthread_t tmp;
    abort_loop=1;
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
			   (void*) 0))
      sql_print_error("Can't create thread to kill server");
  }
#endif
  DBUG_VOID_RETURN;
}
 

 

//如果在kill的时候创建一个kill线程,逻辑如下
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
{
  my_thread_init();				// Initialize new thread
  kill_server(0);
...
}
static void *kill_server(void *sig_ptr)
{
...
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
    sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
  else
    sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
...
  close_connections();
  if (sig != MYSQL_KILL_SIGNAL &&
      sig != 0)
    unireg_abort(1);				/* purecov: inspected */
  else
    unireg_end();
...
}
/**
  cleanup all memory and end program nicely.

    If SIGNALS_DONT_BREAK_READ is defined, this function is called
    by the main thread. To get MySQL to shut down nicely in this case
    (Mac OS X) we have to call exit() instead if pthread_exit().

  @note
    This function never returns.
*/
void unireg_end(void)
{
  clean_up(1);
...
}

 

//mysqld启动的时候,创建kill线程
  start_signal_handler();
...
static void start_signal_handler(void)
{
...
  if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
...
}
...
/** This threads handles all signals and alarms. */
/* ARGSUSED */
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
{
...
    switch (sig) {
    case SIGTERM:
    case SIGQUIT:
    case SIGKILL:
...
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
...
}

 

 

 

 

链接:

http://dev.mysql.com/doc/refman/5.5/en/server-shutdown.html

http://ebergen.net/wordpress/2012/09/29/shutting-down-with-mysqld-mysqladmin-sigterm-or-sigkill/

http://www.xaprb.com/blog/2012/04/24/the-mysql-init-script-mess/

http://www.dbafree.net/?p=870

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值