PostgreSQL中vacuum过程HeapTupleSatisfiesVacuum函数分析

分类:编程技术 时间:2024-02-20 15:53 浏览:0 评论:0
0
本文主要讲解《PostgreSQL中的vacuum过程HeapTupleSatisfiesVacuum函数分析》。有兴趣的朋友不妨看一下。文章介绍的方法简单、快捷、实用。让小编带你学习《PostgreSQL中vacuum过程HeapTupleSatisfiesVacuum函数分析》!

跨度>1。数据结构

宏定义
真空和分析命令选项

/* ---------- ---- -------- * Vacuum 和Analyze 语句 * Vacuum 和Analyze 命令选项 * * 尽管这些名义上是两个语句,但* 仅对这两个语句使用一种节点类型会很方便。请注意,选项中必须至少设置 VACOPT_VACUUM * 和 VACOPT_ANALYZE 之一。 * 这里虽然有两种不同的说法,但是只需要使用统一的Node类型即可。 * 注意,选项中至少必须设置VACOPT_VACUUM/VACOPT_ANALYZE。 * ----- ------------------ */输入ef enum VacuumOption{ VACOPT_VACUUM = 1 << 0, /* 进行 VACUUM */ VACOPT_ANALYZE = 1 << 1, /* 进行分析 */ VACOPT_VERBOSE = 1 << 2, /* 打印进度信息 * / VACOPT_FREEZE = 1 << 3 , /* FREEZE 选项 */ VACOPT_FULL = 1 << 4, /* FULL(非并发)真空 */ VACOPT_SKIP_LOCKED = 1 << 5, /* 如果无法获得锁定则跳过 */ VACOPT_SKIP TOAST = 1 << 6, / *不处理 TOAST 表(如果有)*/ VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* 不跳过任何页面 */} VacuumOption;

2.源代码解释

HeapTupleSatisfiesVacuum
HeapTupleSatisfiesVacuum 确定 VACUUM 操作的元组的状态。在这里,我们主要想要知道的是一个元组是否对所有正在运行的事务都可见。如果可见,则无法通过VACUUM删除该元组。

主要处理流程如下:
0.获取元组并合并执行相关验证
1.康迪蒂on:插入事务未提交
1.1条件:xmin无效,tuple已废弃,可以删除
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 是否为 before重新或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.默认元组已死亡

