PostgreSQL 動(dòng)態(tài)追蹤

2021-09-01 17:21 更新
27.5.1. 動(dòng)態(tài)追蹤的編譯
27.5.2. 內(nèi)建探針
27.5.3. 使用探針
27.5.4. 定義新探針

PostgreSQL提供了功能來(lái)支持?jǐn)?shù)據(jù)庫(kù)服務(wù)器的動(dòng)態(tài)追蹤。這樣就允許在代碼中的特 定點(diǎn)上調(diào)用外部工具來(lái)追蹤執(zhí)行過(guò)程。

一些探針或追蹤點(diǎn)已經(jīng)被插入在源代碼中。這些探針的目的是被數(shù)據(jù)庫(kù)開(kāi)發(fā)者和管理員使用。默認(rèn)情況下,探針不被編譯到PostgreSQL中;用戶(hù)需要顯式地告訴配置腳本使得探針可用。

目前,在寫(xiě)本文當(dāng)時(shí)DTrace已被支持,它在 Solaris、macOS、FreeBSD、NetBSD 和 Oracle Linux 上可用。 Linux 的SystemTap項(xiàng)目提供了一種可用的 DTrace 等價(jià)物。支持其他動(dòng)態(tài)追蹤工具在理論上可以通過(guò)改變src/include/utils/probes.h中的宏定義實(shí)現(xiàn)。

27.5.1. 動(dòng)態(tài)追蹤的編譯

默認(rèn)情況下,探針是不可用的,因此你將需要顯式地告訴配置腳本讓探針在PostgreSQL中可用。要包括 DTrace 支持,在配置時(shí)指定--enable-dtrace。更多信息請(qǐng)見(jiàn)第 16.4 節(jié)。

27.5.2. 內(nèi)建探針

如表 27.42所示,源代碼中提供了一些標(biāo)準(zhǔn)探針。表 27.43顯式了在探針中使用的類(lèi)型。當(dāng)然,可以增加更多探針來(lái)增強(qiáng) PostgreSQL的可觀測(cè)性。

表 27.42. 內(nèi)建 DTrace 探針

