成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PostgreSQL鎖淺析

IT那活兒 / 684人閱讀
PostgreSQL鎖淺析
點(diǎn)擊上方“IT那活兒”公眾號(hào),關(guān)注后了解更多內(nèi)容,不管IT什么活兒,干就完了!??! 

鎖存在的意義

在了解PostgreSQL鎖之前,我們需要了解鎖存在的意義是啥?

當(dāng)多個(gè)會(huì)話同時(shí)訪問數(shù)據(jù)庫(kù)的同一數(shù)據(jù)時(shí),理想狀態(tài)是為所有會(huì)話提供高效的訪問,同時(shí)還要維護(hù)嚴(yán)格的數(shù)據(jù)一致性。那這數(shù)據(jù)一致性通過什么來(lái)維護(hù)呢?就是之前文章多次提到的MVCC(多版本并發(fā)控制),可以點(diǎn)擊下列文章標(biāo)題回顧早前發(fā)布的內(nèi)容:

聊聊PostgreSQL事務(wù)id那點(diǎn)事
Mvcc機(jī)制
MVCC:每個(gè)SQL語(yǔ)句看到的都只是當(dāng)前事務(wù)開始的數(shù)據(jù)快照,而不管底層數(shù)據(jù)的當(dāng)前狀態(tài)。這樣可以保護(hù)語(yǔ)句不會(huì)看到可能由其他在相同數(shù)據(jù)行上執(zhí)行更新的并發(fā)事務(wù)造成的不一致數(shù)據(jù),為每一個(gè)數(shù)據(jù)庫(kù)會(huì)話提供事務(wù)隔離。MVCC避免了傳統(tǒng)的數(shù)據(jù)庫(kù)系統(tǒng)的鎖定方法,將通過鎖爭(zhēng)奪最小化的方法來(lái)達(dá)到多會(huì)話并發(fā)訪問時(shí)的性能最大化目的。

PostgreSQL提供了多種鎖模式用于控制對(duì)表中數(shù)據(jù)的并發(fā)訪問,其中最主要的是表級(jí)鎖與行級(jí)鎖,此外還有頁(yè)級(jí)鎖,咨詢鎖等等,接下來(lái)主要介紹表級(jí)鎖與行級(jí)鎖。

表級(jí)鎖

