是否有像apache httpd这样的MySQL正常或安全重启?


29

我想像httpd那样优雅地重新启动mysql,在重新启动之前为线程提供服务。我不喜欢查询中断。

Answers:


37

MySQL中任何“请求的”关闭序列(缺少kill -9)都比较合适,因为正在进行的事务(在事务表上)会回滚,但是这里有两种方法可以使重新启动尽可能的干净。

注意:如果要关闭服务器以进行升级,则不要使用此过程;相反,请遵循此答案详细介绍的过程。

否则,如果您只是重新启动运行状况良好的服务器,以便可以更改只读全局变量或类似的内容,则这是一条正常的路径:

首先,启用innodb_fast_shutdown尚未启用的功能。这与关闭的顺畅程度没有直接关系,但是可以使您的服务器恢复更快。

mysql> SHOW VARIABLES LIKE 'innodb_fast_shutdown';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_fast_shutdown | 0     |
+----------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_fast_shutdown = 1;
Query OK, 0 rows affected (0.01 sec)

接下来,指示服务器在没有当前正在运行的查询引用它们时立即关闭所有打开的表。此步骤也与正常关机无关,但是它将使后续步骤更快:

mysql> FLUSH LOCAL TABLES;
Query OK, 0 rows affected (41.12 sec)

FLUSH TABLES语句(带有可选LOCAL关键字,可以避免不必要地但无害地清除任何从属对象)将阻塞,并且直到所有表都可以关闭时,您的提示才会返回。一旦每个表都被“清空”(关闭),如果查询随后引用了该表,它将自动重新打开,但这没关系。我们通过此步骤完成的工作是减少最后一步的工作:

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (13.74 sec)

mysql>

该语句将刷新所有表(因此具有在上一步中不破坏某些表的优势)并在其上获取全局(服务器范围)只读锁。

直到每个当前正在运行的“写”查询(即,除了几乎所有其他操作SELECT)都完成后,您才能拥有全局读取锁定。发出锁定请求将允许现有查询完成,但不允许新查询开始。

直到持有此全局锁,您的提示才会返回,因此,当您请求该锁时,正在进行的每个查询都能够完成,并且您知道它们已完成,因为您会收到提示。任何后续尝试将任何内容写入任何表的查询都将停止,不更改任何数据,无限期地等待锁,直到...

  • 您改变主意重新启动并手动释放锁定(UNLOCK TABLES;
  • 您重新启动服务器,或者
  • 您无意或有意从此线程断开了命令行客户端的连接(因此请不要这样做)。保持此窗口的连接并坐在mysql提示符下:

抵制诱惑,以结束这一点。

mysql>

这个空闲的控制台提示是为您保持全局锁定的原因。丢掉这个,丢掉锁。

在另一个控制台窗口中,通过初始化脚本(例如的本地变体service mysql.server restart)或mysqladmin shutdown手动重启,以通常的方式重启MySQL 。


使用innodb_fast_shutdown = 1真的可以确保MySQL启动更快吗?查看文档,似乎可以提高关机速度(以启动速度为代价吗?)。
克里斯(Chris)

@Chris的想法是,它有助于确保整个关闭+启动过程尽可能快,但它有点奇怪,因为理论上完成的工作量是相同的-只是移到序列的另一端-由于某种原因,它总体上似乎总是比较快,就像关闭时发生的效率低下,而启动时却没有。很难说。
Michael-sqlbot

2

简而言之,关闭MySQL之前应考虑的一些最佳做法是:

  1. 确认要关闭的实例,以免错误地停止另一个实例。
  2. 如果要关闭从属服务器,请停止复制mysql> STOP SLAVE;
  3. 提前刷新脏页面以减少关闭时间mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;
  4. 检查运行时间较长的查询mysql> SHOW PROCESSLIST;,将其杀死mysql> kill thread_id;或等待它们结束。
  5. 在关闭时转储缓冲池,mysql> SET GLOBAL innodb_buffer_pool_dump_at_shutdown = ON;并在启动时重新加载它 # vi /etc/my.cnf innodb_buffer_pool_load_at_startup = ON 以预热缓冲池。

然后,在确认了之前的几点之后,您可以安全地重新启动MySQL shell$ service mysql restart

有关更多详细信息,请参阅我的文章在关闭MySQL之前检查这些!


为什么这被否决?我还不知道什么命令不好,但是我想知道所以我可以避免它们。
乔恩

我不知道上述任何命令是错误的。我正在执行上述步骤,因此有很多人这样做。仅第4步应格外小心,在确定自己正在做什么之前,请勿杀死任何查询,否则,请等待长时间运行的查询结束。尝试一下,如果有帮助,请对其进行投票;否则,请对其进行投票!
Moll
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.