如何正确杀死MySQL?


28

我安装了带有CPanel的CentOS 64位,并且使用:

service mysql stop

它只是保持滴答作响,似乎从未停止过。在日志中,它仅发布了许多内容:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

err.log文件中,我看到了很多这些:

[Warning] /usr/sbin/mysqld: Forcing close of thread

它曾经是即时的。任何想法为什么这样做以及如何解决?

现在我必须做,killall -9 mysql但是有更好的方法吗?

服务器也非常活跃。

这是配置问题吗?记忆设置是否太高?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Answers:


37

关闭mysql的最简单方法是简单地运行

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

原因如下:

mysql服务文件(/etc/init.d/mysql)依赖于套接字文件的存在。从历史上讲,追溯到MySQL 4.0,套接字文件有时会莫名其妙地消失。这妨碍了service mysql stop工作的标准。

仅仅说还不够

mysqladmin -uroot -p -h127.0.0.1 shutdown

因为mysqld的意志航线在未来一个用户作为root@127.0.0.1root@localhost如果没有明确启用TCP / IP。缺省地,mysqld会选择阻力最小的路径,并连接root@127.0.0.1root@localhost通过套接字文件。但是,如果没有套接字文件,root@localhost将永远不会连接。

甚至mysqladmin上MySQL文档都说:

如果在使用Unix套接字文件连接到本地服务器时执行mysqladmin shutdown,则mysqladmin将等待直到服务器的进程ID文件被删除,以确保服务器已正确停止。

这就是为什么必须启用TCP / IP的原因:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

回到2011年9月30日,我剧本我自己的版本mysqld_multimysqlservice(请参见我的文章:在同一台主机上运行多个实例)。它用作从不同端口连接到mysqld的虚拟引擎。您只需要my.cnf自定义参数即可。在该脚本中,我这样发出关闭命令:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

但是什么${MYSQLD_STOP}呢?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

请注意,我使用127.0.0.1了一个显式端口。这样,我就不再依赖套接字文件了。

mysqladmin --protocol=tcp shtudown如果service mysql stop挂起,我一直作为关闭mysql的适当替代方法。这样做kill -9mysqldmysqld_safe应该的最后的最后的最后一个度假胜地的。(是的,我说了三遍)。

很多时候,mysqld毫无警告地删除了mysql.sock。这些年来,其他人也遇到了这个问题:

结语

秘密就如我所说:使用mysqladmin通过TCP / IP(--protocol=tcp)连接到mysql 并发出shutdown。这必须起作用,因为关闭特权mysql.user专用于经过身份验证的关闭的。当我能够在关闭Linux服务器上的mysqld时从Windows计算机发出远程关闭命令时,这节省了我的工作时间。

更新2013-03-06 22:48 EST

如果您担心关闭期间发生了什么,可以使用一种方法来控制关闭时间以及将数据刷新到磁盘的方式,尤其是在缓冲池中有大量InnoDB数据的情况下

建议#1

如果您有很多脏页,可以将innodb_max_dirty_pages_pct降低为0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

在关机前大约15-30分钟进行设置。这将使mysqld最少数量的脏页写入磁盘。

建议#2

默认情况下,innodb_fast_shutdown为1。此选项有三个值

  • 0:在关闭之前,InnoDB执行缓慢关闭,完全清除和插入缓冲区合并。
  • 1:InnoDB在关闭时跳过这些操作,该过程称为快速关闭。
  • 2:InnoDB刷新其日志并关闭冷启动,就好像MySQL崩溃了一样;不会丢失任何已提交的事务,但是崩溃恢复操作会使下次启动花费更长的时间。

文档进一步说:

缓慢关闭可能需要几分钟,甚至在仍然缓冲大量数据的极端情况下,甚至需要数小时。在MySQL主要版本之间进行升级或降级之前,请使用慢速关机技术,以便为所有数据文件做好充分准备,以防升级过程更新文件格式。

在紧急情况或故障排除情况下,使用innodb_fast_shutdown = 2可以绝对绝对最快地关闭数据,如果有损坏数据的危险。

在大多数情况下,innodb_max_dirty_pages_pct和innodb_fast_shutdown的默认值应该很好。


2
套接字文件在Red Hat派生工具上消失了,因为将其tmpwatch删除,并且其中的所有其他文件的时间/tmp早于其配置的阈值。
Michael-sqlbot

谢谢@ Michael-sqlbot,我终于需要听到某人的来信。我猜这就是为什么MySQL AB(Oracle之前,Sun之前)的某人决定添加SHUTDOWN特权来mysql.user解决此类问题的原因。
RolandoMySQLDBA 2013年

