交易統計資料

Spanner 提供內建資料表,用於儲存交易相關統計資料。您可以使用 SQL 陳述式從這些 SPANNER_SYS.TXN_STATS* 資料表擷取統計資料。

使用交易統計資料的時機

交易統計資料可用於調查效能問題。舉例來說,您可以檢查是否有任何執行速度緩慢的交易,可能會影響資料庫中的效能或每秒查詢次數 (QPS)。另一種情況是,您的用戶端應用程式發生高交易執行延遲情形。分析交易統計資料有助於發現可能影響延遲時間的潛在瓶頸,例如特定資料欄的大量更新。

可用性

SPANNER_SYS 資料只能透過 SQL 介面取得,例如:

  • Google Cloud 控制台中資料庫的 Spanner Studio 頁面

  • gcloud spanner databases execute-sql 指令

  • 「交易深入分析」資訊主頁

  • executeQuery API

Spanner 提供的其他單一讀取方法不支援 SPANNER_SYS

按交易分組的延遲時間統計資料

下表會追蹤特定時間範圍內 TOP 資源消耗交易的統計資料。

  • SPANNER_SYS.TXN_STATS_TOP_MINUTE:匯總 1 分鐘間隔內的交易統計資料。

  • SPANNER_SYS.TXN_STATS_TOP_10MINUTE:每 10 分鐘間隔匯總的交易統計資料。

  • SPANNER_SYS.TXN_STATS_TOP_HOUR:每 1 小時間隔匯總的交易統計資料。

這些資料表具備下列屬性:

  • 每個資料表都包含資料表名稱所指定的非重疊時間間隔長度的資料。

  • 間隔是基於時鐘時間。1 分鐘間隔的結束時間是目前這一分鐘、10 分鐘間隔的結束時間是目前這個小時的每 10 分鐘,而 1 小時間隔的結束時間是目前這個小時。

    舉例來說,在上午 11:59:30,SQL 查詢的最近可用間隔如下:

    • 1 分鐘:上午 11:58:00–11:58:59
    • 10 分鐘:上午 11:40:00–11:49:59
    • 1 小時:上午 10:00:00–10:59:59
  • Spanner 會依據交易的 FPRINT (指紋) 將統計資料分組。如果有交易標記,FPRINT 就是標記的雜湊值。否則,雜湊是根據交易涉及的作業計算得出。

  • 統計資料是根據 FPRINT 分組,因此如果在任何時間間隔內執行相同交易多次,這些表格中仍只會顯示該交易的一個項目。

  • 每個資料列都包含 Spanner 在指定間隔期間擷取特定交易的統計資料,這些資料是針對該交易的所有執行作業擷取。

  • 如果 Spanner 無法在這些表格中儲存間隔期間執行的所有交易統計資料,系統會優先處理在指定間隔期間延遲時間、提交嘗試次數和寫入位元組最高的交易。

  • 資料表中的所有欄均可為空值。

資料表結構定義

資料欄名稱 類型 說明
INTERVAL_END TIMESTAMP 包含的交易執行作業發生時的時間間隔結束時間。
TRANSACTION_TAG STRING 這項交易作業的選用交易標記。如要進一步瞭解如何使用標記,請參閱「使用交易標記排解問題」。多筆具有相同代碼字串的交易統計資料會在單一列中分組,其中的 `TRANSACTION_TAG` 會與該代碼字串相符。
FPRINT INT64 如果存在 TRANSACTION_TAG,則為 TRANSACTION_TAG 的雜湊;否則,雜湊會根據交易涉及的作業計算。INTERVAL_ENDFPRINT 可共同做為這些資料表的專屬索引鍵。
READ_COLUMNS ARRAY<STRING> 交易讀取的資料欄組合。
WRITE_CONSTRUCTIVE_COLUMNS ARRAY<STRING> 交易已有效寫入 (即指派給新值) 的資料欄組合。

