对pg_locks视图中的virtualxid和transactionid字段感到困惑,经查阅资料,特此在此整理一下学习内容:

pg_locks Columns

Name Type References Description
locktype text   Type of the lockable object: relationextendpagetupletransactionidvirtualxidobjectuserlock, or advisory
database oid pg_database.oid OID of the database in which the lock target exists, or zero if the target is a shared object, or null if the target is a transaction ID
relation oid pg_class.oid OID of the relation targeted by the lock, or null if the target is not a relation or part of a relation
page integer   Page number targeted by the lock within the relation, or null if the target is not a relation page or tuple
tuple smallint   Tuple number targeted by the lock within the page, or null if the target is not a tuple
virtualxid text   Virtual ID of the transaction targeted by the lock, or null if the target is not a virtual transaction ID
transactionid xid   ID of the transaction targeted by the lock, or null if the target is not a transaction ID
classid oid pg_class.oid OID of the system catalog containing the lock target, or null if the target is not a general database object
objid oid any OID column OID of the lock target within its system catalog, or null if the target is not a general database object
objsubid smallint   Column number targeted by the lock (the classid and objid refer to the table itself), or zero if the target is some other general database object, or null if the target is not a general database object
virtualtransaction text   Virtual ID of the transaction that is holding or awaiting this lock
pid integer   Process ID of the server process holding or awaiting this lock, or null if the lock is held by a prepared transaction
mode text   Name of the lock mode held or desired by this process (see Section 13.3.1 and Section 13.2.3)
granted boolean   True if lock is held, false if lock is awaited
fastpath boolean   True if lock was taken via fast path, false if taken via main lock table
 
从字义上来看,一个是虚拟事务号,一个是事务号。
实际上他们表达的意思也是不一样的,虚拟事务号由两个部分组成,分别是backendid和local transaction id。

查看src/include/storage/lock.h,可以看到对virtualxid结构的定义:

virtualxid不是针对pg实例整体来将的。

/*
* Top-level transactions are identified by VirtualTransactionIDs comprising
* the BackendId of the backend running the xact, plus a locally-assigned
* LocalTransactionId. These are guaranteed unique over the short term,
* but will be reused after a database restart; hence they should never
* be stored on disk.
*
* Note that struct VirtualTransactionId can not be assumed to be atomically
* assignable as a whole. However, type LocalTransactionId is assumed to
* be atomically assignable, and the backend ID doesn't change often enough
* to be a problem, so we can fetch or assign the two fields separately.
* We deliberately refrain from using the struct within PGPROC, to prevent
* coding errors from trying to use struct assignment with it; instead use
* GET_VXID_FROM_PGPROC().
*/
typedef struct
{
BackendId backendId; /* determined at backend startup */
LocalTransactionId localTransactionId; /* backend-local transaction
* id */
} VirtualTransactionId;

本地事务号和事务号又有什么分别呢?实际上一个是用来表示本地事务的,并且本地事务号不会存储在磁盘中,只存在于内存中。而事务号则是存储在磁盘中的,属于持久化的值。

