全部產品
Search
文件中心

ApsaraDB for ClickHouse:查詢日誌分析

更新時間:Oct 10, 2024

通過查詢日誌,您可以查看查詢的執行情況、識別慢查詢,有助於您提升系統效能和解決潛在問題。本文介紹如何通過SQL查看雲資料庫ClickHouse的查詢日誌。

前提條件

確保查詢日誌已開啟。

說明
  • ClickHouse預設查詢日誌已開啟。

  • 您可以通過執行SHOW settings like 'log_queries'; 來檢查參數配置log_queries,以確認查詢日誌是否已開啟。如果該參數配置為1,則表示查詢日誌已開啟;若該參數為0,則表示查詢日誌未開啟。您可以通過以下SQL語句開啟查詢日誌。

    SET GLOBAL ON CLUSTER default log_queries = 1;

注意事項

  • 查詢日誌可能會包含敏感資訊,請妥善管理查詢日誌資訊。

  • 定期清理歸檔查詢日誌,避免記錄檔太大。

    說明
    • ClickHouse中為query_log表預設配置了15天的TTL策略,查詢日誌產生後會在15天后自動刪除。

    • 如果您希望減少查詢日誌相關的系統資料表佔用的磁碟空間,可以通過控制台參數管理功能修改query_log表的TTL策略。為了方便定位執行個體問題,建議您query_log表的TTL策略至少設定為7天。如何修改參數,請參見配置config.xml參數

樣本環境

以下樣本以s-2-r-0節點為基礎環境,在實際使用過程中,請根據您的情境修改對應參數。如果您不知道如何擷取節點名稱,可以通過以下方式擷取。

  • 通過控制台:您可以在叢集監控頁面,擷取節點名稱。如何進入叢集監控頁面,請參見查看叢集監控資訊

  • 通過SQL語句:您可以執行以下語句,擷取叢集所有節點的名稱。

    SELECT * FROM system.clusters;

查看最近報錯的Query

查看報錯日誌對於提升系統的穩定性和安全性具有重要意義。主要體現在以下幾個方面:

  • 快速定位問題:通過報錯資訊可以直接定位到導致問題的具體原因,從而快速修複問題。

  • 趨勢分析:通過分析報錯日誌,識別錯誤發生的時間與模式,可以進行防禦性的代碼最佳化或者配置調整。

  • 安全:通過分析錯誤記錄檔,發現系統存在的潛在安全問題,比如SQL注入、非法訪問等。

查詢範本

SELECT
    written_rows,
    written_bytes,
    query_duration_ms,
    event_time,
    exception
FROM clusterAllReplicas('default',system.query_log) ql
WHERE ((event_time >= '<startTime>') 
       AND 
       (event_time <= '<endTime>')) AND (lowerUTF8(query) LIKE '%insert into sdk_event_record_local%') 
       AND (type != 'QueryStart')
       AND (exception_code != 0)
       [AND substring(hostname(),38,8) = '<nodeName>']
ORDER BY event_time DESC
[LIMIT <x>]

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2021-11-22 22:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2021-11-22 23:00:00

nodeName

叢集節點名稱。

s-2-r-0

x

返回查詢結果集中的前x行。

30

樣本

查詢2021-11-22 22:00:00 至 2021-11-22 23:00:00時間段內,s-2-r-0節點上的執行查詢的錯誤記錄檔資訊,返回結果中的前30行資料。

SELECT
    written_rows,
    written_bytes,
    query_duration_ms,
    event_time,
    exception
FROM clusterAllReplicas('default',system.query_log) ql
WHERE (lowerUTF8(query) LIKE '%insert into sdk_event_record_local%') AND 
 ((event_time >= '2021-11-22 22:00:00') 
       AND 
       (event_time <= '2021-11-22 23:00:00')) 
       AND (type != 'QueryStart')
       AND (exception_code != 0)
AND substring(hostname(),38,8) = 's-2-r-0'
ORDER BY event_time DESC
LIMIT 30

查看最近SQL

寫入SQL

查詢範本

--查看最新寫入的SQL,每個batch的行數和bytes大小:
SELECT
    written_rows,
    written_bytes,
    query_duration_ms,
    event_time
FROM clusterAllReplicas('default',system.query_log) ql
WHERE ((event_time >= '<startTime>') 
       AND (event_time <= '<endTime>'))
       AND (lowerUTF8(query) ILIKE '%insert into%') AND (type != 'QueryStart')
       [AND substring(hostname(),38,8) = '<nodeName>']
ORDER BY event_time DESC
[LIMIT x]

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2021-11-22 22:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2021-11-22 23:00:00

nodeName

叢集節點名稱。

s-2-r-0

x

返回查詢結果集中的前x行。

30

樣本

查詢2021-11-22 22:00:00 至 2021-11-22 23:00:00時間段內,s-2-r-0節點上寫入SQL的日誌資訊,返回結果中的前30行資料。

--查看最新寫入的SQL,每個batch的行數和bytes大小: 
SELECT
    written_rows,
    written_bytes,
    query_duration_ms,
    event_time
