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

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章