對於變更串流,如果交易涉及變更串流監控的資料欄和資料表,WRITE_CONSTRUCTIVE_COLUMNS 會包含兩個資料欄 - .data._exists 1,前面加上變更串流名稱。
WRITE_DELETE_TABLES ARRAY<STRING> 交易刪除或取代資料列的資料表組合。
ATTEMPT_COUNT INT64 交易嘗試的總次數,包括在呼叫 `commit` 之前中斷的嘗試次數。
COMMIT_ATTEMPT_COUNT INT64 交易提交嘗試次數總數。這必須與交易 commit 方法的呼叫次數相符。
COMMIT_ABORT_COUNT INT64 已中止的交易嘗試總數,包括在呼叫交易的 commit 方法前中止的嘗試。
COMMIT_RETRY_COUNT INT64 從先前中止的嘗試重試中,重試的嘗試次數總數。由於鎖定爭用或暫時事件,Spanner 交易可能會在提交前進行多次嘗試。如果相對於提交嘗試次數的重試次數過多,表示可能有問題需要調查。詳情請參閱本頁的「瞭解交易和修訂版本計數」一節。
COMMIT_FAILED_PRECONDITION_COUNT INT64 傳回失敗預先條件錯誤 (例如 UNIQUE 索引違規、資料列已存在、找不到資料列等等) 的交易提交嘗試次數總數。
AVG_PARTICIPANTS FLOAT64 每個提交嘗試的平均參與者人數。如要進一步瞭解參與者,請參閱「Spanner 讀取與寫入的生命週期」。
AVG_TOTAL_LATENCY_SECONDS FLOAT64 從交易的第一個作業到提交/中止所需的平均秒數。
AVG_COMMIT_LATENCY_SECONDS FLOAT64 執行修訂版本作業所需的平均秒數。
AVG_BYTES FLOAT64 交易寫入的平均位元組數。
TOTAL_LATENCY_DISTRIBUTION ARRAY<STRUCT>

總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到承諾或中止時間之間,所有交易嘗試的時間。

如果交易中止多次後成功提交,系統會為每次嘗試 (直到最終成功提交為止) 測量延遲時間。這些值以秒為單位。

陣列包含單一元素,類型如下:
ARRAY<STRUCT<
  COUNT INT64,
  MEAN FLOAT64,
  SUM_OF_SQUARED_DEVIATION FLOAT64,
  NUM_FINITE_BUCKETS INT64,
  GROWTH_FACTOR FLOAT64,
  SCALE FLOAT64,
  BUCKET_COUNTS ARRAY<INT64>>>

如要進一步瞭解這些值,請參閱「發布」一文。

如要計算分布資料中的所需百分位數延遲時間,請使用 SPANNER_SYS.DISTRIBUTION_PERCENTILE(distribution, n FLOAT64) 函式,該函式會傳回預估的 n 百分位數。如需相關範例,請參閱「找出交易的第 99 百分位數延遲時間」。

詳情請參閱「百分位數和分佈值指標」。

OPERATIONS_BY_TABLE ARRAY<STRUCT>

每個交易對 INSERTUPDATE 作業的影響。這會以受影響的資料列次數和寫入的位元組數表示。

這個欄可協助您以視覺化方式呈現資料表的負載情形,並提供交易寫入資料表的速率洞察資料。

請按照下列方式指定陣列:
ARRAY<STRUCT<
  TABLE STRING(MAX),
  INSERT_OR_UPDATE_COUNT INT64,
  INSERT_OR_UPDATE_BYTES INT64>>

1 _exists 是用於檢查特定資料列是否存在的內部欄位。

查詢範例

本節包含多個擷取交易統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫gcloud spannerGoogle Cloud 主控台執行這些 SQL 陳述式。

列出特定時間範圍內每筆交易的基本統計資料

下列查詢會傳回前一分鐘中,前幾筆交易的原始資料。

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds,
       avg_commit_latency_seconds,
       operations_by_table,
       avg_bytes
FROM spanner_sys.txn_stats_top_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_top_minute);
查詢輸出
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds avg_commit_latency_seconds operations_by_table avg_bytes
40015598317 [] ["Routes.name", "Cars.model"] ["Users"] 0.006578737 0.006547737 [["Cars",1107,30996],["Routes",560,26880]] 25286
20524969030 ["id", "no"] [] [] 0.001732442 0.000247442 [] 0
77848338483 [] [] ["Cars", "Routes"] 0.033467418 0.000251418 [] 0

