国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

postgresql內(nèi)核分析 spinlock與lwlock原理與實(shí)現(xiàn)機(jī)制

這篇具有很好參考價(jià)值的文章主要介紹了postgresql內(nèi)核分析 spinlock與lwlock原理與實(shí)現(xiàn)機(jī)制。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

postgresql內(nèi)核分析 spinlock與lwlock原理與實(shí)現(xiàn)機(jī)制,#  postgresql內(nèi)核源碼分析,postgresql,postgresql,數(shù)據(jù)庫(kù),linux,database,c語(yǔ)言,架構(gòu),分布式

?專欄內(nèi)容
postgresql內(nèi)核源碼分析
手寫數(shù)據(jù)庫(kù)toadb
并發(fā)編程
個(gè)人主頁(yè):我的主頁(yè)
座右銘:天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物.

========================================

概述

在postgresql 中,有大量的并發(fā)同步,所以避免不了使用很多保護(hù)鎖。
同時(shí)為了提升并發(fā)的性能,針對(duì)不同場(chǎng)景下的加鎖需求,設(shè)計(jì)了:

  • spinlock 自旋鎖
  • lightweight lock(LWLocks) 輕量級(jí)鎖
  • regular lock(a/k/a heavyweight locks) 普通鎖
  • SIReadLock predicate locks 謂詞鎖

本文主要針對(duì)這四種鎖進(jìn)行分享,起拋磚引玉的作用。

spinlock

是一種持有時(shí)間非常短的鎖。它是通過(guò)test and set 原子操作來(lái)實(shí)現(xiàn)。

通過(guò)一定時(shí)間內(nèi)的檢測(cè),如果沒(méi)有持有就獲得,這個(gè)時(shí)間大概是1min,超時(shí)就會(huì)導(dǎo)致ERR錯(cuò)誤。
所以此類鎖,都是一些狀態(tài)保護(hù),很快就釋放,中間沒(méi)有IO,大的內(nèi)存操作。

它的實(shí)現(xiàn)依賴于操作系統(tǒng)的原子操作實(shí)現(xiàn),所以通過(guò)宏定義共公接口,底層根據(jù)不同操作系統(tǒng)實(shí)現(xiàn)不同。

也可以說(shuō)是一種無(wú)鎖化的實(shí)現(xiàn),需要原子操作TAS和內(nèi)存同步。

操作函數(shù)

#define SpinLockInit(lock)	S_INIT_LOCK(lock)

#define SpinLockAcquire(lock) S_LOCK(lock)

#define SpinLockRelease(lock) S_UNLOCK(lock)

#define SpinLockFree(lock)	S_LOCK_FREE(lock)

底層操作函數(shù)有這四個(gè),是通過(guò)宏定義給出,對(duì)于不同操作系統(tǒng)下,定義了具體的原子操作。
在支持TAS 原語(yǔ)的操作系統(tǒng)上,用TAS來(lái)實(shí)現(xiàn),如加鎖的函數(shù)如下

int s_lock(volatile slock_t *lock, const char *file, int line, const char *func)
{
	SpinDelayStatus delayStatus;

	init_spin_delay(&delayStatus, file, line, func);

	while (TAS_SPIN(lock))
	{
		perform_spin_delay(&delayStatus);
	}

	finish_spin_delay(&delayStatus);

	return delayStatus.delays;
}

#define TAS_SPIN(lock)    (*(lock) ? 1 : TAS(lock))

static __inline__ int
tas(volatile slock_t *lock)
{
	slock_t		_res = 1;

	__asm__ __volatile__(
		"	lock			\n"
		"	xchgb	%0,%1	\n"
:		"+q"(_res), "+m"(*lock)
:		/* no inputs */
:		"memory", "cc");
	return (int) _res;
}

