PG高速缓冲区(Cache)——系统表元组缓冲区SysCache访问
在CatCache中查找元组有两种方式:精确匹配SearchCatCache和部分匹配SearchCatcacheList。前者用于给定CatCache所需的所有键值,并返回CatCache中能完全匹配这个键值的元组;而后者只需要给出部分键值,并将部分匹配的元组以一个CatCList的方式返回。
SysCache提供了SearchSysCache、SearchSysCacheList、ReleaseSysCache、SearchSysCacheCopy、SearchSysCacheExists、GetSysCacheOid、SearchSysCacheAttName、SearchSysCacheCopyAttName、SearchSysCacheExistsAttName,主要就是调用catcache.c提供的查找元组的函数,以及释放计数函数。
SearchSysCache是SearchCatCache的一层封装,为调用者执行初始化和进行查找键设置。如果找到元组,则返回该元组的缓存副本;如果未找到,则返回NULL。元组是“cache”副本,不能修改。调用方使用完元组后,调用ReleaseSysCache()释放SearchSysCache()获取的引用计数。如果不这样做,元组将一直锁定在缓存中,直到事务结束,这是可以容忍的,但不可取的。注意:调用方不能释放返回的元组!
1 HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) { 2 if (cacheId < 0 || cacheId >= SysCacheSize || 3 !PointerIsValid(SysCache[cacheId])) 4 elog(ERROR, "invalid cache id: %d", cacheId); 5 return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4); 6 }
SearchSysCacheList同理
1 struct catclist *SearchSysCacheList(int cacheId, int nkeys, 2 Datum key1, Datum key2, Datum key3, Datum key4){ 3 if (cacheId < 0 || cacheId >= SysCacheSize || 4 !PointerIsValid(SysCache[cacheId])) 5 elog(ERROR, "invalid cache id: %d", cacheId); 6 7 return SearchCatCacheList(SysCache[cacheId], nkeys, 8 key1, key2, key3, key4); 9 }
ReleaseSysCache是RelesaseCatCache的房子,用于释放tuple的引用计数
1 void ReleaseSysCache(HeapTuple tuple) { 2 ReleaseCatCache(tuple); 3 }
SearchSysCacheCopy调用SearchSysCache并返回syscache条目的一份拷贝,并释放原条目
1 HeapTuple SearchSysCacheCopy(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) { 2 HeapTuple tuple, newtuple; 3 tuple = SearchSysCache(cacheId, key1, key2, key3, key4); 4 if (!HeapTupleIsValid(tuple)) 5 return tuple; 6 newtuple = heap_copytuple(tuple); 7 ReleaseSysCache(tuple); 8 return newtuple; 9 }
SearchSysCacheExists查看某个tuple释放存在
1 bool SearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) { 2 HeapTuple tuple; 3 tuple = SearchSysCache(cacheId, key1, key2, key3, key4); 4 if (!HeapTupleIsValid(tuple)) 5 return false; 6 ReleaseSysCache(tuple); 7 return true; 8 }
GetSysCacheOid调用SearchSysCache,返回获取到的tuple的OID
1 Oid GetSysCacheOid(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4){ 2 HeapTuple tuple; 3 Oid result; 4 tuple = SearchSysCache(cacheId, key1, key2, key3, key4); 5 if (!HeapTupleIsValid(tuple)) 6 return InvalidOid; 7 result = HeapTupleGetOid(tuple); 8 ReleaseSysCache(tuple); 9 return result; 10 }
SearchSysCacheAttName调用SearchSysCache查找ATTNAME,返回获取到的tuple
1 HeapTuple SearchSysCacheAttName(Oid relid, const char *attname){ 2 HeapTuple tuple; 3 tuple = SearchSysCache(ATTNAME, 4 ObjectIdGetDatum(relid), 5 CStringGetDatum(attname), 6 0, 0); 7 if (!HeapTupleIsValid(tuple)) 8 return NULL; 9 if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped){ 10 ReleaseSysCache(tuple); 11 return NULL; 12 } 13 return tuple; 14 }
1 HeapTuple 2 SearchSysCacheCopyAttName(Oid relid, const char *attname) 3 { 4 HeapTuple tuple, 5 newtuple; 6 7 tuple = SearchSysCacheAttName(relid, attname); 8 if (!HeapTupleIsValid(tuple)) 9 return tuple; 10 newtuple = heap_copytuple(tuple); 11 ReleaseSysCache(tuple); 12 return newtuple; 13 }
SysCacheAttr给定先前由SearchSysCache()获取的元组,提取特定属性。这相当于对从非缓存关系获取的元组使用heap_ghtattr()。通常,这只用于可能为NULL或可变长度的属性;通过将元组映射到include/catalog/中的C struct声明,可以访问系统表中的固定大小属性。与heap_getattr()一样,如果属性是按引用传递的类型,则返回一个指向元组数据区域的指针---调用方不能修改或释放数据!注意:使用带有cacheId的SysCacheGetAttr()是合法的,它引用了从中获取元组的同一目录的不同缓存。
1 Datum 2 SysCacheGetAttr(int cacheId, HeapTuple tup, 3 AttrNumber attributeNumber, 4 bool *isNull) 5 { 6 /* 7 * We just need to get the TupleDesc out of the cache entry, and then we 8 * can apply heap_getattr(). Normally the cache control data is already 9 * valid (because the caller recently fetched the tuple via this same 10 * cache), but there are cases where we have to initialize the cache here. 11 */ 12 if (cacheId < 0 || cacheId >= SysCacheSize || 13 !PointerIsValid(SysCache[cacheId])) 14 elog(ERROR, "invalid cache id: %d", cacheId); 15 if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc)) 16 { 17 InitCatCachePhase2(SysCache[cacheId], false); 18 Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc)); 19 } 20 21 return heap_getattr(tup, attributeNumber, 22 SysCache[cacheId]->cc_tupdesc, 23 isNull); 24 }

浙公网安备 33010602011771号