列出平均提交延遲時間最長的交易

下列查詢會傳回前一小時中平均提交延遲時間較高的交易,並依平均提交延遲時間由高至低排序。

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds,
       avg_commit_latency_seconds,
       avg_bytes
FROM spanner_sys.txn_stats_top_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_top_hour)
ORDER BY avg_commit_latency_seconds DESC;
查詢輸出
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds avg_commit_latency_seconds avg_bytes
40015598317 [] ["Routes.name", "Cars.model"] ["Users"] 0.006578737 0.006547737 25286
77848338483 [] [] ["Cars", "Routes"] 0.033467418 0.000251418 0
20524969030 ["id", "no"] [] [] 0.001732442 0.000247442 0

找出讀取特定欄位的交易平均延遲時間

下列查詢會傳回交易的平均延遲時間資訊,這些交易會從 1 小時的統計資料中讀取 ADDRESS 欄:

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds
FROM spanner_sys.txn_stats_top_hour
WHERE 'ADDRESS' IN UNNEST(read_columns)
ORDER BY avg_total_latency_seconds DESC;
查詢輸出
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds
77848338483 ["ID", "ADDRESS"] [] ["Cars", "Routes"] 0.033467418
40015598317 ["ID", "NAME", "ADDRESS"] [] ["Users"] 0.006578737

依據平均修改位元組數列出交易

下列查詢會傳回過去一小時內取樣的交易,並依據交易修改的平均位元組數排序。

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_bytes
FROM spanner_sys.txn_stats_top_hour
ORDER BY avg_bytes DESC;
查詢輸出
fprint read_columns write_constructive_columns write_delete_tables avg_bytes
40015598317 [] [] ["Users"] 25286
77848338483 [] [] ["Cars", "Routes"] 12005
20524969030 ["ID", "ADDRESS"] [] ["Users"] 10923

匯總統計資料

SPANNER_SYS 也包含資料表,可儲存 Spanner 在特定時間範圍內擷取所有交易的匯總資料:

  • SPANNER_SYS.TXN_STATS_TOTAL_MINUTE:1 分鐘間隔期間內所有交易的匯總統計資料
  • SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE:10 分鐘間隔期間內所有交易的匯總統計資料
  • SPANNER_SYS.TXN_STATS_TOTAL_HOUR:1 小時間隔期間內所有交易的匯總統計資料

匯總統計資料表格具有下列屬性:

  • 每個資料表都包含資料表名稱所指定的非重疊時間間隔長度的資料。

  • 間隔是基於時鐘時間。1 分鐘間隔的結束時間是目前這一分鐘、10 分鐘間隔的結束時間是目前這個小時的每 10 分鐘,而 1 小時間隔的結束時間是目前這個小時。

    舉例來說,在上午 11:59:30,SQL 查詢的最近可用間隔如下:

    • 1 分鐘:上午 11:58:00–11:58:59
    • 10 分鐘:上午 11:40:00–11:49:59
    • 1 小時:上午 10:00:00–10:59:59
  • 每個資料列都會包含指定間隔期間,資料庫上執行的所有交易的統計資料匯總。每個時間間隔只有一個資料列。

  • SPANNER_SYS.TXN_STATS_TOTAL_* 資料表中擷取的統計資料可能包含 Spanner 未在 SPANNER_SYS.TXN_STATS_TOP_* 資料表中擷取的交易。

  • 這些資料表中的部分欄會在 Cloud Monitoring 中顯示為指標。公開的指標如下:

    • 提交嘗試次數
    • 提交重試次數
    • 交易參與者
    • 交易延遲時間
    • 寫入的位元組

    詳情請參閱「Spanner 指標」。

資料表結構定義