在Debian或Ubuntu上使用mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown...该文件包含类似root的MySQL帐户的凭据。
0xC0000022L

和往常一样,@ RolandoMySQLDBA是Stack Exchange站点上最好的DBA资源之一。6多年后,这里的出色工作对我有所帮助。
杰克古尔德

5

听起来您的问题似乎不是关于“如何”关闭MySQL的问题,而更多是关于为什么您的关闭如此缓慢的问题。

我对类似问题的回答中,我提出了一些有关平稳重启的建议,这些建议可以减少请求MySQL开始关闭过程后必须进行的活动,从而有所帮助。

如果您不是该SHOW FULL PROCESSLIST;项目#1 的经常使用者,因为您需要了解服务器中正在发生的事情,这会使关机如此缓慢。如果存在可以安全中断的长期运行的查询,则可以使用杀死它们KILL <thread-id>

总结其他建议:

设置全局变量innodb_fast_shutdown = 1(默认)将加快InnoDB关闭的速度。但是,只有在由于与执行升级无关的原因而关闭服务器时,这才是安全的。如果要关闭升级,则必须将其设置为0。

FLUSH TABLES;正常使用会关闭所有打开的表。如果随后的查询引用了它们,它们将被重新打开,但是此操作仍将最终减少从您请求关闭到关闭完成之间的时间,因为它会做一些早期的内务处理,更重要的是,它设置了阶段最后一步

FLUSH TABLES WITH READ LOCK;关闭所有打开的表并获取当前客户端连接拥有的排他锁,以防止任何其他连接写入整个服务器上的任何表。mysql>除非您拥有此锁,否则您将无法得到提示,此时您可以发出关闭请求-但不要断开此会话的连接。

在繁忙的服务器上,这些步骤应减少服务器上的活动级别,使操作更安静,并有助于使关机或重新启动更加顺利。


2

MySQL可能不是纯粹被锁定,而是在关闭时正在执行清理活动(回滚等)。如果关闭时不执行所有操作,则通常必须在启动时等待。

这里是要看的东西:在一个终端窗口中关闭mysql,同时在另一个终端窗口中查看错误日志(tail -f [yourerror.log])。错误日志将显示MySQL在做什么。


1

很遗憾听到您的经历,并希望我对类似MySQL的愚蠢场景的经验能对您有所帮助。

在某些情况下,您无需尝试找出如何从服务器上终止MySQL服务的方法,而需要通过以下方法检查系统的运行状况,以确定是否存在服务滥用(假设基于CentOS / RHEL环境):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

使用以下命令确定平均系统负载和系统中消耗最大的资源。

您还需要安装mytop以获取有关系统正在处理的SQL语句的总体视图。

要安装mytop,只需执行以下操作:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(使用您喜欢的任何文本编辑器)

搜索"long|!" => \$config{long_nums}

注释为#"long|!" => \$config{long_nums}

chmod 555 /usr/local/bin/mytop

而且,与mytop搭配使用非常好。使用它来检查正在占用MySQL服务的MySQL语句并停止它们。

执行以上指令将为您提供以下功能:

  • 诊断服务器的状态/运行状况
  • 诊断您的瓶颈原因

一旦消除了瓶颈的原因,当您尝试重新启动MySQL服务时,应该会过上轻松的一天。我希望您会发现上述信息有用。

注意: mytop是古老且未维护的。您可能应该innotop在现代系统上使用。


0

MySQL的初始化脚本的标准实现通过SIGTERM向MySQL发出信号,并等待一定时间以使MySQL关闭。

在收到SIGTERM之后,MySQL将首先停止接收新的连接,然后完成执行仍待处理的查询(这可能需要一段时间,具体取决于您的工作负载和并发客户端的数量),然后开始将数据刷新到磁盘(这可能需要花费一些时间)。时间长短,再次取决于您的工作负载,配置,可用内存和存储引擎选择)。完成所有数据刷新后,MySQL将释放其在初始化阶段分配的任何内存(这也可能需要一段时间,具体取决于MySQL分配的内存量),关闭所有仍打开的文件句柄,然后调用“退出(0)”。

如果在关闭请求后MySQL需要很长时间才能关闭,则很可能其中一个或多个阶段需要很长时间才能完成。如果您有时间,我强烈建议您等待该过程完成(这样可以避免在再次启动数据库实例时造成数据丢失或冗长的恢复过程)。

不幸的是,您的问题中没有足够的信息,无法让我为您的问题提供适当的解决方案。我希望这有助于理解问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.