欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PostgreSQL死鎖了怎么辦及處理方法

 更新時(shí)間:2023年01月13日 11:17:03   作者:慕楓技術(shù)筆記  
這篇文章主要介紹了PostgreSQL死鎖了怎么辦?本文給大家講解了死鎖原因及解決方法,介紹l避免死鎖的實(shí)戰(zhàn)建議,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下

什么是數(shù)據(jù)庫(kù)死鎖

在操作系統(tǒng)領(lǐng)域當(dāng)中,死鎖指的是兩個(gè)或者兩個(gè)以上的進(jìn)程在運(yùn)行的過(guò)程中,因?yàn)闋?zhēng)奪共同的訪問(wèn)資源而相互等待阻塞,最終造成阻礙進(jìn)程繼續(xù)執(zhí)行的一種阻塞現(xiàn)象。那么在數(shù)據(jù)庫(kù)領(lǐng)域當(dāng)中死鎖又是怎樣的表現(xiàn)形式呢?

如下圖所示,假設(shè)事務(wù)A持有行1的共享鎖,事務(wù)B持有行2的共享鎖,那么此時(shí)事務(wù)A請(qǐng)求持有行2的排他鎖,那么在事務(wù)B釋放資源之前都處于阻塞等待的狀態(tài),同樣的事務(wù)B請(qǐng)求持有行1的排他鎖,在事務(wù)A 釋放資源之前同樣也是處于阻塞等待的狀態(tài)。也就是說(shuō)事務(wù) B 完成之后事務(wù) A 才能完成,而事務(wù)A的完成又依賴于事務(wù)B的完成,這就形成了循環(huán)依賴的問(wèn)題,最終導(dǎo)致死鎖情況的發(fā)生。

如何確定死鎖位置

//先確定數(shù)據(jù)庫(kù)有沒(méi)有死鎖情況發(fā)生
select * from pg_stat_activity where datname = 'product_db';

//查詢可能鎖了的表的oid
select oid from pg_class where relname='product';

//查詢對(duì)應(yīng)的pid
select pid from pg_locks where relation='oid'  //上面查詢出來(lái)的oid

//取消或者終止對(duì)應(yīng)的進(jìn)程
select pg_cancel_backend(pid);
select pg_terminate_backend(pid);

死鎖的可能原因以及解決辦法

以上分析了PostgreSQL出現(xiàn)死鎖后如何定位分析,那么接下來(lái)就需要總結(jié)分析分析下數(shù)據(jù)庫(kù)出現(xiàn)死鎖情況的原因以及一般的應(yīng)對(duì)解決辦法。

1、索引使用問(wèn)題導(dǎo)致的死鎖問(wèn)題

索引使用存在問(wèn)題的話會(huì)導(dǎo)致死鎖問(wèn)題,假設(shè)在一個(gè)數(shù)據(jù)查詢的事務(wù)當(dāng)中,進(jìn)行數(shù)據(jù)檢索的時(shí)候沒(méi)辦法按照SQL中的where條件進(jìn)行查詢,因此導(dǎo)致了全表掃描,那么此時(shí)數(shù)據(jù)庫(kù)表的行級(jí)鎖會(huì)上升為表級(jí)鎖。如果此時(shí)有多個(gè)未能按照where條件進(jìn)行數(shù)據(jù)查詢的事務(wù)存在,那么就容易導(dǎo)致數(shù)據(jù)庫(kù)死鎖問(wèn)題。也就是說(shuō)在數(shù)據(jù)庫(kù)表數(shù)據(jù)量比較大的時(shí)候,對(duì)應(yīng)進(jìn)行數(shù)據(jù)查詢的表沒(méi)有建立索引或者說(shuō)索引創(chuàng)建的不合理導(dǎo)致無(wú)法通過(guò)索引進(jìn)行數(shù)據(jù)查詢,只能通過(guò)全表索引,這樣的場(chǎng)景下就容易產(chǎn)生死鎖。

如何避免:
在進(jìn)行數(shù)據(jù)查詢的時(shí)候,對(duì)應(yīng)的SQL語(yǔ)句不宜太過(guò)復(fù)雜,也就是說(shuō)盡量避免多張表的關(guān)聯(lián)查詢。

2、不同事務(wù)之間的訪問(wèn)順序問(wèn)題