获得本地事务号的函数如下,不需要vacuum,因为不会持久化到磁盘,也不用于MVCC,所以直接轮询使用是没问题的,见如下函数:
src/backend/storage/ipc/sinvaladt.c
/*
* GetNextLocalTransactionId --- allocate a new LocalTransactionId
*
* We split VirtualTransactionIds into two parts so that it is possible
* to allocate a new one without any contention for shared memory, except
* for a bit of additional overhead during backend startup/shutdown.
* The high-order part of a VirtualTransactionId is a BackendId, and the
* low-order part is a LocalTransactionId, which we assign from a local
* counter. To avoid the risk of a VirtualTransactionId being reused
* within a short interval, successive procs occupying the same backend ID
* slot should use a consecutive sequence of local IDs, which is implemented
* by copying nextLocalTransactionId as seen above.
*/
LocalTransactionId
GetNextLocalTransactionId(void)
{
LocalTransactionId result; /* loop to avoid returning InvalidLocalTransactionId at wraparound */
do
{
result = nextLocalTransactionId++;
} while (!LocalTransactionIdIsValid(result)); return result;
}
那么虚拟事务号到底有什么用呢?
举一些例子,
1. 因为虚拟事务号是在内存中管理的,所以在处理锁冲突时效率更高,可以用于唯一标示发生锁冲突的事务对象。
src/backend/storage/lmgr/lock.c
VirtualTransactionId *
GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
{
。。。。。。
2. 同时应用于standby的查询和恢复的锁冲突标示。
3. 还可以用于标示检查点和用户执行的查询之间的锁冲突。
总的来说,虚拟事务号就是用来标示锁冲突的对象的。
 
对视图pg_locks查看,就会产生virtualxid
swrd=# select * from pg_locks where locktype = 'virtualxid';
-[ RECORD 1 ]------+--------------
locktype | virtualxid
database |
relation |
page |
tuple |
virtualxid | 3/6510
transactionid |
classid |
objid |
objsubid |
virtualtransaction | 3/6510
pid | 20682
mode | ExclusiveLock
granted | t
fastpath | t swrd=#

As long as you query pg_locks, you in fact run a query and hence start a transaction. It needs to acquire AccessShareLock on pg_locks, for instance. That's why virtualxid is allocated.

参考:

http://blog.163.com/digoal@126/blog/static/16387704020156136857214

http://stackoverflow.com/questions/32996020/understanding-the-virtualxid-transaction-type-in-postgres

Understanding virtualxid && transactionid的更多相关文章

  1. Freezing Your Tuples Off 之 vacuum_freeze_min_age

    The vacuum_freeze_min_age setting determines the youngest XID which will be changed to FrozenXID on ...

  2. PostgreSQL 监控数据库活动

    监控数据库活动 1. 标准Unix 工具 [root@mysqlhq ~]# ps auxww | grep ^postgrespostgres 12106 0.0 0.0 340060 15064 ...

  3. PostgreSQL 锁机制浅析

    锁机制在 PostgreSQL 里非常重要 (对于其他现代的 RDBMS 也是如此).对于数据库应用程序开发者(特别是那些涉及到高并发代码的程序员),需要对锁非常熟悉.对于某些问题,锁需要被重点关注与 ...

  4. Postgresql Useful SQL/Commands

    Update records ' and a.subscriber_id=b.subscriber_id; Connections select count(*) from pg_stat_activ ...

  5. 仅4步,就可通过SQL进行分布式死锁的检测与消除

    摘要:本文主要介绍在 GaussDB(DWS) 中,如何通过 SQL 语句,对分布式死锁进行检测和恢复. 分布式数仓应用场景中,我们经常遇到数据库系统 hang 住的问题,所谓 hang 是指虽然数据 ...

  6. 游标长时间open导致表无法vacuum问题

    一.问题描述 用户在实际中可能会碰到类似以下 dead rows 无法 vacuum的问题,一个可能的原因是由于游标未结束的原因. test=# vacuum(verbose) t1; INFO: v ...

  7. KingbaseES V8R6 锁等待检测

    背景 对于多数数据库,dba技能之一就是查找锁.锁的存在有效合理的在多并发场景下保证业务有序进行.下面我们看一下KingbaseESV8R6中查找阻塞的方法. 1.找到"被阻塞者" ...

  8. KingabseES 锁机制

    KingabseES的锁机制 目录 KingabseES的锁机制 一.前言 二.锁机制 三.表级锁 ( Table-Level Locks ) 1.访问共享(ACCESS SHARE) 2.行共享(R ...

  9. GOOD MEETINGS CREATE SHARED UNDERSTANDING, NOT BRDS!

      Deliverables and artifacts were a focal point of BA work during the early part of my career. If I ...

随机推荐

  1. stm32 dac 配置过程

    DAC模块的通道1来输出模拟电压,其详细设置步骤如下: 1)开启PA口时钟,设置PA4为模拟输入. STM32F103ZET6的DAC通道1是接在PA4上的,所以,我们先要使能PORTA的时钟,然后设 ...

  2. c++高质量编程手册

    怡化主管强烈要求我读这本书.... 笔记尚未完成,持续更新呗.. 第1章 高质量软件开发之道 1.1 软件质量基本概念 1.1.1 如何理解软件的质量:功能性和非公能性 1.1.2 提高软件质量的基本 ...

  3. HDU 1695

    http://acm.hdu.edu.cn/showproblem.php?pid=1695 x是[1,b],y是[1,d],求GCD(x,y)=k的对数(x,y无序) 对x,y都除以k,则求GCD( ...

  4. [转]慎用slice

    在go中,slice是对固定长度数组的一段切片,其底层是用对数值空间的指针实现的. 在slice的赋值过程中,slice的容量会被初始化成“数组长度 - slice的起点位置”,举例说明: 假设有长度 ...

  5. 实现Magento多文件上传代码功能开发

    在Magento中上传单个文件很简单,可以直接在继承的Mage_Adminhtml_Block_Widget_Form类中直接添加如下组件Field:  对于图片:   $fieldset->a ...

  6. csdn第三名

    编号:1026时间:22016年7月18日11:10:35功能:csdn第三名URL :http://blog.csdn.net/phphot

  7. 《JavaScript Ninja》之闭包

    闭包 闭包是什么,它们是如何工作的 闭包 是一个函数在创建时允许该自身函数访问并操作该自身函数之外的变量时所创建的作用域. 即:闭包可以让函数访问所有的变量和函数,只要这些变量和函数存在于该函数声明时 ...

  8. 【题解】【数组】【查找】【Leetcode】Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  9. 在虚拟上安装kali

    1.创建新的虚拟机 2.选择典型 下一步 3.选安装程序光盘映像文件:写入自己.iso的位置 4.linux--Ubuntu 5.给虚拟机名称 虚拟机在你电脑的位置 6.最大自盘自己定义 7.选自定义 ...

  10. editplus 常用快捷键汇总 大小写代码折叠

    文本类 新建普通文本:Ctrl+N新建浏览器窗口:Ctrl+Shift+B新建HTML页:Ctrl+Shift+N打开:Ctrl+O打开一个现有的文档文件结尾:Ctrl+End选区扩展到文档结尾处:C ...