W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
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)。
默認(rèn)情況下,探針是不可用的,因此你將需要顯式地告訴配置腳本讓探針在PostgreSQL中可用。要包括 DTrace 支持,在配置時(shí)指定--enable-dtrace
。更多信息請(qǐng)見(jiàn)第 16.4 節(jié)。
如表 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
|
下面的例子展示了一個(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í),一定要附上使用的腳本以便其也被檢查和討論。
開(kāi)發(fā)者可以在代碼中任意位置定義新的探針,當(dāng)然這要重新編譯之后才能生效。下面是插入新探針的步驟:
決定探針名稱(chēng)以及探針可用的數(shù)據(jù)
把該探針定義加入到src/backend/utils/probes.d
如果pg_trace.h
還不存在于包含該探針點(diǎn)的模塊中,包括它,并且在源代碼中期望的位置插入TRACE_POSTGRESQL
探針宏
重新編譯并驗(yàn)證新探針是可用的
例子:. 這里是一個(gè)如何增加一個(gè)探針來(lái)用事務(wù) ID 追蹤所有新事務(wù)的例子。
決定探針將被命名為transaction-start
并且需要一個(gè)LocalTransactionId
類(lèi)型的參數(shù)
將該探針定義加入到src/backend/utils/probes.d
:
probe transaction__start(LocalTransactionId);
注意探針名字中雙下劃線(xiàn)的使用。在一個(gè)使用探針的 DTrace 腳本中,雙下劃線(xiàn)需要被替換為一個(gè)連字符,因此 ,對(duì)用戶(hù)而言transaction-start
是文檔名。
在編譯時(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);
在重新編譯和運(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
宏。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: