<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 27.4\. 動態跟蹤 PostgreSQL允許對數據庫服務器進行動態跟蹤。 這樣就允許在代碼內特定的點上調用外部工具來跟蹤執行過程。 許多跟蹤點(也被稱為"探頭")已經插入在源代碼中了, 這些探針的目的是被用于數據庫開發者和管理員,默認情況下, 探頭不編譯成PostgreSQL; 用戶必須運行配置腳本時明確啟用它們。 目前,只有[DTrace](https://en.wikipedia.org/wiki/DTrace)支持實用工具,在寫這的時候, 它可在Solaris, Mac OS X, FreeBSD, NetBSD和Oracle Linux上使用。 [SystemTap](http://sourceware.org/systemtap/) 項目為Linux還提供了一個DTrace的等效并且也是可用的。 通過改變`src/include/utils/probes.h` 中的宏命令定義為支持其他的動態跟蹤工具在理論上是可能的 。 ## 27.4.1\. 編譯動態跟蹤支持 跟蹤點是默認禁止的,你必須明確告訴配置腳本以使得PostgreSQL中的探頭可用。 使用`--enable-dtrace`選項來啟用DTrace支持。 參見[Section 15.4](#calibre_link-637)獲取更多信息。 ## 27.4.2\. 內置跟蹤點 [Table 27-15](#calibre_link-1989)顯示的是在源代碼中提供的標準跟蹤點, [Table 27-16](#calibre_link-1990)顯示探測中使用的類型。 更多探測可以被添加以提高PostgreSQL的觀測性。 **Table 27-15\. 內置DTrace跟蹤** | 名字 | 參數 | 描述 | | --- | --- | --- | | transaction-start | (LocalTransactionId) | 開始新的事務觸發探測器。arg0是事務ID。 | | transaction-commit | (LocalTransactionId) | 當事務成功完成時觸發探測器,arg0是事務ID。 | | transaction-abort | (LocalTransactionId) | 當事務未成功完成時觸發探測器,arg0是事務ID。 | | query-start | (const char *) | 開始查詢處理時觸發探測器,arg0是查詢字符串。 | | query-done | (const char *) | 當完成查詢處理時觸發探測器,arg0是查詢字符串。 | | query-parse-start | (const char *) | 當開始查詢解析時觸發探測器,arg0是查詢字符串。 | | query-parse-done | (const char *) | 查詢解析完成時觸發探測器,arg0是查詢字符串。 | | query-rewrite-start | (const char *) | 啟動查詢重寫時觸發探測器。arg0是查詢字符串。 | | query-rewrite-done | (const char *) | 當查詢重寫完成時觸發探測器,arg0是查詢字符串。 | | query-plan-start | () | 查詢規劃開始時觸發探測器。 | | query-plan-done | () | 查詢規劃完成時觸發探測器。 | | query-execute-start | () | 執行規劃開始時將觸發的探測器 | | query-execute-done | () | 執行規劃完成時將觸發的探測器 | | statement-status | (const char *) | 服務進程隨時更新`pg_stat_activity`.`status`時觸發的探測器。 arg0是一個新的狀態字符串 | | checkpoint-start | (int) | 檢查點開始時觸發的探測器。arg0可以逐位標記以區分不同的檢查點類型, 如;shutdown,immediate,或force。 | | checkpoint-done | (int, int, int, int, int) | 檢查點完成時觸發的探測器(觸發探測器列出檢查點處理過程序列中的下一個探測器)。 arg0表示要寫入的緩沖區的數目。arg1表示總的緩沖區的數目。 arg2,arg3和arg4包含了增加,刪除和循環回收的xlog文件的數目。 | | clog-checkpoint-start | (bool) | 一個檢查點的CLOG部分開始時觸發的探測器。 arg0對正常檢查點是真,對關閉檢查點是假。 | | clog-checkpoint-done | (bool) | 當一個檢查點的CLOG部分完成時觸發的探測器。 arg0的含義與CLOG-checkpoint-start一樣。 | | subtrans-checkpoint-start | (bool) | 當一個檢查點的SUBTRANS部分開始時觸發的探測器。 arg0對正常檢查點是真,對關閉檢查點是假。 | | subtrans-checkpoint-done | (bool) | 當一個檢查點的SUBTRANS部分完成時觸發的探測器。 arg0的含義與SUBTRANS-checkpoint-start一樣。 | | multixact-checkpoint-start | (bool) | 當一個檢查點的MultiXact部分開始時觸發探測器。 arg0對正常檢查點表示真,對關閉檢查點表示假。 | | multixact-checkpoint-done | (bool) | 當一個檢查點的MultiXact部分完成時觸發的探測器, arg0的含義與multixact-checkpoint-start一樣。 | | buffer-checkpoint-start | (int) | 開始一個檢查點的緩沖區寫部分時觸發的探測器。 arg0持有逐位標識以區分不同的檢查點類型,如shutdown,immediate或force。 | | buffer-sync-start | (int, int) | 檢查點期間,開始寫臟緩沖區時觸發的探測器(在識別出那個緩沖區必須寫之后)。 arg0表示總緩沖區數,arg1表示當前臟的,需要寫的緩沖區數。 | | buffer-sync-written | (int) | 在檢查點期間,每個緩沖區都被寫了之后觸發的探測器,arg0表示緩沖區的ID號。 | | buffer-sync-done | (int, int, int) | 當所有臟緩沖被寫之后觸發的探測器。 arg0表示總緩沖區的數目。 arg1表示檢查點進程實際寫的緩沖區數。 arg2表示期望寫的數目(arg1的buffer-sync-start); 任何的不同會導致另一個進程在檢查點發生時刷新緩沖區。 | | buffer-checkpoint-sync-start | () | 當完成將臟緩沖區寫入到內核,并且還沒有發出fsync請求之前觸發的探測器。 | | buffer-checkpoint-done | () | 當同步緩沖區到磁盤完成時觸發的探測器 | | twophase-checkpoint-start | () | 當一個檢查點的兩相階段狀態部分開始時觸發的探測器。 | | twophase-checkpoint-done | () | 當一個檢查點的兩相階段狀態部分完成時觸發的探測器。 | | buffer-read-start | (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) | 當開始一次緩沖區讀時觸發的探測器。 arg0和arg1包含page塊的鎖和派生的子進程數(如果是一個關系擴展請求,arg1會是-1)。 arg2,arg3和arg4包含表空間,數據庫和關系OID,以識別關系。 arg5是為局部緩沖創建臨時關系時后端ID,或者共享緩沖區InvalidBackendId (-1)。 arg6對關系擴展請求表示真,對正常讀表示假。 | | buffer-read-done | (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) | 當完成一次緩沖區讀時觸發的探測器。 arg0和arg1包含page塊的鎖和派生的子進程數 (如果是一個關系擴展請求,arg1會表示新增鎖的數目)。 arg2,arg3和arg4包含表空間,數據庫和關系OID,以識別關系。 arg5是為局部緩沖創建臨時關系時后端ID,或者共享緩沖區InvalidBackendId (-1)。 arg6對關系擴展請求表示真, 對正常讀表示假。如果池中有緩沖區, 則arg7表示真,反之表示假。 | | buffer-flush-start | (ForkNumber, BlockNumber, Oid, Oid, Oid) | 在發出共享緩沖區的任意寫入請求時觸發的探測器。 arg0和arg1包含分叉和頁中塊數。 arg2,arg3和arg4包含表空間,數據庫和關系OID,以識別關系。 | | buffer-flush-done | (ForkNumber, BlockNumber, Oid, Oid, Oid) | 當完成一條寫要求時觸發的探測器。 需要注意的是, 它只影響將數據傳遞到內核參數的時間; 實際上,它不會寫到磁盤上。這個參數與buffer-flush-start一致。 | | buffer-write-dirty-start | (ForkNumber, BlockNumber, Oid, Oid, Oid) | 當服務器進程開始寫臟緩沖區時觸發的探測器。 如果經常發生,表示[shared_buffers](#calibre_link-1370)太小, 或需要調整bgwriter控制參數。 arg0和arg1包含分叉和頁中的塊數。 arg2,arg3和arg4包含表空間, 數據庫和關系OID,以識別關系。 | | buffer-write-dirty-done | (ForkNumber, BlockNumber, Oid, Oid, Oid) | 當完成臟緩沖區寫時觸發的探測器。參數與buffer-write-dirty-start一樣。 | | wal-buffer-write-dirty-start | () | 當服務器進程開始寫臟WAL緩沖時觸發的探測器(此時WAL緩沖區已滿)。 如果經常發生,應該是[wal_buffers](#calibre_link-1991)設置的太小了。 | | wal-buffer-write-dirty-done | () | 當完成一次臟WAL寫時觸發的探測器。 | | xlog-insert | (unsigned char, unsigned char) | 當插入一條WAL記錄時觸發的探測器。 arg0表示記錄的rm id。 arg1包含信息標志。 | | xlog-switch | () | 當要求進行WAL切換時觸發的探測器。 | | smgr-md-read-start | (ForkNumber, BlockNumber, Oid, Oid, Oid, int) | 開始從一個關系中讀取鎖時觸發的探測器。 arg0和arg1包含page塊的鎖和派生的子進程數。 arg2,arg3和arg4包含表空間,數據庫和關系OID, 以識別關系。arg5是為局部緩沖創建臨時關系時的后端ID,或者共享緩沖InvalidBackendId (-1) | | smgr-md-read-done | (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) | 當一個鎖讀取完成時觸發的探測器。 arg0和arg1包含page塊的鎖和派生的子進程數。 arg2,arg3和arg4包含表空間, 數據庫和關系OID,以識別關系。 arg5是為局部緩沖創建臨時關系時的后端ID,或者共享緩沖InvalidBackendId (-1), 而arg6表示實際讀取的字節數,而arg7是要求數(如果不一樣會報錯) | | smgr-md-write-start | (ForkNumber, BlockNumber, Oid, Oid, Oid, int) | 當向一個關系中寫入鎖時觸發的探測器。 arg0和arg1包含page塊的鎖和派生的子進程數。 arg2,arg3和arg4包含表空間,數據庫和關系OID,以識別關系。 arg5是為局部緩沖創建臨時關系時的后端ID,或者共享緩沖InvalidBackendId (-1)。 | | smgr-md-write-done | (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) | 當一個鎖寫進程完成時觸發的探測器。 arg0和arg1表示page塊的鎖和派生的子進程數。 arg2,arg3和arg4包含表空間,數據庫和關系OID,以識別關系。 arg5表示為局部緩沖創建臨時關系時的后端ID,或者共享緩沖InvalidBackendId (-1), 而arg6表示實際讀取的字節數,而arg7是要求數(如果不一樣會報錯)。 | | sort-start | (int, bool, int, int, bool) | 排序操作開始時觸發的探測器。 arg0表示堆,索引或者基準點。 arg1對強制唯一值表示真。arg2表示鍵列的數目。 arg3表示允許使用的內存數目(以千字節為單位)。 如果要求隨機訪問排序結果,那么arg4表示真。 | | sort-done | (bool, long) | 排序操作結束時觸發的探測器。 arg0對外部排序表示真,內部排序表示假。 arg1表示用于一個外部排序的磁盤鎖的數目, 或用于一個內部排序的,以千字節為單位的內存數目。 | | lwlock-acquire | (LWLockId, LWLockMode) | 當成功獲得一個LWLock時觸發的探測器。 arg0是LWLock的ID號,arg1表明請求的鎖模式,要么獨占要么共享 | | lwlock-release | (LWLockId) | LWLock釋放時觸發的探測器 (但是請注意任何發布的等待者還未覺醒)。 arg0表示LWLock的ID號 | | lwlock-wait-start | (LWLockId, LWLockMode) | 當不能立即獲得LWLock鎖,同時服務進程進入等待時觸發的探測器。 arg0是LWLock的ID號,arg1表明請求的鎖模式,要么獨占要么共享。 | | lwlock-wait-done | (LWLockId, LWLockMode) | 當從一個LWLock鎖中釋放服務進程時觸發的探測器(實際上沒有進行鎖)。 arg0是LWLock的ID號,arg1表明請求的鎖模式,要么獨占要么共享。 | | lwlock-condacquire | (LWLockId, LWLockMode) | 當成功獲得一個LWLock時觸發的探測器(已聲明調用無需等待)。 arg0是LWLock的ID號,arg1表明請求的鎖的模式,要么獨占要么共享。 | | lwlock-condacquire-fail | (LWLockId, LWLockMode) | 當沒有成功獲得一個LWLock時觸發的探測器(已聲明調用無需等待)。 arg0是LWLock的ID號,arg1表明請求的鎖的模式,要么獨占要么共享。 | | lock-wait-start | (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) | 當一個重量級鎖(lmgr鎖)的請求開始等待(因為無法獲得鎖)時觸發的探測器。 arg0到arg3是辨別被鎖定對象的標簽字段。arg4指出被鎖對象的類型。 arg5表示請求的鎖類型。 | | lock-wait-done | (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) | 當一個重量級鎖(lmgr鎖)的請求結束等待時觸發的探測器, 參數與lock-wait-start一樣。 | | deadlock-found | () | 當死鎖探測器發現死鎖時觸發的探測器 | **Table 27-16\. 定義用于探測器參數的類型** | 類型 | 定義 | | --- | --- | | LocalTransactionId | unsigned int | | LWLockId | int | | LWLockMode | int | | LOCKMODE | int | | BlockNumber | unsigned int | | Oid | unsigned int | | ForkNumber | int | | bool | char | ## 27.4.3\. 使用跟蹤點 下面的例子顯示了一個分析事務次數的DTrace腳本, 可以用來代替性能測試之前和之后的`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腳本執行時,如輸出: ``` # ./txn_count.d `pgrep -n postgres` or ./txn_count.d <PID> ^C Start 71 Commit 70 Total time (ns) 2312105013 ``` > **Note:** SystemTap為跟蹤腳本使用一個不同的標記而不是Dtrace, 即使底層的跟蹤點是兼容的。有一點需要注意, 在這樣寫的時候,SystemTap腳本必須使用雙下劃線代替連字符來指向探測器名。 希望在未來SystemTap的版本中修復。 你應該記住DTrace腳本需要仔細的編寫和充分的調試, 否則收集到的跟蹤信息可能毫無意義。 大多數情況下問題是手段是錯誤的而不是底層系統。 在討論使用動態跟蹤發現的信息時,應確保包含允許檢查和討論使用的腳本。 更多的示例腳本可以在PgFoundry [dtrace project](http://pgfoundry.org/projects/dtrace/) 中找到。 ## 27.4.4\. 定義新的跟蹤點 開發者可以在代碼中任意位置定義新的跟蹤點, 當然這要重新編譯之后才能生效。下面是用于新探測器插入步驟: 1. 通過探頭決定探頭名字和可利用數據。 2. 新增探頭定義為`src/backend/utils/probes.d` 3. 包括`pg_trace.h`,如果已經不在模塊中包含探測點, 并且在所需源代碼中期望的位置插入`TRACE_POSTGRESQL`探測宏。 4. 重新編譯和驗證新探頭是可用的。 **例子:** 下面是一個例子,你將如何添加一個探頭通過事務ID追蹤所有新的事務。 1. 決定探測器將被命名為`transaction-start`并且需要LocalTransactionId類型參數。 2. 新增探頭定義為`src/backend/utils/probes.d`: ``` probe transaction__start(LocalTransactionId); ``` 注意探測器名字中的雙下劃線的使用。在使用探測器的DTrace腳本中, 需要用一個連字符來替換雙下劃線, 因此,對用戶而言,`transaction-start`是文檔名。 3. 在編譯時,`transaction__start`被轉換成一個宏調用 `TRACE_POSTGRESQL_TRANSACTION_START`(注意這里是單下劃線), 可以從`pg_trace.h`中獲得。將宏調用放在源代碼中的合適位置。 在這種情況下,類似于下面: ``` TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); ``` 4. 在重新編譯和運行新的二進制文件之后, 通過運行下面的DTrace命令來檢查新增的探測器是否可用。 應該得到類似下面的結果: ``` # 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代碼中添加跟蹤宏時,有一些注意事項,見下文: * 需要注意的是,為探測器參數聲明的數據類型要匹配宏中可用的數據類型, 否則會發生編譯錯誤。 * 在大多數平臺上,如果編譯PostgreSQL 時帶有`--enable-dtrace`選項, 無論何時通過宏來控制時,都會估算該跟蹤宏的參數, _即使沒有進行跟蹤_。通常不需要擔心是否你只是報告一些局部變量的值。 但要注意將重要的函數調用放置在參數中。如果需要這么做, 考慮通過檢查是否真的開啟跟蹤來保護宏: ``` if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) TRACE_POSTGRESQL_TRANSACTION_START(some_function(...)); ``` 每個跟蹤宏都有一個相應的`ENABLED`宏。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看