enter
This commit is contained in:
parent
1a3b0e6c56
commit
679db10bf3
|
|
@ -47,77 +47,115 @@ static Block GetLocalBufferStorage(void);
|
||||||
* Do PrefetchBuffer's work for temporary relations.
|
* Do PrefetchBuffer's work for temporary relations.
|
||||||
* No-op if prefetching isn't compiled in.
|
* No-op if prefetching isn't compiled in.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
这个函数的目的是在需要访问数据块之前,尽量将其加载到缓冲区中,
|
||||||
|
以加速后续的数据访问。它在有条件的情况下执行本地预取,以提高数据库性能。
|
||||||
|
*/
|
||||||
void LocalPrefetchBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
|
void LocalPrefetchBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
|
||||||
{
|
{
|
||||||
#ifdef USE_PREFETCH
|
#ifdef USE_PREFETCH
|
||||||
BufferTag new_tag; /* identity of requested block */
|
BufferTag new_tag; /* 请求块的标识 */
|
||||||
LocalBufferLookupEnt *hresult = NULL;
|
LocalBufferLookupEnt *hresult = NULL;
|
||||||
|
|
||||||
|
// 初始化请求块的标识
|
||||||
INIT_BUFFERTAG(new_tag, smgr->smgr_rnode.node, forkNum, blockNum);
|
INIT_BUFFERTAG(new_tag, smgr->smgr_rnode.node, forkNum, blockNum);
|
||||||
|
|
||||||
/* Initialize local buffers if first request in this session */
|
// 如果在当前会话中首次请求本地缓冲区,初始化本地缓冲区
|
||||||
if (u_sess->storage_cxt.LocalBufHash == NULL)
|
if (u_sess->storage_cxt.LocalBufHash == NULL)
|
||||||
InitLocalBuffers();
|
InitLocalBuffers();
|
||||||
|
|
||||||
/* See if the desired buffer already exists */
|
// 查看所需的缓冲区是否已经存在
|
||||||
hresult = (LocalBufferLookupEnt*)hash_search(u_sess->storage_cxt.LocalBufHash, (void*)&new_tag, HASH_FIND, NULL);
|
hresult = (LocalBufferLookupEnt*)hash_search(u_sess->storage_cxt.LocalBufHash, (void*)&new_tag, HASH_FIND, NULL);
|
||||||
if (hresult != NULL) {
|
if (hresult != NULL) {
|
||||||
/* Yes, so nothing to do */
|
/* 是的,所以不需要进行预取操作 */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in buffers, so initiate prefetch */
|
// 如果缓冲区中不存在所需块,启动预取操作
|
||||||
smgrprefetch(smgr, forkNum, blockNum);
|
smgrprefetch(smgr, forkNum, blockNum);
|
||||||
#endif /* USE_PREFETCH */
|
#endif /* USE_PREFETCH */
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
函数执行以下步骤:
|
||||||
|
|
||||||
|
查找缓冲区对应的存储管理器关系(SMgrRelation)。
|
||||||
|
对缓冲区中的数据进行加密(如果有加密需求的话,这部分可能是自定义函数)。
|
||||||
|
计算并设置数据页的校验和,以确保数据的完整性。
|
||||||
|
调用 smgrwrite 函数将数据写入磁盘,指定存储管理器关系、分支(fork)、数据块号以及要写入的数据。
|
||||||
|
这个函数用于确保本地缓冲区中的数据在适当的时候被写回磁盘,以保持数据的一致性和持久性。根据需要,它可能还包括了数据加密和校验和计算的步骤。
|
||||||
|
*/
|
||||||
void LocalBufferWrite(BufferDesc *bufHdr)
|
void LocalBufferWrite(BufferDesc *bufHdr)
|
||||||
{
|
{
|
||||||
SMgrRelation oreln;
|
SMgrRelation oreln;
|
||||||
Page localpage = (char *)LocalBufHdrGetBlock(bufHdr);
|
Page localpage = (char *)LocalBufHdrGetBlock(bufHdr);
|
||||||
char *bufToWrite = NULL;
|
char *bufToWrite = NULL;
|
||||||
|
|
||||||
/* Find smgr relation for buffer */
|
/* 查找缓冲区对应的SMgrRelation */
|
||||||
oreln = smgropen(bufHdr->tag.rnode, BackendIdForTempRelations);
|
oreln = smgropen(bufHdr->tag.rnode, BackendIdForTempRelations);
|
||||||
/* data encrypt */
|
|
||||||
|
/* 对缓冲区中的数据进行加密(data encrypt) */
|
||||||
bufToWrite = PageDataEncryptForBuffer(localpage, bufHdr);
|
bufToWrite = PageDataEncryptForBuffer(localpage, bufHdr);
|
||||||
|
|
||||||
|
/* 计算并设置数据页的校验和 */
|
||||||
PageSetChecksumInplace((Page)bufToWrite, bufHdr->tag.blockNum);
|
PageSetChecksumInplace((Page)bufToWrite, bufHdr->tag.blockNum);
|
||||||
|
|
||||||
/* And write... */
|
/* 将数据写入磁盘 */
|
||||||
smgrwrite(oreln, bufHdr->tag.forkNum, bufHdr->tag.blockNum, bufToWrite, false);
|
smgrwrite(oreln, bufHdr->tag.forkNum, bufHdr->tag.blockNum, bufToWrite, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LocalBufferFlushForExtremRTO(BufferDesc *bufHdr)
|
void LocalBufferFlushForExtremRTO(BufferDesc *bufHdr)
|
||||||
{
|
{
|
||||||
if (dw_enabled()) {
|
if (dw_enabled()) {
|
||||||
/* double write */
|
/* 如果启用了双写(double write)机制,执行相应的操作 */
|
||||||
|
/* 双写是一种数据持久性保护机制,确保数据写入磁盘的安全性 */
|
||||||
|
/* 在此处可能包括双写操作的代码 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 调用 FlushBuffer 函数将本地缓冲区刷新到磁盘 */
|
||||||
|
/* WITH_LOCAL_CACHE 参数表示使用本地缓存 */
|
||||||
FlushBuffer(bufHdr, NULL, WITH_LOCAL_CACHE);
|
FlushBuffer(bufHdr, NULL, WITH_LOCAL_CACHE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
这个函数的主要功能是遍历所有本地缓冲区,检查每个缓冲区的状态。
|
||||||
|
如果发现某个缓冲区是有效的且脏的(即需要刷新到磁盘),
|
||||||
|
则调用 LocalBufferFlushForExtremRTO 函数将该缓冲区的数据刷新到磁盘,
|
||||||
|
然后清除缓冲区的脏标志。
|
||||||
|
最后,更新本地缓冲区写入计数。
|
||||||
|
这个函数用于确保本地缓冲区中的脏数据在需要时能够被及时刷新到磁盘,以保证数据的持久性。
|
||||||
|
*/
|
||||||
void LocalBufferFlushAllBuffer()
|
void LocalBufferFlushAllBuffer()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// 遍历所有本地缓冲区
|
||||||
for (i = 0; i < u_sess->storage_cxt.NLocBuffer; i++) {
|
for (i = 0; i < u_sess->storage_cxt.NLocBuffer; i++) {
|
||||||
BufferDesc *bufHdr = &u_sess->storage_cxt.LocalBufferDescriptors[i];
|
BufferDesc *bufHdr = &u_sess->storage_cxt.LocalBufferDescriptors[i];
|
||||||
uint32 buf_state;
|
uint32 buf_state;
|
||||||
|
|
||||||
|
// 读取缓冲区状态
|
||||||
buf_state = pg_atomic_read_u32(&bufHdr->state);
|
buf_state = pg_atomic_read_u32(&bufHdr->state);
|
||||||
|
|
||||||
|
// 确保本地引用计数为0,表示没有任何进程正在使用该缓冲区
|
||||||
Assert(u_sess->storage_cxt.LocalRefCount[i] == 0);
|
Assert(u_sess->storage_cxt.LocalRefCount[i] == 0);
|
||||||
|
|
||||||
|
// 如果缓冲区是有效的且脏的
|
||||||
if ((buf_state & BM_VALID) && (buf_state & BM_DIRTY)) {
|
if ((buf_state & BM_VALID) && (buf_state & BM_DIRTY)) {
|
||||||
|
// 调用 LocalBufferFlushForExtremRTO 函数刷新缓冲区到磁盘
|
||||||
LocalBufferFlushForExtremRTO(bufHdr);
|
LocalBufferFlushForExtremRTO(bufHdr);
|
||||||
|
|
||||||
|
// 清除缓冲区的脏标志
|
||||||
buf_state &= ~BM_DIRTY;
|
buf_state &= ~BM_DIRTY;
|
||||||
pg_atomic_write_u32(&bufHdr->state, buf_state);
|
pg_atomic_write_u32(&bufHdr->state, buf_state);
|
||||||
|
|
||||||
|
// 更新本地缓冲区写入计数
|
||||||
u_sess->instr_cxt.pg_buffer_usage->local_blks_written++;
|
u_sess->instr_cxt.pg_buffer_usage->local_blks_written++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LocalBufferSanityCheck(BufferTag tag1, BufferTag tag2)
|
static void LocalBufferSanityCheck(BufferTag tag1, BufferTag tag2)
|
||||||
{
|
{
|
||||||
if (!BUFFERTAGS_EQUAL(tag1, tag2)) {
|
if (!BUFFERTAGS_EQUAL(tag1, tag2)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue