MySQL8.0 core dump介绍

2023年 10月 9日 70.7k 0

在Linux系统中,将“主内存”称为核心 (core),而核心映像(core image)就是“进程”(process)执行当时的内存内容。当进程发生错误或收到“信号” (signal) 而终止执行时, 系统会将核心映像写入一个文件,以作为调试之用,这就是所谓的核心转储 (core dump)。当在一个程序崩溃时,系统会在指定目录下生成一个core 文件,就可以通过core文件来对造成程序崩贵的原因进行调试定位。

MySQL Core dump

在Linux环境中运行的MySQL也提供core dump功能。core file记录正在运行的进程的状态和内存映像。MySQL8.0里两个参数生成cor文件。
1.core-file
如果MySQL服务意外退出,是否写入核心文件。此变量控制。这里core dump里去掉buffer pool的内容。
2.innodb_buffer_pool_in_core_file
在8.0.14版本中新增了参数innodb_buffer_pool_in_core_file可以动态修改,默认是启用.可以禁用来禁止缓冲池页被写入到核心文件中,从而减少核心文件的大小。因为buffer-pool一般设置内存的50%以上,如果当mysqld进程失效时,具有大型缓冲池的系统可以生成大型核心文件。大型核心文件可能会出现问题,原因有很多,包括写入所需的时间、所消耗的磁盘空间量,以及与传输大型文件相关的挑战。

在启用core_file变量同时,操作系统需要支持madvise函数。madvise函数是Linux系统提供的一个操作系统调用(system call),用于控制系统内存管理。调用madvise函数可以对指定的内存区域设置适当的使用策略,从而优化系统整体性能和内存利用率。
如果innodb_buffer_pool_in_core_file变量被禁用,但操作系统不支持MADV_DONTDUMP,或者发生madvise()故障,则会在MySQL服务器错误日志中写入警告,并禁用core_file变量,以防止写入无意中包含缓冲池页面的核心文件。
下表显示了配置和MADV_DONTDUMP支持场景,用于确定是否生成核心文件以及它们是否包括缓冲池页面。

core_file variable innodb_buffer_pool_in_core_file variable madvise() MADV_DONTDUMP Support Outcome
OFF (default) Not relevant to outcome Not relevant to outcome Core file is not generated
ON ON (default) Not relevant to outcome Core file is generated with buffer pool pages
ON OFF Yes Not relevant to outcome
ON OFF No Core file is not generated, core_file is disabled, and a warning is written to the server error log

通过禁用innodb_buffer_pool_in_core_file变量实现的核心文件大小的减少取决于缓冲池的大小,但也受innodb页面大小的影响。较小的页面大小意味着相同数量的数据需要更多的页面,而更多的页面意味着更多的页面元数据。下表提供了不同页面大小的1GB缓冲池的大小缩减示例。

innodb_page_size Setting Buffer Pool Pages Included (innodb_buffer_pool_in_core_file=ON) Buffer Pool Pages Excluded (innodb_buffer_pool_in_core_file=OFF)
4KB 2.1GB 0.9GB
64KB 1.7GB 0.7GB

查看mysql core dump是否开启:

mysql> show variables like '%core%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| core_file | OFF |
| innodb_buffer_pool_in_core_file | ON |
+---------------------------------+-------+
2 rows in set (0.01 sec)

需要在配置文件开启。并重新启动mysql服务。

[mysqld]
core_file

Linux生成core文件限制

1.还需要查看系统是否对core file 有限制。0表示未开启,unlimited表示无限制。

shell$> ulimit -c
unlimited

备注:ulimit -c filesize,限制生成core文件的大小,ulimit -c 0表示不开启,ulimit -c 1000表示限制core文件限制为1000KB,ulimit -c unlimited无限制。

2.core文件生成路径

#查看目录
shell$> cat /proc/sys/kernel/core_pattern
/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e

#创建目录,赋予权限
shell$> mkdir -p /corefile
shell$> chmod 0777 /corefile

#设置core文件输出路径和sysctl应用
shell$> vim /etc/sysctl.conf
kernel.core_pattern = /home/mysql/corefile/core-%e-%p
kernel.core_uses_pid = 0
shell$> sysctl -p
#mysql 通常会以 suid 方式启动,所以需要打开 suid_dumpable
shell$> echo 1 >/proc/sys/kernel/core_uses_pid

Core文件查看

1.模拟崩溃

如下生成core dump文件。

shell$> ps -ef |grep mysql
root 1123 1074 0 10:53 pts/0 00:00:00 mysqld_safe --defaults-file=/etc/my8.0.cnf --user=mysql
mysql 2490 1123 3 10:53 pts/0 00:00:01 mysqld --defaults-file=/etc/my8.0.cnf --basedir=/opt/idc/mysql8.0 --datadir=/opt/data8.0/data --port=3380

#kill pid
shell$> kill -SEGV 2490
shell$> /mysqld_safe: line 199: 2490 Segmentation fault (core dumped) env MYSQLD_PARENT_PID=1123 LD_PRELOAD=/usr/lib64/libjemalloc.so.2 nohup mysqld --defaults-file=/etc/my8.0.cnf --port=3380
/dev/null 2>&1
2023-10-09T02:54:49.570357Z mysqld_safe Number of processes running now: 0
2023-10-09T02:54:49.575222Z mysqld_safe mysqld restarted
。。。

shell$> ll /corefile
total 518892
-rw------- 1 mysql mysql 911060992 Oct 9 10:54 core-mysqld-2490

2.GDB查看core文件堆栈信息

gdb [exec file] [core file],启动gdb进入core文件.

shell$> gdb /opt/idc/mysql8.0/bin/mysqld core-mysqld-2490

#1.设置输出的文件名称
(gdb) set logging file thread_info.txt

#2.输入这个命令后,此后的调试信息将输出到指定文件
(gdb) set logging on
Copying output to thread_info.txt.

#3.打印说有线程栈信息,查看程序的崩溃现场所有信息
(gdb) thread apply all bt full

#4.输入这个命令,关闭到指定文件的输出
(gdb) set logging off
Done logging to thread_info.txt.

#5.退出gdb
(gdb) quit

通过对信息,分析具体问题。

shell$> less thread_info.txt.
Thread 37 (LWP 2532):
#0 0x00007fccd50b048c in ?? ()
No symbol table info available.
#1 0x0000000000000000 in ?? ()
No symbol table info available.

0x00007f11d70e397c in pthread kill () from /lib64/libpthread.so.0
symbol table info available .
0x00000000007ed750 in handle fatal signal (sig=11) at /home/buildbot/buildbot/build/sgl/signal handler.cc:343
curr time = 1693902706
tm = (tm sec = 46,tm min = 31, tm hour = 16, tm mday = 5, tm mon = 8, tm year = 123, tm wday = 2, tm yday = 247, tm isdst = 0, tm gmtoff = 23800
tm zone = 0x35b4720 "CST"]
thd = 0x7f106c0008c8
print invalid query pointer =
。。。

上述问题是因为value optimized out导致的。

总结

有时MySQL突然宕机,需要分析具体原因,可以通过查看core文件,找到问题点。但很多环境下突然宕机,一般情况下为了尽快恢复业务,会马上拉起mysqld进程(有可能会继续crash,有可能通过mysql内部recover机制修复错误),继续提供服务。但core dump生成需要时间和一定的空间。如:innodb buffer pool设置越大生成core文件的时间越长,空间需要更大。因此谨慎配置core dump参数。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论