FROM clusterAllReplicas('default',system.query_log) ql
WHERE ((event_time >= '2021-11-22 22:00:00') 
       AND (event_time <= '2021-11-22 23:00:00'))
       AND (lowerUTF8(query) LIKE '%insert into sdk_event_record_local%') 
       AND (type != 'QueryStart')
       AND substring(hostname(),38,8) = 's-2-r-0'
ORDER BY event_time DESC
LIMIT 30

非寫入SQL

查詢範本

SELECT   
    event_time,   
    user,   
    query_id AS query,   
    read_rows,   
    read_bytes,   
    result_rows,   
    result_bytes,   
    memory_usage,   
    exception  
FROM clusterAllReplicas('default', system.query_log)  
WHERE (event_date = today()) AND (event_time >= (now() - <time>)) AND (is_initial_query = 1) AND (query NOT ILIKE 'INSERT INTO%'  [AND substring(hostname(),38,8) = '<nodeName>'])  
ORDER BY event_time DESC  
[LIMIT x]

參數說明

參數

說明

樣本

time

查詢目前時間往前推的時間。

單位:分。

60

nodeName

叢集節點名稱

s-2-r-0

x

返回查詢結果集中的前x行。

100

樣本

查詢s-2-r-0節點上近60分鐘的非寫入SQL,返回查詢結果中的前100條資料。

SELECT   
    event_time,   
    user,   
    query_id AS query,   
    read_rows,   
    read_bytes,   
    result_rows,   
    result_bytes,   
    memory_usage,   
    exception  
FROM clusterAllReplicas('default', system, query_log)  
WHERE (event_date = today()) AND (event_time >= (now() - 60)) AND (is_initial_query = 1) AND (query NOT LIKE 'INSERT INTO%')  
AND substring(hostname(),38,8) = 's-2-r-0'
ORDER BY event_time DESC  
LIMIT 100

查看時間段內執行次數超過n次的非寫入語句

查詢範本

SELECT *
FROM
  (SELECT LEFT(query, 100) AS SQL,
          count() AS queryNum,
          sum(query_duration_ms) AS totalTime,
          totalTime/queryNum AS avgTime
   FROM clusterAllReplicas('default', system.query_log) ql
   WHERE event_time > toDateTime('<startTime>')
     AND event_time < toDateTime('<endTime>')
     AND query not like '%INSERT INTO%'
     AND substring(hostname(), 38, 8) = '<nodeName>'
   GROUP BY SQL
   ORDER BY avgTime DESC)
WHERE queryNum > <queryNum> 
[LIMIT <x>]

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 12:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 17:00:00

queryNum

要查詢超出的次數。

1000

nodeName

叢集節點名稱。

s-2-r-0

x

返回查詢結果集中的前x行。

50

樣本

查詢2022-09-23 12:00:00 至 2022-09-23 17:00:00時間段內,s-2-r-0節點上查詢次數超過1000次的非寫入的SQL語句。

SELECT *
FROM
  (SELECT LEFT(query, 100) AS SQL,
          count() AS queryNum,
          sum(query_duration_ms) AS totalTime,
          totalTime/queryNum AS avgTime
   FROM clusterAllReplicas('default', system.query_log) ql
   WHERE event_time > toDateTime('2022-09-23 12:00:00')
     AND event_time < toDateTime('2022-09-23 17:00:00')
     AND query not like '%INSERT INTO%'
     AND substring(hostname(), 38, 8) = 's-2-r-0'
   GROUP BY SQL
   ORDER BY avgTime DESC)
WHERE queryNum > 1000
LIMIT 50

查詢一段時間內每小時或每分鐘執行查詢的統計

每小時彙總

一段時間內,每小時查詢數量的統計和查詢的平均耗時。

查詢範本

--按照每小時彙總
SELECT toHour(event_time) AS t,
       count() AS queryNum,
       sum(query_duration_ms) AS totalTime,
       totalTime/queryNum AS avgTime
FROM clusterAllReplicas('default', system.query_log) ql
WHERE event_time > toDateTime('<startTime>')
  AND event_time < toDateTime('<endTime>')
  AND query not like '%INSERT INTO%'
  AND query like '%異常容器%'
  AND read_rows != 0
  AND substring(hostname(), 38, 8) = '<nodeName>'
GROUP BY t
[LIMIT x]

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 12:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 17:00:00

nodeName

叢集節點名稱。

s-2-r-0

x

返回查詢結果集中的前x行。

50

查詢樣本

查詢2022-09-23 08:00:00 至 2022-09-23 17:00:00時間段內,s-2-r-0節點上每小時查詢數量的統計和查詢的平均耗時。

--按照每小時彙總
SELECT toHour(event_time) AS t,
       count() AS queryNum,
       sum(query_duration_ms) AS totalTime,
       totalTime/queryNum AS avgTime