名稱(chēng) 參數(shù) 描述
transaction-start (LocalTransactionId) 在一個(gè)新事務(wù)開(kāi)始時(shí)觸發(fā)的探針。arg0 是事務(wù) ID。
transaction-commit (LocalTransactionId) 在一個(gè)事務(wù)成功完成時(shí)觸發(fā)的探針。arg0 是事務(wù) ID。
transaction-abort (LocalTransactionId) 當(dāng)一個(gè)事務(wù)失敗完成時(shí)觸發(fā)的探針。arg0 是事務(wù) ID。
query-start (const char *) 當(dāng)一個(gè)查詢(xún)的處理被開(kāi)始時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-done (const char *) 當(dāng)一個(gè)查詢(xún)的處理完成時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-parse-start (const char *) 當(dāng)一個(gè)查詢(xún)的解析被開(kāi)始時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-parse-done (const char *) 當(dāng)一個(gè)查詢(xún)的解析完成時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-rewrite-start (const char *) 當(dāng)一個(gè)查詢(xún)的重寫(xiě)被開(kāi)始時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-rewrite-done (const char *) 當(dāng)一個(gè)查詢(xún)的重寫(xiě)完成時(shí)觸發(fā)的探針。arg0 是查詢(xún)字符串。
query-plan-start () 當(dāng)一個(gè)查詢(xún)的規(guī)劃被開(kāi)始時(shí)觸發(fā)的探針。
query-plan-done () 當(dāng)一個(gè)查詢(xún)的規(guī)劃完成時(shí)觸發(fā)的探針。
query-execute-start () 當(dāng)一個(gè)查詢(xún)的執(zhí)行被開(kāi)始時(shí)觸發(fā)的探針。
query-execute-done () 當(dāng)一個(gè)查詢(xún)的執(zhí)行完成時(shí)觸發(fā)的探針。
statement-status (const char *) 任何時(shí)候當(dāng)服務(wù)器進(jìn)程更新它的pg_stat_activity.status時(shí)觸發(fā)的探針。arg0 是新的狀態(tài)字符串。
checkpoint-start (int) 當(dāng)一個(gè)檢查點(diǎn)被開(kāi)始時(shí)觸發(fā)的探針。arg0 傳遞位標(biāo)志來(lái)區(qū)分不同的檢查點(diǎn)類(lèi)型,例如關(guān)閉(shutdown)、立即(immediate)或強(qiáng)制(force)。
checkpoint-done (int, int, int, int, int) 當(dāng)一個(gè)檢查點(diǎn)完成時(shí)觸發(fā)的探針(檢查點(diǎn)處理過(guò)程中序列中列出的下一個(gè)觸發(fā)的探針)。arg0 是要寫(xiě)的緩沖區(qū)數(shù)量。arg1 是緩沖區(qū)的總數(shù)。arg2、arg3 和 arg4 分別包含了增加、刪除和循環(huán)回收的 WAL 文件的數(shù)量。
clog-checkpoint-start (bool) 當(dāng)一個(gè)檢查點(diǎn)的 CLOG 部分被開(kāi)始時(shí)觸發(fā)的探針。arg0 為真表示正常檢查點(diǎn),為假表示關(guān)閉檢查點(diǎn)。
clog-checkpoint-done (bool) 當(dāng)一個(gè)檢查點(diǎn)的 CLOG 部分完成時(shí)觸發(fā)的探針。arg0 的含義與clog-checkpoint-start中相同。
subtrans-checkpoint-start (bool) 當(dāng)一個(gè)檢查點(diǎn)的 SUBTRANS 部分被開(kāi)始時(shí)觸發(fā)的探針。arg0 為真表示正常檢查點(diǎn),為假表示關(guān)閉檢查點(diǎn)。
subtrans-checkpoint-done (bool) 當(dāng)一個(gè)檢查點(diǎn)的 SUBTRANS 部分完成時(shí)觸發(fā)的探針。arg0 的含義與subtrans-checkpoint-start中相同。
multixact-checkpoint-start (bool) 當(dāng)一個(gè)檢查點(diǎn)的 MultiXact 部分被開(kāi)始時(shí)觸發(fā)的探針。arg0 為真表示正常檢查點(diǎn),為假表示關(guān)閉檢查點(diǎn)。
multixact-checkpoint-done (bool) 當(dāng)一個(gè)檢查點(diǎn)的 MultiXact 部分完成時(shí)觸發(fā)的探針。arg0 的含義與multixact-checkpoint-start中相同。
buffer-checkpoint-start (int) 當(dāng)一個(gè)檢查點(diǎn)的寫(xiě)緩沖區(qū)部分被開(kāi)始時(shí)觸發(fā)的探針。arg0 傳遞位標(biāo)志來(lái)區(qū)分不同的檢查點(diǎn)類(lèi)型,例如關(guān)閉(shutdown)、立即(immediate)或強(qiáng)制(force)。
buffer-sync-start (int, int) 當(dāng)我們?cè)跈z查點(diǎn)期間開(kāi)始寫(xiě)臟緩沖區(qū)時(shí)(在標(biāo)識(shí)哪些緩沖區(qū)必須被寫(xiě)之后)觸發(fā)的探針。arg0 是緩沖區(qū)總數(shù),arg1 是當(dāng)前為臟并且需要被寫(xiě)的緩沖區(qū)數(shù)量。
buffer-sync-written (int) 在檢查點(diǎn)期間當(dāng)每個(gè)緩沖區(qū)被寫(xiě)完之后觸發(fā)的探針。arg0 是緩沖區(qū)的 ID。
buffer-sync-done (int, int, int) 當(dāng)所有臟緩沖區(qū)被寫(xiě)之后觸發(fā)的探針。arg0 是緩沖區(qū)總數(shù)。arg1 是檢查點(diǎn)進(jìn)程實(shí)際寫(xiě)的緩沖區(qū)數(shù)量。arg2 是期望寫(xiě)的數(shù)目(buffer-sync-start的 arg1);arg1 和 arg2 的任何的不同反映在該檢查點(diǎn)期間有其他進(jìn)程刷寫(xiě)了緩沖區(qū)。
buffer-checkpoint-sync-start () 在臟緩沖區(qū)被寫(xiě)入到內(nèi)核之后并且在開(kāi)始發(fā)出 fsync 請(qǐng)求之前觸發(fā)的探針。
buffer-checkpoint-done () 當(dāng)同步緩沖區(qū)到磁盤(pán)完成時(shí)觸發(fā)的探針。
twophase-checkpoint-start () 當(dāng)一個(gè)檢查點(diǎn)的兩階段部分被開(kāi)始時(shí)觸發(fā)的探針。
twophase-checkpoint-done () 當(dāng)一個(gè)檢查點(diǎn)的兩階段部分完成時(shí)觸發(fā)的探針。
buffer-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) 當(dāng)一次緩沖區(qū)讀被開(kāi)始時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)(如果這是一次關(guān)系擴(kuò)展請(qǐng)求,arg1 為 -1)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。對(duì)一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端的 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是 InvalidBackendId(-1)。arg6 為真表示一次關(guān)系擴(kuò)展請(qǐng)求,為假表示正常讀。
buffer-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) 當(dāng)一次緩沖區(qū)讀完成時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)(如果這是一次關(guān)系擴(kuò)展請(qǐng)求,arg1 現(xiàn)在包含新增加塊的塊號(hào))。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。對(duì)一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端的 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是 InvalidBackendId(-1)。arg6 為真表示一次關(guān)系擴(kuò)展請(qǐng)求,為假表示正常讀。arg7 為真表示在池中找到該緩沖區(qū),為假表示沒(méi)有找到。
buffer-flush-start (ForkNumber, BlockNumber, Oid, Oid, Oid) 在發(fā)出對(duì)一個(gè)共享緩沖區(qū)的任意寫(xiě)請(qǐng)求之前觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。
buffer-flush-done (ForkNumber, BlockNumber, Oid, Oid, Oid) 當(dāng)一個(gè)寫(xiě)請(qǐng)求完成時(shí)觸發(fā)的探針(注意這只反映傳遞數(shù)據(jù)給內(nèi)核的時(shí)間,它通常并沒(méi)有實(shí)際地被寫(xiě)入到磁盤(pán))。參數(shù)和buffer-flush-start的相同。
buffer-write-dirty-start (ForkNumber, BlockNumber, Oid, Oid, Oid) 當(dāng)一個(gè)服務(wù)器進(jìn)程開(kāi)始寫(xiě)一個(gè)臟緩沖區(qū)時(shí)觸發(fā)的探針(如果這經(jīng)常發(fā)生,表示shared_buffers太小,或需要調(diào)整后臺(tái)寫(xiě)入器的控制參數(shù))。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。
buffer-write-dirty-done (ForkNumber, BlockNumber, Oid, Oid, Oid) 當(dāng)一次臟緩沖區(qū)寫(xiě)完成時(shí)觸發(fā)的探針。參數(shù)與buffer-write-dirty-start相同。
wal-buffer-write-dirty-start () 當(dāng)一個(gè)服務(wù)器進(jìn)程因?yàn)闆](méi)有可用 WAL 緩沖區(qū)空間開(kāi)始寫(xiě)一個(gè)臟 WAL 緩沖區(qū)時(shí)觸發(fā)的探針(如果這經(jīng)常發(fā)生,表示wal_buffers太?。?。
wal-buffer-write-dirty-done () 當(dāng)一次臟 WAL 緩沖區(qū)完成時(shí)觸發(fā)的探針。
wal-insert (unsigned char, unsigned char) 當(dāng)一個(gè) WAL 記錄被插入時(shí)觸發(fā)的探針。arg0 是該記錄的資源管理者(rmid)。arg1 包含 info 標(biāo)志。
wal-switch () 當(dāng)請(qǐng)求一次 WAL 段切換時(shí)觸發(fā)的探針。
smgr-md-read-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) 當(dāng)開(kāi)始從一個(gè)關(guān)系讀取一塊時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。對(duì)一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端的 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是InvalidBackendId(-1)。
smgr-md-read-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) 當(dāng)一次塊讀取完成時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。對(duì)一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端的 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是InvalidBackendId(-1)。arg6 是實(shí)際讀取的字節(jié)數(shù),而 arg7 是請(qǐng)求讀取的字節(jié)數(shù)(如果兩者不同就意味著麻煩)。
smgr-md-write-start (ForkNumber, BlockNumber, Oid, Oid, Oid, int) 當(dāng)開(kāi)始向一個(gè)關(guān)系中寫(xiě)入一個(gè)塊時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3 和 arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID 用以識(shí)別該關(guān)系。對(duì)一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端的 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是InvalidBackendId(-1)。
smgr-md-write-done (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) 當(dāng)一個(gè)塊寫(xiě)操作完成時(shí)觸發(fā)的探針。arg0 和 arg1 包含該頁(yè)的分叉號(hào)和塊號(hào)。arg2、arg3和arg4 包含表空間、數(shù)據(jù)庫(kù)和關(guān)系 OID來(lái)標(biāo)識(shí)該關(guān)系。對(duì)于一個(gè)本地緩沖區(qū),arg5 是創(chuàng)建臨時(shí)關(guān)系的后端 ID;對(duì)于一個(gè)共享緩沖區(qū),arg5 是InvalidBackendId(-1)。arg6 是實(shí)際寫(xiě)的字節(jié)數(shù),而 arg7 是要求寫(xiě)的字節(jié)數(shù)(如果這兩者不同,則意味著麻煩)。
sort-start (int, bool, int, int, bool, int) 當(dāng)一次排序操作開(kāi)始時(shí)觸發(fā)的探針。arg0 指示是堆排序、索引排序或數(shù)據(jù)排序。arg1 為真表示唯一值強(qiáng)制。arg2 是鍵列的數(shù)目。arg3 是允許使用的工作內(nèi)存數(shù)(以千字節(jié)計(jì))。如果要求隨機(jī)訪(fǎng)問(wèn)排序結(jié)果,那么 arg4 為真。arg5為0時(shí)表示串行,為1時(shí)表示并行工作者,為2時(shí)表示并行領(lǐng)袖。
sort-done (bool, long) 當(dāng)一次排序完成時(shí)觸發(fā)的探針。arg0 為真表示外排序,為假表示內(nèi)排序。arg1 是用于一次外排序的磁盤(pán)塊的數(shù)目,或用于一次內(nèi)排序的以千字節(jié)計(jì)的內(nèi)存。
lwlock-acquire (char *, LWLockMode) 當(dāng)成功獲得一個(gè) LWLock 時(shí)觸發(fā)的探針。 arg0 是該 LWLock 所在的切片(Tranche)。 arg1 所請(qǐng)求的鎖模式,是排他或共享。
lwlock-release (char *) 當(dāng)一個(gè) LWLock 被釋放時(shí)(但是注意還沒(méi)有喚醒任何一個(gè)被釋放的等待者)觸發(fā)的探針。 arg0 是該 LWLock 所在的切片(Tranche)。
lwlock-wait-start (char *, LWLockMode) 當(dāng)一個(gè) LWLock不是當(dāng)即可用并且一個(gè)服務(wù)器進(jìn)程因此開(kāi)始等待該鎖變?yōu)榭捎脮r(shí)觸發(fā)的探針。 arg0 是該 LWLock 所在的切片(Tranche)。 arg1 請(qǐng)求的鎖模式,是排他或共享。
lwlock-wait-done (char *, LWLockMode) 當(dāng)一個(gè)進(jìn)程從對(duì)一個(gè) LWLock 的等待中被釋放時(shí)(它實(shí)際還沒(méi)有得到該鎖)時(shí)觸發(fā)的探針。arg0 是該 LWLock 所在的切片(Tranche)。 arg1 所請(qǐng)求的鎖模式,是排他或共享。
lwlock-condacquire (char *, LWLockMode) 當(dāng)調(diào)用者指定無(wú)需等待而成功獲得一個(gè) LWLock 時(shí)觸發(fā)的探針。arg0 是該 LWLock 所在的切片(Tranche)。 arg1 所請(qǐng)求的鎖模式,是排他或共享。
lwlock-condacquire-fail (char *, LWLockMode) 當(dāng)調(diào)用者指定無(wú)需等待而沒(méi)有成功獲得一個(gè) LWLock 時(shí)觸發(fā)的探針。arg0 是該 LWLock 所在的切片(Tranche)。 arg1 所請(qǐng)求的鎖模式,是排他或共享。
lock-wait-start (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) 當(dāng)一個(gè)重量級(jí)鎖(lmgr鎖)的請(qǐng)求由于鎖不可用開(kāi)始等待時(shí)觸發(fā)的探針。arg0 到 arg3 是標(biāo)識(shí)被鎖定對(duì)象的標(biāo)簽域。arg4 指示被鎖對(duì)象的類(lèi)型。arg5 表示被請(qǐng)求的鎖類(lèi)型。
lock-wait-done (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) 當(dāng)一個(gè)重量級(jí)鎖(lmgr 鎖)的請(qǐng)求結(jié)束等待時(shí)(即已經(jīng)得到鎖)觸發(fā)的探針。參數(shù)與lock-wait-start一樣。
deadlock-found () 當(dāng)死鎖檢測(cè)器發(fā)現(xiàn)死鎖時(shí)觸發(fā)的探針。