資料欄名稱 類型 說明
INTERVAL_END TIMESTAMP 擷取這項統計資料的時間間隔結束時間。
ATTEMPT_COUNT INT64 嘗試交易的總次數,包括在呼叫 `commit` 之前中止的嘗試次數。
COMMIT_ATTEMPT_COUNT INT64 交易提交嘗試次數總數。這必須與交易 commit 方法的呼叫次數相符。
COMMIT_ABORT_COUNT INT64 已中止的交易嘗試總數,包括在呼叫交易的 commit 方法之前中止的嘗試。
COMMIT_RETRY_COUNT INT64 從先前中止的嘗試重試中,提交嘗試次數。由於鎖定爭用或暫時事件,Spanner 交易可能會在提交前進行多次嘗試。如果相對於提交嘗試次數的重試次數過多,表示可能有問題需要調查。詳情請參閱本頁的「瞭解交易和修訂版本計數」一節。
COMMIT_FAILED_PRECONDITION_COUNT INT64 傳回失敗預先條件錯誤 (例如 UNIQUE 索引違規、資料列已存在、找不到資料列等等) 的交易提交嘗試次數總數。
AVG_PARTICIPANTS FLOAT64 每個提交嘗試的平均參與者人數。如要進一步瞭解參與者,請參閱「Spanner 讀取與寫入的生命週期」。
AVG_TOTAL_LATENCY_SECONDS FLOAT64 從交易的第一個作業到提交/中止所需的平均秒數。
AVG_COMMIT_LATENCY_SECONDS FLOAT64 執行修訂版本作業所需的平均秒數。
AVG_BYTES FLOAT64 交易寫入的平均位元組數。
TOTAL_LATENCY_DISTRIBUTION ARRAY<STRUCT>

總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到所有交易嘗試的承諾或中止時間。

如果交易中止多次後成功提交,系統會為每次嘗試 (直到最終成功提交為止) 測量延遲時間。這些值以秒為單位。

陣列包含單一元素,類型如下:
ARRAY<STRUCT<
  COUNT INT64,
  MEAN FLOAT64,
  SUM_OF_SQUARED_DEVIATION FLOAT64,
  NUM_FINITE_BUCKETS INT64,
  GROWTH_FACTOR FLOAT64,
  SCALE FLOAT64,
  BUCKET_COUNTS ARRAY<INT64>>>

如要進一步瞭解這些值,請參閱「發布」一文。

如要計算分布資料中的所需百分位數延遲時間,請使用 SPANNER_SYS.DISTRIBUTION_PERCENTILE(distribution, n FLOAT64) 函式,該函式會傳回預估的 n 百分位數。如需範例,請參閱「找出交易的第 99 百分位數延遲時間」。

詳情請參閱「百分位數和分佈值指標」。

OPERATIONS_BY_TABLE ARRAY<STRUCT>

所有交易對每個資料表的 INSERTUPDATE 作業所造成的影響。這會透過受影響的資料列次數和寫入的位元組數來表示。

這個欄可協助您以視覺化方式呈現表格的負載情形,並提供交易寫入表格的速率洞察資料。

請按照下列方式指定陣列:
ARRAY<STRUCT<
  TABLE STRING(MAX),
  INSERT_OR_UPDATE_COUNT INT64,
  INSERT_OR_UPDATE_BYTES INT64>>

查詢範例

本節包含多個擷取交易統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫gcloud spannerGoogle Cloud 主控台執行這些 SQL 陳述式。

找出所有交易的總提交嘗試次數

下列查詢會傳回最近完成的 1 分間隔內,所有交易的提交嘗試次數總數:

SELECT interval_end,
       commit_attempt_count
FROM spanner_sys.txn_stats_total_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_minute)
ORDER BY interval_end;
查詢輸出
interval_end commit_attempt_count
2020-01-17 11:46:00-08:00 21

請注意,結果中只有一個資料列,因為匯總統計資料在任何時間範圍內,每個 interval_end 只有一個項目。

找出所有交易的總提交延遲時間

下列查詢會傳回過去 10 分鐘內所有交易的總提交延遲時間:

SELECT (avg_commit_latency_seconds * commit_attempt_count / 60 / 60)
  AS total_commit_latency_hours
FROM spanner_sys.txn_stats_total_10minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_10minute);
查詢輸出
total_commit_latency_hours
0.8967

請注意,結果中只有一個資料列,因為匯總統計資料在任何時間範圍內,每個 interval_end 只有一個項目。

找出交易的第 99 個百分位數延遲時間

下列查詢會傳回過去 10 分鐘內執行的交易第 99 個百分位數延遲時間:

