PostgreSQL模擬兩個update語句死鎖-利用掃描方法
標籤
PostgreSQL , 死鎖 , update , 模擬
背景
在單條UPDATE中模擬死鎖,需要藉助掃描方法,以及明確讓AB兩個會話分別鎖定一條記錄後再鎖定對方已經鎖定的記錄。
利用批量update的語法以及values子句即可實現,這裡利用了巢狀迴圈,確保被更新的表被多次掃描,並且每次掃描時兩個會話更新的記錄被錯開,達到死鎖效果。
同時為了讓速度慢下來,使用pg_sleep函式,讓每一條更新都放緩1秒。
例子
1、建表
postgres=# create table a (id int primary key, info timestamp);
CREATE TABLE
2、寫入測試資料
postgres=# insert into a select generate_series(1,10);
INSERT 0 10
3、會話1 SQL,執行計劃
先鎖定ID=2的記錄,然後鎖定ID=1的記錄。
postgres=# explain update a set info=clock_timestamp() from (values (2),(1)) t(id) where a.id=t.id and pg_sleep(1) is not null;
QUERY PLAN
-----------------------------------------------------------------------------
Update on a (cost=0.15..4.80 rows=2 width=46)
-> Nested Loop (cost=0.15..4.80 rows=2 width=46)
Join Filter: (pg_sleep(`1`::double precision) IS NOT NULL) -- 放緩1秒
-> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=32) -- 按values寫的順序掃描
-> Index Scan using a_pkey on a (cost=0.15..2.37 rows=1 width=10) -- 先更新2,再更新1
Index Cond: (id = "*VALUES*".column1)
(6 rows)
4、會話2 SQL,執行計劃,與會話1相反。
先鎖定ID=1的記錄,然後鎖定ID=2的記錄。
postgres=# explaIN update a set info=clock_timestamp() from (values (2),(1)) t(id) where a.id=t.id and pg_sleep(1) is not null;
QUERY PLAN
-----------------------------------------------------------------------------
Update on a (cost=0.15..4.80 rows=2 width=46)
-> Nested Loop (cost=0.15..4.80 rows=2 width=46)
Join Filter: (pg_sleep(`1`::double precision) IS NOT NULL) -- 放緩1秒
-> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=32) -- 按values寫的順序掃描
-> Index Scan using a_pkey on a (cost=0.15..2.37 rows=1 width=10) -- 先更新1,再更新2
Index Cond: (id = "*VALUES*".column1)
(6 rows)
5、模擬死鎖
會話1
postgres=# update a set info=clock_timestamp() from (values (2),(1)) t(id) where a.id=t.id and pg_sleep(1) is not null;
ERROR: deadlock detected
DETAIL: Process 19893 waits for ShareLock on transaction 18613573; blocked by process 9910.
Process 9910 waits for ShareLock on transaction 18613572; blocked by process 19893.
HINT: See server log for query details.
CONTEXT: while updating tuple (0,1) in relation "a"
馬上發起會話2
postgres=# update a set info=clock_timestamp() from (values (1),(2)) t(id) where a.id=t.id and pg_sleep(1) is not null;
UPDATE 2
相關文章
- PostgreSQL掃描方法綜述SQL
- 【Mysql】兩條insert 語句產生的死鎖MySql
- 查詢全表掃描語句
- 【DEADLOCK】Oracle“死鎖”模擬Oracle
- 模擬SQLserver死鎖現象SQLServer
- 【Mysql】兩條select for update引起的死鎖MySql
- 面試官:請用SQL模擬一個死鎖面試SQL
- oracle 檢視死鎖語句Oracle
- 關於oracle死鎖的模擬Oracle
- select for update語句造成ORA-00060 deadlock死鎖問題分析
- mac掃描和模擬ibeacon的工具Mac
- 理解資料庫掃描方法-利用掃描方法對資料儲存進行優化資料庫優化
- 一條全表掃描sql語句的分析SQL
- PostgreSQL死鎖相關SQL
- PostgreSQL 死鎖異常SQL
- Oracle vs PostgreSQL,研發注意事項(13) - UPDATE語句OracleSQL
- SQLSERVER 語句交錯引發的死鎖研究SQLServer
- MySQL insert on duplicate key update 死鎖MySql
- sybase空間監控和死鎖檢測語句
- PostgreSQL技術內幕(七)索引掃描SQL索引
- Mysql 兩階段鎖和死鎖MySql
- java兩個控制語句(轉)Java
- 【SQL】10 SQL UPDATE 語句SQL
- Sql Server系列:Update語句SQLServer
- FORALL執行UPDATE語句
- SQL update select語句SQL
- PostgreSQL 跟蹤checkpointer出現死鎖SQL
- 電腦掃描檔案怎麼掃描 win10電腦掃描檔案方法介紹Win10
- sipp模擬uas傳送update
- 查詢處理死鎖會話的sql語句(轉貼)會話SQL
- 使用 TRY/CATCH 語句解決 SQL Server 2005 死鎖SQLServer
- 每一千行UPDATE語句後插入一條COMMIT語句的編輯方法MIT
- 如何透過sid查詢造成死鎖的sql語句,並殺死會話SQL會話
- 如何通過sid查詢造成死鎖的sql語句,並殺死會話SQL會話
- MySQL -update語句流程總結MySql
- ORACLE多表關聯UPDATE語句Oracle
- MySQL的update語句避坑MySql
- ORACLE多表關聯UPDATE 語句Oracle