表 27.43. 定義用在探針參數(shù)中的類(lèi)型

類(lèi)型 定義
LocalTransactionId unsigned int
LWLockMode int
LOCKMODE int
BlockNumber unsigned int
Oid unsigned int
ForkNumber int
bool unsigned char

27.5.3. 使用探針

下面的例子展示了一個(gè)分析系統(tǒng)中事務(wù)計(jì)數(shù)的 DTrace 腳本,可以用來(lái)代替一次性能測(cè)試之前和之后的pg_stat_database快照:

#!/usr/sbin/dtrace -qs

postgresql$1:::transaction-start
{
      @start["Start"] = count();
      self->ts  = timestamp;
}

postgresql$1:::transaction-abort
{
      @abort["Abort"] = count();
}

postgresql$1:::transaction-commit
/self->ts/
{
      @commit["Commit"] = count();
      @time["Total time (ns)"] = sum(timestamp - self->ts);
      self->ts=0;
}

當(dāng)被執(zhí)行時(shí),該例子 D 腳本給出這樣的輸出:

# ./txn_count.d `pgrep -n postgres` or ./txn_count.d <PID>
^C

Start                                          71
Commit                                         70
Total time (ns)                        2312105013

注意

SystemTap 為追蹤腳本使用一個(gè)不同于 DTrace 的標(biāo)記,但是底層的探針是兼容的。值得注意的是,在這樣寫(xiě)的時(shí)候,SystemTap 腳本必須使用雙下劃線(xiàn)代替連字符來(lái)引用探針名。在未來(lái)的 SystemTap 發(fā)行中這很可能會(huì)被修復(fù)。

