前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PostgreSQL vacuum可见性

PostgreSQL vacuum可见性

原创
作者头像
yzsDBA
修改2020-03-30 10:33:51
5920
修改2020-03-30 10:33:51
举报
文章被收录于专栏:PostgreSQL研究与原理解析

本文介绍vacuum可见性判断。分两种情况,一是XMIN事务未提交,一个是xmin事务已提交。

针对xmin未提交的事务,即当前的tuple刚insert还未提交:

1)元组不合法,即坏元组时,返回HEAPTUPLE_DEAD

2)该tuple是当前事务产生的:此时这个记录在这个事务未删除或只是被锁住或进行了delete但是delete abort了,那返回HAPTUPLE_INSERT_IN_PROGRESS;若则记录又被删除了,那返回HEAPTUPLE_DELETE_IN_PROGRESS

3)该tuple是其他事务产生的,tuple头中标记未提交:HEAP_INSERT_IN_POGRESS

4)该tuple是其他事务产生,clog中显示xmin已提交:则标记tuple头为HEAP_XMIN_COMMITTED。

5)其他情况下,这个xmin事务确实未提交,abort或损坏了:返回HEAPTUPLE_DEAD

针对xmin已提交的事务,即当前的tuple insert已提交了:

1)xmax未提交,返回HEAPTUPLE_LIVE

2)tuple只是被锁着:xmax未提交:返回HEAPTUPLE_LIVE

3)tuple正在delete:返回HEAPTUPLE_DELETE_IN_PROGRESS

4)clog中查到xmax已提交:标记tuple头HEAP_XMAX_COMMITTED

5)其他情况delete确实未提交:HEAPTUPLE_LIVE

6)剩下的情况,tuple.t_xmax >= OldestXmin表示有事务还能看到insert的值:HEAPTUPLE_RECENTLY_DEAD

7)其他情况XMAX已提交了:返回HEAPTUPLE_DEAD

函数

代码语言:c
复制
HeapTupleSatisfiesVacuum
{
	HeapTupleHeader tuple = htup->t_data;

	if (!HeapTupleHeaderXminCommitted(tuple))//未提交
	{
		if (HeapTupleHeaderXminInvalid(tuple))//元组不合法,坏的元组
			return HEAPTUPLE_DEAD;
		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
		{//当前事务产生的元组
			if (tuple->t_infomask & HEAP_XMAX_INVALID)//未被删除,当前事务正在insert
				return HEAPTUPLE_INSERT_IN_PROGRESS;
			//元组被锁住,未被删除 或者 
			if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) || HeapTupleHeaderIsOnlyLocked(tuple))
				return HEAPTUPLE_INSERT_IN_PROGRESS;
			//insert后当前事务又删除
			if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
				return HEAPTUPLE_DELETE_IN_PROGRESS;
			//delete的子事务被abort,即insert正在进行
			return HEAPTUPLE_INSERT_IN_PROGRESS;
		}
		else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
		{//其他事务正在insert
			return HEAPTUPLE_INSERT_IN_PROGRESS;
		}//从clog中读取tuple的事务状态,为提交则标记提交
		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,HeapTupleHeaderGetRawXmin(tuple));
		else
		{
			//真的tuple未提交、abort或者损坏
			SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,InvalidTransactionId);
			return HEAPTUPLE_DEAD;
		}
		//此时,xmin已提交了。
	}

	/*
	 * Okay, the inserter committed, so it was good at some point.  Now what
	 * about the deleting transaction?
	 */
	if (tuple->t_infomask & HEAP_XMAX_INVALID)
		return HEAPTUPLE_LIVE;//未被删除则该记录是活的

	if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
	{//只是锁住,未进行delete
		if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
		{//delete事务未提交
			if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
				return HEAPTUPLE_LIVE;
			SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,InvalidTransactionId);
			
		}
		return HEAPTUPLE_LIVE;
	}
	//delete未提交
	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
	{
		if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
			return HEAPTUPLE_DELETE_IN_PROGRESS;//delete正在进行
		else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))//从clog中检查delete提交了
			SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,HeapTupleHeaderGetRawXmax(tuple));
		else
		{
			//真的未提交、abort或者损坏
			SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,InvalidTransactionId);
			return HEAPTUPLE_LIVE;
		}
		//此时delete已提交
	}
	//有事务还可能看到他
	//tuple->t_choice.t_heap.t_xmax >= OldestXmin
	if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin))
		return HEAPTUPLE_RECENTLY_DEAD;
	/* Otherwise, it's dead and removable */
	return HEAPTUPLE_DEAD;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档