SELECT interval_end, avg_total_latency_seconds,
       SPANNER_SYS.DISTRIBUTION_PERCENTILE(total_latency_distribution[OFFSET(0)], 99.0)
  AS percentile_latency
FROM spanner_sys.txn_stats_total_10minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_10minute)
ORDER BY interval_end;

查詢輸出
interval_end avg_total_latency_seconds percentile_latency
2022-08-17 11:46:00-08:00 0.34576998305986395 9.00296190476190476

請注意,平均延遲時間與第 99 百分位延遲時間之間的差異很大。第 99 個百分位數的延遲時間有助於找出可能的異常交易,這些交易的延遲時間較長。

結果中只有一列,因為匯總統計資料在任何時間範圍內,每個 interval_end 只有一筆項目。

資料保留

Spanner 至少會在下列時間範圍保留每個資料表的資料:

  • SPANNER_SYS.TXN_STATS_TOP_MINUTESPANNER_SYS.TXN_STATS_TOTAL_MINUTE:涵蓋前 6 個小時的間隔。

  • SPANNER_SYS.TXN_STATS_TOP_10MINUTESPANNER_SYS.TXN_STATS_TOTAL_10MINUTE:涵蓋前 4 天的間隔。

  • SPANNER_SYS.TXN_STATS_TOP_HOURSPANNER_SYS.TXN_STATS_TOTAL_HOUR:涵蓋前 30 天的間隔。

Spanner 中的交易統計資料可讓您深入瞭解應用程式如何使用資料庫,並在調查效能問題時提供實用資訊。舉例來說,您可以檢查是否有任何執行速度緩慢的交易可能導致爭用情形,或是找出可能造成高負載的潛在來源,例如對特定資料欄進行大量更新。我們將透過以下步驟,說明如何使用交易統計資料,調查資料庫中的競爭行為。

瞭解交易和提交次數

Spanner 交易可能會在修訂之前進行多次嘗試。這種情況最常發生在兩個交易嘗試同時處理相同資料,且其中一個交易需要中止,以保留交易的隔離屬性時。其他可能導致交易中止的暫時性事件包括:

  • 網路發生暫時性問題。

  • 在交易提交期間,套用資料庫結構定義變更。

  • Spanner 執行個體無法處理收到的所有要求。

在這種情況下,用戶端應重試已中止的交易,直到交易成功提交或逾時為止。對於官方 Spanner 用戶端程式庫的使用者,每個程式庫都已實作自動重試機制。如果您使用的是自訂版本的用戶端程式碼,請在重試迴圈中包裝交易提交作業。

由於無法復原的錯誤 (例如交易逾時、權限問題或無效的資料表/欄名稱),Spanner 交易也可能會中止。這類交易不需要重試,Spanner 用戶端程式庫會立即傳回錯誤。

下表列出 COMMIT_ATTEMPT_COUNTCOMMIT_ABORT_COUNTCOMMIT_RETRY_COUNT 在不同情境下記錄的範例。

情境 COMMIT_ATTEMPT_COUNT COMMIT_ABORT_COUNT COMMIT_RETRY_COUNT
交易在第一次嘗試時就已成功提交。 1 0 0
交易因逾時錯誤而中止。 1 1 0
交易因暫時性網路問題而中止,並在重試一次後成功提交。 2 1 1
在 10 分鐘的間隔內執行 5 筆具有相同 FPRINT 的交易。其中 3 筆交易在第一次嘗試時成功提交,而 2 筆交易則在第一次重試時遭到中止,隨後成功提交。 7 2 2

交易統計資料表中的資料是一段時間內的匯總資料。在特定間隔內,交易可能會在邊界附近中止及重試,並落入不同的分層。因此,在特定時間間隔內,中斷和重試的次數可能不相等。

這些統計資料旨在協助排解問題和進行內省,但不保證 100% 準確。統計資料會先在記憶體中匯總,再儲存在 Spanner 資料表中。在升級或其他維護作業期間,Spanner 伺服器可能會重新啟動,進而影響數字的準確性。

使用交易統計資料排解資料庫爭用問題

您可以使用 SQL 程式碼或「交易深入分析」資訊主頁,查看資料庫中可能因鎖定爭用而造成高延遲的交易。

