一尘不染

如何正确杀死 MySQL?

mysql

我安装了 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

阅读 56

收藏
2022-10-10

共1个答案

一尘不染

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

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

原因如下:

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

光说还不够

mysqladmin -uroot -p -h127.0.0.1 shutdown

因为如果没有明确启用 TCP/IP root@127.0.0.1, mysqld 将路由用户进入。root@localhost默认情况下,mysqld 会选择阻力最小的路径并通过套接字文件root@127.0.0.1连接。root@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 日,我编写了自己的 call 版本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关闭 mysql 的正确替代方法。service mysql stopkill -9mysqld最后mysqld_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 的默认值应该没问题。

2022-10-10