改進PostgreSQL鎖機制

2021-07-07 01:25:12 字數 2008 閱讀 7084

如果你想構建乙個大規模的**,單憑橫向擴充套件web伺服器是遠遠不夠的。如何巧妙地管理資料庫也是非常必要的。在postgresql中,借助於併發性的改進,通過減少鎖及加速執行得到若干令人滿意的特性。

如果你想構建乙個大規模的**,單憑橫向擴充套件web伺服器是遠遠不夠的。如何巧妙地管理資料庫也是非常必要的。鎖(locking)便是實現**高擴充套件性的乙個關鍵。

在postgresql中,借助於併發性的改進,通過減少鎖及加速執行得到若干令人滿意的特性。

一般推薦的做法是:在解決鎖問題之前,無論如何先要檢查出在你的postgresql資料庫伺服器上正在執行的是什麼,這非常有必要。我建議參考pg_stat_statements並仔細地檢查系統瓶頸(bottleneck)。下面是給出的是其執行機制:

改進select for update語句

假設兩人同時試圖修改資料庫中同一行的內容,每個使用者會首先選擇(select)一行來檢查它的內容,然後開始更新。令人討厭的事情是:這兩個使用者很可能會找到原來的行並且覆蓋彼此做的改變。這是乙個經典的競態事件。

在現實生活中,這樣會導致惡劣的後果:例如兩個人也許會預定了同一架飛機的同乙個航班;或者取款時取出的錢可能會比帳戶中實際的數額更多。這顯然不是我們想要的。

再拿前面的航班機票預定為例,假設有人想要預定飛機的某一座位:

select ...

from table

where class = 'economy'

and empty = true

limit 1

for update

現在的麻煩是:如果另外乙個人也試圖搶占乙個座位,他會發現該座位已經被第乙個人選擇。但是,這一行是被鎖定的。第二個人的select for update操作必須等到第乙個人的事務處理完成。值得提醒的是,乘客可能非常樂意接受該航班上的其它任意座位,所以沒有必要等待某個特定的座位。

postgresql 9.5將會解決這一問題。下面是一種新的讀取行的方式:

select ...

from table

where class = 'economy'

and empty = true

limit 1

for update skip locked

這裡的巧妙之處在於postgresql將會簡單地忽略被鎖定的行,並返回乙個沒有被別人鎖定的行。這樣是非常有意義的,因為100個同時在檢視乙個免費座位的使用者會得到100個不同的行。這樣的結果是你沒有死守乙個cpu,而是巧妙地橫向擴充套件了系統中的所有cpu。由於衝突不再發生,沒有人必須等其他人。

select for share

還有一種可以使postgresql提供更高併發的方法。看下面的例子:

select *

from account as a, currency as c

where a.currency = c.id

and a.account = 4711

for update

在這個例子中,某人想檢視他的銀行賬戶。現在主要的問題是:哪些行是被鎖定的?答案是:account和currency。僅僅因為乙個人想從atm中取錢而鎖定整個currency表顯然並不是個好辦法,而應該讓很多人可以同時取錢,在這一問題上,postgresql的解決方法是提前告知需要更新哪張表。

方法很簡單:

for update of account for share of currency

通過告訴postgresql我們要做的事情,postgresql資料庫會在currency表上使用乙個無害的鎖。這樣大部分人可以同時檢視相同的currency而無需相互鎖定,同時又保證了account表的安全。

併發就是一切

請記住:如果你只有單個cpu,併發將會是問題。因此,多個cpu能夠同時進行資源共享在某種程上來講是很有必要的。

譯者簡介:牛亞真,中科院計算機資訊處理專業碩士研究生,關注大資料技術和資料探勘方向。

測試postgreSQL中表鎖

檢視視窗連線到的服務程序的pid。select pg backend pid 三個視窗的pid分別如下 select locktype,relation regclass,virtualxid,transactionid,virtualtransaction pid,mode,granted fro...

postgresql解決鎖表

查詢是否鎖表了 select oid from pg class where relname 可能鎖表了的表 select pid from pg locks where relation 上面查出的oid 如果查詢到了結果,表示該錶被鎖 則需要釋放鎖定 select pg cancel backe...

python鎖機制 python 鎖機制

當有兩個或跟多個執行緒或程序需要操作乙個變數或程序時,會出現意想不到的結果,這是因為執行緒或程序時迸發進行的,對同意變數或檔案操作時,會出現同時對其操作,從到導致邏輯錯誤。bin usr env python coding utf 8 import multiprocessing import ti...