下列主題說明如何使用 SQL 程式碼調查這類交易。

選取要調查的時間範圍

這項資訊可在使用 Spanner 的應用程式中找到。

在本練習中,假設問題是在 2020 年 5 月 17 日下午 5 點 20 分左右開始發生。

您可以使用交易標記來找出交易來源,並將交易統計資料表和鎖定統計資料表進行關聯,以便有效排解鎖定爭用問題。詳情請參閱交易標記疑難排解

收集所選時間範圍內的交易統計資料

為了展開調查,我們會查詢問題開始時的 TXN_STATS_TOTAL_10MINUTE 資料表。這項查詢的結果會顯示延遲和其他交易統計資料在該期間的變化情形。

舉例來說,下列查詢會傳回從 4:30 pm7:40 pm (含) 的匯總交易統計資料。

SELECT
  interval_end,
  ROUND(avg_total_latency_seconds,4) as avg_total_latency_seconds,
  commit_attempt_count,
  commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
WHERE
  interval_end >= "2020-05-17T16:40:00"
  AND interval_end <= "2020-05-17T19:40:00"
ORDER BY interval_end;

下表列出查詢傳回的資料範例。

interval_end avg_total_latency_seconds commit_attempt_count commit_abort_count
2020-05-17 16:40:00-07:00 0.0284 315691 5170
2020-05-17 16:50:00-07:00 0.0250 302124 3828
2020-05-17 17:00:00-07:00 0.0460 346087 11382
2020-05-17 17:10:00-07:00 0.0864 379964 33826
2020-05-17 17:20:00-07:00 0.1291 390343 52549
2020-05-17 17:30:00-07:00 0.1314 456455 76392
2020-05-17 17:40:00-07:00 0.1598 507774 121458
2020-05-17 17:50:00-07:00 0.1641 516587 115875
2020-05-17 18:00:00-07:00 0.1578 552711 122626
2020-05-17 18:10:00-07:00 0.1750 569460 154205
2020-05-17 18:20:00-07:00 0.1727 613571 160772
2020-05-17 18:30:00-07:00 0.1588 601994 143044
2020-05-17 18:40:00-07:00 0.2025 604211 170019
2020-05-17 18:50:00-07:00 0.1615 601622 135601
2020-05-17 19:00:00-07:00 0.1653 596804 129511
2020-05-17 19:10:00-07:00 0.1414 560023 112247
2020-05-17 19:20:00-07:00 0.1367 570864 100596
2020-05-17 19:30:00-07:00 0.0894 539729 65316
2020-05-17 19:40:00-07:00 0.0820 479151 40398

這裡顯示,在已醒目顯示的期間,匯總的延遲時間和中止次數較高。我們可以選擇任何 10 分鐘的間隔,其中的總延遲時間和/或中止計數較高。請選擇結束於 2020-05-17T18:40:00 的間隔,並在下一個步驟中使用該間隔,找出造成高延遲和中止計數的交易。

找出延遲時間偏高的交易

接下來,我們將針對先前步驟中選取的時間間隔,查詢 TXN_STATS_TOP_10MINUTE 資料表。我們可以利用這些資料,找出哪些交易的延遲時間和/或中止次數偏高。

執行下列查詢,針對結束於 2020-05-17T18:40:00 的範例間隔,依總延遲時間由高至低的順序取得影響效能表現的交易。

SELECT
  interval_end,
  fprint,
  ROUND(avg_total_latency_seconds,4) as avg_total_latency_seconds,
  ROUND(avg_commit_latency_seconds,4) as avg_commit_latency_seconds,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC;
