Update mmap_shared.cpp
This commit is contained in:
parent
a4317b822b
commit
fc4b67f9ea
|
|
@ -54,96 +54,148 @@ static inline pthread_mutex_t *MmapPartitionLock(size_t hashCode)
|
|||
{
|
||||
return &mmapLockArray[hashCode % LOCK_ARRAY_SIZE];
|
||||
}
|
||||
|
||||
/*
|
||||
* 功能:同步页压缩内存映射的数据到磁盘
|
||||
*
|
||||
* 参数列表:
|
||||
* pcMap:PageCompressHeader 结构的指针,表示页压缩内存映射的头部信息
|
||||
* 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:指向文件描述符信息的指针
|
||||
* chunkSize:uint16 类型,表示页面压缩的块大小
|
||||
* relFileNodeForkNum:RelFileNodeForkNum 结构,表示文件的标识信息
|
||||
*/
|
||||
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(); // 解锁
|
||||
}
|
||||
Loading…
Reference in New Issue