慢查詢診斷
AnalyticDB PostgreSQL版提供了慢查詢診斷功能,旨在幫助您對慢查詢進行診斷、分析和采取優化措施。在使用該功能前,您需要開啟慢查詢功能。開啟后,系統將自動記錄超過閾值為1秒的SQL語句,您可以連接到postgres庫進行查詢和分析。
前提條件
慢查詢診斷功能僅支持存儲彈性模式7.0版本,且內核版本必須為V7.0.5.0及以上。如何查看和升級內核版本以及內核小版本,請參見查看內核小版本和版本升級。
注意事項
慢查詢日志默認保留一個星期的數據,但不會記錄失敗的查詢。它記錄所有執行時間超過GUC
slow_query_min_duration
參數設置(默認值是1秒)的SQL語句,即記錄執行時間超過1秒的所有查詢(包括DDL),為了保障系統的穩定性,建議不要修改該參數。慢查詢日志將不會記錄文本長度超過1024字節的慢SQL語句,超過該數值的SQL文本將被截斷。
開啟或關閉慢查詢
--on代表開啟, off代表關閉
SHOW adbpg_feature_enable_query_monitor;
--業務庫開啟慢查詢診斷功能
ALTER database {業務庫} SET adbpg_feature_enable_query_monitor to ON;
使用示例
系統將默認采集執行時間大于1秒的查詢以及所有的DDL,慢查詢日志存放在postgres系統庫中。如需查詢當前實例的慢查詢情況,請切換到postgres庫,通過查詢qmonitor.instance_slow_queries(實例級別)
和qmonitor.host_slow_queries(節點級別)
這兩個視圖來進行慢查詢的診斷。以下將為您介紹進行慢查詢診斷的典型場景,主要包括:
詳細字段信息請參考:附錄
查詢某時間范圍內所有的慢Query語句。
查詢最近某個時間段(如30分鐘)所有慢Query語句。您也可以根據業務需求修改具體時間,查詢目標時間段消耗較高的慢Query語句。
SELECT query_start AS "開始時間", query_end AS "結束時間", query_duration_ms AS "耗時(ms)", query_id AS "查詢ID", query AS "查詢SQL" FROM qmonitor.instance_slow_queries WHERE query_start >= now() - interval '30 min';
查詢2024年02月26日這天(慢查詢日志默認保留最近7天的數據)所有慢Query語句。
SELECT query_start AS "開始時間", query_end AS "結束時間", query_duration_ms AS "耗時(ms)", query_id AS "查詢ID", query AS "查詢SQL" FROM qmonitor.instance_slow_queries WHERE query_start >= '2024-02-26 00:00:00' AND query_end <= '2024-02-27 00:00:00';
查詢某時間范圍內實例級別某資源(CPU使用、內存使用或者落地文件大小)TopN的慢Query語句。
查詢實例某個時間段(如30分鐘)CPU消耗排名前20的慢Query語句。您也可以根據業務需求修改具體時間,查詢目標時間段消耗較高的慢Query語句。
SELECT (cpu_time_ms/1000)::text || ' s' AS "CPU時間", query_start AS "開始時間", query_end AS "結束時間", query_duration_ms AS "耗時(ms)", query_id AS "查詢ID", query AS "查詢SQL" FROM qmonitor.instance_slow_queries WHERE query_start >= now() - interval '30 min' ORDER BY cpu_time_ms DESC LIMIT 20;
查詢實例某個時間段(如30分鐘)內存消耗排名前20的慢Query語句。您也可以根據業務需求修改具體時間,查詢目標時間段消耗較高的慢Query語句。
SELECT pg_size_pretty(memory_bytes) AS "內存使用", query_start AS "開始時間", query_end AS "結束時間", query_duration_ms AS "耗時(ms)", query_id AS "查詢ID", query AS "查詢SQL" FROM qmonitor.instance_slow_queries WHERE query_start >= now() - interval '30 min' ORDER BY memory_bytes DESC LIMIT 20;
說明在進行統計查詢時,需要考慮內存的消耗情況。在查詢過程中,內存的消耗呈現出一定的波動。因此,僅采集查詢過程中的內存使用峰值作為內存的消耗數值,這并非精確值,而是對Query內存使用量的粗略體現。
查詢2024年02月26日0點至12點CPU消耗排名前10的慢Query語句:
SELECT (cpu_time_ms/1000)::text || ' s' AS "CPU時間", query_start AS "開始時間", query_end AS "結束時間", query_duration_ms AS "耗時(ms)", query_id AS "查詢ID", query AS "查詢SQL" FROM qmonitor.instance_slow_queries WHERE query_start >= '2024-02-26 00:00:00' AND query_end <= '2024-02-26 12:00:00' ORDER BY cpu_time_ms DESC LIMIT 10;
查詢某時間范圍內節點級別某資源(CPU使用、內存使用或者落地文件大小)TopN的慢Query語句。
查詢某節點某個時間段(如30分鐘)CPU消耗排名前20的慢Query語句。您也可以根據業務需求修改具體時間,查詢目標時間段消耗較高的慢Query語句:
SELECT (host_cpu_time_ms/1000)::text || ' s' as "CPU時間", query_start as "開始時間", query_end as "結束時間", query_duration_ms as "耗時(ms)", query_id as "查詢ID", query as "查詢SQL" FROM qmonitor.host_slow_queries WHERE hostname = '節點hostname' AND query_start >= now() - interval '30 min' ORDER BY host_cpu_time_ms DESC LIMIT 20;
查詢某節點某個時間段(如30分鐘)內存消耗排名前20的慢Query語句。您也可以根據業務需求修改具體時間,查詢目標時間段消耗比較高的慢Query語句:
SELECT pg_size_pretty(host_mem_bytes) as "內存使用", query_start as "開始時間", query_end as "結束時間", query_duration_ms as "耗時(ms)", query_id as "查詢ID", query as "查詢SQL" FROM qmonitor.host_slow_queries WHERE hostname = '節點hostname' AND query_start >= now() - interval '30 min' ORDER BY host_mem_bytes DESC LIMIT 20;
查詢某個慢查詢日志的具體信息。
SELECT * FROM qmonitor.instance_slow_queries WHERE query_id = '<某查詢的QueryId>';
查詢某時間范圍內每個用戶的慢Query情況。
查詢某時間范圍內(如10分鐘)每個用戶的慢Query情況,您也可以根據業務需求修改具體時間,查詢目標時間段內每個用戶的慢Query情況:
SELECT user_name AS "用戶", COUNT(1) AS "Query個數" FROM qmonitor.instance_slow_queries WHERE query_start >= now() - interval '10 min' GROUP BY user_name ORDER BY COUNT(1) DESC;
導出慢查詢日志
AnalyticDB PostgreSQL版支持使用SELECT語句將慢查詢日志(qmonitor.instance_slow_queries)或(qmonitor.host_slow_queries)中的數據導出到用戶自定義的內部表或者MaxCompute、OSS等外部表中,詳細請參考數據湖分析。為了正確和高效地導出慢查詢日志中的數據,您需要注意:
在AnalyticDB PostgreSQL版中,慢查詢日志會根據查詢開始時間query_start
創建索引并進行分區表字段的設置。當按時間范圍導出時,在查詢條件中包含query_start
列,從而實現更佳的性能和更少的資源消耗。例如想導出2024年2月26日下午1點到4點的慢日志, 則可添加條件:query_start >= '2024-02-26 13:00:00' and query_start <= '2024-02-26 16:00:00' 。
配置項
通過配置項可以修改慢Query語句的默認閾值,方便您查詢出不同條件下的慢查詢日志。
只支持超級用戶(Superuser)修改該配置項。
slow_query_min_duration
該配置項記錄的慢Query語句的閾值默認是1秒,也可以通過修改該配置項記錄小于1秒的慢Query語句。某個語句的執行時間大于或等于該設置值時,慢查詢日志會記錄該語句、執行時間以及其它相關信息。將該參數設置為-1則表示不記錄任何慢查詢。
示例如下;
設置當前數據庫記錄大于5秒的慢Query語句,需要高權限用戶進行設置。
ALTER DATABASE '<數據庫名稱>' SET slow_query_min_duration = '5s';
設置當前Session記錄大于5秒的慢Query語句,普通用戶可以執行。
SET slow_query_min_duration = '5s';
slow_query_plan_min_duration
該配置項記錄的執行計劃信息,系統將默認展示大于等于10秒的慢執行計劃。當某個語句的執行時間大于等于該數值時,慢查詢日志會記錄該語句的執行計劃。通常情況下,可以通過
explain
命令連接SELECT語句即時查看執行計劃,無需記錄。該參數取值設置為-1則表示關閉對執行計劃的記錄。示例如下:
設置記錄大于10秒的執行計劃,需要高權限用戶進行設置。
ALTER DATABASE '<數據庫名稱>' SET slow_query_plan_min_duration = '10s';
設置記錄大于10秒的執行計劃,普通用戶可以執行。
SET slow_query_plan_min_duration = '10s';
附錄
qmonitor.instance_slow_queries(實例級別)
視圖的各個字段如下:字段
類型
說明
query_id
text
查詢ID,代表Query的唯一性。
session_id
integer
查詢會話的ID。
db_name
character varying(128)
查詢的數據庫名。
user_name
character varying(128)
查詢的用戶名。
application_name
character varying(128)
查詢應用類型。
client_hostname
character varying(128)
Query的來源客戶端Hostname地址。
client_addr
character varying(128)
Query的來源客戶端IP地址。
client_port
character varying(32)
Query的來源客戶端端口。
rsg_name
character varying(128)
如果開啟了資源管理resource group,則查詢的是所在resource group的組名。
query_start
timestamptz
查詢開始時間。
query_end
timestamptz
查詢結束時間。
query_duration_ms
bigint
查詢的耗時(ms)。
query_duration代表SQL的總耗時時間,其中包含:
optimizer_duration_ms
lock_wait_time_ms
queue_wait_time_ms
executor_duration_ms
optimizer_duration_ms
bigint
生成執行計劃的耗時(ms),耗時較高通常是因為SQL較復雜。
lock_wait_time_ms
bigint
查詢等鎖耗時(ms)。
queue_wait_time_ms
bigint
查詢等待資源隊列耗時(ms)。
executor_duration_ms
bigint
該查詢在執行引擎上運行耗時(ms)。
query
text
查詢文本內容。
is_plpgsql
boolean
查詢是否為一個PL/PGSQL存儲過程。
query_optimizer
character varying(16)
查詢所使用的優化器(ORCA or Planner)。
access_tables
text
查詢所訪問的表名。
result_rows
bigint
返回查詢的行數。
如果是INSERT命令,則返回插入的行數。
num_segments
integer
查詢所在計算節點的個數。
num_slices
integer
查詢計劃生成slice的個數。
cpu_time_ms
numeric
總的CPU使用時間(ms)。
包含如下時間:
協調節點Master上消耗的CPU時間。
所有計算節點上任務所耗費CPU時間的累加值。
mem_bytes
numeric
各節點上使用內存峰值的累加值為非精確值,可以粗略地體現Query的內存使用量。
spill_bytes
numeric
由于在計算過程中,內存不足可能導致數據落盤。落盤峰值的累加值并非精確值,反映了查詢在所有計算節點上落盤文件峰值的累加情況,即查詢操作所使用的落盤空間。
qmonitor.host_slow_queries(節點級別)
視圖的各個字段如下:字段
類型
說明
hostname
character varying(128)
節點所在的hostname。
hostrole
text
節點的角色包含以下兩種:
master(協調節點)
segment(計算節點)
query_id
text
查詢ID,代表Query的唯一性。
db_name
character varying(128)
查詢數據庫名。
user_name
character varying(128)
查詢用戶名。
query_start
timestamptz
查詢開始時間。
query_end
timestamptz
查詢結束時間。
query
text
查詢文本內容。
query_duration_ms
bigint
查詢耗時(ms)。
optimizer_duration_ms
bigint
生產執行計劃的耗時(ms),通常耗時較高是因為SQL較為復雜。
host_cpu_time_ms
numeric
該節點上查詢使用CPU時間(ms)。
host_mem_bytes
numeric
該節點上查詢使用的內存峰值。
host_spill_bytes
numeric
該節點上查詢過程中落盤的峰值。