你應(yīng)該記住,DTrace 腳本需要細(xì)心地編寫(xiě)和調(diào)試,否則被收集的追蹤信息可能會(huì)毫無(wú)意義。在大部分發(fā)現(xiàn)問(wèn)題的情況中,它就是發(fā)生問(wèn)題的部件,而不是底層系統(tǒng)。當(dāng)討論使用動(dòng)態(tài)追蹤發(fā)現(xiàn)的信息時(shí),一定要附上使用的腳本以便其也被檢查和討論。

27.5.4. 定義新探針

開(kāi)發(fā)者可以在代碼中任意位置定義新的探針,當(dāng)然這要重新編譯之后才能生效。下面是插入新探針的步驟:

  1. 決定探針名稱(chēng)以及探針可用的數(shù)據(jù)

  2. 把該探針定義加入到src/backend/utils/probes.d

  3. 如果pg_trace.h還不存在于包含該探針點(diǎn)的模塊中,包括它,并且在源代碼中期望的位置插入TRACE_POSTGRESQL探針宏

  4. 重新編譯并驗(yàn)證新探針是可用的

例子:.  這里是一個(gè)如何增加一個(gè)探針來(lái)用事務(wù) ID 追蹤所有新事務(wù)的例子。

  1. 決定探針將被命名為transaction-start并且需要一個(gè)LocalTransactionId類(lèi)型的參數(shù)

  2. 將該探針定義加入到src/backend/utils/probes.d

    probe transaction__start(LocalTransactionId);
    

    注意探針名字中雙下劃線(xiàn)的使用。在一個(gè)使用探針的 DTrace 腳本中,雙下劃線(xiàn)需要被替換為一個(gè)連字符,因此 ,對(duì)用戶(hù)而言transaction-start是文檔名。

  3. 在編譯時(shí),transaction__start被轉(zhuǎn)換成一個(gè)宏調(diào)用TRACE_POSTGRESQL_TRANSACTION_START(注意這里是單下劃線(xiàn)),可以通過(guò)包括頭文件pg_trace.h獲得。將宏調(diào)用加入到源代碼中的合適位置。在這種情況下,看起來(lái)類(lèi)似:

    TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
    

  4. 在重新編譯和運(yùn)行新的二進(jìn)制文件之后,通過(guò)運(yùn)行下面的 DTrace 命令來(lái)檢查新增的探針是否可用。你應(yīng)該看到類(lèi)似下面的輸出:

    # dtrace -ln transaction-start
       ID    PROVIDER          MODULE           FUNCTION NAME
    18705 postgresql49878     postgres     StartTransactionCommand transaction-start
    18755 postgresql49877     postgres     StartTransactionCommand transaction-start
    18805 postgresql49876     postgres     StartTransactionCommand transaction-start
    18855 postgresql49875     postgres     StartTransactionCommand transaction-start
    18986 postgresql49873     postgres     StartTransactionCommand transaction-start
    

向C代碼中添加追蹤宏時(shí),有一些事情需要注意:

  • 需要小心的是,為探針參數(shù)指定的數(shù)據(jù)類(lèi)型要匹配宏中使用的變量的數(shù)據(jù)類(lèi)型,否則會(huì)發(fā)生編譯錯(cuò)誤。

  • 在大多數(shù)平臺(tái)上,如果用--enable-dtrace編譯了PostgreSQL,無(wú)論何時(shí)當(dāng)控制經(jīng)過(guò)一個(gè)追蹤宏時(shí),都會(huì)評(píng)估該宏的參數(shù),即使沒(méi)有進(jìn)行追蹤也會(huì)這樣做。通常不需要擔(dān)心你是否只在報(bào)告一些局部變量的值。但是要注意不要將開(kāi)銷(xiāo)大的函數(shù)調(diào)用放入?yún)?shù)中。如果你需要這樣做,考慮通過(guò)檢查追蹤是否真的被啟用來(lái)保護(hù)該宏:

    if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));

    每個(gè)追蹤宏有一個(gè)對(duì)應(yīng)的ENABLED宏。


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)