表級(jí)鎖通常會(huì)在執(zhí)行各種命令執(zhí)行時(shí)自動(dòng)獲取,或者通過在事務(wù)中使用LOCK語(yǔ)句顯式獲取。
每種鎖都有自己的沖突集合, 兩個(gè)事務(wù)在同一時(shí)刻不能在同一個(gè)表上持有屬于相互沖突模式的鎖,但可以持有不沖突的鎖。
表級(jí)鎖總共有八種模式,其存在于PG的共享內(nèi)存中,可以通過pg_locks系統(tǒng)視圖查閱。
1. ACCESS SHARE
只與ACCESS EXCLUSIVE鎖模式?jīng)_突。
SELECT命令在被引用的表上獲得一個(gè)這種模式的鎖。通常,任何只讀取表而不修改它的查詢都將獲得這種鎖模式。
2. ROW SHARE
與EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。
SELECT FOR UPDATE和SELECT FOR SHARE命令在目標(biāo)表上取得一個(gè)這種模式的鎖 (加上在被引用但沒有選擇FOR UPDATE/FOR SHARE的任何其他表上的ACCESS SHARE鎖)。
3. ROW EXCLUSIVE
與SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。
命令UPDATE、DELETE和INSERT在目標(biāo)表上取得這種鎖模式(加上在任何其他被引用表上的ACCESS SHARE鎖)。通常,這種鎖模式將被任何修改表中數(shù)據(jù)的命令取得。
4. SHARE UPDATE EXCLUSIVE
與SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。這種模式保護(hù)一個(gè)表不受并發(fā)模式改變和VACUUM運(yùn)行的影響。
由VACUUM(不帶FULL)、ANALYZE、 CREATE INDEX CONCURRENTLY、REINDEX CONCURRENTLY、 CREATE STATISTICS以及某些ALTER INDEX和 ALTER TABLE的變體獲得。
5. SHARE
與ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。這種模式保護(hù)一個(gè)表不受并發(fā)數(shù)據(jù)改變的影響。
由CREATE INDEX(不帶CONCURRENTLY)取得。
6. SHARE ROW EXCLUSIVE
與ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。這種模式保護(hù)一個(gè)表不受并發(fā)數(shù)據(jù)修改所影響,并且是自排他的,這樣在一個(gè)時(shí)刻只能有一個(gè)會(huì)話持有它。
由CREATE TRIGGER和某些形式的ALTER TABLE所獲得。
7. EXCLUSIVE
與ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。這種模式只允許并發(fā)的ACCESS SHARE鎖,即只有來(lái)自于表的讀操作可以與一個(gè)持有該鎖模式的事務(wù)并行處理。
由REFRESH MATERIALIZED VIEW CONCURRENTLY獲得。
8. ACCESS EXCLUSIVE
與所有模式的鎖沖突(ACCESS SHARE、ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE)。這種模式保證持有者是訪問該表的唯一事務(wù)。
由ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL和REFRESH MATERIALIZED VIEW(不帶CONCURRENTLY)命令獲取。很多形式的ALTER INDEX和ALTER TABLE也在這個(gè)層面上獲得鎖。這也是未顯式指定模式的LOCK TABLE命令的默認(rèn)鎖模式。
表級(jí)鎖模式?jīng)_突表:
注:X表示沖突。
怎么去看上面這個(gè)圖呢?
我們?cè)谶@里以2個(gè)例子說明:
場(chǎng)景一
當(dāng)一個(gè)會(huì)話運(yùn)行了update語(yǔ)句,此時(shí)會(huì)話表上的鎖模式為ROW EXCLUSIVE,從上圖我們可以看出ROW EXCLUSIVE與SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE鎖模式?jīng)_突。
也就是說在這個(gè)會(huì)話未提交事務(wù)釋放鎖之前,我們不能做申請(qǐng)SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE和ACCESS EXCLUSIVE相關(guān)的操作,例如CREATE INDEX(不帶CONCURRENTLY)、ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL和REFRESH MATERIALIZED VIEW(不帶CONCURRENTLY)等。
會(huì)話一執(zhí)行update語(yǔ)句:
會(huì)話二執(zhí)行alter table語(yǔ)句時(shí)處于等待狀態(tài):
我們查看等待情況如下:
注:Lock_Granted: true即為堵塞源。
一直到會(huì)話一結(jié)束,會(huì)話二語(yǔ)句才執(zhí)行成功。
場(chǎng)景二
當(dāng)一個(gè)會(huì)話運(yùn)行了truncate語(yǔ)句,此時(shí)會(huì)話表上的鎖模式為ACCESS EXCLUSIVE,從圖上看我們可以看到它和所有鎖模式都沖突,意味著在當(dāng)前會(huì)話未結(jié)束之前,這個(gè)表上的其他操作都做不了。
會(huì)話一執(zhí)行truncate語(yǔ)句:
會(huì)話二執(zhí)行select語(yǔ)句時(shí)處于等待狀態(tài):

查看鎖等待情況如下:

通過上面2個(gè)案例我們應(yīng)該比較了解各種鎖模式?jīng)_突的情況了。接下來(lái)我們介紹行級(jí)鎖。

行級(jí)鎖

