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_END 和 FPRINT 可共同做為這些資料表的專屬索引鍵。 |
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>
|
總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到承諾或中止時間之間,所有交易嘗試的時間。
如果交易中止多次後成功提交,系統會為每次嘗試 (直到最終成功提交為止) 測量延遲時間。這些值以秒為單位。
陣列包含單一元素,類型如下:
如要計算分布資料中的所需百分位數延遲時間,請使用 詳情請參閱「百分位數和分佈值指標」。 |
OPERATIONS_BY_TABLE |
ARRAY<STRUCT> |
每個交易對
這個欄可協助您以視覺化方式呈現資料表的負載情形,並提供交易寫入資料表的速率洞察資料。
請按照下列方式指定陣列:
|
1 _exists
是用於檢查特定資料列是否存在的內部欄位。
查詢範例
本節包含多個擷取交易統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫、gcloud spanner 或 Google 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>
|
總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到所有交易嘗試的承諾或中止時間。
如果交易中止多次後成功提交,系統會為每次嘗試 (直到最終成功提交為止) 測量延遲時間。這些值以秒為單位。
陣列包含單一元素,類型如下:
如要計算分布資料中的所需百分位數延遲時間,請使用 詳情請參閱「百分位數和分佈值指標」。 |
OPERATIONS_BY_TABLE |
ARRAY<STRUCT> |
所有交易對每個資料表的
這個欄可協助您以視覺化方式呈現表格的負載情形,並提供交易寫入表格的速率洞察資料。
請按照下列方式指定陣列:
|
查詢範例
本節包含多個擷取交易統計資料的範例 SQL 陳述式。您可以使用用戶端程式庫、gcloud spanner 或 Google 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_MINUTE
和SPANNER_SYS.TXN_STATS_TOTAL_MINUTE
:涵蓋前 6 個小時的間隔。SPANNER_SYS.TXN_STATS_TOP_10MINUTE
和SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
:涵蓋前 4 天的間隔。SPANNER_SYS.TXN_STATS_TOP_HOUR
和SPANNER_SYS.TXN_STATS_TOTAL_HOUR
:涵蓋前 30 天的間隔。
Spanner 中的交易統計資料可讓您深入瞭解應用程式如何使用資料庫,並在調查效能問題時提供實用資訊。舉例來說,您可以檢查是否有任何執行速度緩慢的交易可能導致爭用情形,或是找出可能造成高負載的潛在來源,例如對特定資料欄進行大量更新。我們將透過以下步驟,說明如何使用交易統計資料,調查資料庫中的競爭行為。
瞭解交易和提交次數
Spanner 交易可能會在修訂之前進行多次嘗試。這種情況最常發生在兩個交易嘗試同時處理相同資料,且其中一個交易需要中止,以保留交易的隔離屬性時。其他可能導致交易中止的暫時性事件包括:
網路發生暫時性問題。
在交易提交期間,套用資料庫結構定義變更。
Spanner 執行個體無法處理收到的所有要求。
在這種情況下,用戶端應重試已中止的交易,直到交易成功提交或逾時為止。對於官方 Spanner 用戶端程式庫的使用者,每個程式庫都已實作自動重試機制。如果您使用的是自訂版本的用戶端程式碼,請在重試迴圈中包裝交易提交作業。
由於無法復原的錯誤 (例如交易逾時、權限問題或無效的資料表/欄名稱),Spanner 交易也可能會中止。這類交易不需要重試,Spanner 用戶端程式庫會立即傳回錯誤。
下表列出 COMMIT_ATTEMPT_COUNT
、COMMIT_ABORT_COUNT
和 COMMIT_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 pm
到 7: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_columns
、write_constructive_columns
和 write_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_count
、commit_abort_count
和 commit_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_columns
、write_constructive_columns
和 write_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.FirstName
和 Singer.LastName
欄。這項資訊有助於判斷自訂用戶端程式庫中實作的交易重試機制是否正常運作。
後續步驟
- 瞭解其他內省工具。
- 瞭解 Spanner 為每個資料庫儲存的其他資訊。這些資訊儲存在資料庫的資訊結構定義資料表中。
- 進一步瞭解 Spanner 的 SQL 最佳做法。
- 進一步瞭解如何調查 CPU 使用率偏高的問題。