抽丝剥茧丨PostgreSQL 系国产数据库%SYS CPU newfstatat() high 调优一例(二)

续接上回PostgreSQL 系国产数据库%SYS CPU newfstatat() high 调优一例(一),这个问题还在持续,并且原因并不只是一个,从调了文件系统级atime,到调整wal size减少日志被动清理,还有在验证temp文件,这里后来又发现了sysdate函数的timezone调用,简单记录。

前面有提到是newfsatat()函数产生的system CPU,用于文件验证,这可能是因为是BClinux 22的原因,也有可能早期版本调用的是stat()函数。

分析思路

  1. 确认是系统级还是进程级

  2. 如果是PG进程,跟踪当时执行的命令

  3. 多并发会话,压力测试还原问题

  4. 使用strace跟踪定位函数占用

  5. 使用strace跟踪函数调用的内容,如newfsatat()验证的是什么文件

  6. 根据操作的文件类型,判断相关功能。

相关命令

--确认进程idselect pg_backend_pid();-- 跟踪函数占比strace -c -p xxx--跟踪进程strace -p xxx   -o  str.log-- 查看文件调用grep newfsatat str.log

使用捕捉的SQL几个并发pgbench压测,负载如下,可见sys cpu使用近80%

问题一

产生的是pg_temp

$grep newfsatat xxx
newfstatat(AT_FDCWD, "base/pgsql_tmp/pgsql_tmp....newfstatat(AT_FDCWD, "base/pgsql_tmp/pgsql_tmp....

案例中一条3张表的left join操作,调用了3000多次newfstatat调用,并且几乎全是pgsql_tmp的临时文件。

PostgreSQL 哪些使用临时文件

在数据库中的一些操作,可能会用到临时文件,比如排序、HASH JOIN、聚合、distinct、中间结果存储等等。为了提高数据库的执行效率,一些操作可能会使用内存代替临时存储,仅仅当内存不足时使用临时文件。通过work_mem可以设置会话Query使用的临时内存的阈值,这里的临时都是Query执行过程中产生的临时文件,而不是临时表,通常临时空间在事务结束、Query结束后会自动回收。

加大work_mem可以减少临时文件,配置参数temp_file_limit=0可以把产生临时文件和SQL信息写到日志中。另外注意explain执行计划中的Sort Method: external merge Disk: xxxkB,仅显示了一部分的临时文件使用情况,这里的实际情况是,explain显示的是峰值使用量,而不是总使用量。

可以在视图pg_stat_database中看到数据库级别的统计信息,其中有temp_files和temp_bytes。这两列非常重要,因为它们会告诉您数据库是否必须向磁盘写入临时文件,这将不可避免地减慢操作速度。通常是因为work_mem设置太低,大量的低效SQL操作大数据,当时在创建索引等。

问题二

读取/etc/timezone

基于上面的问题我们压测是在tmp文件,查看执行计划使用的是hash join,该join是会产生tmp,我们在谓词列和join列创建了索引,优化器使用了nest loop join而不是hash join,结果不再产生temp,再使用相同的负载压测,负载sys cpu缩少了一倍,近30%,但显然也不正常。

使用上面的方法继续strace跟踪,发现如下:

newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0...

近几千次的/etc/localtime调用。判断应该是在做timezone相关调用,查看SQL 谓词条件有使用一个oracle兼容的函数sysdate,取的是一个join查询后日期字段(已创建索引)最近8小时的记录,cdate> sysdate-to_dsinterval(‘0 8:00:00).

测试是否sysdate()和now()调用localtime

数据库名=# select pg_backend_pid(); pg_backend_pid----------------         785320(1 row)数据库名=# select  sysdate;      sysdate------------------- 20250612 18:07:59(1 row)[{events=EPOLLIN, data={u32=669907864, u64=669907864}}], 1, -1, NULL, 8) = 1recvfrom(12, "Q\0\0\0\25select  sysdate;\0", 8192, 0, NULL, NULL) = 22newfstatat(AT_FDCWD, "/etc/localtime", {st_mode=S_IFREG|0644, st_size=561, ...}, 0) = 0sendto(11, "\2\0\0\0\300\3\0\0\216?\0\0\10\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 960, 0, NULL, 0) = 960sendto(12, "T\0\0\0 \0\1sysdate\0\0\0\0\0\0\0\0\0#0\0\10\377\377\377\377\0"..., 81, 0, NULL, 0) = 81recvfrom(12, 0xc03d58, 8192, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)epoll_pwait(4,数据库名=#  SELECT now();              now------------------------------- 2025-06-12 18:08:10.254791+08(1 row)[{events=EPOLLIN, data={u32=669907864, u64=669907864}}], 1, -1, NULL, 8) = 1recvfrom(12, "Q\0\0\0\22SELECT now();\0", 8192, 0, NULL, NULL) = 19sendto(11, "\2\0\0\0@\0\0\0\216?\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 64, 0, NULL, 0) = 64sendto(12, "T\0\0\0\34\0\1now\0\0\0\0\0\0\0\0\0\4\240\0\10\377\377\377\377\0\0D\0\0"..., 89, 0, NULL, 0) = 89recvfrom(12, 0xc03d58, 8192, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)epoll_pwait(4,

验证了我的判断,在该国产数据库中使用sysdate需要调用newfstatat(AT_FDCWD,“/etc/localtime”),而 PostgreSQL 原生的now函数并没有,而当前使用nl join后可能是关连的filter时,多过的调用了sysdate,而导致了问题的发生,继续优化改为使用now(),继续压测。

如果不放大看,几乎没有波动,sys CPU占用的问题得到解决,并且SQL整体的响应时间大大得到了优化提升。

图片

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨创立于2011年,是业界领先的“智能的数据技术提供商”。公司以“数据驱动,成就未来”为使命,致力于将创新的数据技术产品和解决方案带给全球的企业和组织,帮助客户构建安全、高效、敏捷且经济的数据环境,持续增强客户在数据洞察和决策上的竞争优势,实现数据驱动的业务创新和升级发展。

自成立以来,云和恩墨专注于数据技术领域,根据不断变化的市场需求,创新研发了系列软件产品,涵盖数据库、数据库存储、数据库管理和数据智能等领域。这些产品已经在集团型、大中型、高成长型客户以及行业云场景中得到广泛应用,证明了我们的技术和商业竞争力,展现了公司在数据技术端到端解决方案方面的优势。

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值