同一個(gè)事務(wù)可能會(huì)在相同的行上保持沖突的鎖,甚至是在不同的子事務(wù)中。但是除此之外,兩個(gè)事務(wù)永遠(yuǎn)不可能在相同的行上持有沖突的鎖。行級(jí)鎖不影響數(shù)據(jù)查詢,它們只阻塞對(duì)同一行的寫入者和加鎖者。行級(jí)鎖在事務(wù)結(jié)束時(shí)或保存點(diǎn)回滾的時(shí)候釋放,就像表級(jí)鎖一樣。
行級(jí)鎖模式
1. FOR UPDATE
FOR UPDATE會(huì)導(dǎo)致由SELECT語(yǔ)句檢索到的行被鎖定,就好像它們要被更新。這可以阻止它們被其他事務(wù)鎖定、修改或者刪除,一直到當(dāng)前事務(wù)結(jié)束。
也就是說其他嘗試UPDATE、DELETE、SELECT FOR UPDATE、SELECT FOR NO KEY UPDATE、SELECT FOR SHARE或者SELECT FOR KEY SHARE這些行的事務(wù)將被阻塞,直到當(dāng)前事務(wù)結(jié)束。
反過來(lái),SELECT FOR UPDATE將等待已經(jīng)在相同行上運(yùn)行以上這些命令的并發(fā)事務(wù),并且接著鎖定并且返回被更新的行(或者沒有行,因?yàn)樾锌赡芤驯粍h除)。
2. FOR NO KEY UPDATE
行為與FOR UPDATE類似,不過獲得的鎖較弱:這種鎖將不會(huì)阻塞嘗試在相同行上獲得鎖的SELECT FOR KEY SHARE命令。任何不獲取FOR UPDATE鎖的UPDATE也會(huì)獲得這種鎖模式。
3. FOR SHARE
行為與FOR NO KEY UPDATE類似,不過它在每個(gè)檢索到的行上獲得一個(gè)共享鎖而不是排他鎖。
一個(gè)共享鎖會(huì)阻塞其他事務(wù)在這些行上執(zhí)行UPDATE、DELETE、SELECT FOR UPDATE或者SELECT FOR NO KEY UPDATE,但是它不會(huì)阻止它們執(zhí)行SELECT FOR SHARE或者SELECT FOR KEY SHARE。
4. FOR KEY SHARE
行為與FOR SHARE類似,不過鎖較弱:SELECT FOR UPDATE會(huì)被阻塞,但是SELECT FOR NO KEY UPDATE不會(huì)被阻塞。一個(gè)鍵共享鎖會(huì)阻塞其他事務(wù)執(zhí)行修改鍵值的DELETE或者UPDATE,但不會(huì)阻塞其他UPDATE,也不會(huì)阻止SELECT FOR NO KEY UPDATE、SELECT FOR SHARE或者SELECT FOR KEY SHARE。
行級(jí)鎖模式?jīng)_突表:
PG中我們要查看鎖信息,pg_locks視圖提供了詳細(xì)的信息,不同于oracle的dba_locks,pg_locks稍顯復(fù)雜。
接下來(lái)我們對(duì)pg_locks視圖各字段做下詳細(xì)介紹:
  • locktype
    可鎖對(duì)象的類型:relation, extend, frozenid, page, tuple, transactionid, virtualxid, spectoken, object, userlock, or advisory.
    locktype的等待事件:
  • database oid (參考 pg_database.oid)

    鎖目標(biāo)存在的數(shù)據(jù)庫(kù)的OID,如果目標(biāo)是一個(gè)共享對(duì)象則為0,如果目標(biāo)是一個(gè)事務(wù)ID則為空。

  • relation oid (參考 pg_class.oid)

    作為鎖目標(biāo)的關(guān)系的OID,如果目標(biāo)不是一個(gè)關(guān)系或者只是關(guān)系的一部分則此列為空。

  • page int4

    作為鎖目標(biāo)的頁(yè)在關(guān)系中的頁(yè)號(hào),如果目標(biāo)不是一個(gè)關(guān)系頁(yè)或元組則此列為空。

  • tuple int2

    作為鎖目標(biāo)的元組在頁(yè)中的元組號(hào),如果目標(biāo)不是一個(gè)元組則此列為空。

  • virtualxid text

    作為鎖目標(biāo)的事務(wù)虛擬ID,如果目標(biāo)不是一個(gè)虛擬事務(wù)ID則此列為空。

  • transactionid xid

    作為鎖目標(biāo)的事務(wù)ID,如果目標(biāo)不是一個(gè)事務(wù)ID則此列為空ID。

  • classid oid (參考 pg_class.oid)

    包含鎖目標(biāo)的系統(tǒng)目錄的OID,如果目標(biāo)不是一個(gè)普通數(shù)據(jù)庫(kù)對(duì)象則此列為空。

  • objid oid (參考 any OID column)

    鎖目標(biāo)在它的系統(tǒng)目錄中的OID,如果目標(biāo)不是一個(gè)普通數(shù)據(jù)庫(kù)對(duì)象則為空。

  • objsubid int2

    鎖的目標(biāo)列號(hào)(classid和objid指表本身),如果目標(biāo)是某種其他普通數(shù)據(jù)庫(kù)對(duì)象則此列為0,如果目標(biāo)不是一個(gè)普通數(shù)據(jù)庫(kù)對(duì)象則此列為空。

  • virtualtransaction text

    保持這個(gè)鎖或者正在等待這個(gè)鎖的事務(wù)的虛擬ID。

  • pid int4

    保持這個(gè)鎖或者正在等待這個(gè)鎖的服務(wù)器進(jìn)程的PID,如果此鎖被一個(gè)預(yù)備事務(wù)所持有則此列為空。

  • mode text

    此進(jìn)程已持有或者希望持有的鎖模式的名稱。

  • granted bool

    如果鎖已授予則為真,如果鎖被等待則為假。

  • fastpath bool
    如果鎖通過快速路徑獲得則為真,通過主鎖表獲得則為假。