FROM clusterAllReplicas('default', system.query_log) ql
WHERE event_time > toDateTime('2022-09-23 08:00:00')
  AND event_time < toDateTime('2022-09-23 17:00:00')
  AND query not like '%INSERT INTO%'
  AND query like '%異常容器%'
  AND read_rows != 0
  AND substring(hostname(), 38, 8) = 's-2-r-0'
GROUP BY t
LIMIT 50

每分鐘彙總

一段時間內,每分鐘的查詢數量統計和查詢的平均耗時。

查詢範本

--按照每分鐘彙總
SELECT toMinute(event_time) AS t,
       count() AS queryNum,
       sum(query_duration_ms) AS totalTime,
       totalTime/queryNum AS avgTime
FROM clusterAllReplicas('default', system.query_log) ql
WHERE event_time > toDateTime('<startTime>')
  AND event_time < toDateTime('<endTime>')
  AND query not like '%INSERT INTO%'
  AND query like '%異常容器%'
  AND substring(hostname(), 38, 8) = '<nodeName>'
  AND read_rows != 0
GROUP BY t
[LIMIT x]

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 12:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 17:00:00

nodeName

叢集節點名稱。

s-2-r-0

x

返回查詢結果集中的前x行。

50

查詢樣本

查詢 2022-09-23 08:00:00 至 2022-09-23 17:00:00 時間段內,s-2-r-0節點上每分鐘查詢數量的統計和查詢的平均耗時。

--按照每分鐘彙總
SELECT toMinute(event_time) AS t,
       count() AS queryNum,
       sum(query_duration_ms) AS totalTime,
       totalTime/queryNum AS avgTime
FROM clusterAllReplicas('default', system.query_log) ql
WHERE event_time > toDateTime('2022-09-23 12:00:00')
  AND event_time < toDateTime('2022-09-23 13:00:00')
  AND query not like '%INSERT INTO%'
  AND query like '%異常容器%'
  AND substring(hostname(), 38, 8) = 's-2-r-0'
  AND read_rows != 0
GROUP BY t
LIMIT 50

查看LEFT JOIN的查詢個數

查詢一個時間段內LEFT JOIN的查詢個數。

查詢範本

SELECT *
FROM
  (SELECT LEFT(query, 100) AS SQL,
          count() AS queryNum,
          sum(query_duration_ms) AS totalTime,
          totalTime/queryNum AS avgTime
   FROM clusterAllReplicas('default', system.query_log) ql
   WHERE query like '%JOIN%'
     AND read_rows != 0
     AND event_time > toDateTime('<startTime>')
     AND event_time < toDateTime('<endTime>')
     AND query not like '%INSERT INTO%'
     AND substring(hostname(), 38, 8) = '<nodeName>'
   GROUP BY SQL
   ORDER BY queryNum DESC)

參數說明

參數

說明

值樣本

startTime

要查詢資料的開始時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 12:00:00

endTime

要查詢資料的結束時間。

格式:yyyy-mm-dd hh:mi:ss

2022-09-23 21:00:00

nodeName

叢集節點名稱。

s-2-r-0

查詢樣本

查詢2024-06-25 12:00:00 至 2024-06-25 15:00:00時間段內,s-2-r-0節點上執行LEFT JOIN語句的個數。

SELECT *
FROM
  (SELECT LEFT(query, 100) AS SQL,
          count() AS queryNum,
          sum(query_duration_ms) AS totalTime,
          totalTime/queryNum AS avgTime
   FROM clusterAllReplicas('default', system.query_log) ql
   WHERE query like '%JOIN%'
     AND read_rows != 0
     AND event_time > toDateTime('2024-06-25 12:00:00')
     AND event_time < toDateTime('2024-06-25 15:00:00')
     AND query not like '%INSERT INTO%'
     AND substring(hostname(), 38, 8) = 's-2-r-0'
   GROUP BY SQL
   ORDER BY queryNum DESC)

查詢使用者執行非寫入SQL數量排行

查詢範本

SELECT   
    user,   
    count(1) AS query_times,   
    sum(read_bytes) AS query_bytes,   
    sum(read_rows) AS query_rows  
FROM clusterAllReplicas('default', system, query_log)  
WHERE (event_date = yesterday()) AND (is_initial_query = 1) AND (query NOT LIKE 'INSERT INTO%' AND substring(hostname(),38,8) = '<nodeName>')  
GROUP BY user  
ORDER BY query_times DESC  
[LIMIT x]

參數說明

參數

說明

值樣本

nodeName

叢集節點名稱

s-2-r-0

x

要查詢的排名次數。

10

樣本

查詢在s-2-r-0節點上執行非寫入查詢語句的前十名使用者。

SELECT   
    user,   
    count(1) AS query_times,   
    sum(read_bytes) AS query_bytes,   
    sum(read_rows) AS query_rows  
FROM clusterAllReplicas('default', system, query_log)  
WHERE (event_date = yesterday()) AND (is_initial_query = 1) AND (query NOT LIKE 'INSERT INTO%' AND substring(hostname(),38,8) = 's-2-r-0')  
GROUP BY user  
ORDER BY query_times DESC  
LIMIT 10