天天看點

PostgreSQL 使用advisory lock或skip locked消除行鎖沖突, 提高幾十倍并發更新效率

digoal

2016-10-18

postgresql , advisory lock , 高并發更新

通常在資料庫中最小粒度的鎖是行鎖,當一個事務正在更新某條記錄時,另一個事務如果要更新同一條記錄(或者申請這一條記錄的鎖),則必須等待鎖釋放。

通常持鎖的時間需要保持到事務結束,也就是說,如果一個長事務持有了某條記錄的鎖,其他會話要持有這條記錄的鎖,可能要等很久。

如果某張表的全表或者大部分記錄要被更新的話,有幾種做法。

1. 在一個事務中更新需要更新的記錄,很顯然時間可能很長,因為沒有了并發。

2. 在多個事務中更新不同的記錄,使用高并發來縮短更新的時間,但是就需要解決并發更新時存在的行鎖沖突的問題。

本文将要給大家介紹兩種解決并發更新行鎖沖突問題的方法。

測試表,單條記錄越大,更新單條記錄的時間越久(例如更新億級别的超長bit類型)。

每個人群都有一個唯一的id,即parallel_update_test.id。

測試資料

更新需求,每條記錄都有更新

例如我存儲的數組是userid,每條記錄代表某個屬性的人群資料,這個屬性的人群資料不斷的在變化,是以會不斷的需要更新。

使用并發的手段提高更新效率。

是以隻要保證并行的會話更新的是不同的id對應的資料即可,同時需要避免單次重複更新。

使用advisory lock可以避免并發更新同一條記錄。

使用掃描式的擷取advisory lock,保證不會重複擷取即可。

代碼如下:

設計上盡量保證id全局唯一,否則擷取advisory lock的沖突可能性會增多。

測試,使用100個并行度

并行更新耗時4秒

這個方法需要9.5以及以上版本支援

使用100個并行度

在實時推薦系統中,通常可以使用數組或者比特位來标記人群,而每個人群都在不斷的發生變化,也就是說,整張表都是熱表。

為了提高更新的效率,本文給大家提供了兩種并行消除行鎖沖突更新的方法。

使用postgresql提供的skip locked 或者advisory lock特性,消除行鎖沖突,提高并行度,進而提高更新效率,發揮機器的最大能力。

<a href="http://info.flagcounter.com/h9v1">count</a>