技术原理
核心机制
以预编译PreparedStatement为例,计划缓存在当前会话上时,内存位置如图1所示,开启GPC全局共享计划后,内存位置如图2所示。
用户指定预编译计划缓存,在会话上基于指定键Key(SQL语句和会话级GUC参数)生成预编译语句,通过Key在共享计划缓存中进行匹配并直接引用已匹配的缓存计划。自动参数化、相同语句计划复用、存储过程中计划缓存共享逻辑与之类似。
- 由于计划缓存在会话上, CN与DN间计划缓存复用和会话存在耦合关系。CN连接一个DN执行PBE后,连接不会释放,必须保留长连接,确保在CN上转发语句Key给DN会话时获取到预期的计划缓存。仅当CN上会话退出之后,才能释放和该DN的连接。
- 在高并发场景下,DN将成为集群的连接瓶颈。
如图3所示,CN上长连接场景下,假设每个CN为2500并发,在4CN+4DN的集群上,由于DN上保留了所有CN的PBE连接,每个DN上有10000并发。每个会话都会占用内存,所以DN的主要瓶颈在内存,系统整体并发能力受限于单DN的并发能力。
当开启GPC时,CN每次执行预编译语句均直接转发原始PBE命令给DN,与预编译计划缓存场景不同,不通过语句名作为Key在会话中获取计划缓存,而是通过每次转发给DN的PBE中的SQL文本作为Key,从全局共享计划中获取计划缓存。
通过GPC功能,无需保留会话进行缓存计划,使得CN与DN间会话可以和预编译语句解耦,不必保持长连接。因此DN上的连接数为正在执行的连接数,执行结束的可直接释放,且DN上不存在预编译语句缓存,每次将从原始SQL直接解析。
接口介绍
| 名称 | 说明 | |
|---|---|---|
| GUC参数 | enable_global_plancache | 控制全局计划缓存功能开启,具体请参见《参考》中“数据库运行参数说明 > GUC参数说明 > 查询规划 > 其他优化器选项”章节。 |
| gpc_clean_timeout | 控制不使用的共享计划的保留时间,具体请参见《参考》中“数据库运行参数说明 > GUC参数说明 > 查询规划 > 其他优化器选项”章节。 | |
| disable_gpc_store | 用于阻止后续计划存入全局计划缓存,具体请参见《参考》中“数据库运行参数说明 > GUC参数说明 > 查询规划 > 其他优化器选项”章节。 | |
| enable_gpc_grayrelease_mode | 在不重启集群的情况下开启GPC,具体请参见《参考》中“数据库运行参数说明 > GUC参数说明 > 查询规划 > 其他优化器选项”章节。 | |
| Hint名 | no_gpc | 强制单个查询语句不在全局共享计划缓存,具体请参见请参见《SQL调优指南》中“使用Plan Hint进行调优”章节。 |
| 函数或视图名 | DBE_PERF.GLOBAL_PLANCACHE_STATUS | 该视图显示GPC全局计划缓存状态信息,具体请参见《参考》中“Schema > DBE_PERF Schema> Global Plancache”章节。 |
| DBE_PERF.LOCAL_PLANCACHE_STATUS | 该视图显示当前节点的GPC全局计划缓存状态信息,具体请参见《参考》中“Schema > DBE_PERF Schema > Global Plancache”章节。 | |
| DBE_PERF.LOCAL_PLANCACHE_CEALN | 清理当前节点上无人使用的全局计划缓存,具体请参见《参考》中“Schema > DBE_PERF Schema > Global Plancache”章节。 | |
| DBE_PERF.GLOBAL_PLANCACHE_CLEAN | 该视图清理当前节点上无人使用的全局计划缓存,具体请参见《参考》中“Schema > DBE_PERF Schema > Global Plancache”章节。 | |
| pg_catalog.plancache_status(is_with_plan) | 显示在当前节点上的全局计划缓存的状态信息,即plan_info列。入参is_with_plan为bool类型,默认值为false。当入参为true时,显示plan_info的信息。具体请参见《参考》中“SQL参考 > 函数和操作符 > 统计信息函数”章节。 | |
| dbe_perf.global_plancache_status(is_with_plan) | 显示在所有节点上的全局计划缓存的状态信息,即plan_info列。入参is_with_plan为bool类型,默认值为false。当入参为true时,显示plan_info的信息。具体请参见《参考》中“SQL参考 > 函数和操作符 > 统计信息函数”章节。 | |
| DBE_PERF.global_plancache_clean() | 清理所有节点上无人使用的全局计划缓存,具体请参见《参考》中“SQL参考 > 函数和操作符 > 系统管理函数 > 其它函数”章节。 | |
| pg_catalog.plancache_clean() | 清理当前节点上无人使用的全局计划缓存,具体请参见《参考》中“SQL参考 > 函数和操作符 > 系统管理函数 > 其它函数”章节。 | |
| pg_catalog.global_plancache_set_invalid(hashkey, unique_sql_id) | 支持通过bigint类型的入参hashkey和unique_sql_id手动失效本节点的GPC缓存计划,具体请参见《参考》中“SQL参考 > 函数和操作符 > 系统管理函数 > 其它函数”章节。 | |
| pg_catalog.global_plancache_show_plan (hashkey, unique_sql_id) | 通过bigint类型的入参hashkey和unique_sql_id,用于查看对应hashkey和unique_sql_id的GPC缓存计划,具体请参见《参考》中“SQL参考 > 函数和操作符 > 系统管理函数 > 其它函数”章节。 | |


