91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

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

子洲县| 连云港市| 娱乐| 改则县| 扬中市| 彭州市| 巫山县| 奉节县| 贵港市| 湘潭县| 嘉定区| 黎城县| 泾阳县| 贵溪市| 凤翔县| 平江县| 西城区| 肥东县| 南溪县| 伊吾县| 凤阳县| 贞丰县| 宜兰市| 黄山市| 沛县| 沅江市| 曲水县| 兴安盟| 石狮市| 郸城县| 汉中市| 邛崃市| 光山县| 郑州市| 龙泉市| 阜新市| 象山县| 西盟| 台北市| 宜宾市| 德化县|