giorgio79 Asked: 2013-02-26 11:33:07 +0800 CST2013-02-26 11:33:07 +0800 CST 2013-02-26 11:33:07 +0800 CST mysql 是否有像 apache httpd 这样的优雅或安全重启? 772 我想像httpd一样优雅地重新启动mysql,在重新启动之前提供线程服务。我不喜欢查询中断。 mysql 2 个回答 Voted Best Answer Michael - sqlbot 2013-02-26T17:43:55+08:002013-02-26T17:43:55+08:00 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> 这个空闲的控制台提示是为你持有全局锁的东西。丢了这个,丢了锁。 从另一个控制台窗口,以您通常的方式重新启动 MySQL,或者使用 initscripts(例如,您的本地变体service mysql.server restart)或mysqladmin shutdown手动重新启动。 Moll 2016-11-22T13:49:04+08:002016-11-22T13:49:04+08:00 简而言之,在关闭 MySQL 之前应该考虑的一些最佳实践是: 确认您要关闭的实例,以避免错误地停止另一个实例。 如果要关闭从站,请停止复制mysql> STOP SLAVE;。 提前刷新脏页以减少关机时间mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;。 检查长时间运行的查询mysql> SHOW PROCESSLIST;,杀死它们mysql> kill thread_id;或等到它们完成。 在关闭时转储缓冲池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 之前检查这些!
MySQL 中的任何“请求”关闭序列(缺少
kill -9
)都有些优雅,因为正在进行的事务(在事务表上)被回滚,但这里有几种方法可以使重启尽可能干净。注意:如果您要关闭服务器进行升级,请不要使用此过程;相反,请遵循此答案中详述的过程。
否则,如果您只是重新启动一个健康的服务器,以便您可以更改只读全局变量或类似的东西,这里是一个优雅的路径:
首先,
innodb_fast_shutdown
如果尚未启用,请启用。这与关闭的优雅性没有直接关系,但它应该让您的服务器更快地恢复。接下来,一旦没有当前运行的查询引用它们,就指示服务器关闭所有打开的表。这一步也和优雅关机无关,但是会让后面的步骤走得更快:
该
FLUSH TABLES
语句(带有可选LOCAL
关键字,可避免不必要但无害的任何从属设备的刷新)将阻塞,并且您的提示将不会返回,直到所有表都可以关闭。一旦每个表都被“刷新”(关闭),如果查询随后引用了该表,它将自动重新打开,但这没关系。我们通过这一步完成的是减少最后一步的工作:该语句会刷新所有表(因此在前面的步骤中可以减少一些破坏性)并在它们上获取全局(服务器范围)只读锁。
在每个当前正在运行的“写”查询(即,除了 之外的几乎所有内容
SELECT
)都完成之前,您不能拥有全局读锁。发出锁定请求将允许现有查询完成,但不允许启动新查询。在您持有此全局锁之前,您的提示不会返回,因此当您请求锁时正在进行的每个查询都能够完成,并且您知道它们已完成,因为您会收到提示。任何尝试向任何表写入任何内容的后续查询都将停止,不更改任何数据,无限期地等待锁定,直到...
UNLOCK TABLES;
)抵制关闭它的诱惑。
这个空闲的控制台提示是为你持有全局锁的东西。丢了这个,丢了锁。
从另一个控制台窗口,以您通常的方式重新启动 MySQL,或者使用 initscripts(例如,您的本地变体
service mysql.server restart
)或mysqladmin shutdown
手动重新启动。简而言之,在关闭 MySQL 之前应该考虑的一些最佳实践是:
mysql> STOP SLAVE;
。mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;
。mysql> SHOW PROCESSLIST;
,杀死它们mysql> kill thread_id;
或等到它们完成。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 之前检查这些!