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
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;
}
- BZOJ1269: [AHOI2006]文本编辑器editor
- 开发人员为何需要企业服务总线?
- 搭建Visual Studio Code+Python开发环境1.对象简介2. 搭建步骤3.小结
- 洛谷P3835 【模板】可持久化平衡树
- 17.HTML
- 洛谷P2925 [USACO08DEC]干草出售Hay For Sale
- Numpy 修炼之道 (13)—— 将python函数向量化
- 洛谷P1887 乘积最大3
- 18.CSS
- R语言可视化——ggplot图表系统中的形状
- [机器学习Lesson 1 Introduction] 机器学习的动机与应用
- 洛谷P3377 【模板】左偏树(可并堆)
- Numpy 修炼之道 (12)—— genfromtxt函数
- 19.JavaScript
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 015.Nginx重定向
- 明了 | MongoDB 外键的基本使用
- 优雅 | koa处理异常
- iOS开发之Context Menus
- 快速解释如何使用pandas的inplace参数
- bam格式转bigWig
- 46. Vue路由传参的基本使用
- H3C在端口同时配置MAC地址认证和802.1x
- proxmox notes
- Unix每分钟监控进程的状态
- webpack实战——资源输入与输出
- R语言读取 xlsx 和xls 文件
- pytest文档42-fixture参数化params
- 搭建node服务(三):使用TypeScript
- Antd for Vue使用Form组件报错You cannot set a form field before rendering