本文說明 Spanner 以內建資料表形式提供的交易統計資料。您可以使用 SQL 陳述式,從這些 SPANNER_SYS.TXN_STATS* 資料表擷取統計資料。
交易統計資料的使用時機
調查效能問題時,交易統計資料非常實用。舉例來說,您可以檢查是否有任何執行速度緩慢的交易,可能會影響資料庫的效能或每秒查詢次數 (QPS)。另一種情況是,用戶端應用程式的交易執行延遲時間過長。分析交易統計資料有助於找出潛在瓶頸,例如特定資料欄有大量更新,可能影響延遲時間。
如何查看交易統計資料
。Spanner 會在 SPANNER_SYS 結構定義中提供資料表交易統計資料。您可以透過下列方式存取 SPANNER_SYS 資料:
Google Cloud 控制台中的資料庫 Spanner Studio 頁面。
交易洞察資訊主頁。
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 的雜湊 (如有);否則,系統會根據交易涉及的作業計算雜湊。INTERVAL_END 和 FPRINT 共同做為這些資料表的專屬索引鍵。 |
READ_COLUMNS |
ARRAY<STRING> |
交易讀取的資料欄組合。 |
WRITE_CONSTRUCTIVE_COLUMNS |
ARRAY<STRING> |
交易中以建設性方式寫入 (即指派新值) 的資料欄組合。 如果是變更串流,且交易涉及寫入變更串流監控的資料欄和資料表, WRITE_CONSTRUCTIVE_COLUMNS 會包含 .data 和 ._exists 兩個資料欄,並加上變更串流名稱前置字元。_exists 是用來檢查特定資料列是否存在的欄位。 |
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 索引違規、資料列已存在或找不到資料列) 的交易修訂嘗試總數。 |
SERIALIZABLE_PESSIMISTIC_TXN_COUNT |
INT64 |
使用 SERIALIZABLE 隔離層級和PESSIMISTIC鎖定功能啟動的交易嘗試總數。這是 ATTEMPT_COUNT 的子集。 |
SERIALIZABLE_OPTIMISTIC_TXN_COUNT |
INT64 |
使用 SERIALIZABLE 隔離層級和 OPTIMISTIC 鎖定功能啟動的交易嘗試總數。這是 ATTEMPT_COUNT 的子集。 |
REPEATABLE_READ_OPTIMISTIC_TXN_COUNT |
INT64 |
使用 REPEATABLE READ 隔離層級和OPTIMISTIC鎖定功能啟動的交易嘗試總數。這是 ATTEMPT_COUNT 的子集。 |
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> |
交易對各資料表的
這個資料欄可協助您以視覺化方式呈現資料表的負載,並深入瞭解交易寫入資料表的速率。
請按照下列方式指定陣列:
|
TOTAL_LATENCY_DISTRIBUTION_JSON_STRING |
STRING
|
總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到承諾或取消時間的時間,適用於交易的所有嘗試。
如果交易多次取消後才成功提交,系統會測量每次嘗試的延遲時間,直到最終成功提交為止。值以秒為單位。 GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。此欄包含發行版本。 如要從分布情形計算百分位數延遲時間,請使用 詳情請參閱「百分位數和分布值指標」。 |
OPERATIONS_BY_TABLE_JSON_STRING |
STRING |
交易對各資料表的
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 這個資料欄可協助您以視覺化方式呈現資料表的負載,並深入瞭解交易寫入資料表的速率。 |
COMMIT_LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
顯示執行修訂作業所需秒數的直方圖。
陣列結構如下:
如要根據分布情形計算修訂延遲時間百分位數,請使用 |
COMMIT_LATENCY_DISTRIBUTION_JSON_STRING |
STRING |
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 如要根據分布情形計算修訂延遲時間百分位數,請使用 |
PARTICIPANTS_DISTRIBUTION |
ARRAY<STRUCT> |
直方圖,顯示每次嘗試提交時的參與者人數。
陣列結構如下:
如要根據分布情形計算參與者百分位數,請使用 |
PARTICIPANTS_DISTRIBUTION_JSON_STRING |
STRING |
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 如要根據分布情形計算參與者百分位數,請使用 |
查詢範例
本節提供多個 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 |
找出讀取特定資料欄的交易平均延遲時間
下列查詢會傳回讀取 ADDRESS 欄的交易平均延遲時間資訊 (根據 1 小時統計資料):
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 索引違規、資料列已存在或找不到資料列。 |
SERIALIZABLE_PESSIMISTIC_TXN_COUNT |
INT64 |
使用 SERIALIZABLE 隔離層級和 PESSIMISTIC 鎖定功能啟動的交易嘗試總數。這是 ATTEMPT_COUNT 的子集。 |
REPEATABLE_READ_OPTIMISTIC_TXN_COUNT |
INT64 |
使用 REPEATABLE READ 隔離層級和OPTIMISTIC鎖定功能啟動的交易嘗試總數。這是 ATTEMPT_COUNT 的子集。 |
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> |
所有交易對各資料表執行
這個資料欄可協助您以視覺化方式呈現資料表的負載,並提供交易寫入資料表的速率深入分析。
請按照下列方式指定陣列:
|
TOTAL_LATENCY_DISTRIBUTION_JSON_STRING |
STRING
|
總承諾延遲時間的直方圖,也就是從第一個交易作業開始時間到承諾或取消時間的時間,適用於交易的所有嘗試。
如果交易多次取消後才成功提交,系統會測量每次嘗試的延遲時間,直到最終成功提交為止。值以秒為單位。 GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。此欄包含發行版本。 如要從分布情形計算百分位數延遲時間,請使用 詳情請參閱「百分位數和分布值指標」。 |
OPERATIONS_BY_TABLE_JSON_STRING |
STRING |
交易對各資料表的
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 這個資料欄可協助您以視覺化方式呈現資料表的負載,並深入瞭解交易寫入資料表的速率。 |
COMMIT_LATENCY_DISTRIBUTION |
ARRAY<STRUCT> |
顯示執行修訂作業所需秒數的直方圖。
陣列結構如下:
如要根據分布情形計算修訂延遲時間百分位數,請使用 |
COMMIT_LATENCY_DISTRIBUTION_JSON_STRING |
STRING |
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 如要根據分布情形計算修訂延遲時間百分位數,請使用 |
PARTICIPANTS_DISTRIBUTION |
ARRAY<STRUCT> |
直方圖,顯示每次嘗試提交時的參與者人數。
陣列結構如下:
如要根據分布情形計算參與者百分位數,請使用 |
PARTICIPANTS_DISTRIBUTION_JSON_STRING |
STRING |
GoogleSQL 方言和 PostgreSQL 方言資料庫支援這個資料欄。 如要根據分布情形計算參與者百分位數,請使用 |
查詢範例
本節提供多個 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 個百分位數。
如果是 GoogleSQL 方言資料庫,可以使用 TOTAL_LATENCY_DISTRIBUTION 資料欄:
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;
如果是 PostgreSQL 方言資料庫,請改用 TOTAL_LATENCY_JSON_DISTRIBUTION_JSON_STRING 資料欄:
SELECT interval_end, avg_total_latency_seconds,
SPANNER_SYS.DISTRIBUTION_PERCENTILE(total_latency_distribution_json_string, 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 |
transaction-stats 資料表中的資料是特定時間間隔內的匯總資料。在特定時間間隔內,交易可能會在邊界附近中止並重試,並落入不同的值區。因此,在特定時間間隔內,中止和重試次數可能不相等。
這些統計資料旨在協助疑難排解和自我檢查,不保證 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 使用率過高的問題。