浅谈MySQL数据库崩溃(crash)的常见原因和解决办法
作者:姚远Oracle 发布时间:2024-01-17 12:52:58
检查 MySQL 数据库的启动时间
Linux 系统中的 systemd 和 mysqld_safe 会在 mysqld 进程 crash 后自动重新启动 MySQL 的服务,需要注意的是使用 kill -9 杀死 mysqld 进程系统会自动重新启动,而只使用 kill 命令则不会重新启动,因为执行 kill 命令,系统会发送一个 SIGTERM 信号给 mysqld,mysql 数据库会正常关闭,日志中会出现类似下面的记录:
2020-10-26T09:06:48.435181Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.
MySQL 数据库 crash 后都会重新启动,因此我们有时可能不知道 MySQL 数据库已经 crash 过了,但我们可以从mysql数据库启动时间上找到线索,下面介绍四种检查 MySQL 数据库启动时间的方法。
检查 MySQL 服务状态
scutech@scutech:~$ service mysql status
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-10-21 05:54:18 NDT; 4 days ago
Process: 774 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
Process: 708 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 791 (mysqld)
Tasks: 27 (limit: 2328)
CGroup: /system.slice/mysql.service
└─791 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
显示 MySQL 数据库已经运行 4 天多。
检查 MySQL 中的 uptime 状态
mysql> show global status like 'uptime';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| Uptime | 428334 |
+---------------+--------+
1 row in set (0.32 sec)
这个值是以秒为单位,下面换算成以天为单位是 4 天多。
mysql> select 428334/60/60/24;
+-----------------+
| 428334/60/60/24 |
+-----------------+
| 4.957569444444 |
+-----------------+
1 row in set (0.01 sec)
查询 uptime 状态的另一种方法是使用 mysqladmin version 或在 mysql 客户端里用 “\s” 进行查询。
使用 ps 检查进程启动时间
使用 ps 命令查询发现 mysqld 启动了4天23小时3分种54秒
scutech@scutech:~$ ps -eo pid,user,args,etime|grep mysqld
791 mysql /usr/sbin/mysqld --daemoniz 4-23:03:54
检查 MySQL 日志
找关键字 “ready for connections”,可以查到启动信息。
2020-10-21T08:24:18.986765Z 0 [Note] /usr/sbin/mysqld: ready for connections.
Version: '5.7.28-log' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
MySQL 数据库 crash 的常见原因
MySQL 数据库 crash 的最常见原因有两个,一个是 mysql 的 bug , 另一个是 mysql 申请系统资源失败或内存泄漏。
MySQL 的 bug
MySQL数据库 crash 的最常见的一个原因当然是 MySQL 的bug。95% 的 bug 都是和具体的 sql 相关,通常是 MySQL crash 前执行的最后一个 sql 有问题,因此定位 bug 时应打开 general query log ,根据最后一个 sql 来查找线索。
当你确定了 crash 的原因后,应该检查一下 MySQL 的 bug 库(https://bugs.mysql.com),通常采用 Advanced search,看看有没有类似的问题。如果你找到了可能与你相关的 bug,确认它是否修复了。如果已经修复了,那么把 MySQL 升级到 bug 已经修复的版本。
在每个版本的 Release Notes 里面有一节 Bugs Fixed ,可以查到修复的 bug 。
MySQL 申请系统资源失败或内存泄漏
内存不足或 MySQL 申请系统资源失败外都会造成 MySQL 崩溃,例如磁盘空间满了,磁盘上的文件 corrupt 等。此时需要定位 crash 的根本原因有下面几种方法:
仔细阅读 MySQL 的错误日志,这个日志里面的一些程序调试信息看起来很让人困惑,但静下心来仔细看,很多时候会找到线索;
打开 general query log ,找到最后一个 sql 访问的表或索引,检查这个表或索引,如果有问题就重建,通常可以解决问题。
使用 strace、pstack、pmap、gdb 分析 mysqld 的代码,可能需要打开 core dump;
使用 CMake 的选项 -DWITH_DEBUG=1 重新编译 mysqld,然后运行重新编译后的 mysqld,查看 trace 文件、error log 进行排错。
MySQL 内存占用的计算
全局内存
innodb_buffer_pool_size innodb_log_buffer_size thread_cache_size table_open_cache table_definition_cache key_buffer_size
线程内存
binlog_cache_size thread_stack
单次操作内存
join_buffer_size read_buffer_size read_rnd_buffer_size tmp_table_size sort_buffer_size
计算公式
MySQL 8 中最大内存占用参考值计算公式:
SELECT ( @@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@key_buffer_size
+ @@max_connections * (@@binlog_cache_size + @@thread_stack + @@read_buffer_size
+ @@read_rnd_buffer_size + @@sort_buffer_size + @@join_buffer_size + @@tmp_table_size )
) / 1024 /1024 AS MAX_MEM_MB;
innodb_buffer_pool_size
key_buffer_size
max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)
max_connections*2MB
临时解决可以使用下面的命令释放缓存:
echo 1 > /proc/sys/vm/drop_caches
0:0是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存
从长远看还是要修改对应的参数进行解决。
MySQL 客户端的内存泄漏
MySQL 客户端的内存泄漏时通常会有下面的提示
mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
这通常是客户端收到的返回结果集太大造成的,解决办法有两种:
检查正在运行的 SQL ,看看您真的需要这么大的返回结果集吗?
允许 mysql 时加上 --quick 选项,这会减少客户端单次收到的返回集,但会增加 mysqld 的负载。
来源:https://yaoyuan.blog.csdn.net/article/details/109294148