可以看到核心代碼是通過(guò)匯編實(shí)現(xiàn)TAS操作,大致流程是這樣:

  1. 檢測(cè)lock是否為0 ,如果不為0,說(shuō)明還沒(méi)有解鎖,繼續(xù)等,直到超時(shí);
  2. 如果已經(jīng)解鎖,就走入?yún)R編代碼;鎖定總線,通過(guò)xchgb 原子交換lock和_res=1 兩個(gè)值,進(jìn)行內(nèi)存同步;加鎖成功;
  3. 此時(shí)TAS_PIN返回0,等待結(jié)束;

而slock_t 是什么類型呢?
如果在支持TAS指令的操作系統(tǒng)下是如下定義

typedef unsigned char slock_t;

是一個(gè)字節(jié),這樣可以很快的檢測(cè)和原子交換賦值

注意事項(xiàng)

通過(guò)上面的原理介紹,可以看到它等待的時(shí)間非常短,這就是說(shuō)在鎖持有時(shí),不能占用太久時(shí)間。

因此,在持有spinlock時(shí),只是一些狀態(tài)的獲取和賦值,就要立即釋放,否則就會(huì)有大量超時(shí)。
在鎖持有此間,避免磁盤,網(wǎng)絡(luò),函數(shù)調(diào)用等其它額外操作。

輕量級(jí)鎖 lightweight lock

介紹

輕量級(jí)鎖將加鎖過(guò)程分成了兩個(gè)階段,第一階段通過(guò)原子操作來(lái)檢測(cè),如果可以加鎖,就加鎖成功;如果不能加鎖,進(jìn)入第二階段,將自己加入等待隊(duì)列,并阻塞在信號(hào)量上;

主要用于共享內(nèi)存和數(shù)據(jù)塊的操作保護(hù)

它因?yàn)榉至藘蓚€(gè)階段,所以較一般的系統(tǒng)級(jí)鎖性能更高效一些。
它提供了如下特點(diǎn):

  • 能夠快速檢測(cè)鎖狀態(tài),并且獲取到鎖;
  • 每個(gè)后臺(tái)進(jìn)程只能有一個(gè)排隊(duì)中的輕量級(jí)鎖;
  • 在持有鎖期間,信號(hào)會(huì)被阻塞
  • 在錯(cuò)誤時(shí)會(huì)釋放鎖;

數(shù)據(jù)結(jié)構(gòu)

typedef struct LWLock
{
	uint16		tranche;		/* tranche ID */
	pg_atomic_uint32 state;		/* state of exclusive/nonexclusive lockers */
	proclist_head waiters;		/* list of waiting PGPROCs */
#ifdef LOCK_DEBUG
	pg_atomic_uint32 nwaiters;	/* number of waiters */
	struct PGPROC *owner;		/* last exclusive owner of the lock */
#endif
} LWLock;

extern bool LWLockAcquire(LWLock *lock, LWLockMode mode);
extern bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode);
extern bool LWLockAcquireOrWait(LWLock *lock, LWLockMode mode);
extern void LWLockRelease(LWLock *lock);

初始化

加鎖

  • 判斷是否已經(jīng)持有鎖數(shù)量,超過(guò)上限;阻塞信號(hào)中斷;
  • 第一階段 嘗試加鎖,加上時(shí)直接返回鎖;否則將自己放入等待隊(duì)列;再次嘗試加鎖;
  • 第二階段 如果仍沒(méi)有獲取到鎖時(shí),在當(dāng)前backend對(duì)應(yīng)的 MyProc中的信號(hào)量上進(jìn)行等待;

直到被喚醒,如果proc->lwWaiting == LW_WS_NOT_WAITING時(shí),繼續(xù)等待;

  • 當(dāng)獲取到鎖時(shí),將鎖加入自己持有鎖的數(shù)組中記錄;

解鎖

從本等數(shù)據(jù)中獲取當(dāng)前鎖的加鎖模式; 從鎖中解除;
如果有等待者,將它們從等待隊(duì)列中移除,然后喚醒它們;等待者們將再次競(jìng)爭(zhēng);

