本篇内容主要讲解“postgresql中vacuum过程HeapTupleSatisfiesVacuum函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“P
本篇内容主要讲解“postgresql中vacuum过程HeapTupleSatisfiesVacuum函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Postgresql中vacuum过程HeapTupleSatisfiesVacuum函数分析”吧!
宏定义
Vacuum和Analyze命令选项
typedef enum VacuumOption
{
VACOPT_VACUUM = 1 << 0,
VACOPT_ANALYZE = 1 << 1,
VACOPT_VERBOSE = 1 << 2,
VACOPT_FREEZE = 1 << 3,
VACOPT_FULL = 1 << 4,
VACOPT_SKIP_LOCKED = 1 << 5,
VACOPT_SKIPTOAST = 1 << 6,
VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7
} VacuumOption;
HeapTupleSatisfiesVacuum
HeapTupleSatisfiesVacuum为VACUUM操作确定元组的状态.在这里,我们主要想知道的是一个元组是否可对所有正在运行中的事务可见.如可见,则不能通过VACUUM删除该元组.
主要处理流程如下:
0.获取tuple并执行相关校验
1.条件:插入事务未提交
1.1条件:无效的xmin,该元组已废弃可删除
1.2条件:旧版本(9.0-)的判断
1.3条件:xmin为当前事务ID
1.4条件:插入事务非当前事务,正在进行中
1.5条件:xmin事务确实已提交(通过clog判断)
1.6条件:其他情况
— 至此,可以确定xmin已提交
2.条件:xmax是无效的事务ID,直接返回LIVE
3.条件:xmax只是锁定
3.1条件:xmax事务未提交,分多事务&非多事务进行判断
3.2条件:只是锁定,返回LIVE
4.条件:存在子事务
4.1条件:xmax正在进行,返回事务进行中
4.2条件:xmax已提交,区分xmax在OldestXmin之前还是之后
4.3条件:xmax不在运行中/没有提交/没有回滚或崩溃,则设置xmax为无效事务ID
4.4默认返回LIVE
5.条件:xmax没有提交
5.1条件:删除过程中
5.2条件:通过clog判断,该事务已提交,设置事务标记位
5.3条件:其他情况,设置为无效事务ID
5.4默认返回LIVE
— 至此,可以确定xmax已提交
6.元组xmax≥OldestXmin,最近删除
7.默认元组已DEAD
HTSV_Result
HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
Buffer buffer)
{
//获取tuple
HeapTupleHeader tuple = htup->t_data;
//校验
Assert(ItemPointerIsValid(&htup->t_self));
Assert(htup->t_tableOid != InvalidOid);
if (!HeapTupleHeaderXminCommitted(tuple))
{
//1.插入事务未提交
if (HeapTupleHeaderXminInvalid(tuple))
//1-1.无效的xmin,该元组已废弃可删除
return HEAPTUPLE_DEAD;
//用于9.0以前版本的升级,HEAP_MOVED_OFF&HEAP_MOVED_IN已不再使用
else if (tuple->t_infomask & HEAP_MOVED_OFF)
{
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
if (TransactionIdIsCurrentTransactionId(xvac))
return HEAPTUPLE_DELETE_IN_PROGRESS;
if (TransactionIdIsInProgress(xvac))
return HEAPTUPLE_DELETE_IN_PROGRESS;
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId);
return HEAPTUPLE_DEAD;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId);
}
//用于9.0以前版本的升级
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
if (TransactionIdIsCurrentTransactionId(xvac))
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdIsInProgress(xvac))
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId);
return HEAPTUPLE_DEAD;
}
}
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
{
//1-3.xmin为当前事务ID
if (tuple->t_infomask & HEAP_XMAX_INVALID)
//1-3-1.xmax无效,说明插入事务正在进行中
return HEAPTUPLE_INSERT_IN_PROGRESS;
//只是锁定?性能考虑,首先执行infomask-only检查
if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) ||
HeapTupleHeaderIsOnlyLocked(tuple))
//1-3-2.锁定状态(如for update之类),事务正在进行中
return HEAPTUPLE_INSERT_IN_PROGRESS;
//插入,然后删除
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
//1-3-3.插入,然后删除
return HEAPTUPLE_DELETE_IN_PROGRESS;
//默认:插入事务正在进行中
return HEAPTUPLE_INSERT_IN_PROGRESS;
}
else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
{
//1-4.插入事务非当前事务,正在进行中
return HEAPTUPLE_INSERT_IN_PROGRESS;
}
else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
//1-5.xmin事务确实已提交(通过clog判断)
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetRawXmin(tuple));
else
{
//1-5.其他情况
//既不在进行中,也没有提交,要么是回滚,要么是崩溃了
//设置标记位
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId);
//返回废弃标记
return HEAPTUPLE_DEAD;
}
}
if (tuple->t_infomask & HEAP_XMAX_INVALID)
//------- 2.xmax是无效的事务ID,直接返回LIVE
return HEAPTUPLE_LIVE;
if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
{
//------- 3.锁定
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
{
//3.1 xmax事务未提交
if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
{
//3.1.1 多事务
if (!HEAP_LOCKED_UPGRADED(tuple->t_infomask) &&
MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple),
true))
return HEAPTUPLE_LIVE;
//其他情况,根据clog重新设置事务状态标记位
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
}
else
{
//3.1.2 非多事务
if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
//xmax事务正在进行,返回LIVE
return HEAPTUPLE_LIVE;
//否则,根据clog重新设置事务状态标记位
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId);
}
}
//3.2 只是锁定,返回LIVE
return HEAPTUPLE_LIVE;
}
if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
{
//4.存在子事务
//获取删除事务号xmax
TransactionId xmax = HeapTupleGetUpdateXid(tuple);
Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
//根据上述xmax的判断,到这里可以肯定xmax是有效的
Assert(TransactionIdIsValid(xmax));
if (TransactionIdIsInProgress(xmax))
//4.1 xmax正在进行,返回进行中
return HEAPTUPLE_DELETE_IN_PROGRESS;
else if (TransactionIdDidCommit(xmax))
{
//4.2 xmax已提交
if (!TransactionIdPrecedes(xmax, OldestXmin))
//4.2.1 xmax在OldestXmin之后,
//表示在OldestXmin之后才删除,返回HEAPTUPLE_RECENTLY_DEAD
return HEAPTUPLE_RECENTLY_DEAD;
//4.2.2 xmax在OldestXmin之前,返回DEAD
return HEAPTUPLE_DEAD;
}
else if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false))
{
//4.3 xmax不在运行中/没有提交/没有回滚或崩溃,则设置xmax为无效事务ID
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
}
//4.4 默认返回LIVE
return HEAPTUPLE_LIVE;
}
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
{
//5.xmax没有提交
if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple)))
//5.1 删除过程中
return HEAPTUPLE_DELETE_IN_PROGRESS;
else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
//5.2 通过clog判断,该事务已提交,设置事务标记位
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetRawXmax(tuple));
else
{
//5.3 其他情况,设置为无效事务ID
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId);
//返回LIVE
return HEAPTUPLE_LIVE;
}
//至此,xmax可以确认已提交
}
if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin))
//6.元组xmax≥OldestXmin,最近删除
return HEAPTUPLE_RECENTLY_DEAD;
//7. 默认元组已DEAD
return HEAPTUPLE_DEAD;
}
到此,相信大家对“PostgreSQL中vacuum过程HeapTupleSatisfiesVacuum函数分析”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
--结束END--
本文标题: PostgreSQL中vacuum过程HeapTupleSatisfiesVacuum函数分析
本文链接: https://lsjlt.com/news/64244.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0