关于KingbaseES临时文件过大问题

背景

前几天碰到一个问题,现场并发很高,数据量很大(6T),主备库经常出现临时文件过多。

临时文件概念:

当私有进程buffer不够用时,会将buffer内容dump到tempfile供数据库正常sql使用。常见的几个功能场景:ExecSorts、ExecHashJoin、ExecMergejoin、tempTable、CTE等,当work_mem或者是temp_buffers不足以容纳sql中间功能环节结果集时会产生tempfile。

通过work_mem可以设置会话Query使用的临时内存的阈值,当然一个Query中如果使用了大量并行的排序等操作时,或者使用了并行计算多个WORKER PROCESS时,可能用到多个WORK_MEM空间,那么内存的使用量会比较大。

注意,临时表与Query执行过程中使用的临时文件概念不同,包括我们后面提到的几个临时文件使用跟踪的参数,实际上跟踪的都是Query执行过程中产生的临时文件,而不是临时表。请注意。

在控制临时文件使用量,使用个数的参数上,控制的也是Query执行过程中产生的临时文件,并不会控制临时表使用多少文件。

Query使用临时文件相关

限制一条个backend process最多能使用多少临时空间,通常临时空间在事务结束、Query结束后会自动回收。

包括数据库启动时,也会自动清理临时文件。

#temp_file_limit = -1                   # limits per-process temp file space  
                                        # in kB, or -1 for no limit  

1、temp_file_limit (integer)

指定进程可用于临时文件的最大磁盘空间量,例如排序和哈希临时文件,或用于保留光标的存储文件。试图超过此限制的交易将被取消。该值以KB为单位指定,而-1(默认值)表示没有限制。只有超级用户可以更改此设置。

此设置限制给定Kingbase进程使用的所有临时文件在任何时刻使用的总空间。应该注意的是,用于显式临时表的磁盘空间,与查询执行中后台使用的临时文件不同,不计入此限制。

这个参数作用可以避免操作系统磁盘空间被临时文件占用过多。

当临时文件使用量大于设置阈值时,记录日志。

#log_temp_files = -1                    # log temporary files equal or larger  
                                        # than the specified size in kilobytes;  
                                        # -1 disables, 0 logs all temp files 

2、log_temp_files (integer)

控制临时文件名和大小的日志记录。可以为排序、哈希和临时查询结果创建临时文件。删除每个临时文件时,会为其创建一个日志条目。值为零记录所有临时文件信息,而正值仅记录大小大于或等于指定KB数的文件。默认设置为-1,这将禁用此类日志记录。只有超级用户可以更改此设置。

例如,把log_temp_files设置成0 ,就会针对需要到临时空间的sql记录日志。

3、work_mem (integer)

指定内部排序操作和哈希表在写入临时磁盘文件之前要使用的内存量。该值默认为4MB。请注意,对于复杂的查询,可能会并行运行多个排序或哈希操作;在开始将数据写入临时文件之前,将允许每个操作使用此值指定的内存量。此外,几个正在运行的会话可以同时执行此类操作。因此,使用的总内存可能是work_mem值的许多倍;在选择值时,有必要牢记这一事实。排序操作用于ORDER BY、DISTINCT和merge联接。哈希表用于哈希联接、基于哈希的聚合和子查询中基于哈希的处理。

最后需要说明,虽然增大work_mem可以避免过多临时文件,但是如果查询并发过大有可能造成内存溢出的严重后果。

相关参数

临时表相关

前面提到临时表和Query使用临时文件不相干。

#temp_buffers = 8MB                     # min 800kB 

1、temp_buffers (integer)

设置每个数据库会话使用的最大临时缓冲区数。这些是会话本地缓冲区,仅用于访问临时表。默认值为8MB。设置可以在单个会话中更改,但只能在会话中首次使用临时表之前更改;随后更改该值的尝试将不会对该会话产生影响。

会话将根据需要分配临时缓冲区,直至达到temp_buffers缓冲区给定的限制。在实际上不需要许多临时缓冲区的会话中设置一个大值的成本仅为一个缓冲区描述符,即temp_buffers缓冲区中的每一增量约64个字节。但是,如果实际使用了缓冲区,则会为其消耗额外的8192字节(或者通常为BLCKSZ字节)。

#temp_tablespaces = ''                  # a list of tablespace names, '' uses  
                                        # only default tablespace  

总结

当进行一些Query的操作,使用的内存量大于work_mem指定阈值时,就会触发使用临时文件。包括排序,IDSTINCT,MERGE JOIN,HASH JOIN,哈希聚合,分组聚合,SRF,递归查询 等操作。

通过设置 log_temp_files ,当会话使用临时文件大小超过了设置大小,就可以跟踪到临时文件的使用。

posted @ 2022-06-23 11:07  KINGBASE研究院  阅读(241)  评论(0编辑  收藏  举报