等待鎖釋放

bool
LWLockAcquireOrWait(LWLock *lock, LWLockMode mode);
  • 介紹

這個(gè)接口有點(diǎn)意思,即可以獲取鎖,也用來(lái)等待別人釋放鎖;

當(dāng)前鎖如果沒(méi)有被占用,則占有鎖后函數(shù)返回;
如果當(dāng)前鎖被占用,則等待鎖,等別人釋放鎖后,就直接返回,而不持有鎖。

  • 用途

這個(gè)函數(shù)主要用來(lái)在寫WAL時(shí),獲取鎖,因?yàn)橥瑫r(shí)只能有一個(gè)進(jìn)程寫WAL;
如果當(dāng)前沒(méi)有人寫WAL,則持有鎖后,執(zhí)行WAL寫入。
如果當(dāng)前已經(jīng)有人持有鎖,在寫WAL,那么自己的WAL也會(huì)被寫入,因?yàn)閃AL是順序?qū)懭?,后寫時(shí),需要把前面的內(nèi)容都要寫入。

條件變量

static bool LWLockConflictsWithVar(LWLock *lock,
					   uint64 *valptr, uint64 oldval, uint64 *newval,
					   bool *result)
bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval);
void LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 val);

基于輕量級(jí)鎖,又實(shí)現(xiàn)了一組類似于條件變量的接口;

LWLockWaitForVar檢測(cè)變量是否變化,如果沒(méi)人持有鎖,那就直接返回;如果有鎖,則等待,直到鎖釋放后,返回新值;
LWLockUpdateVar是改變變量的值,并通知等待者,喚醒等待者;

鎖排隊(duì)

lightweiht lock可能會(huì)長(zhǎng)時(shí)間等待,因此每個(gè)backend只能有一個(gè)正在等待的輕量級(jí)鎖,所以每個(gè)backend都會(huì)有一個(gè)信號(hào)量;

struct PGPROC
{
	// other members ... 
	PGSemaphore sem;			/* ONE semaphore to sleep on */
	// other members ... 
};

信號(hào)量定義在PROC結(jié)構(gòu)上,當(dāng)進(jìn)入信號(hào)量等待時(shí),同時(shí)也會(huì)把自己的MyProc添加到 lock->waiters 列表成員中。

在鎖持有者釋放鎖時(shí),會(huì)刪除隊(duì)列中的所有成員,同時(shí)喚醒等待者的信號(hào)量;

在介紹了排隊(duì)和釋放后,就會(huì)發(fā)現(xiàn)它存在兩個(gè)問(wèn)題:

  • 等鎖的餓死問(wèn)題
  • 驚群?jiǎn)栴}

當(dāng)然lwlock 隊(duì)列的喚醒也是順序喚醒,同時(shí)加鎖分為兩階段,這就在一定程度上避免了上述問(wèn)題。

另外lwlock加鎖是非常頻,可能在很短時(shí)間有加鎖/釋放,所以需要更簡(jiǎn)潔直接的加鎖方式。

結(jié)尾

非常感謝大家的支持,在瀏覽的同時(shí)別忘了留下您寶貴的評(píng)論,如果覺(jué)得值得鼓勵(lì),請(qǐng)點(diǎn)贊,收藏,我會(huì)更加努力!

作者郵箱:study@senllang.onaliyun.com
如有錯(cuò)誤或者疏漏歡迎指出,互相學(xué)習(xí)。

注:未經(jīng)同意,不得轉(zhuǎn)載!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-537244.html

