[toc]
1.设置core
1.1是否有core
--1. 找到pid [postgres@cent9-test91 ~]$ cat "$PGDATA/postmaster.pid" | head -n1 63732 --2. 查看core的限制(没有就是不生成core) [root@cent9-test91 ~]# cat /proc/63732/limits |grep core Max core file size unlimited unlimited bytes 或: [root@cent9-test91 ~]# prlimit --pid 63732 --core RESOURCE DESCRIPTION SOFT HARD UNITS CORE max core file size unlimited unlimited bytes
1.2查看core的输出规则
- 查看core文件位置
sysctl kernel.core_pattern
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h
此时,内核并不会生成单独的core文件,直接交由
systemd-coredump处理,默认输出存储到日志中()。
- 查看是否在核心转储的文件名中包含进程ID
sysctl kernel.core_uses_pid
kernel.core_uses_pid = 1
- 是否允许设置特定程序
sysctl fs.suid_dumpable
fs.suid_dumpable = 2
- core文件大小限制
ulimit -c
1048576 #当前大小1048576kb=1G
ulimit -c 1048576 #临时设置
/etc/security/limits.conf #永久设置
* hard core unlimited
youruser hard core 1048576
如果数据库是通过systemd 启动的
添加:
[Service]
LimitCORE=infinity
# 生效:
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart <服务名>
1.3自定义处理core
(1)systemd-coredump处理
用户态进程的 core(由 systemd-coredump 管理);区别内核态崩溃的 dump(由 kdump 管理)
case1:
/etc/systemd/coredump.conf设置核心转储的处理行为:(所有参数如下)
[Coredump]
Storage=external|journal|none|both
Compress=yes|no
ProcessSizeMax=1G
ExternalSizeMax=1G
JournalSizeMax=
MaxUse=
KeepFree=
# systemd-coredump是按需触发的处理器,而非长期常驻服务,改完无需重启.
Storage=external输出在/var/lib/systemd/coredump/下面(不可自定义),文件名由kernel.core_pattern控制。
ExternalSizeMax值和/etc/security/limits.conf的ulimit -c的值优先级:
进程崩溃 → 内核根据ulimit -c判断是否生成 core
内核生成 core → 交给 systemd-coredump 处理
systemd 再根据 /etc/systemd/coredump.conf的限制处理
例如:/etc/security/limits.conf 里 core=512000,ExternalSizeMax=2G:表示内核最多交出 512MB core,systemd 也只能收到这么多数据,给不了2G让systemd-coredump处理
case2:
**(不建议)**搭配/etc/rsyslog.conf配置:(os高版本不再使用rsyslog)
if $programname == 'systemd-coredump' then /var/log/coredumps.log
& stop
- systemctl restart rsyslog -
举例
核心转储文件将存储在默认目录下,同时所有由
systemd-coredump生成的崩溃日志将被转储到/var/log/coredumps.log。
/etc/systemd/coredump.conf
[Coredump]
Storage=external
Compress=yes
/etc/rsyslog.conf
if $programname == 'systemd-coredump' then /var/log/coredumps.log
& stop
--RHEL 8 / CentOS 8 / Rocky / AlmaLinux / Fedora / Ubuntu 18+ 默认使用 systemd-journald,不再启用 rsyslog。
systemctl restart systemd-coredump
systemctl restart rsyslog
ps:因为有rsyslog进程(它会把 systemd 的 journal 里的日志“抄写/转发”成传统文本日志),在centos7的messages里可以看到相关崩溃信息,但是在高版本中,相关core信息存在/var/lib/systemd/coredump/
(2)只生成core不处理
- 直接写入核心转储文件(core dump)
sysctl -w kernel.core_pattern=/var/crash/core.%e.%p.%h.%t
# 表示核心转储文件将直接写入 /var/crash/ 目录,文件名格式为 core.<可执行文件名>.<进程ID>.主机名(`%h`).时间戳(`%t`)。
- 禁用核心转储文件
sysctl -w kernel.core_pattern=|/bin/true
- core送到外部工具
sysctl -w kernel.core_pattern=|/usr/local/bin/core_handler(工具)
以上的修改可以在**/etc/sysctl.conf**中,配置永久生效:
echo "kernel.core_pattern=/tmp/cores/core.%e.%p.%h.%t" >> /etc/sysctl.conf
sysctl -p
1.4systemd-coredump的简单使用
coredumpctl list | grep -i postgres # 检查是否已有core
coredumpctl info <PID 或 时间索引> # 查看某条记录详情
coredumpctl dump <PID> --output=postgres.core # 导出文件
2.模拟生成core
2.1systemd-coredump放在coredump目录下
/etc/systemd/coredump.conf
[Coredump]
Storage=external
Compress=yes
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
75929
(1 row)
[root@cent9-test91 coredump]# kill -SEGV 75929
[root@cent9-test91 coredump]# coredumpctl list | grep -i postgres
Tue 2025-11-11 02:17:08 CST 75929 1000 1000 SIGSEGV present /data/v18_pg/bin/postgres 1.3M
[root@cent9-test91 coredump]# coredumpctl info 75929
PID: 75929 (postgres)
UID: 1000 (postgres)
GID: 1000 (postgres)
Signal: 11 (SEGV) <<<<--------------------------------
Timestamp: Tue 2025-11-11 02:17:07 CST (2min 24s ago)
Command Line: $'postgres: postgres postgres [local] idle'
Executable: /data/v18_pg/bin/postgres
Control Group: /user.slice/user-0.slice/session-38.scope
Unit: session-38.scope
Slice: user-0.slice
Session: 38
Owner UID: 0 (root)
Boot ID: 302b03d205b348f896417564d8592384
Machine ID: e8c2bb90b1f3483db01544b55dc3ee27
Hostname: cent9-test91
Storage: /var/lib/systemd/coredump/core.postgres.1000.302b03d205b348f896417564d8592384.75929.1762798627000000.zst (present)
Size on Disk: 1.3M
Message: Process 75929 (postgres) of user 1000 dumped core.
Stack trace of thread 75929:
#0 0x0000ffffa5f4a5e8 __GI_epoll_pwait (libc.so.6 + 0xeb5e8)
#1 0x000000000080e2c8 WaitEventSetWaitBlock (postgres + 0x40e2c8)
#2 0x00000000006b7c7c secure_read (postgres + 0x2b7c7c)
#3 0x00000000006be4fc pq_recvbuf (postgres + 0x2be4fc)
#4 0x00000000006bf38c pq_getbyte (postgres + 0x2bf38c)
#5 0x000000000082bbfc SocketBackend (postgres + 0x42bbfc)
#6 0x0000000000826d24 BackendMain (postgres + 0x426d24)
#7 0x000000000078b164 postmaster_child_launch (postgres + 0x38b164)
#8 0x000000000078e8fc BackendStartup (postgres + 0x38e8fc)
#9 0x0000000000790120 PostmasterMain (postgres + 0x390120)
#10 0x000000000049d830 main (postgres + 0x9d830)
#11 0x0000ffffa5e86540 __libc_start_call_main (libc.so.6 + 0x27540)
#12 0x0000ffffa5e86618 __libc_start_main_impl (libc.so.6 + 0x27618)
#13 0x000000000049dbb0 _start (postgres + 0x9dbb0)
ELF object binary architecture: AARCH64
[root@cent9-test91 coredump]# coredumpctl dump 75929 --output=postgres.core
[root@cent9-test91 coredump]# ll
total 210784
-rw-r-----+ 1 root root 1386200 Nov 11 02:17 core.postgres.1000.302b03d205b348f896417564d8592384.75929.1762798627000000.zst
-rw-r--r-- 1 root root 214450176 Nov 11 02:22 postgres.core
2.2把core文件放到指定目录
echo "kernel.core_pattern=/tmp/cores/core.%e.%p.%h.%t" >> /etc/sysctl.conf
sysctl -p
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
76111
(1 row)
[root@cent9-test91 coredump]# kill -SEGV 76111
[root@cent9-test91 cores]# ll /tmp/cores/
total 209256
-rw------- 1 postgres postgres 214441984 Nov 11 03:16 core.postgres.76111.cent9-test91.1762802188
[root@cent9-test91 cores]# coredumpctl info 76111
No coredumps found.
[root@cent9-test91 cores]# gdb /data/v18_pg/bin/postgres core.postgres.76111.cent9-test91.1762802188
...
Program terminated with signal SIGSEGV, Segmentation fault <<------------------------
...




