PostgreSQL Tutorial: MVCC

First of all, we need to understand why there is MVCC.

If a database frequently performs read and write operations, a lock mechanism is used to ensure security. But if a locking mechanism is used, if some transactions are writing data, another transaction cannot read the data. This will cause reading and writing to block each other. Most databases use a mechanism, multi-version concurrency control (MVCC), to solve this problem.

For example, if you want to query a row of data, but this row of data is being modified and the transaction has not yet been committed, if you lock this row of data at this time, other read operations will be blocked and need to wait. If PostgreSQL is used, it will internally save multiple versions of this row of data. If the data is being written, the previous data version will be saved. Let the read operation query the previous version without blocking. Only when the transaction for the write operation is committed can the read operation view the latest data. These mechanisms can ensure that there are no conflicts in read and write operations . This is the main feature of MVCC.

Write and write operations have nothing to do with MVCC, that is the locking method!

Ps: The MVCC here is based on read submitted . If it is serialized, it cannot be read.

Before operating, first understand that in PGSQL, each table comes with two fields.

  • xmin: The data version assigned to the current transaction. If other transactions perform write operations and commit the transaction, a new version will be assigned to xmin.
  • xmax: There is no new version of the current transaction, xmax is 0. If other transactions perform write operations and the transaction is not committed, the version of the write operation is placed in xmax. After the transaction is committed, xmax will be allocated to xmin, and then xmax will return to 0.

image.png

View a wave of effects based on the operation above

Transaction A

-- 左,事务A
--1、开启事务
begin;
--2、查询某一行数据,  xmin = 630,xmax = 0
select xmin,xmax,* from test where id = 8;
--3、每次开启事务后,会分配一个事务ID 事务id=631
select txid_current();
--7、修改id为8的数据,然后在本事务中查询   xmin = 631, xmax = 0
update test set name = '铃铛' where id = 8;
select xmin,xmax,* from test where id = 8;
--9、提交事务
commit;

Transaction B

-- 右,事务B
--4、开启事务
begin;
--5、查询某一行数据,  xmin = 630,xmax = 0
select xmin,xmax,* from test where id = 8;
--6、每次开启事务后,会分配一个事务ID 事务id=632
select txid_current();
--8、事务A修改完,事务B再查询  xmin = 630  xmax = 631
select xmin,xmax,* from test where id = 8;
--10、事务A提交后,事务B再查询  xmin = 631  xmax = 0
select xmin,xmax,* from test where id = 8;

Guess you like

Origin blog.csdn.net/a772304419/article/details/132929120