iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >如何优雅、安全的关闭MySQL进程
  • 212
分享到

如何优雅、安全的关闭MySQL进程

MySQL进程MySQL关闭进程 2022-05-12 02:05:44 212人浏览 泡泡鱼
摘要

前言 本文分析了 Mysqld 进程关闭的过程,以及如何安全、缓和地关闭 mysql 实例,对这个过程不甚清楚的同学可以参考下。 关闭过程 发起 shutdown,发出 SIGTERM 信号 有必要的话,新建一个关闭

前言

本文分析了 Mysqld 进程关闭的过程,以及如何安全、缓和地关闭 mysql 实例,对这个过程不甚清楚的同学可以参考下。

关闭过程

发起 shutdown,发出 SIGTERM 信号

有必要的话,新建一个关闭线程(shutdown thread)

如果是客户端发起的关闭,则会新建一个专用的关闭线程

如果是直接收到 SIGTERM 信号进行关闭的话,专门负责信号处理的线程就会负责关闭工作,或者新建一个独立的线程负责这个事

当无法创建独立的关闭线程时(例如内存不足),MySQL Server 会发出类似下面的告警信息:

Error: Can't create thread to kill server

Mysql Server 不再响应新的连接请求

关闭 tcp/IP 网络监听,关闭 Unix Socket 等渠道

逐渐关闭当前的连接、事务

空闲连接,将立刻被终止;

当前还有事务、SQL 活动的连接,会将其标识为 killed,并定期检查其状态,以便下次检查时将其关闭;(参考 KILL 语法)

当前有活跃事务的,该事物会被回滚,如果该事务中还修改了非事务表,则已经修改的数据无法回滚,可能只会完成部分变更;

如果是 Master/Slave 复制场景里的 Master,则对复制线程的处理过程和普通线程也是一样的;

如果是 Master/Slave 复制场景里的 Slave,则会依次关闭 io、SQL 线程,如果这 2 个线程当前是活跃的,则也会加上 killed 标识,然后再关闭;

Slave 服务器上,SQL 线程是允许直接停止当前的 SQL 操作的(为了避免复制问题),然后再关闭该线程;

在 MySQl 5.0.80 及以前的版本里,如果 SQL 线程当时正好执行一个事务到中间,该事务会回滚;从 5.0.81 开始,则会等待所有的操作结束,除非用户发起 KILL 操作。

当 Slave 的 SQL 线程对非事务表执行操作时被强制 KILL 了,可能会导致 Master、Slave 数据不一致;

MySQL Server 进程关闭所有线程,关闭所有存储引擎;

刷新所有表 cache,关闭所有打开的表;

每个存储引擎各自负责相关的关闭操作,例如 MyISAM 会刷新所有等待写入的操作;InnoDB 会将 buffer pool 刷新到磁盘中(从 MySQL 5.0.5 开始,如果 innodb_fast_shutdown 不设置为 2 的话),把当前的 LSN 记录到表空间中,然后关闭所有的内部线程。

MySQL Server 进程退出

关于 KILL 指令

从 5.0 开始,KILL 支持指定 CONNECTION | QUERY 两种可选项:

KILL CONNECTION 和原来的一样,停止回滚事务,关闭该线程连接,释放相关资源;
KILL QUERY 则只停止线程当前提交执行的操作,其他的保持不变;
提交 KILL 操作后,该线程上会设置一个特殊的 kill 标记位。通常需要一段时间后才能真正关闭线程,因为 kill 标记位只在特定的情况下才检查:

执行 SELECT 查询时,在 ORDER BY 或 GROUP BY 循环中,每次读完一些行记录块后会检查 kill 标记位,如果发现存在,该语句会终止;

执行 ALTER TABLE 时,在从原始表中每读取一些行记录块后会检查 kill 标记位,如果发现存在,该语句会终止,删除临时表;

执行 UPDATE 和 DELETE 时,每读取一些行记录块并且更新或删除后会检查 kill 标记位,如果发现存在,该语句会终止,回滚事务,若是在非事务表上的操作,则已发生变更的数据不会回滚;

GET_LOCK() 函数返回 NULL;

INSERT DELAY 线程会迅速内存中的新增记录,然后终止;

如果当前线程持有表级,则会释放,并终止;

如果线程的写操作调用在等待释放磁盘空间,则会直接抛出“磁盘空间满”错误,然后终止;

当 MyISAM 表在执行 REPaiR TABLE 或 OPTIMIZE TABLE 时被 KILL 的话,会导致该表损坏不可用,指导再次修复完成。

安全关闭 MySQL 几点建议

想要安全关闭 mysqld 服务进程,建议按照下面的步骤来进行:

0、用具有 SUPER、ALL 等最高权限的账号连接 MySQL,最好是用 unix socket 方式连接;

在 5.0 及以上版本,设置 innodb_fast_shutdown = 1,允许快速关闭 InnoDB(不进行 full purge、insert buffer merge),如果是为了升级或者降级 MySQL 版本,则不要设置;

设置 innodb_max_dirty_pages_pct = 0,让 InnoDB 把所有脏页都刷新到磁盘中去;

设置 max_connections 和 max_user_connections 为 1,也就最后除了自己当前的连接外,不允许再有新的连接创建;

关闭所有不活跃的线程,也就是状态为 Sleep 且 Time 大于 1 的线程 ID;
5、执行 SHOW PROCESSLIST 确认是否还有活跃的线程,尤其是会产生表锁的线程,例如有大数据集的 SELECT,或者大范围的 UPDATE,或者执行 DDL,都是要特别谨慎的;

执行 SHOW ENGINE INNODB STATUS 确认 History list length 的值较低(一般要低于 500),也就是未 PURGE 的事务很少,并且确认 Log sequence number、Log flushed up to、Last checkpoint at 三个状态的值一样,也就是所有的 LSN 都已经做过检查点了;

然后执行 FLUSH LOCKAL TABLES 操作,刷新所有 table cache,关闭已打开的表(LOCAL 的作用是该操作不记录 BINLOG);

如果是 SLAVE 服务器,最好是先关闭 IO_THREAD,等待所有 RELAY LOG 都应用完后,再关闭 SQL_THREAD,避免 SQL_THREAD 在执行大事务被终止,耐心待其全部应用完毕,如果非要强制关闭的话,最好也等待大事务结束后再关闭 SQL_THREAD;

最后再执行 mysqladmin shutdown。

紧急情况下,可以设置 innodb_fast_shutdown = 1,然后直接执行 mysqladmin shutdown 即可,甚至直接在操作系统层调用 kill 或者 kill -9 杀掉 mysqld 进程(在 innodb_flush_log_at_trx_commit = 0 的时候可能会丢失部分事务),不过 mysqld 进程再次启动时,会进行 CRASH RECOVERY 工作,需要有所权衡。

??履敲炊啵?涫嫡?G榭鱿轮葱 mysqladmin shutdown 就够了,如果发生阻塞,再参考上面的内容进行分析和解决吧,哈哈:)

以上就是如何优雅、安全的关闭MySQL进程的详细内容,更多关于关闭MySQL进程的资料请关注自学编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 如何优雅、安全的关闭MySQL进程

本文链接: https://www.lsjlt.com/news/9735.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-14
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-14
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-14
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-14
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-14
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-14
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-14
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-14
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作