猜你喜欢
- 系统环境:win10 开发环境:JetBrains PyCharm 2017.1.5 x64 Python版本:2.7假如我们有一个clas
- DateDiff 函数描述 返回两个日期之间的时间间隔。 语法 DateDiff(interval, date1, date2 [,firs
- 一、装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现
- 本文介绍sqlite数据库,如何使用sqlite3包操作轻量级关系型数据库。sqlite概述sqlite是嵌入式关系型数据库引擎,官方描述为
- 1.CNN概述CNN的整体思想,就是对图片进行下采样,让一个函数只学一个图的一部分,这样便得到少但是更有效的特征,最后通过全连接神经网络对结
- 本文介绍了PyTorch上搭建简单神经网络实现回归和分类的示例,分享给大家,具体如下:一、PyTorch入门1. 安装方法登录PyTorch
- 1.基于rbac的权限管理RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联
- 正好最近的域名备案通过了,兴起就突然想做一个网页,虽然之前去备案域名也是有这个目的。问过几个人,说用linux上用PHP搭建网站很简单,就试
- 前言本文主要给大家介绍了关于WebSocket部署服务器外网无法连接的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍
- 看到网上有一篇文章,是介绍如何做网站测试的.从一开始的链接测试,页面内容测试,到浏览器兼容性测试,负载压力测试,一直到最后的安全性测试,甚至
- 不是很难哦,我们现在就可以实现VBScript在服务器端验证,就是下面的函数:<%FUNCTION TestString(S
- Access SQL 函数 收藏 ▲日期/时间CDate 将字符串转化成为日期 select CDate("2005/
- 前言嗨,彦祖们,不会过圣诞了还是一个人吧?今天我们来讲一下如何用python来画一个圣诞树,学会就快给那个她发过去吧,我的朋友圈已经让圣诞树
- 1、先说结论:使用xml-rpc的机制可以很方便的实现服务器间的RPC调用。2、试验结果如下:3、源码如下:服务器端的源代码如下:impor
- 解决2个问题:1.身份证之类的文本数据自动转为科学计数法的问题。2.中文乱码的问题excel从web页面上导出的原理。当我们把这些数据发送到
- 前言:关于数据库范式,时常有听说过,一直没有详细去了解。一般数据库书籍或数据库课程会介绍范式相关内容,范式也经常出现在数据库考试题目中。不清
- 正在看的ORACLE教程是:Oracle数据安全面面观。
- 0. 前言这几天在写软件工程课设,题目是:设计一款疫苗管理系统,于是用PyQT5写GUI,MySQL做数据库写了一个demo出来。做完之后,
- 1.命名空间先看看官方文档的一段话:命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的
- 环境准备Python3.6pip install Django==2.0.1pip install celery==4.1.0pip ins