本文介绍临时文件常见的问题及排查方法。
临时文件在不同的 OceanBase 数据库版本上存在不同的使用限制,具体如下:
-
单个 observer 节点同时写入的最大文件数
- OceanBase 数据库 V2.x 及之前版本,默认最大 4000 个,可以通过
_temporary_file_io_area_size
调整,重启生效。 - OceanBase 数据库 V3.x、4.x 版本,不存在。
- OceanBase 数据库 V2.x 及之前版本,默认最大 4000 个,可以通过
-
单租户临时文件最大磁盘总空间
- OceanBase 数据库 V2.2.x 及之前版本,不存在。
- OceanBase 数据库 V3.x 版本:单个租户,最大可用临时文件总空间为 4TB,不可以调整。
- OceanBase 数据库 V4.x 版本:单个租户,与租户内存大小相关,
tenant_memory * 70% * 500GB
磁盘空间,最大可达 100TB。
-
单个 observer 节点同一时刻 read IO 最大带宽
- OceanBase 数据库 V3.x 版本:最大支持 4GB。
- OceanBase 数据库 V4.x 版本:最大支持 4GB。
常见问题
Q1: 如何判断临时文件空间使用情况?
A:可通过查询虚拟表 _ _all_virtual_macro_block_marker_status 或 __all_space_usage 获取临时文件空间使用情况,详细 SQL 如下。
-
通过
__all_virtual_macro_block_marker_status
查询。-
在 OceanBase 数据库 V3.2.x 及之后版本中,临时文件空间和 mark 不到宏块一起统计在 hold count 字段中。若想要查询具体临时文件空间占用,可以通过
__all_space_usage
表,查看file type
为tenant tmp data
的行。obclient> select * from __all_virtual_macro_block_marker_status where svr_ip = 'xxx' and svr_port = xx;
-
202306之前的 OceanBase 数据库 V3.2.x 版本,hold count 统计有存在问题,可使用下列公式计算实际的 hold count 值。
hold_count = hold_count - macro_meta_count - partition_meta_count - data_count - second_index_count - lob_data_count - lob_second_index_count - bloomfilter_count
obclient> select svr_ip, svr_port, total_count, reserved_count, macro_meta_count, partition_meta_count, data_count, second_index_count, lob_data_count,lob_second_index_count, bloomfilter_count, (hold_count - macro_meta_count - partition_meta_count - data_count - second_index_count - lob_data_count - lob_second_index_count - bloomfilter_count) as actual_hold_count, pending_free_count, free_count, mark_cost_time, sweep_cost_time from __all_virtual_macro_block_marker_status where svr_ip = 'xxx' and svr_port = xx;
-
-
通过
__all_space_usage
查询在 OceanBase 数据库 V3.1.x 及之后版本中,具体临时文件空间占用,也可以通过
__all_space_usage
表,看file type
为tenant tmp data
的行。obclient> select svr_ip, svr_port, file_type, sum(data_size) from __all_space_usage group by svr_ip, svr_port, file_type;
Q2: 如何判断是否达到单租户临时文件最大磁盘总空间?
A:查询 __all_space_usage
看临时文件磁盘占用大小,或查看 __all_virtual_memory_info
表中 label 为 TmpBlockManager 的内存是否达到上限(3x: 15GB,4x:租户内存70%)。
-
通过查询
__all_space_usage
表,查看 file type 为 tenant tmp data 的行。obclient> select svr_ip, svr_port, file_type, sum(data_size) from __all_space_usage group by svr_ip, svr_port, file_type;
-
通过查询
__all_virtual_memory_info
表,查看 label 为 TmpBlockManager 的行。obclient> select * from __all_virtual_memory_info where label = 'TmpBlockManager' and svr_ip = 'xxx' and svr_port = xx;
Q3: 为什么会有单租户临时文件最大磁盘总空间?
A:之所以会有临时文件总空间限制,是因为临时文件的元数据不持久化,仅存储在内存中,避免打爆租户内存,影响系统稳定,该部分内存设置了上限。
Q4: 如何判断是否达到单个 observer 节点同一时刻 read IO 最大带宽?
A:查看__all_virtual_memory_info 表中 label 为 TmpPageCache 的内存是否达到 4GB 上限。
通过查询 __all_virtual_memory_info
表,查看 label 为 TmpBlockManager 的行。
obclient> select * from __all_virtual_memory_info where label = 'TmpPageCache' and svr_ip = 'xxx' and svr_port = xx;
在 OceanBase 数据库 V3.x 版本内,该模块存在已知的内存泄露,具体可参考临时文件 READ IO 内存发生泄露导致内存容量超出了4GB 的最大限制
Q5: 什么是临时文件空间放大?如何判断临时文件是否已发生了空间放大?如果避免空间放大?
A:对于临时文件,空间放大是指实际磁盘占用大于写入数据的数据量。简单地说,写入的 buffer 的大小是固定的,当写入并发度(dir_id)大于写入 buffer 中可以容纳的宏块个数时,就有可能会产生写入放大问题。可以使用下面的方法,确认临时文件宏块是否发生了空间放大。
-
OceanBase 数据库 V4.1.x 及之前版本。
grep 'ob_tmp_file*' observer.log.2023031022* | grep 'succeed to wash a block' | grep -o 'free_page_nums:[0-9]*' | awk -F ':' '{ sum += $2; } END { print "total_free_page_num = " sum; print "avg_free_page_nums = " sum/NR; print "enlargement_factor = " (252*NR)/(252*NR - sum); print "macro_block_count = " NR }'
-
OceanBase 数据库 V4.2.x 及之后版本。
grep 'ob_tmp_file*' observer.log.2023031022* | grep 'succeed to wash a block' | grep -o 'free_page_nums=[0-9]*' | awk -F '=' '{ sum += $2; } END { print "total_free_page_num = " sum; print "avg_free_page_nums = " sum/NR; print "enlargement_factor = " (252*NR)/(252*NR - sum); print "macro_block_count = " NR }'
如果发生空间放大,通常可以采用下面两种调整方法,降低放大,
- 降低并发度,确保写入buffer的宏块个数少于文件写入并发数。
- 增大buffer大小,可以通过调整租户级
_temporary_file_io_area_size
配置项。
Q6: 什么是临时文件泄露?如何判断临时文件是否发生了泄露?一旦发生文件泄露,如果规避?
A:如果一个任务开始时打开了一个临时文件,但在该任务结束时却没有删除该文件,即临时文件泄露。一旦发生了临时文件泄露,会导致磁盘空间长期被占用,无法回收。
发生临时文件泄漏可以通过如下方法找出文件泄漏点属于模块。
-
大查询超时设置不合理,导致残留临时文件,可以查询
__all_virtual_dtl_interm_result_monitor
。 -
如果没有可以,则按照如下方法找出泄漏点属于模块。
-
找出所有临时文件日志。
grep 'ob_tmp_file' observer.log* > ~/tmp_file.log
-
找出打开临时文件日志。
grep 'succeed to open a tmp file' tmp_file.log | grep -o 'fd=[0-9]*' | awk -F '=' '{print $2}' | sort -h > open.fd
-
找出删除临时文件日志。
grep 'succeed to remove a tmp file' tmp_file.log | grep -o 'fd=[0-9]*' | awk -F '=' '{print $2}' | sort -h > remove.fd
-
找出只打开没有删除的临时文件 fd。
grep -f remove.fd -F -v -x open.fd
-
找出只打开没有删除的临时文件日志。
grep 'succeed to open a tmp file' tmp_file.log | grep 'fd=11'
-
找出只打开没有删除的临时文件函数调用堆栈。
addr2line -pCfe bin/observer 0x1aae97c7 0x14ac6511 0x14ac5363 0xf530a2b 0xf52fa9b 0xf53a0bd 0xf52c62c 0xf480d43 0xf47ee17 0xf4448c5 0xe6cb79c 0x5e7e4ac 0x5e7e0e2 0x60c5dd6 0x5e37331 0xf0b4f3f 0x5e37331 0xe1cfc40 0xe287349 0xe1d23c7 0x604c94a 0x601848c 0x79262e5 0x5cd8eae 0x792486c 0x5cd7014 0x7925594 0x1b230a66 0x1b220c25 0x7f03699a8e25 0x7f0369467f1d
-
如果真的发生了临时文件泄露,可以通过重启发生泄露的 observer 进程即可。
适用版本
OceanBase 数据库所有版本。