附上一些網(wǎng)上摘錄的常用查鎖SQL:
1)查看當(dāng)前事務(wù)鎖等待、持鎖信息的SQL:
with
t_wait as
(
select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,
b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name
from pg_locks a,pg_stat_activity b where a.pid=b.pid and not a.granted
),
t_run as
(
select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,
b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name
from pg_locks a,pg_stat_activity b where a.pid=b.pid and a.granted
),
t_overlap as
(
select r.* from t_wait w join t_run r on
(
r.locktype is not distinct from w.locktype and
r.database is not distinct from w.database and
r.relation is not distinct from w.relation and
r.page is not distinct from w.page and
r.tuple is not distinct from w.tuple and
r.virtualxid is not distinct from w.virtualxid and
r.transactionid is not distinct from w.transactionid and
r.classid is not distinct from w.classid and
r.objid is not distinct from w.objid and
r.objsubid is not distinct from w.objsubid and
r.pid <> w.pid
)
),
t_unionall as
(
select r.* from t_overlap r
union all
select w.* from t_wait w
)
select locktype,datname,relation::regclass,page,tuple,virtualxid,transactionid::text,classid::regclass,objid,objsubid,
string_agg(
Pid: ||case when pid is null then NULL else pid::text end||chr(10)||
Lock_Granted: ||case when granted is null then NULL else granted::text end|| , Mode: ||case when mode is null then NULL else mode::text end|| , FastPath: ||case when fastpath is null then NULL else fastpath::text end|| , VirtualTransaction: ||case when virtualtransaction is null then NULL else virtualtransaction::text end|| , Session_State: ||case when state is null then NULL else state::text end||chr(10)||
Username: ||case when usename is null then NULL else usename::text end|| , Database: ||case when datname is null then NULL else datname::text end|| , Client_Addr: ||case when client_addr is null then NULL else client_addr::text end|| , Client_Port: ||case when client_port is null then NULL else client_port::text end|| , Application_Name: ||case when application_name is null then NULL else application_name::text end||chr(10)||
Xact_Start: ||case when xact_start is null then NULL else xact_start::text end|| , Query_Start: ||case when query_start is null then NULL else query_start::text end|| , Xact_Elapse: ||case when (now()-xact_start) is null then NULL else (now()-xact_start)::text end|| , Query_Elapse: ||case when (now()-query_start) is null then NULL else (now()-query_start)::text end||chr(10)||
SQL (Current SQL in Transaction): ||chr(10)||
case when query is null then NULL else query::text end,
chr(10)||--------||chr(10)
order by
( case mode
when INVALID then 0
when AccessShareLock then 1
when RowShareLock then 2
when RowExclusiveLock then 3
when ShareUpdateExclusiveLock then 4
when ShareLock then 5
when ShareRowExclusiveLock then 6
when ExclusiveLock then 7
when AccessExclusiveLock then 8
else 0
end  ) desc,
(case when granted then 0 else 1 end)
) as lock_conflict
from t_unionall
group by
locktype,datname,relation,page,tuple,virtualxid,transactionid::text,classid,objid,objsubid ;
輸出結(jié)果格式如下:
注:Lock_Granted: true即為堵塞源。
2)查看堵塞會(huì)話,并生成kill sql:
with recursive tmp_lock as (
select distinct
--w.mode w_mode,w.page w_page,
--w.tuple w_tuple,w.xact_start w_xact_start,w.query_start w_query_start,
--now()-w.query_start w_locktime,w.query w_query
w.pid as id,--w_pid,
r.pid as parentid--r_pid,
--r.locktype,r.mode r_mode,r.usename r_user,r.datname r_db,
--r.relation::regclass,
--r.page r_page,r.tuple r_tuple,r.xact_start r_xact_start,
--r.query_start r_query_start,
--now()-r.query_start r_locktime,r.query r_query,
from (
select a.mode,a.locktype,a.database,
a.relation,a.page,a.tuple,a.classid,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,
a.transactionid,
b.query as query,
b.xact_start,b.query_start,b.usename,b.datname
from pg_locks a,
pg_stat_activity b
where a.pid=b.pid
and not a.granted
) w,
(
select a.mode,a.locktype,a.database,
a.relation,a.page,a.tuple,a.classid,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,
a.transactionid,
b.query as query,
b.xact_start,b.query_start,b.usename,b.datname
from pg_locks a,
pg_stat_activity b -- select pg_typeof(pid) from pg_stat_activity
where a.pid=b.pid
and a.granted
) r
where 1=1
and r.locktype is not distinct from w.locktype
and r.database is not distinct from w.database
and r.relation is not distinct from w.relation
and r.page is not distinct from w.page
and r.tuple is not distinct from w.tuple
and r.classid is not distinct from w.classid
and r.objid is not distinct from w.objid
and r.objsubid is not distinct from w.objsubid
and r.transactionid is not distinct from w.transactionid
and r.pid <> w.pid

),tmp0 as (
select *
from tmp_lock tl
union all
select t1.parentid,0::int4
from tmp_lock t1
where 1=1
and t1.parentid not in (select id from tmp_lock)
),tmp3 (pathid,depth,id,parentid) as (
SELECT array[id]::text[] as pathid,1 as depth,id,parentid
FROM tmp0
where 1=1
and parentid=0
union
SELECT t0.pathid||array[t1.id]::text[] as pathid,t0.depth+1 as depth,t1.id,t1.parentid
FROM tmp0 t1,
tmp3 t0
where 1=1
and t1.parentid=t0.id
)
select distinct
/||array_to_string(a0.pathid,/) as pathid,
a0.depth,
a0.id,a0.parentid,lpad(a0.id::text, 2*a0.depth-1+length(a0.id::text), ) as tree_id,
--select pg_cancel_backend(||a0.id|| ); as cancel_pid,
--select pg_terminate_backend(||a0.id|| ); as term_pid,
case when a0.depth =1 then select pg_terminate_backend(|| a0.id || ); else null end  as term_pid,
case when a0.depth =1 then select cancel_backend(|| a0.id || ); else null end  as cancel_pid
,a2.datname,a2.usename,a2.application_name,a2.client_addr,a2.wait_event_type,a2.wait_event,a2.state
--,a2.backend_start,a2.xact_start,a2.query_start
from tmp3 a0
left outer join (select distinct /||id||/ as prefix_id,id
from tmp0
where 1=1 ) a1
on position( a1.prefix_id in /||array_to_string(a0.pathid,/)||/ ) >0
left outer join pg_stat_activity a2 -- select * from pg_stat_activity
on a0.id = a2.pid
order by /||array_to_string(a0.pathid,/),a0.depth;
輸出結(jié)果格式如下:

本文作者:魏 斌(上海新炬王翦團(tuán)隊(duì))

本文來(lái)源:“IT那活兒”公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/129295.html

相關(guān)文章

  • 線程間的同步與通信(3)——淺析synchronized的實(shí)現(xiàn)原理

    摘要:由此可見,自旋鎖和各有優(yōu)劣,他們分別適用于競(jìng)爭(zhēng)不多和競(jìng)爭(zhēng)激烈的場(chǎng)景中。每一個(gè)試圖進(jìn)入同步代碼塊的線程都會(huì)被封裝成對(duì)象,它們或在對(duì)象的中,或在中,等待成為對(duì)象的成為的對(duì)象即獲取了監(jiān)視器鎖。 前言 系列文章目錄 前面兩篇文章我們介紹了synchronized同步代碼塊以及wait和notify機(jī)制,大致知道了這些關(guān)鍵字和方法是干什么的,以及怎么用。 但是,知其然,并不知其所以然。 例如...

    keithxiaoy 評(píng)論0 收藏0
  • 淺析如何用Redis實(shí)現(xiàn)分布式

    摘要:刪除在使用實(shí)現(xiàn)分布式鎖的時(shí)候,主要就會(huì)使用到這三個(gè)命令。其實(shí),使用的可靠性是要大于使用實(shí)現(xiàn)的分布式鎖的,但是相比而言,的性能更好。 選用Redis實(shí)現(xiàn)分布式鎖原因 Redis有很高的性能 Redis命令對(duì)此支持較好,實(shí)現(xiàn)起來(lái)比較方便 使用命令介紹 SETNX SETNX key val當(dāng)且僅當(dāng)key不存在時(shí),set一個(gè)key為val的字符串,返回1;若key存在,則什么都不做,返回...

    張率功 評(píng)論0 收藏0
  • PostgreSQL9.6:新增pg_blocking_pids函數(shù)準(zhǔn)確定位 Blocking SQ

    摘要:創(chuàng)建測(cè)試表會(huì)話一備注會(huì)話一在事務(wù)里更新的記錄,并不提交。會(huì)話二備注會(huì)話二刪除的記錄,此時(shí)由于這條記錄之前被并沒有提交,這句仍然處于等待狀態(tài)。 PosttgreSQL 的SQL被鎖情況在數(shù)據(jù)庫(kù)維護(hù)過程中非常常見,之前博客 PostgreSQL 鎖分析 演示了 PostgreSQL 鎖的一些場(chǎng)景,在開始本文的介紹之前特做以下說明,假如會(huì)話A堵住會(huì)話B,我們稱會(huì)話B為 blocked 會(huì)話...

    liuchengxu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<