interval_end fprint avg_total_latency_seconds avg_commit_latency_seconds commit_attempt_count commit_abort_count commit_retry_count
2020-05-17 18:40:00-07:00 15185072816865185658 0.3508 0.0139 278802 142205 129884
2020-05-17 18:40:00-07:00 15435530087434255496 0.1633 0.0142 129012 27177 24559
2020-05-17 18:40:00-07:00 14175643543447671202 0.1423 0.0133 5357 636 433
2020-05-17 18:40:00-07:00 898069986622520747 0.0198 0.0158 6 0 0
2020-05-17 18:40:00-07:00 10510121182038036893 0.0168 0.0125 7 0 0
2020-05-17 18:40:00-07:00 9287748709638024175 0.0159 0.0118 4269 1 0
2020-05-17 18:40:00-07:00 7129109266372596045 0.0142 0.0102 182227 0 0
2020-05-17 18:40:00-07:00 15630228555662391800 0.0120 0.0107 58 0 0
2020-05-17 18:40:00-07:00 7907238229716746451 0.0108 0.0097 65 0 0
2020-05-17 18:40:00-07:00 10158167220149989178 0.0095 0.0047 3454 0 0
2020-05-17 18:40:00-07:00 9353100217060788102 0.0093 0.0045 725 0 0
2020-05-17 18:40:00-07:00 9521689070912159706 0.0093 0.0045 164 0 0
2020-05-17 18:40:00-07:00 11079878968512225881 0.0064 0.0019 65 0 0

我們可以清楚看到,上表第一列 (已醒目顯示) 顯示的交易因提交中止次數過多而發生高延遲。我們也發現重試次數過多,這表示系統後續會重試已中止的修訂版本。在下一個步驟中,我們會進一步調查導致這個問題的原因。

找出交易中延遲時間較長的資料欄

在這個步驟中,我們會檢查是否有高延遲交易在相同的資料欄上運作,方法是擷取交易的 read_columnswrite_constructive_columnswrite_delete_tables 資料,並計算中止次數。FPRINT 值也會在下一個步驟中派上用場。

SELECT
  fprint,
  read_columns,
  write_constructive_columns,
  write_delete_tables
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC LIMIT 3;
fprint read_columns write_constructive_columns write_delete_tables
15185072816865185658 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.shares] [TestHigherLatency._exists,TestHigherLatency.shares,TestHigherLatency_lang_status_score_index.shares] []
15435530087434255496 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.likes,globalTagAffinity.score] [TestHigherLatency._exists,TestHigherLatency.likes,TestHigherLatency_lang_status_score_index.likes] []
14175643543447671202 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.ugcCount] [TestHigherLatency._exists,TestHigherLatency.ugcCount,TestHigherLatency_lang_status_score_index.ugcCount] []

如上表的輸出結果所示,平均總延遲時間最高的交易會讀取相同的資料欄。我們也可以觀察到一些寫入競爭,因為交易會寫入相同的資料欄,也就是 TestHigherLatency._exists

判斷交易成效的長期變化

我們可以查看與此交易形狀相關聯的統計資料,在一段時間內的變化情形。請使用下列查詢,其中 $FPRINT 是上一個步驟中高延遲交易的指紋。

SELECT
  interval_end,
  ROUND(avg_total_latency_seconds, 3) AS latency,
  ROUND(avg_commit_latency_seconds, 3) AS commit_latency,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count,
  commit_failed_precondition_count,
  avg_bytes
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end >= "2020-05-17T16:40:00"
  AND interval_end <= "2020-05-17T19:40:00"
  AND fprint = $FPRINT
ORDER BY interval_end;
interval_end 延遲 commit_latency commit_attempt_count commit_abort_count commit_retry_count commit_failed_precondition_count avg_bytes
2020-05-17 16:40:00-07:00 0.095 0.010 53230 4752 4330 0 91
2020-05-17 16:50:00-07:00 0.069 0.009 61264 3589 3364 0 91
2020-05-17 17:00:00-07:00 0.150 0.010 75868 10557 9322 0 91
2020-05-17 17:10:00-07:00 0.248 0.013 103151 30220 28483 0 91
2020-05-17 17:20:00-07:00 0.310 0.012 130078 45655 41966 0 91
2020-05-17 17:30:00-07:00 0.294 0.012 160064 64930 59933 0 91
2020-05-17 17:40:00-07:00 0.315 0.013 209614 104949 96770 0 91
2020-05-17 17:50:00-07:00 0.322 0.012 215682 100408 95867 0 90
2020-05-17 18:00:00-07:00 0.310 0.012 230932 106728 99462 0 91
2020-05-17 18:10:00-07:00 0.309 0.012 259645 131049 125889 0 91
2020-05-17 18:20:00-07:00 0.315 0.013 272171 137910 129411 0 90
2020-05-17 18:30:00-07:00 0.292 0.013 258944 121475 115844 0 91
2020-05-17 18:40:00-07:00 0.350 0.013 278802 142205 134229 0 91
2020-05-17 18:50:00-07:00 0.302 0.013 256259 115626 109756 0 91
2020-05-17 19:00:00-07:00 0.315 0.014 250560 110662 100322 0 91
2020-05-17 19:10:00-07:00 0.271 0.014 238384 99025 90187 0 91
2020-05-17 19:20:00-07:00 0.273 0.014 219687 84019 79874 0 91
2020-05-17 19:30:00-07:00 0.198 0.013 195357 59370 55909 0 91
2020-05-17 19:40:00-07:00 0.181 0.013 167514 35705 32885 0 91