當(dāng)用戶A 訪問(wèn)數(shù)據(jù)庫(kù)表A時(shí),此時(shí)對(duì)表A加了共享鎖,然后又訪問(wèn)數(shù)據(jù)庫(kù)表B。而此時(shí)另一個(gè)用戶B 訪問(wèn)表B,對(duì)表B加了共享鎖,然后試圖訪問(wèn)表A。但是用戶A由于用戶B已經(jīng)鎖住表B,它必須等待用戶B釋放表B才能繼續(xù),同樣用戶B要等用戶A釋放表A才能繼續(xù),也就是說(shuō)互相等待對(duì)方釋放資源,從而導(dǎo)致了死鎖的發(fā)生。

如何避免:
這種情況在實(shí)際項(xiàng)目中遇到的可能比較多,主要還是需要通過(guò)控制代碼的執(zhí)行邏輯,避免多表操作時(shí)同時(shí)鎖住多個(gè)資源。

避免死鎖的實(shí)戰(zhàn)建議

(1)如果平臺(tái)中存在大事務(wù),盡量將其拆分為小事務(wù)。因?yàn)榇笫聞?wù)一般操作的數(shù)據(jù)庫(kù)表或者數(shù)據(jù)都比較多,因此造成死鎖或者阻塞的概率就會(huì)相對(duì)較大。

(2)為數(shù)據(jù)庫(kù)表設(shè)計(jì)合理的索引,盡量避免數(shù)據(jù)查詢時(shí)索引未覆蓋或者索引失效的情況,因?yàn)槿頀呙钑?huì)會(huì)導(dǎo)致給表中的數(shù)據(jù)行上鎖,大大增加了數(shù)據(jù)庫(kù)產(chǎn)生死鎖的概率。

(3)如果業(yè)務(wù)允許,我們可以嘗試將隔離級(jí)別調(diào)低,比如將隔離級(jí)別從RR調(diào)整為RC,可以避免掉很多因?yàn)間ap鎖造成的死鎖。

補(bǔ)充:下面在看下Postgresql死鎖的處理

背景:

對(duì)表進(jìn)行所有操作都卡住,原因可能是更新表時(shí)導(dǎo)致這個(gè)表死鎖了,開(kāi)始進(jìn)行排查

解決一:查詢pg_stat_activity有沒(méi)有記錄

pg版本10.2

select pid,query,* from pg_stat_activity where datname='死鎖的數(shù)據(jù)庫(kù)' and wait_event_type = 'Lock';
select pg_cancel_backend('死鎖那條數(shù)據(jù)的pid值');##只能殺死select 語(yǔ)句, 對(duì)其他語(yǔ)句不生效
pg_terminate_backend('死鎖那條數(shù)據(jù)的pid值');#select,drop等各種操作

執(zhí)行后發(fā)現(xiàn)select和delete表時(shí)正常執(zhí)行,但truncate和drop表時(shí)會(huì)一直運(yùn)行,也不報(bào)錯(cuò)。

“drop table” 和 “truncate table” 需要申請(qǐng)排它鎖"ACCESS EXCLUSIVE", 執(zhí)行這個(gè)命令卡住時(shí),說(shuō)明此時(shí)這張表上還有操作正在進(jìn)行,比如查詢等,

那么只有等待這個(gè)查詢操作完成,“drop table” 或"truncate table"或者增加字段的SQL才能獲取這張表上的 "ACCESS EXCLUSIVE"鎖,操作才能進(jìn)行下去。

解決二:查詢pg_locks是否有這個(gè)對(duì)象的鎖

select oid,relname from pg_class where relname='table name';
select locktype,pid,relation,mode,granted,* from pg_locks where relation= '上面查詢出來(lái)的oid';
select pg_terminate_backend('進(jìn)程ID');

問(wèn)題解決?。。?/p>

坑:一開(kāi)始不知道pg_cancel_backend(‘死鎖那條數(shù)據(jù)的pid值');##只能殺死select 語(yǔ)句, 對(duì)其他語(yǔ)句不生效,殺了進(jìn)程查詢發(fā)現(xiàn)還存在,反復(fù)殺反復(fù)存在,換了pg_terminate_backend(‘進(jìn)程ID')問(wèn)題就解決了。

PS:postgresql表死鎖問(wèn)題的排查方式

1.查詢激活的執(zhí)行中的sql,查看有哪些更新update的sql。

select *
from pg_stat_activity
where state = 'active';

2. 查詢表中存在的鎖

select a.locktype, a.database, a.pid, a.mode, a.relation, b.relname
from pg_locks a
join pg_class b on a.relation = b.oid
where lower(b.relname) = 'h5_game';

3. 殺掉死鎖進(jìn)程

select pg_terminate_backend(pid)
from pg_stat_activity
where state = 'active'
and pid != pg_backend_pid()
--and pid = 14172
and pid in (select a.pid
from pg_locks a
join pg_class b on a.relation = b.oid
where lower(b.relname) = 'news_content')

