海山数据库(He3DB)源码详解:海山PG 可见性映射表VM

一、VM概述

He3DB for PG中为了实现多版本并发控制,当事务删除或更新元组时,并非从物理上删除,而是将其标记为无效的方式进行标记删除,最终对这些无效元组的清理操作需要调用VACUUM完成。

为了能够加快VACUUM查找包含无效元组的文件块的过程,在PostgreSQL8.4.1中为每个表文件定义了一个新的附属文件–可见性映射表(VM)。VM中为表的每个文件块设置了一位,用来标记该文件块是否存在无效元组。对包含无效元组的文件块,VACUUM有两种方式处理,即快速清理(Lazy VACUUM)和完全清理(Full VACUUM)。VM文件仅在Lazy VACUUM操作中被使用到,而Full VACUUM操作由于要执行跨块清理等复杂操作,需要对整个表文件进行扫描,这时候VM文件的作用并不大。当前,VM文件仅仅是作为一个提示(hint)来加快VACUUM的速度,所以即使VM文件损坏也仅仅会导致VACUUM忽略那些需要清理的页面,而不会对数据产生任何负面影响。

与其他文件一样,VM文件也被划分为若干个文件块(简称VM块)。VM块中除了必要的标记信息外,其他的每一位都对应一个表块,当表块中所有的元组对当前的事务都是可见的时候,表块对应的位才设置为1。其文件块结构如下图所示。

PageHeaderData bit bit bit bit …

每个VM文件块中能够记录size = (blcksz - SizeOfPageHeaderData) * 8个表块的信息,第一个VM块记录第1至size号表块的信息,第二个VM块记录第size + 1至2 * size + 1号表块的信息,依此类推。

当对某个表块中的元组进行更新或者删除后,那么该表块在VM文件中对应位置的标志位将被置0,表示有无效元组。在设置标志位的时候,需要对其对应的VM页面加锁。这是为了避免在VACUUM判断该页面是否对所有事务可见的同时,其他进程修改该页面,从而导致VACUUM清理过程中忽略了此页面。

当标志位为1时,表示没有无效元组,VACUUM操作会忽略扫描对应的表块,所以能大大提高VACUUM的效率。由于VM文件不跟踪索引,所以对索引的清理操作还是需要进行完全扫描。

二、VM源码解析

1、visibilitymap_set

功能:

  • 设置可见性标志位
void
visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
				  XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid,
				  uint8 flags)
{
   
	#ifdef HEAP_DEBUG1
	elog(DEBUG1,"visibilitymap_set heapBlk=%u,heapBuf=%d,recptr=%X/%X,vmBuf=%d,cutoff_xid=%u,flags=%u",heapBlk,heapBuf,(uint32) ((recptr) >> 32), ((uint32) (recptr)),vmBuf,cutoff_xid,flags);
	#endif
	/* 根据堆块号,计算对应的可见性映射块号、字节偏移和位偏移 */
	BlockNumber mapBlock = HEAPBLK_TO_MAPBLOCK(heapBlk);
	uint32		mapByte = HEAPBLK_TO_MAPBYTE(heapBlk);
	uint8		mapOffset = HEAPBLK_TO_OFFSET(heapBlk);
	Page		page;
	uint8	   *map;

#ifdef TRACE_VISIBILITYMAP
	elog(DEBUG1, "vm_set %s %d", RelationGetRelationName(rel), heapBlk);   // 输出调试信息,帮助开发者跟踪函数的执行
#endif

	Assert(InRecovery || XLogRecPtrIsInvalid(recptr));
	Assert(InRecovery || BufferIsValid(heapBuf));
	Assert(flags & VISIBILITYMAP_VALID_BITS);

	/* 确保传入的堆缓冲区和可见性映射缓冲区与预期的块号相匹配 */
	if (BufferIsValid(heapBuf) && BufferGetBlo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值