在上述輸出結果中,我們可以觀察到在醒目顯示的時間範圍內,總延遲時間偏高。而且,無論總延遲時間有多高,commit_attempt_countcommit_abort_countcommit_retry_count 也都會很高,即使提交延遲時間 (commit_latency) 並未大幅變動也是如此。由於交易提交作業會更頻繁地中止,因此提交重試也會導致提交嘗試次數增加。

結論

在這個範例中,我們發現高提交中止計數是造成高延遲的原因。下一個步驟是查看應用程式收到的提交中止錯誤訊息,瞭解中止的原因。檢查應用程式中的記錄後,我們發現應用程式在此期間確實變更了工作負載,也就是說,其他交易形狀顯示出高 attempts_per_second,而其他交易 (可能是每晚的清理工作) 導致其他鎖定衝突。

找出未正確重試的交易

下列查詢會傳回過去十分鐘內取樣的交易,這些交易的提交中止次數偏高,但沒有重試。

SELECT
  *
FROM (
  SELECT
    fprint,
    SUM(commit_attempt_count) AS total_commit_attempt_count,
    SUM(commit_abort_count) AS total_commit_abort_count,
    SUM(commit_retry_count) AS total_commit_retry_count
  FROM
    SPANNER_SYS.TXN_STATS_TOP_10MINUTE
  GROUP BY
    fprint )
WHERE
  total_commit_retry_count = 0
  AND total_commit_abort_count > 0
ORDER BY
  total_commit_abort_count DESC;
fprint total_commit_attempt_count total_commit_abort_count total_commit_retry_count
1557557373282541312 3367894 44232 0
5776062322886969344 13566 14 0

我們發現,使用 fprint 1557557373282541312 的交易已中止 44232 次,但從未重試。這看起來很可疑,因為中止計數很高,而且每個中止都不可能是由無法重試的錯誤造成。另一方面,如果交易的 fprint 為 5776062322886969344,則不太可疑,因為總中止次數不高。

以下查詢會傳回 fprint 交易的更多詳細資料 (1557557373282541312),包括 read_columnswrite_constructive_columnswrite_delete_tables。這項資訊有助於在用戶端程式碼中找出交易,方便您針對此情況查看重試邏輯。

SELECT
  interval_end,
  fprint,
  read_columns,
  write_constructive_columns,
  write_delete_tables,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count
FROM
  SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  fprint = 1557557373282541312
ORDER BY
  interval_end DESC;
interval_end fprint read_columns write_constructive_columns write_delete_tables commit_attempt_count commit_abort_count commit_retry_count
2021-01-27T18:30:00Z 1557557373282541312 ['Singers._exists'] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 805228 1839 0
2021-01-27T18:20:00Z 1557557373282541312 ['Singers._exists'] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 1034429 38779 0
2021-01-27T18:10:00Z 1557557373282541312 ['Singers._exists'] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 833677 2266 0
2021-01-27T18:00:00Z 1557557373282541312 ['Singers._exists'] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 694560 1348 0

我們可以看到,交易涉及讀取 Singers._exists 隱藏欄,以便檢查資料列是否存在。交易也會寫入 Singers.FirstNameSinger.LastName 欄。這項資訊有助於判斷自訂用戶端程式庫中實作的交易重試機制是否正常運作。

後續步驟