鎖模式

/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
#define NoLock                 0
 
#define AccessShareLock         1        /* SELECT */
#define RowShareLock          2        /* SELECT FOR UPDATE/FOR SHARE */
#define RowExclusiveLock        3        /* INSERT, UPDATE, DELETE */
#define ShareUpdateExclusiveLock 4       /* VACUUM (non-FULL),ANALYZE, CREATE
                                         * INDEX CONCURRENTLY */
#define ShareLock                5        /* CREATE INDEX (WITHOUT CONCURRENTLY) */
#define ShareRowExclusiveLock  6        /* like EXCLUSIVE MODE, but allows ROW
                                         * SHARE */
#define ExclusiveLock          7        /* blocks ROW SHARE/SELECT...FOR
                                         * UPDATE */
#define AccessExclusiveLock       8        /* ALTER TABLE, DROP TABLE, VACUUM
                                         * FULL, and unqualified LOCK TABLE */

到此這篇關(guān)于PostgreSQL死鎖了怎么辦?的文章就介紹到這了,更多相關(guān)PostgreSQL死鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng)

    PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng)

    這篇文章主要介紹了PostgreSql生產(chǎn)級(jí)別數(shù)據(jù)庫(kù)安裝要注意事項(xiàng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • PostgreSQL timestamp踩坑記錄與填坑指南

    PostgreSQL timestamp踩坑記錄與填坑指南

    這篇文章主要介紹了PostgreSQL timestamp踩坑記錄與填坑指南,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • 在Ubuntu中安裝Postgresql數(shù)據(jù)庫(kù)的步驟詳解

    在Ubuntu中安裝Postgresql數(shù)據(jù)庫(kù)的步驟詳解

    PostgreSQL 是一款強(qiáng)大的,開(kāi)源的,對(duì)象關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)。它支持所有的主流操作系統(tǒng),包括 Linux、Unix(AIX、BSD、HP-UX,SGI IRIX、Mac OS、Solaris、Tru64) 以及 Windows 操作系統(tǒng)。本文給大家介紹了在Ubuntu中安裝Postgresql數(shù)據(jù)庫(kù)的步驟,需要的朋友可以參考下。
    2017-09-09
  • PostgreSQL 查找當(dāng)前數(shù)據(jù)庫(kù)的所有表操作

    PostgreSQL 查找當(dāng)前數(shù)據(jù)庫(kù)的所有表操作

    這篇文章主要介紹了PostgreSQL 查找當(dāng)前數(shù)據(jù)庫(kù)的所有表操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • postgresql之greenplum字符串去重拼接方式

    postgresql之greenplum字符串去重拼接方式

    這篇文章主要介紹了postgresql之greenplum字符串去重拼接方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • pgsql 實(shí)現(xiàn)分頁(yè)查詢方式

    pgsql 實(shí)現(xiàn)分頁(yè)查詢方式

    這篇文章主要介紹了pgsql 實(shí)現(xiàn)分頁(yè)查詢方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • 教你如何在Centos8-stream安裝PostgreSQL13

    教你如何在Centos8-stream安裝PostgreSQL13

    這篇文章主要介紹了Centos8-stream安裝PostgreSQL13,初始化PostgreSQL需要先創(chuàng)建postgresql儲(chǔ)存目錄,啟動(dòng)postgresql數(shù)據(jù)庫(kù),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • 在docker上部署postgreSQL主從的超詳細(xì)步驟

    在docker上部署postgreSQL主從的超詳細(xì)步驟

    使用Docker能夠更加高效地部署和管理應(yīng)用程序,提高開(kāi)發(fā)和運(yùn)維的效率,下面這篇文章主要給大家介紹了關(guān)于在docker上部署postgreSQL主從的超詳細(xì)步驟,文中通過(guò)代碼及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • 初識(shí)PostgreSQL存儲(chǔ)過(guò)程

    初識(shí)PostgreSQL存儲(chǔ)過(guò)程

    這篇文章主要介紹了初識(shí)PostgreSQL存儲(chǔ)過(guò)程,本文講解了PostgreSQL中存儲(chǔ)過(guò)程的語(yǔ)法,并給出了一個(gè)操作實(shí)例,需要的朋友可以參考下
    2015-01-01
  • PostgreSQL ROW_NUMBER() OVER()的用法說(shuō)明

    PostgreSQL ROW_NUMBER() OVER()的用法說(shuō)明

    這篇文章主要介紹了PostgreSQL ROW_NUMBER() OVER()的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02

最新評(píng)論