Update mmap_shared.cpp

This commit is contained in:
nuoya 2023-09-25 15:31:23 +08:00
parent a4317b822b
commit fc4b67f9ea
1 changed files with 61 additions and 9 deletions

View File

@ -54,96 +54,148 @@ static inline pthread_mutex_t *MmapPartitionLock(size_t hashCode)
{
return &mmapLockArray[hashCode % LOCK_ARRAY_SIZE];
}
/*
*
*
*
* pcMapPageCompressHeader
* wait_event_info
*/
static inline PageCompressHeader *MmapSharedMapFile(Vfd *vfdP, uint16 chunkSize, uint2 opt, bool readonly)
{
// 调用 pc_mmap_real_size 函数映射共享内存文件,返回一个指向 PageCompressHeader 结构体的指针 map。
auto map = pc_mmap_real_size(vfdP->fd, SIZE_OF_PAGE_COMPRESS_ADDR_FILE(chunkSize), false);
// 检查映射的文件区域是否有效,若无效则进行初始化设置。
if (map->chunk_size == 0 || map->algorithm == 0) {
// 检查映射的文件区域是否有效,若无效则进行初始化设置。
map->chunk_size = chunkSize;
map->algorithm = GET_COMPRESS_ALGORITHM(opt);
// 使用 pc_msync 函数将映射区域的数据同步到文件中。
if (pc_msync(map) != 0) {
// 如果同步失败,则生成错误报告。
ereport(data_sync_elevel(ERROR),
(errcode_for_file_access(), errmsg("could not msync file \"%s\": %m", vfdP->fileName)));
}
}
// 如果正在进行恢复操作且映射区域未同步,则调用 CheckAndRepairCompressAddress 函数进行检查和修复。
if (RecoveryInProgress() && !map->sync) {
CheckAndRepairCompressAddress(map, chunkSize, map->algorithm, vfdP->fileName);
}
// 返回映射区域的指针 map。
return map;
}
/*
*
*/
void RealInitialMMapLockArray()
{
// 遍历锁数组,为每个元素初始化一个互斥锁
for (size_t i = 0; i < LOCK_ARRAY_SIZE; ++i) {
pthread_mutex_init(&mmapLockArray[i], NULL);
}
// 初始化哈希表控制结构体
HASHCTL ctl;
/* hash accessed by database file id */
// 使用 memset_s 函数将 ctl 结构体清零
errno_t rc = memset_s(&ctl, sizeof(ctl), 0, sizeof(ctl));
securec_check(rc, "", "");
// 设置哈希键的大小和每个条目的大小
ctl.keysize = sizeof(RelFileNodeForkNum);
ctl.entrysize = sizeof(MmapEntry);
ctl.hash = tag_hash;
ctl.num_partitions = LOCK_ARRAY_SIZE;
const size_t initLen = 256;
// 初始化内存哈希表,用于页压缩内存映射的缓存
g_instance.mmapCache = HeapMemInitHash(
"mmap hash", initLen,
(Max(g_instance.attr.attr_common.max_files_per_process, t_thrd.storage_cxt.max_userdatafiles)) / 2, &ctl,
HASH_ELEM | HASH_FUNCTION | HASH_PARTITION);
}
/*
*
*
*
* vfd
* chunkSizeuint16
* relFileNodeForkNumRelFileNodeForkNum
*/
PageCompressHeader *GetPageCompressHeader(void *vfd, uint16 chunkSize, const RelFileNodeForkNum &relFileNodeForkNum)
{
// 将传入的 vfd 转换为 Vfd 结构体指针
Vfd *currentVfd = (Vfd *)vfd;
// 计算哈希码以用于锁分区
uint32 hashCode = MmapTableHashCode(relFileNodeForkNum);
// 使用 AutoMutexLock 自动加锁,锁定相应的分区
AutoMutexLock mmapLock(MmapPartitionLock(hashCode));
// 加锁
mmapLock.lock();
// 初始化查找结果标志
bool find = false;
// 在内存哈希表中搜索文件标识,并返回相应的 MmapEntry 结构指针
MmapEntry *mmapEntry = (MmapEntry *)hash_search_with_hash_value(g_instance.mmapCache, (void *)&relFileNodeForkNum,
hashCode, HASH_ENTER, &find);
// 如果未找到对应条目,则进行初始化设置
if (!find) {
mmapEntry->pcmap = NULL;
mmapEntry->reference = 0;
}
// 如果 pcmap 为空,则调用 MmapSharedMapFile 函数映射文件
if (mmapEntry->pcmap == NULL) {
mmapEntry->pcmap = MmapSharedMapFile(currentVfd, chunkSize, relFileNodeForkNum.rnode.node.opt, false);
}
// 增加对映射区域的引用计数
++mmapEntry->reference;
// 增加对映射区域的引用计数
mmapLock.unLock();
// 返回映射区域的指针
return mmapEntry->pcmap;
}
/*
* 使
*
*
* vfd
*/
void UnReferenceAddrFile(void *vfd)
{
// 将传入的 vfd 转换为 Vfd 结构体指针
Vfd *currentVfd = (Vfd *)vfd;
// 获取文件标识信息
RelFileNodeForkNum relFileNodeForkNum = currentVfd->fileNode;
// 计算哈希码以用于锁分区
uint32 hashCode = MmapTableHashCode(relFileNodeForkNum);
// 使用 AutoMutexLock 自动加锁,锁定相应的分区
AutoMutexLock mmapLock(MmapPartitionLock(hashCode));
mmapLock.lock();
// 在内存哈希表中搜索文件标识,并返回相应的 MmapEntry 结构指针HASH_FIND 模式)
MmapEntry *mmapEntry = (MmapEntry *)hash_search_with_hash_value(g_instance.mmapCache, (void *)&relFileNodeForkNum,
hashCode, HASH_FIND, NULL);
// 如果没有找到对应的条目,则生成错误报告
if (mmapEntry == NULL) {
ereport(ERROR, (errcode_for_file_access(),
errmsg("UnReferenceAddrFile failed! mmap not found, filePath: %s", currentVfd->fileName)));
}
// 减少对映射区域的引用计数
--mmapEntry->reference;
// 如果引用计数降为零,释放资源
if (mmapEntry->reference == 0) {
// 调用 pc_munmap 函数释放映射区域的资源
if (pc_munmap(mmapEntry->pcmap) != 0) {
ereport(ERROR,
(errcode_for_file_access(), errmsg("could not munmap file \"%s\": %m", currentVfd->fileName)));
}
// 从内存哈希表中移除对应的哈希键
if (hash_search_with_hash_value(g_instance.mmapCache, (void *)&relFileNodeForkNum, hashCode, HASH_REMOVE,
NULL) == NULL) {
ereport(ERROR,
(errcode_for_file_access(),
errmsg("UnReferenceAddrFile failed! remove hash key failed, filePath: %s", currentVfd->fileName)));
}
} else if (mmapEntry->reference < 0) {
}
// 如果引用计数小于零,生成致命错误报告
else if (mmapEntry->reference < 0) {
ereport(FATAL, (errcode_for_file_access(), errmsg("could not munmap file \"%s\": %m", currentVfd->fileName)));
}
mmapLock.unLock();
mmapLock.unLock(); // 解锁
}