Postgresqlddl在事務中可以回滾,truncate時relfilenode在當前會話會改變

lusklusklusk發表於2023-10-29

Postgresql的事務裡面ddl可以回滾,這點和oracle不太一樣。其中postgresql alter table事務操作中,包括回滾的整個過程中表物件的relfilenode不變,但是postgresql truncate事務操作中,一旦執行truncate操作表物件的relfilenode在當前會話就變了,其他會話查詢表物件的relfilenode沒有變化,truncate事務操作回滾後表物件的relfilenode在當前會話中也回滾了



Postgresql的事務裡面ddl可以回滾,如下新增欄位操作的ddl回滾後,新增的欄位就消失了

postgres=# select * from emp;
  id  |  name  | position | managerid | yearmomthday | salary | ticheng | salper
------+--------+----------+-----------+--------------+--------+---------+--------
 7369 | SMITH  | CLERK    |      7902 | 1982-12-17   |    800 |         |     20
 7499 | ALLEN  | SALESMAN |      7698 | 1981-02-20   |   1600 |     300 |     20
 7521 | WARD   | SALESMAN |      7698 | 1981-02-22   |   1250 |     500 |     30
 7566 | JONES  | MANAGER  |      7389 | 1981-04-02   |   2975 |         |     20
 7654 | MARTIN | SALESMAN |      7698 | 1982-09-28   |   1250 |    1400 |     30
(5 rows)
postgres=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16412 | emp     |       16412
(1 row)
postgres=# begin;
BEGIN
postgres=# alter table emp add column lx varchar(100) default 'good';
ALTER TABLE
postgres=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16412 | emp     |       16412
(1 row)
postgres=# select * from emp;
  id  |  name  | position | managerid | yearmomthday | salary | ticheng | salper |  lx
------+--------+----------+-----------+--------------+--------+---------+--------+------
 7369 | SMITH  | CLERK    |      7902 | 1982-12-17   |    800 |         |     20 | good
 7499 | ALLEN  | SALESMAN |      7698 | 1981-02-20   |   1600 |     300 |     20 | good
 7521 | WARD   | SALESMAN |      7698 | 1981-02-22   |   1250 |     500 |     30 | good
 7566 | JONES  | MANAGER  |      7389 | 1981-04-02   |   2975 |         |     20 | good
 7654 | MARTIN | SALESMAN |      7698 | 1982-09-28   |   1250 |    1400 |     30 | good
(5 rows)
postgres=# rollback;
ROLLBACK
postgres=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16412 | emp     |       16412
(1 row)
postgres=# select * from emp;
  id  |  name  | position | managerid | yearmomthday | salary | ticheng | salper
------+--------+----------+-----------+--------------+--------+---------+--------
 7369 | SMITH  | CLERK    |      7902 | 1982-12-17   |    800 |         |     20
 7499 | ALLEN  | SALESMAN |      7698 | 1981-02-20   |   1600 |     300 |     20
 7521 | WARD   | SALESMAN |      7698 | 1981-02-22   |   1250 |     500 |     30
 7566 | JONES  | MANAGER  |      7389 | 1981-04-02   |   2975 |         |     20
 7654 | MARTIN | SALESMAN |      7698 | 1982-09-28   |   1250 |    1400 |     30
(5 rows)





Postgresql的事務裡面ddl可以回滾,如下truncate操作,回滾後,truncate的資料又回來了

testdb=# select * from emp;
  id  |  name  | position | managerid | yearmomthday | salary | ticheng | salper
------+--------+----------+-----------+--------------+--------+---------+--------
 7369 | SMITH  | CLERK    |      7902 | 1982-12-17   |    800 |         |     20
 7499 | ALLEN  | SALESMAN |      7698 | 1981-02-20   |   1600 |     300 |     20
 7521 | WARD   | SALESMAN |      7698 | 1981-02-22   |   1250 |     500 |     30
 7566 | JONES  | MANAGER  |      7389 | 1981-04-02   |   2975 |         |     20
 7654 | MARTIN | SALESMAN |      7698 | 1982-09-28   |   1250 |    1400 |     30
(5 rows)
testdb=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16400 | emp     |       16400
(1 row)
testdb=# begin;
BEGIN
testdb=# truncate table emp;
TRUNCATE TABLE
testdb=# select * from emp;
 id | name | position | managerid | yearmomthday | salary | ticheng | salper
----+------+----------+-----------+--------------+--------+---------+--------
(0 rows)
testdb=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16400 | emp     |       24610
(1 row)
testdb=# rollback;
ROLLBACK
testdb=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16400 | emp     |       16400
(1 row)
testdb=# select * from emp;
  id  |  name  | position | managerid | yearmomthday | salary | ticheng | salper
------+--------+----------+-----------+--------------+--------+---------+--------
 7369 | SMITH  | CLERK    |      7902 | 1982-12-17   |    800 |         |     20
 7499 | ALLEN  | SALESMAN |      7698 | 1981-02-20   |   1600 |     300 |     20
 7521 | WARD   | SALESMAN |      7698 | 1981-02-22   |   1250 |     500 |     30
 7566 | JONES  | MANAGER  |      7389 | 1981-04-02   |   2975 |         |     20
 7654 | MARTIN | SALESMAN |      7698 | 1982-09-28   |   1250 |    1400 |     30
(5 rows)



truncate會話執行過程中ll -rt |grep 24610能查到relfilenode 24610

[root@centos7 16386]# ll -rt |grep 24610
-rw-------. 1 postgres postgres      0 Oct 29 20:55 24610



不過會話退出後不久,ll -rt |grep 24610就查不到對應的檔案了

[root@centos7 16386]# ll -rt |grep 24610
[root@centos7 16386]#




在會話1執行truncate的過程中只要還沒提交,其他會話查詢到表的relfilenode不變

postgres=# select oid,relname,relfilenode from pg_class where relname='emp';
  oid  | relname | relfilenode
-------+---------+-------------
 16412 | emp     |       16412



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2991703/,如需轉載,請註明出處,否則將追究法律責任。

相關文章