本节简单介绍了PostgreSQL缓存管理(Buffer Manager)中的其中一个实现函数ReadBufferExtended,该函数返回对应请求关系数据块的buffer.。
一、数据结构
Relation
关系的内存结构.
typedef struct RelationData
{
RelFileNode rd_node;
struct SMgrRelationData *rd_smgr;
int rd_refcnt;
BackendId rd_backend;
bool rd_islocaltemp;
bool rd_isnailed;
bool rd_isvalid;
char rd_indexvalid;
bool rd_statvalid;
SubTransactionId rd_createSubid;
SubTransactionId rd_newRelfilenodeSubid;
Form_pg_class rd_rel;
TupleDesc rd_att;
Oid rd_id;
LockInfoData rd_lockInfo;
RuleLock *rd_rules;
MemoryContext rd_rulescxt;
TriggerDesc *trigdesc;
struct RowSecurityDesc *rd_rsdesc;
List *rd_fkeylist;
bool rd_fkeyvalid;
MemoryContext rd_partkeycxt;
struct PartitionKeyData *rd_partkey;
MemoryContext rd_pdcxt;
struct PartitionDescData *rd_partdesc;
List *rd_partcheck;
List *rd_indexlist;
Oid rd_oidindex;
Oid rd_pkindex;
Oid rd_replidindex;
List *rd_statlist;
Bitmapset *rd_indexattr;
Bitmapset *rd_projindexattr;
Bitmapset *rd_keyattr;
Bitmapset *rd_pkattr;
Bitmapset *rd_idattr;
Bitmapset *rd_projidx;
PublicationActions *rd_pubactions;
bytea *rd_options;
Form_pg_index rd_index;
struct HeapTupleData *rd_indextuple;
Oid rd_amhandler;
MemoryContext rd_indexcxt;
struct IndexAmRoutine *rd_amroutine;
Oid *rd_opfamily;
Oid *rd_opcintype;
RegProcedure *rd_support;
FmgrInfo *rd_supportinfo;
int16 *rd_indoption;
List *rd_indexprs;
List *rd_indpred;
Oid *rd_exclops;
Oid *rd_exclprocs;
uint16 *rd_exclstrats;
void *rd_amcache;
Oid *rd_indcollation;
struct FdwRoutine *rd_fdwroutine;
Oid rd_toastoid;
struct PgStat_TableStatus *pgstat_info;
} RelationData;
typedef struct RelationData *Relation;
BufferAccessStrategy
buffer访问策略
typedef int Buffer;
#define InvalidBuffer 0
typedef struct BufferAccessStrategyData *BufferAccessStrategy;
typedef struct BufferAccessStrategyData
{
//全局的策略类型
BufferAccessStrategyType btype;
//buffers[]中的元素个数
int ring_size;
int current;
bool current_was_in_ring;
Buffer buffers[FLEXIBLE_ARRAY_MEMBER];
} BufferAccessStrategyData;
//Block结构体指针
typedef void *Block;
//GetAccessStrategy()函数可取值的参数
typedef enum BufferAccessStrategyType
{
//常规的随机访问
BAS_NORMAL,
//大规模的只读扫描
BAS_BULKREAD,
//大量的多块写(如 COPY IN)
BAS_BULKWRITE,
//VACUUM
BAS_VACUUM
} BufferAccessStrategyType;
ReadBufferMode
ReadBufferExtended函数所可能使用的读取模式.
typedef enum
{
RBM_NORMAL,
RBM_ZERO_AND_LOCK,
RBM_ZERO_AND_CLEANUP_LOCK,
RBM_ZERO_ON_ERROR,
RBM_NORMAL_NO_LOG
} ReadBufferMode;
二、源码解读
ReadBufferExtended返回对应请求关系数据块的buffer,实现逻辑比较简单,详见代码.
主要的实现逻辑在ReadBuffer_common中,该函数后续再行介绍.
Buffer
ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum,
ReadBufferMode mode, BufferAccessStrategy strategy)
{
bool hit;
Buffer buf;
//打开relation,级别为smgr
RelationOpenSmgr(reln);
if (RELATION_IS_OTHER_TEMP(reln))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary tables of other sessions")));
pgstat_count_buffer_read(reln);
buf = ReadBuffer_common(reln->rd_smgr, reln->rd_rel->relpersistence,
forkNum, blockNum, mode, strategy, &hit);
if (hit)
pgstat_count_buffer_hit(reln);
return buf;
}
三、跟踪分析
使用bt查看调用栈
(gdb) bt
#0 ReadBufferExtended (reln=0x7f497fe72788, forkNum=MAIN_FORKNUM, blockNum=0, mode=RBM_NORMAL, strategy=0x0)
at bufmgr.c:647
#1 0x00000000004d974f in heapgetpage (scan=0x1d969d8, page=0) at heapam.c:379
#2 0x00000000004daeb2 in heapgettup_pagemode (scan=0x1d969d8, dir=ForwardScanDirection, nkeys=0, key=0x0) at heapam.c:837
#3 0x00000000004dcf2b in heap_getnext (scan=0x1d969d8, direction=ForwardScanDirection) at heapam.c:1842
#4 0x000000000070ec39 in SeqNext (node=0x1d95890) at nodeSeqscan.c:80
#5 0x00000000006e0ab0 in ExecScanFetch (node=0x1d95890, accessMtd=0x70eba9 <SeqNext>, recheckMtd=0x70ec74 <SeqRecheck>)
at execScan.c:95
#6 0x00000000006e0b22 in ExecScan (node=0x1d95890, accessMtd=0x70eba9 <SeqNext>, recheckMtd=0x70ec74 <SeqRecheck>)
at execScan.c:145
#7 0x000000000070ecbe in ExecSeqScan (pstate=0x1d95890) at nodeSeqscan.c:129
#8 0x00000000006dee2a in ExecProcNodeFirst (node=0x1d95890) at execProcnode.c:445
#9 0x00000000007021b8 in ExecProcNode (node=0x1d95890) at ../../../src/include/executor/executor.h:237
#10 0x00000000007022dd in ExecLimit (pstate=0x1d95680) at nodeLimit.c:95
#11 0x00000000006dee2a in ExecProcNodeFirst (node=0x1d95680) at execProcnode.c:445
#12 0x00000000006d3d8d in ExecProcNode (node=0x1d95680) at ../../../src/include/executor/executor.h:237
#13 0x00000000006d65c5 in ExecutePlan (estate=0x1d95468, planstate=0x1d95680, use_parallel_mode=false,
operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x1d00ea8,
execute_once=true) at execMain.c:1723
#14 0x00000000006d4357 in standard_ExecutorRun (queryDesc=0x1cfdc28, direction=ForwardScanDirection, count=0,
execute_once=true) at execMain.c:364
#15 0x00000000006d417f in ExecutorRun (queryDesc=0x1cfdc28, direction=ForwardScanDirection, count=0, execute_once=true)
at execMain.c:307
#16 0x00000000008bffd4 in PortalRunSelect (portal=0x1d3ebf8, forward=true, count=0, dest=0x1d00ea8) at pquery.c:932
#17 0x00000000008bfc72 in PortalRun (portal=0x1d3ebf8, count=9223372036854775807, isTopLevel=true, run_once=true,
dest=0x1d00ea8, altdest=0x1d00ea8, completionTag=0x7ffc1fc513d0 "") at pquery.c:773
#18 0x00000000008b9cd4 in exec_simple_query (query_string=0x1cd8ec8 "select * from t1 limit 10;") at postgres.c:1145
---Type <return> to continue, or q <return> to quit---
#19 0x00000000008bdf5f in PostgresMain (argc=1, argv=0x1d05278, dbname=0x1d050e0 "testdb", username=0x1cd5ba8 "xdb")
at postgres.c:4182
#20 0x000000000081c16d in BackendRun (port=0x1cfae00) at postmaster.c:4361
#21 0x000000000081b8e0 in BackendStartup (port=0x1cfae00) at postmaster.c:4033
#22 0x0000000000817cda in ServerLoop () at postmaster.c:1706
#23 0x0000000000817590 in PostmasterMain (argc=1, argv=0x1cd3b60) at postmaster.c:1379
#24 0x0000000000741003 in main (argc=1, argv=0x1cd3b60) at main.c:228
(gdb)
逻辑较为简单,这里不再详细跟踪.
四、参考资料
PG Source Code
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容猜你喜欢
AI推送时光机 咦!没有更多了?去看看其它编程学习网 内容吧