亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PostgreSQL DBA(23) - MVCC#3(事務快照和隔離級別)

發布時間:2020-08-10 08:47:25 來源:ITPUB博客 閱讀:153 作者:husthxd 欄目:關系型數據庫

如前所述,PostgreSQL使用一種稱為快照隔離Snapshot Isolation (SI)實現并發控制,下面簡單介紹PostgreSQL中與之相關的快照和隔離級別等基本概念。
注意:
1.簡單起見,本節暫不討論事務回滾的情況.
2.如無說明,默認的事務隔離級別為READ COMMITTED

一、事務快照

事務快照(簡稱Snapshot)存儲所有事務在某個時間點是否處于活動狀態(正在進行或尚未啟動)的相關信息.
通過txid_current_snapshot()函數可以獲取當前事務的快照信息.


testdb=# select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2315:2315:
(1 row)

快照的格式如下為xmin : xmax : xip_list
其中:
xmin : 最早仍活躍的事務txid,早于此txid的事務要么被提交并可見,要么回滾并廢棄。
xmax : ShmemVariableCache->latestCompletedXid + 1,即最后已完結事務(COMMITTED/ABORTED)的txid + 1 。在”拍攝”快照時,所有大于或等于此txid的事務尚未啟動,因此不可見。
xip_list : 在”拍攝”快照時處于活動狀態的事務txid。該列表包含xmin和xmax之間的活動txid。
總結一下,簡單來說,對于給定的事務txid:
txid ∈ [2,xmin),是過去的事務,對此快照均可見;
txid ∈ [xmin,xmax),txid仍處于IN_PROGRESS狀態,則不可見;COMMITED狀態,則可見;ABORTED的事務,亦不可見;
txid ∈ [xmax,∞),是未來的事務,對此快照均不可見;

啟動三個客戶端(psql),執行begin啟動事務:
session 1


11:36:04 (xdb@[local]:5432)testdb=# begin;
BEGIN
11:36:09 (xdb@[local]:5432)testdb=#* select 1;
 ?column? 
----------
        1
(1 row)
11:36:09 (xdb@[local]:5432)testdb=#* select txid_current();
 txid_current 
--------------
         2327
(1 row)
11:36:09 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2327:
(1 row)

session 2


11:36:02 (xdb@[local]:5432)testdb=# begin;
BEGIN
11:36:17 (xdb@[local]:5432)testdb=#* select 1;
 ?column? 
----------
        1
(1 row)
11:36:17 (xdb@[local]:5432)testdb=#* select txid_current();
 txid_current 
--------------
         2328
(1 row)
11:36:17 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2327:
(1 row)

session 3


11:35:59 (xdb@[local]:5432)testdb=# begin;
BEGIN
11:36:18 (xdb@[local]:5432)testdb=#* select 1;
 ?column? 
----------
        1
(1 row)
11:36:18 (xdb@[local]:5432)testdb=#* select txid_current();
 txid_current 
--------------
         2329
(1 row)
11:36:18 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2327:
(1 row)

session 1/2/3的txid分別是2327/2328/2329,快照均為2327:2327:,即小于2327的事務可見,大于等于2327的不可見.

session 2創建數據表,插入數據,提交,重新開啟事務,插入數據.


11:36:17 (xdb@[local]:5432)testdb=#* 
11:37:24 (xdb@[local]:5432)testdb=#* create table t_session2 (id int);
CREATE TABLE
11:37:28 (xdb@[local]:5432)testdb=#* insert into t_session2 values(1);
INSERT 0 1
11:37:28 (xdb@[local]:5432)testdb=#* commit;
COMMIT
11:37:28 (xdb@[local]:5432)testdb=# begin;
BEGIN
11:38:25 (xdb@[local]:5432)testdb=#* insert into t_session2 values(2);
INSERT 0 1
11:38:31 (xdb@[local]:5432)testdb=#*

查看session 1/2/3的快照信息變化.
session 1


11:38:03 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2329:
(1 row)

session 1的快照信息變為2327:2329:,即小于2327的事務可見,大于等于2329的事務不可見.
session 2


11:39:02 (xdb@[local]:5432)testdb=#* select txid_current();
 txid_current 
--------------
         2330
(1 row)
11:39:14 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2329:2327
(1 row)

session 2的快照信息變為2327:2329:2327,即小于2327的事務可見,大于等于2329的事務不可見,2327事務進行中,亦不可見.

session 3


11:36:18 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2329:2327
(1 row)
11:39:57 (xdb@[local]:5432)testdb=#*

session 3的快照信息與session 2一致.

session 1創建數據表并插入數據


11:40:36 (xdb@[local]:5432)testdb=#* create table t_session1 (id int);
CREATE TABLE
11:45:10 (xdb@[local]:5432)testdb=#* insert into t_session1 values(1);
INSERT 0 1
11:45:19 (xdb@[local]:5432)testdb=#*