/* * HeapTupleSatisfiesVacuum * * 确定元组的状态以用于 VACUUM 目的。在这里,我们主要想知道的是一个元组是否对任何正在运行的事务可见。如果是这样,则 VACUUM 还无法将其删除。 * 确定 VACUUM 元组的状态。 * 这里,我们主要想知道的是一个tuple是否对所有正在运行的transa可见行动。 * 如果它是可见的,则该元组无法通过 VACUUM 删除。 * * OldestXmin 是截止 XID(从 GetOldestXmin() 获得)。由 XID >= OldestXmin 删除的元组 * 被视为“最近死亡”;它们可能 * 对于某些打开的事务仍然可见,因此我们无法删除它们, * 即使我们看到删除事务已提交。 * OldestXmin 是截止XID(通过GetOldestXmin 函数获得)。 * 通过 XIDs >= OldestXmin 删除的元组被认为是“最近死亡”的,并且它们可能仍然对某些正在进行的事务可见, * 因此即使删除事务已经提交,我们仍然无法清除它们。 */HTSV_ResultHeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin ,                  Buffer buffer){      // 获取元组                            HeapTupleHeader                                                                                                                                        .tableOid != InvalidOid ); /* * 已插入 t交易已完成? * * 如果插入事务中止,则该元组对任何其他事务都永远不可见,因此我们可以立即删除它。 * 如果insert事务已经回滚,该tuple对其他事务不可见,所以可以立即删除。 */ if (!HeapTupleHeaderXminCommited(tuple)) { //1.插入事务未提交 if (HeapTupleHeaderXminInvalid(tuple)) //1-1 .Invalid xmin,该元组已被放弃,可以删除   return HEAPTUPLE_DEAD; /* 9.0之前的二进制升级使用 */ //用于9.0版本之前的升级,HEAP_MOVED_OFF&HEAP_MOVED_IN不再使用 else if (tuple->t_infomask & HEAP_MOV ED_OFF) { TransactionId xvac = HeapTupleHeaderGetXvac(tuple); if (TransactionIdIsCurrentTransactionId(xvac)) 返回 HEAPTUPLE_DELETE_IN_PROGRESS; if (TransactionIdIsInProgress(xvac)) 返回 Heaptuple_delete_in_progress; if (transactioniddidCommit (XVAC)) {Sethintbits (Tuple, Buffer, Heap_xmin_inValid), 无效交易idid ); return headuple_dead;}​​ Sethintbits(Tuple, Buffer, Heap_xmin_Comfilled,InvalidTransactionId); / TransactionId xvac = HeapTupleHeaderGetXvac(tuple); if (TransactionIdIsCurrentTransactionId(xvac)) 返回 HEAPTUPLE_INSERT_IN_PROGRESS; if (TransactionIdIsInProgress(xvac)) 返回 HEAPTUPLE_INSERT_IN_PROGRESS; if (TransactionIdDidCommit(xvac)) SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, InvalidTransactionId); else { SetHintBits(tuple, buffer, HEAP_XMIN_INVALID, InvalidTransactionId);返回HEAPTUPLE_DEAD; else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))                                                                                                                                                                                                 1-3-1.xmax 为无效,表明插入事务正在进行中 return HEAPTUPLE_INSERT_IN_PROGRESS; /* 只锁定?首先运行 infomask-only 检查,以提高性能 */ >t_infomask) || HeapTupleHeaderIsOnlyLocked(tuple) ) // 1-3-2.锁定状态(如更新),事务正在进行中。y 相同 xact */                 //插入,然后删除                                                                                                                                                                               HEAPTULE_DELETE_IN_PROGRESS; /* 删除子事务必须已中止 */ //默认:插入事务正在进行中 return HEAPTUPLE_INSERT_IN_PROGRESS; } else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple))) { //1-4.插入事务不是当前事务并且正在进行中 /* * 可以通过查看 xmax 来辨别正在进行中的 INSERT/DELETE - 但这对于大多数调用者来说似乎并没有什么好处电动车对某些人不利。我们*宁愿让调用者查看/等待 xmin,而不是 xmax。返回 INSERT_IN_PROGRESS 总是正确的,因为从其他后端的角度来看,这就是正在发生的情况。没有任何好处甚至有害 * 我们宁愿让调用者查看/等待 xmin 而不是 xmax。顶部; } else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple))) //1-5.xmin事务确实已提交(通过clog判断) SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, HeapTupleHeaderGetRawXmin(tuple)); else {//1- 5. 其他情况 // 既没有进行中,也没有提交,要么滚动,要么折叠/**没有进行中,没有提交,所以要么中止,要么崩溃 */                                                                                                                             SetHintBitsHEAP_XMIN_INVALID,                                  id);我们可能还没有*能够设置提示位;所以我们不能再断言 * 它已设置。 */ } /* * 好的,插入已提交,所以在某些时候效果很好。现在*关于删除交易怎么办? * 插入数据的事务已经提交,现在可以看到删除事务的状态。 */ if ( tuple->t_infomask & HEAP_XMAX_INVALID) //-------- 2.xmax为无效事务ID,直接返回LIVE return HEAPTUPLE_LIVE; if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) { //-------- 3. 锁定 * * “删除”xact 实际上只是锁定了它,因此元组在任何情况下都是活动的。但是,我们应该确保一旦 xact 消失,就会设置 XMAX_COMMITTED 或 * * XMAX_INVALID,以减少检查元组以查找未来 xact 的成本。 * “删除”事务确实只锁定了元组,因此元组是活动的。 * 但是,我们应该确保是否是e XMAX_COMMITTED 或 XMAX_INVALID 标志,应在事务完成后立即设置, * 这可以减少检查事务的元组状态的成本。 MAX_IS_MULTI)                                                                  sp; //3.1.1 多事务/**如果它是 pre-pg_upgrade 元组,则 Multixact 可以*可能运行;否则必须检查。* 是不可能运行的,否则,只能执行checksp; MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), //其他情况根据堵塞重置事务状态标志位 SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); }                                  nbsp; {//3.1.2 Non-multi -transactions if (transactionidisinprogress(Heaptupleheadergetrawxmax(Tuple))) // xmax 事务当前正在进行,返回 live Return headuple_live; CLOG重新设计了事务状态标记位置Sethintbits(Tuple, Buffer , HEAP_XMAX_INVALID,                                  ;InvalidTransactionId);没有也永远不会真正更新它。需要真正关心 xmax 是否提交/回滚/崩溃。 * 我们知道thenbsp;返回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)); /* 不是LOCKED_ONLY,所以必须有一个xmax */ //根据上面对xmax的判断,我们可以确定xmax在这里有效 Assert(TransactionIdIsValid(xmax)); if (TransactionIdIsInProgress(xmax)) //4.1 xmax正在进行中,返回正在进行中 return HEAPTUPLE_DELETE_IN_PROGRESS; else if (TransactionIdDidCommit(xmax)) { 2 xmax 已提交 /* * 由于储物柜,multixact 可能仍在运行。如果 * 更新器低于 xid 地平线,则无论如何我们都必须返回 DEAD * * ,否则我们最终可能会得到一个元组,其中 * 更新器由于地平线而必须被删除,但不会被修剪掉。修剪该元组不是问题,因为任何剩余的储物柜也将出现在较新的元组版本中。 P; //4.2.1 XMAX After Oldestxmin, // 表示Oldestxmin之后不删除,返回Heaptuple_recently_Dead RetUrn Heaptuple_recently_Dead; Ead Return Heaptuple_dead;}​​ ​​Else if(!Multixactidisrunning(Heaptupleheadergetrawxmax(tuple), false)) {                                                                                       itted,所以要么中止或崩溃。 * 标记 ple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId ;nsactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple))) //5.1 删除过程中 return HEAPTUPLE_DELETE_IN_PROGRESS; else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))                     //5.2 从堵塞情况来看,事务已经提交,设置事务标记位              SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,                                                                                                                              * 未进行中,未提交,因此要么已中止,要么crashed */ //5.3 在其他情况下,设置为无效事务 ID SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); //返回 LIVE 点 xmax 已知已提交,但我们可能无法设置提示位还;所以我们不能再断言 * 它已设置。 /* * 删除者已提交,但也许是最近一些开放 * 交易ns 仍然可以看到该元组。 */ if (!TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin)) //6.元组xmax≥OldestXmin,最近删除返回HEAPTUPLE_RECENTLY_DEAD; /* 否则,它是死的并且可移动的 */ //7.默认tuple已经DEAD return HEAPTUPLE_DEAD;}

至此,相信大家都熟悉《PostgreSQL》了,如果对《HeapTupleSatisfiesVacuum函数分析在Vacuum过程中》有更深入的了解的话不妨来实践一下!这里是网站,更多相关内容,您可以进入相关渠道查询,关注我们,继续学习!

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > PostgreSQL中vacuum过程HeapTupleSatisfiesVacuum函数分析

用户评论