到了這里,關(guān)于postgresql內(nèi)核分析 spinlock與lwlock原理與實(shí)現(xiàn)機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • postgresql15 內(nèi)核源碼分析-buffer查找接口

    postgresql15 內(nèi)核源碼分析-buffer查找接口

    ? ? 專欄內(nèi)容:postgresql內(nèi)核源碼分析 個(gè)人主頁(yè):我的主頁(yè) 座右銘:天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物. 目錄 前言 概述 接口介紹 調(diào)用場(chǎng)景分析 詳細(xì)分解 結(jié)尾 本文是基于postgresql 15的代碼進(jìn)行分析解讀,演示是在centos8系統(tǒng)上進(jìn)行。 ? 在postgresql中,SQL引擎

    2023年04月09日
    瀏覽(25)
  • 【Linux 內(nèi)核源碼分析】RCU機(jī)制

    【Linux 內(nèi)核源碼分析】RCU機(jī)制

    Linux內(nèi)核的RCU(Read-Copy-Update)機(jī)制是一種用于實(shí)現(xiàn)高效讀取和并發(fā)更新數(shù)據(jù)結(jié)構(gòu)的同步機(jī)制。它在保證讀操作不被阻塞的同時(shí),也能夠保證數(shù)據(jù)的一致性。 RCU的核心思想是通過(guò)延遲資源釋放來(lái)實(shí)現(xiàn)無(wú)鎖讀取,并且避免了傳統(tǒng)鎖帶來(lái)的爭(zhēng)用和開銷。具體而言,RCU維護(hù)了一個(gè)“回

    2024年01月15日
    瀏覽(18)
  • postgresql 內(nèi)核源碼分析 btree索引插入分析,索引頁(yè)面分裂流程,多舉措進(jìn)行并發(fā)優(yōu)化,對(duì)異常進(jìn)行保護(hù)處理

    postgresql 內(nèi)核源碼分析 btree索引插入分析,索引頁(yè)面分裂流程,多舉措進(jìn)行并發(fā)優(yōu)化,對(duì)異常進(jìn)行保護(hù)處理

    ? 專欄內(nèi)容 : postgresql內(nèi)核源碼分析 手寫數(shù)據(jù)庫(kù)toadb 并發(fā)編程 ? 開源貢獻(xiàn) : toadb開源庫(kù) 個(gè)人主頁(yè) :我的主頁(yè) 管理社區(qū) :開源數(shù)據(jù)庫(kù) 座右銘:天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物. B樹索引在PostgreSQL中得到了廣泛應(yīng)用,它是一種自平衡樹數(shù)據(jù)結(jié)構(gòu),可以維

    2024年02月08日
    瀏覽(34)
  • Linux內(nèi)核源碼分析 (6)RCU機(jī)制及內(nèi)存優(yōu)化屏障

    問(wèn)題: RCU 英文全稱為 Read-Copy-Update ,顧名思義就是 讀-拷貝-更新 ,是 Linux 內(nèi)核中重要的同步機(jī)制。 Linux 內(nèi)核已有原子操作、讀寫信號(hào)量等鎖機(jī)制,為什么要單獨(dú)設(shè)計(jì)一個(gè)比較復(fù)雜的新機(jī)制? RCU的原理 RCU記錄所有指向共享數(shù)據(jù)的指針的使用者,當(dāng)要修改該共享數(shù)據(jù)時(shí),首先

    2024年02月10日
    瀏覽(32)
  • postgresql 內(nèi)核源碼分析 表鎖relation lock的使用,session lock會(huì)話鎖的應(yīng)用場(chǎng)景,操作表不再困難

    postgresql 內(nèi)核源碼分析 表鎖relation lock的使用,session lock會(huì)話鎖的應(yīng)用場(chǎng)景,操作表不再困難

    ? 專欄內(nèi)容 : postgresql內(nèi)核源碼分析 手寫數(shù)據(jù)庫(kù)toadb 并發(fā)編程 個(gè)人主頁(yè) :我的主頁(yè) 座右銘:天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物. ================================================================== 當(dāng)表打開,或者操作表時(shí),都需要對(duì)表relation 進(jìn)行加鎖,表鎖定義了8種級(jí)互

    2024年02月16日
    瀏覽(24)
  • 【postgresql 基礎(chǔ)入門】表的約束(二) 唯一unique、非空not null、check、exclusion約束,原理機(jī)制以及多列組合約束

    ? 專欄內(nèi)容 : postgresql內(nèi)核源碼分析 手寫數(shù)據(jù)庫(kù)toadb 并發(fā)編程 個(gè)人主頁(yè) :我的主頁(yè) 管理社區(qū) :開源數(shù)據(jù)庫(kù) 座右銘:天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物. 在數(shù)據(jù)庫(kù)中,數(shù)據(jù)類型可以限制數(shù)據(jù)存儲(chǔ)的大小,也能在一定程度上限制存儲(chǔ)的數(shù)據(jù)種類,但是對(duì)于數(shù)

    2024年04月08日
    瀏覽(17)
  • 《Linux內(nèi)核源碼分析》(2)進(jìn)程原理及系統(tǒng)調(diào)用

    《Linux內(nèi)核源碼分析》(2)進(jìn)程原理及系統(tǒng)調(diào)用

    操作系統(tǒng)的作用 :作為硬件的使用層,提供使用硬件資源的能力, 進(jìn)程的作用 :作為操作系統(tǒng)使用層,提供使用操作系統(tǒng)抽象出的資源層的能力 進(jìn)程、線程和程序的區(qū)別 :進(jìn)程指計(jì)算機(jī)中已運(yùn)行的程序。進(jìn)程本身不是基本的運(yùn)行單位,而是線程的容器。 程序本身只是指令

    2024年02月07日
    瀏覽(35)
  • Spark重溫筆記(三):Spark在企業(yè)中為什么能這么強(qiáng)?——持久化、Checkpoint機(jī)制、共享變量與內(nèi)核調(diào)度原理全攻略“

    前言:今天是溫習(xí) Spark 的第 3 天啦!主要梳理了 Spark 核心數(shù)據(jù)結(jié)構(gòu):RDD(彈性分布式數(shù)據(jù)集),包括RDD持久化,checkpoint機(jī)制,spark兩種共享變量以及spark內(nèi)核調(diào)度原理,希望對(duì)大家有幫助! Tips:\\\"分享是快樂(lè)的源泉??,在我的博客里,不僅有知識(shí)的海洋??,還有滿滿的正能量

    2024年04月09日
    瀏覽(32)
  • Linux源碼解讀系列是一套深入剖析Linux內(nèi)核源碼的教程,旨在幫助讀者理解Linux操作系統(tǒng)的底層原理和工作機(jī)制

    Linux源碼解讀系列是一套深入剖析Linux內(nèi)核源碼的教程,旨在幫助讀者理解Linux操作系統(tǒng)的底層原理和工作機(jī)制

    Linux源碼解讀系列是一套深入剖析Linux內(nèi)核源碼的教程,旨在幫助讀者理解Linux操作系統(tǒng)的底層原理和工作機(jī)制。該系列教程從Linux內(nèi)核的各個(gè)模塊入手,逐一分析其源碼實(shí)現(xiàn),并結(jié)合實(shí)際應(yīng)用場(chǎng)景進(jìn)行講解。通過(guò)學(xué)習(xí)本系列,讀者可以深入了解Linux操作系統(tǒng)的底層機(jī)制,掌握

    2024年01月21日
    瀏覽(26)
  • SpringBoot源碼解讀與原理分析(五)SpringBoot的裝配機(jī)制

    SpringBoot源碼解讀與原理分析(五)SpringBoot的裝配機(jī)制

    前面三小節(jié)分別介紹了Spring Framewoek的模塊裝配、條件裝配和SPI機(jī)制。下面正式進(jìn)入Spring Boot的裝配機(jī)制。 實(shí)際上, Spring Boot的自動(dòng)裝配是模塊裝配+條件裝配+SPI機(jī)制的組合使用 ,而這一切都凝聚在Spring Boot主啟動(dòng)類的@SpringBootApplication注解上。 @SpringBootApplication注解是由三個(gè)注

    2024年02月19日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包