session 2查詢數據表t_session1


11:39:17 (xdb@[local]:5432)testdb=#* select * from t_session1;
ERROR:  relation "t_session1" does not exist
LINE 1: select * from t_session1;
11:49:58 (xdb@[local]:5432)testdb=#! select txid_current_snapshot(); --> 一旦出錯,就要回滾事務了
ERROR:  current transaction is aborted, commands ignored until end of transaction block
11:50:28 (xdb@[local]:5432)testdb=#! commit; --> 雖然是commit,按提示信息,其實是rollback.
ROLLBACK

報錯,提示關系不存在.
注意:事務處理過程中,如出錯,Oracle仍可提交先前成功執行的操作,但PG要求回滾事務

在上述案例中,在同一個事務中,執行新的SQL時事務快照是會變化的,這是因為默認的隔離級別READ COMMITTED的機制使然,如隔離級別為REPEATABLE READ則事務快照只會獲取一次并記錄獲取快照時事務的狀態.

二、隔離級別

在PostgreSQL中,有四種隔離級別,分別是READ UNCOMMITTED/READ COMMITTED/REPEATABLE READ/SERIALIZABLE.
其中READ UNCOMMITTED與READ COMMITTED一致,沒有區別;SERIALIZABLE級別較少使用,這里不作敘述.
READ COMMITTED
沿用第1小節的session 1/2.
session 2重新啟動事務


12:06:17 (xdb@[local]:5432)testdb=#*  select txid_current();
 txid_current 
--------------
         2331
(1 row)
12:06:23 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2327:2331:2327,2329
(1 row)

session 1提交事務


11:40:36 (xdb@[local]:5432)testdb=#* create table t_session1 (id int);
CREATE TABLE
11:45:10 (xdb@[local]:5432)testdb=#* insert into t_session1 values(1);
INSERT 0 1
11:45:19 (xdb@[local]:5432)testdb=#* commit;
COMMIT
12:07:21 (xdb@[local]:5432)testdb=#

這時候session 2可讀取session 1中的t_session1數據表


12:08:21 (xdb@[local]:5432)testdb=#* select * from t_session1;
 id 
----
  1
(1 row)

REPEATABLE READ
session 1,隔離級別為READ COMMITTED


12:12:14 (xdb@[local]:5432)testdb=# START TRANSACTION ISOLATION LEVEL READ COMMITTED; 
START TRANSACTION

session 2,隔離級別為REPEATABLE READ


12:12:41 (xdb@[local]:5432)testdb=# START TRANSACTION ISOLATION LEVEL REPEATABLE READ; 
START TRANSACTION
12:12:43 (xdb@[local]:5432)testdb=#* select * from t_session1;
 id 
----
  1
(1 row)

仍使用上述場景,session 1插入數據,提交事務,這時候新插入的數據對session 2仍不可見.
session 1


12:12:18 (xdb@[local]:5432)testdb=#* insert into t_session1 values(2);
INSERT 0 1
12:13:22 (xdb@[local]:5432)testdb=#* commit;
COMMIT
12:13:25 (xdb@[local]:5432)testdb=#

session 2


12:13:38 (xdb@[local]:5432)testdb=#* select * from t_session1;
 id 
----
  1 --> 新插入的數據2不可見
(1 row)
12:13:58 (xdb@[local]:5432)testdb=#* select txid_current_snapshot();
 txid_current_snapshot 
-----------------------
 2329:2332:2329
(1 row)

session 2的事務快照只會獲取一次.
獲取事務快照的邏輯以及如何確定heap tuple是否可見的邏輯后續在源碼解讀中將作具體解析.

三、參考資料

Concurrency Control

四、號外

打錯字,PG也要求回滾事務?


12:06:25 (xdb@[local]:5432)testdb=#* selet * from t_session1;
ERROR:  syntax error at or near "selet"
LINE 1: selet * from t_session1;
        ^
12:07:56 (xdb@[local]:5432)testdb=#! select * from t_session1;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
12:08:02 (xdb@[local]:5432)testdb=#! commit;
ROLLBACK

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南召县| 兴业县| 西平县| 大港区| 巴东县| 姚安县| 华亭县| 抚远县| 安福县| 商城县| 盘山县| 赤峰市| 本溪| 玛多县| 重庆市| 新兴县| 五台县| 花莲市| 柯坪县| 庐江县| 壶关县| 长宁县| 克东县| 万年县| 四会市| 新民市| 梓潼县| 扎鲁特旗| 平果县| 独山县| 东兰县| 日喀则市| 盖州市| 阿克陶县| 招远市| 翁牛特旗| 普洱| 津南区| 合阳县| 东莞市| 隆化县|