本文介绍了Global RelCache的简介和使用方法。
背景信息
目前RelCache为Session私有,且无淘汰机制,导致连接数过多或者表个数过多时,RelCache消耗过多内存,甚至出现OOM的风险。
PolarDB PostgreSQL版(兼容Oracle)采用Global RelCache + Local RelCache两层缓存架构。部分系统表都只会存在Local RelCache中,其他普通的用户表和大部分系统表都会自动加载到Global RelCache中,而Local RelCache日常只需要设置比较小的容量,在需要的时候从Global RelCache加载,如果Local RelCache容量超限,则按照淘汰策略进行淘汰。
简介
PostgreSQL的RelCache缓存了所有表的元数据信息,为每个进程私有,在连接数较多时消耗很多内存。Global RelCache将RelCache放到共享内存中,为所有进程共享,提高内存利用率。
参数说明
Global RelCache引入了以下GUC参数,在必要的时候可以通过参数开启或关闭Global RelCache和Local RelCache的相关功能,或者进行一些性能调优。
参数 | 说明 | 级别 |
---|---|---|
polar_local_relcache_size | 用于设置Local RelCache的容量大小。取值范围:0 ~ INT_MAX,默认值为0(表示没有容量限制,不会开启淘汰能力)。单位为KB。 说明 建议根据活跃表的数量进行设置,一般使用默认值即可,无需修改,也可以参考监控中的查询命中率进行设置。 | PGC_USERSET |
polar_enable_global_relcache | 是否开启Global RelCache功能。取值范围:on(开启)/off(关闭),默认值为on。 说明
| PGC_SIGHUP |
polar_global_relcache_size | 用于设置Global RelCache的容量大小。取值范围:0 ~ INT_MAX,默认值为1024 ,单位为MB。 说明 建议该参数设置足够容纳所有表(包括索引、toast table、view 等),该内存为所有Session共享,并且在系统启动时进行初始化,所以需要重启生效。 | PGC_POSTMASTER |
运维
所有监控接口都在polar_grc插件中,如果需要使用请先执行create extension polar_grc;
,主要的运维动作为create/drop extension
。
- Local RelCache强制淘汰
因为Local RelCache是被动且逐步淘汰的策略,如果遇到定时任务或者突发异常大流量之后又突然idle的session,Local RelCache可以通过定时机制快速的把内存降下来。但依然有部分场景可能需要手动去干预某个session的Local RelCache内存情况。
例如,在运行过程中,发现Local RelCache设置的太大了,消耗了太多的内存,然后在线调低之后,有部分session已经占了超限的内存,但因为session处于idle的状态,如果有需要的话,可以通过该接口手动干预。说明 因为PostgreSQL的config reload
是lazy模式,在收到SIGHUP信号之后,实际重新加载config file
可能是在下一次执行SQL之前,对PostgreSQL而言这样操作是合理的,因为在这期间,调整了也不会使用。执行以下命令调用polar_relcache_evict函数,可以把指定backend进程淘汰Local RelCache中所有可以淘汰的relation,从而降低内存。select polar_relcache_evict($backend_pid);
- 重置监控数据大多数监控数据的计数器会持续递增或者递减,可以在获取监控数据的函数中通过
reset
参数重置,也可以通过额外的重置接口。当然也可以在获取监控数据的同时通过polar_relcache_get_stat
、polar_relcache_get_partition_stat
函数参数来直接重置。CREATE FUNCTION polar_relcache_reset_stat( OUT num_reset int4) RETURNS integer AS 'MODULE_PATHNAME', 'polar_relcache_reset_stat' LANGUAGE C; CREATE FUNCTION polar_grc_reset_stat( OUT num_reset int4) RETURNS integer AS 'MODULE_PATHNAME', 'polar_grc_reset_stat' LANGUAGE C;
监控
Global RelCache和Local RelCache提供了若干函数和视图,函数是视图的超集,视图只是为了方便使用而创建。所有函数和视图的定义都在 polar_grc插件中。
- Local RelCache
- polar_relcache_get_stat函数和polar_relcache_stat视图
polar_relcache_get_stat函数和polar_relcache_stat视图的输出完全一致,主要用于输出Local RelCache内部的各种状态和统计信息。
不同的是函数带了一个输入参数reset,表示是否重置统计计数器。绝大部分统计信息都是一个计数器,如果不重置的话,计数器会一直累加,如果想获取特定时间区间内的状态情况,可以在开始时对状态进行重置。
指标说明:指标 说明 reset 表示是否需要重置所有的统计计数器。取值如下: - true:表示需要重置所有的统计计数器。在返回本次结果之后会清零所有计数器。
- false:表示不需要重置所有的统计计数器。
backend_pid 表示统计信息所属的backend进程。 num_entry 表示当前Local RelCache中缓存了多少个Relation。 count_insert 表示Local RelCache从上次计数器重置开始到现在插入的次数。 count_delete 表示Local RelCache从上次计数器重置开始到现在删除的次数。 count_nailed_lookup 表示Local RelCache从上次计数器重置到现在nailed table查询次数。 count_lookup 表示Local RelCache从上次计数器重置到现在查询的次数。 说明 此处只包含非nailed表的次数。这个指标和上一个count_nailed_lookup加起来表示整个Local RelCache的查询次数。count_lookup_miss 表示Local RelCache从上次计数器重置到现在查询未命中的次数。 说明 count_nailed_lookup和count_lookup两个指标包含了命中和不命中的查询次数,这个指标表示不命中的次数,通过 (count_lookup - count_lookup_miss) / count_lookup可以计算出非nailed table的缓存命中率,而(count_lookup + count_nailed_lookup - count_lookup_miss) / count_lookup 可以计算出整个Local RelCache所有查询的命中率。一般来说,前一个命中率更有意义。count_evict 表示Local RelCache从上次计数器重置到现在一共淘汰了多少个Relation。 count_forced_evict 表示Local RelCache从上次计数器重置到现在通过polar_relcache_evict函数强制淘汰了多少个Relation。 count_timeout_evict 表示Local RelCache从上次计数器重置到现在通过timeout机制一共淘汰了多少个Relation。 说明 对活跃连接来说,这个值一般为0,count_timeout_evict + count_evict 反映了Local RelCache正常淘汰的个数。count_evictcycle 表示Local RelCache从上次计数器重置到现在一共淘汰了多少次。 count_empty_evictcycle 表示Local RelCache从上次计数器重置到现在一共有多少淘汰是空扫的,也就是徒劳的。正常情况下该值为0。 avg_step_length 表示Local RelCache从上次计数器重置到现在平均每次淘汰的Relation个数。 说明 一般情况下这个值不会很大,因为淘汰算法会让淘汰尽量平缓。max_step_length 表示Local RelCache从上次计数器重置到现在最多一次淘汰了多少个Relation。 说明 在突发大流量的情况可能出现该值比较大的情况。avg_idletime 表示Local RelCache从上次计数器重置到现在所有淘汰的Relation平均空闲时间。 说明 该值越小表示目前Local RelCache的淘汰压力越大,说明polar_local_relcache_size设置偏低,允许的情况下可以适当调高阈值。max_idletime 表示Local RelCache从上次计数器重置到现在所有淘汰的Relation中最大的空闲时间。 说明 该指标反映了当前的Local RelCache淘汰压力,如果这个值很大,说明当前容量设置是很充裕的,可以适当调小。如果这个值非常小,说明容量设置有些偏小。avg_evict_time 表示Local RelCache从上次计数器重置到现在平均每次用于淘汰消耗的时间。 max_evict_time 表示Local RelCache从上次计数器重置到现在单次淘汰最大消耗的时间。 说明 该指标和avg_evict_time一起反映淘汰算法本身的性能情况,一般情况下,这两个值都非常低,如果出现比较高的值,属于非预期的异常情况,需要进行排查。memory_context_total_space 表示当前RelCache MemoryContext总共分配的内存,单位为Bytes。 memory_context_free_space 表示当前RelCache MemoryContext内部空闲内存。包括未使用完的block和空闲的chunk。 说明 该指标和memory_context_total_space一起用于评估当前的内存占用,以及内部碎片情况。 - polar_relcache_get_relation函数和polar_relcache_relation视图
polar_relcache_get_relation函数和polar_relcache_relation视图用于将Local RelCache中当前缓存的Relation都输出出来。因为Local RelCache是每个Sesion私有的,所以只能输出自己Session中缓存的。主要作用是用于调试和问题排查、定位等用途。
- polar_relcache_get_stat函数和polar_relcache_stat视图
- Global RelCache
polar_grc_get_stat函数和polar_grc_stat视图
与polar_relcache_stat类似,主要用于输出Global RelCache内部的各种状态和统计信息。视图和函数输出的结果一致,只是额外多一个输入参数,用于控制是否重置统计计数器。
指标说明:CREATE FUNCTION polar_grc_get_stat( IN reset boolean, OUT num_entry int8, OUT count_insert int8, OUT count_update int8, OUT count_delete int8, OUT count_lookup int8, OUT count_lookup_miss int8, OUT count_OOM int8, OUT count_invalid_lookup int8, OUT count_error_clean int8, OUT num_partitions int4, OUT shm_free_space int8, OUT shmaset_total_space int8, OUT shmaset_free_space int8 ) RETURNS record AS 'MODULE_PATHNAME', 'polar_grc_get_stat' LANGUAGE C; CREATE VIEW polar_grc_stat AS SELECT * FROM polar_grc_get_stat(false);
指标 说明 num_entry 表示Global RelCache中缓存的Relation个数,包含所有数据库。 count_insert 表示Global RelCache从上次重置到现在插入的次数。 count_update 表示Global RelCache从上次重置到现在更新的次数。 count_delete 表示Global RelCache从上次重置到现在删除的次数。 count_lookup 表示Global RelCache从上次重置到现在查询的次数。 count_lookup_miss 表示Global RelCache从上次重置到现在查询未命中的次数。 说明 通过 (count_lookup - count_lookup_miss) / count_lookup可以得到Global RelCache的查询命中率,一般来说,在缓存预热之后,Global RelCache的命中率会稳定在高水平。count_OOM 表示Global RelCache从上次重置到现在发生OOM的次数。 说明 因为Shared Memory内存在集群启动时初始化且容量固定,所以如果容量设置不合理,在使用期间shared memory不够用的话,会发生Global RelCache的插入和更新失败,该值记录了发生OOM的次数。count_invalid_lookup 表示Global RelCache查询命中数。 说明 如果该Relation正在被其他Session并发更新,目前的状态为invalid,所以本次查询无效。正常情况下,该值为0或者很小;如果出现比较大的值,除非特殊业务场景,否则需要进行排查。count_error_clean 进程异常退出或者事务提交过程中出现ERROR,在回滚或者进程退出之前会清理Global RelCache中维护的relation信息,该指标记录了发生这种异常清理的次数。 说明 如果这个指标非常高,表示当前集群的处于不太正常的状态。num_partitions 表示Global RelCache使用的分区哈希表数量。 说明 正常情况下,这个值等于polar_global_relcache_partitions
配置的值,如果该值比配置要小,说明如果发生了OOM,部分哈希分区被停用了。shm_free_space 表示Global RelCache剩余的共享内存字节数。 说明 如果该值很小,表示polar_global_relcache_size
设置的太小了,最好调大,否则可能会发生OOM,进而影响性能。shmaset_total_space 表示Global RelCache使用的Memory Context共分配的内存大小。 说明 shmaset_total_space + shm_free_space = polar_global_relcache_sizeshmaset_free_space 表示Global RelCache使用的Memory Context内部的空闲内存。 说明 该指标和shmaset_total_space一起反映共享内存的使用情况以及内部碎片。