Ketika instans Hologres merespons secara lambat atau kueri membutuhkan waktu terlalu lama, log kueri lambat membantu Anda mengidentifikasi dan mendiagnosis masalah tersebut. Topik ini menjelaskan cara melakukan kueri pada tabel hologres.hg_query_log, menginterpretasikan bidang-bidang utama, serta menggunakan SQL diagnostik untuk mengidentifikasi akar permasalahan performa.
Panduan versi
| Versi | Perubahan |
|---|---|
| V0.10 | Memperkenalkan log kueri lambat. Log untuk kueri yang GAGAL tidak mencakup statistik waktu proses (memori, pembacaan disk, volume data yang dibaca, waktu CPU, atau query_stats). |
| V2.2 | Menambahkan kolom digest (sidik jari SQL) ke hg_query_log. |
| V2.2.7 | Mengubah nilai default log_min_duration_statement dari 1.000 ms menjadi 100 ms. |
| V3.0.2 | Menambahkan catatan agregasi untuk operasi DML dan DQL yang berjalan di bawah 100 ms. Juga menambahkan bidang calls dan agg_stats. |
| V3.0.27 | Menambahkan dukungan untuk memodifikasi periode retensi log melalui hg_query_log_retention_time_sec. |
Fitur ini memerlukan Hologres V0.10 atau yang lebih baru. Untuk memeriksa versi instans Anda, buka halaman detail instans di Konsol Hologres. Untuk meningkatkan instans versi sebelumnya, lihat Kesalahan umum persiapan peningkatan atau hubungi dukungan Hologres. Untuk informasi selengkapnya, lihat Bagaimana cara mendapatkan dukungan online tambahan?.
Batasan
Log kueri lambat disimpan selama satu bulan secara default.
Satu kueri mengembalikan maksimal 10.000 entri log kueri lambat. Beberapa bidang memiliki batas panjang — lihat deskripsi bidang di bagian tabel
hg_query_log.Log kueri lambat merupakan bagian dari gudang metadata Hologres. Pencarian log kueri lambat yang gagal tidak memengaruhi kueri bisnis Anda, dan ketersediaan log tidak dicakup oleh Perjanjian Tingkat Layanan (SLA) Hologres.
Cara kerja
Hologres menyimpan log kueri lambat dalam tabel sistem `hologres.hg_query_log`. Tabel ini hanya mencatat pernyataan SQL yang telah selesai — kueri yang masih berjalan tidak ditulis ke dalam tabel. Perilaku ini konsisten di seluruh versi V2, V3, dan versi setelahnya.
Apa yang dicatat:
Setelah Anda meningkatkan ke V0.10: kueri DML lambat yang berjalan lebih dari 100 ms, dan semua operasi DDL.
Mulai dari V3.0.2: selain catatan rinci untuk kueri di atas 100 ms, catatan agregasi juga ditulis untuk kueri DQL dan DML yang selesai dalam waktu kurang dari 100 ms.
Cara kerja agregasi (V3.0.2+):
Untuk kueri cepat (di bawah 100 ms), sistem mengelompokkan kueri DQL dan DML yang berhasil dan memiliki sidik jari SQL (digest) yang sama. Kunci agregasi adalah: server_addr, usename, datname, warehouse_id, application_name, dan digest. Setiap koneksi mengirim satu catatan agregasi per menit.
Tabel hg_query_log
Tabel ini memiliki dua jenis catatan, yang berbagi skema yang sama tetapi memiliki semantik berbeda:
| Bidang | Tipe data | Catatan rinci (di atas 100 ms) | Catatan agregasi (di bawah 100 ms) |
|---|---|---|---|
usename | text | Username untuk kueri tersebut. | Username untuk kueri tersebut. |
status | text | SUCCESS atau FAILED. | Selalu SUCCESS (hanya kueri yang berhasil yang diagregasi). |
query_id | text | ID kueri unik. Kueri yang gagal selalu memiliki query_id; kueri yang berhasil mungkin tidak. | query_id dari kueri pertama dalam periode agregasi dengan kunci agregasi yang sama. |
digest | text | Sidik jari SQL (hash MD5). Ditambahkan di V2.2. Untuk informasi selengkapnya, lihat Sidik jari SQL. | Sidik jari SQL. |
datname | text | Nama database. | Nama database. |
command_tag | text | Jenis kueri: DML (COPY, DELETE, INSERT, SELECT, UPDATE), DDL (ALTER TABLE, BEGIN, COMMENT, COMMIT, CREATE FOREIGN TABLE, CREATE TABLE, DROP FOREIGN TABLE, DROP TABLE, IMPORT FOREIGN SCHEMA, ROLLBACK, TRUNCATE TABLE), atau Lainnya (CALL, CREATE EXTENSION, EXPLAIN, GRANT, SECURITY LABEL). | command_tag dari kueri pertama dalam periode agregasi. |
warehouse_id | integer | ID gudang virtual yang digunakan untuk kueri. | ID gudang virtual dari kueri pertama dalam periode agregasi. |
warehouse_name | integer | Nama gudang virtual yang digunakan untuk kueri. | Nama gudang virtual dari kueri pertama dalam periode agregasi. |
warehouse_cluster_id | integer | Ditambahkan di V3.0.2. ID kluster dalam gudang virtual. ID kluster dimulai dari 1. | ID kluster dari kueri pertama dalam periode agregasi. |
duration | integer | Durasi total kueri dalam milidetik. Terbagi menjadi tiga tahap — lihat di bawah. | Durasi rata-rata dari semua kueri dalam periode agregasi. |
message | text | Pesan kesalahan untuk kueri yang gagal. | Kosong. |
query_start | timestamptz | Waktu mulai kueri. | query_start dari kueri pertama dalam periode agregasi. |
query_date | text | Tanggal mulai kueri. | query_date dari kueri pertama dalam periode agregasi. |
query | text | Teks kueri. Maksimal 51.200 karakter; kueri yang lebih panjang dipotong. | Teks kueri dari kueri pertama dalam periode agregasi. |
result_rows | bigint | Baris yang dikembalikan. Untuk INSERT, jumlah baris yang dimasukkan. | Nilai rata-rata dari semua kueri dalam periode agregasi. |
result_bytes | bigint | Byte yang dikembalikan. | Nilai rata-rata. |
read_rows | bigint | Baris yang dibaca (tidak eksak; mungkin berbeda dari baris yang benar-benar dipindai saat indeks bitmap digunakan). | Nilai rata-rata. |
read_bytes | bigint | Byte yang dibaca. | Nilai rata-rata. |
affected_rows | bigint | Baris yang dipengaruhi oleh pernyataan DML. | Nilai rata-rata. |
affected_bytes | bigint | Byte yang dipengaruhi oleh pernyataan DML. | Nilai rata-rata. |
memory_bytes | bigint | Penggunaan memori puncak kumulatif di seluruh node (tidak eksak). Mencerminkan jumlah data yang dibaca oleh kueri. | Nilai rata-rata. |
shuffle_bytes | bigint | Perkiraan byte yang di-shuffle melalui jaringan (tidak eksak). | Nilai rata-rata. |
cpu_time_ms | bigint | Total waktu CPU dalam milidetik di seluruh tugas komputasi (tidak eksak). Mencerminkan kompleksitas kueri. | Nilai rata-rata. |
physical_reads | bigint | Jumlah batch catatan yang dibaca dari disk. Mencerminkan frekuensi cache miss. | Nilai rata-rata. |
pid | integer | ID proses layanan kueri. | ID proses dari kueri pertama dalam periode agregasi. |
application_name | text | Identifikasi aplikasi. Lihat nilai application_name. | Jenis aplikasi. |
engine_type | text[] | Mesin eksekusi yang digunakan. Lihat Jenis mesin. | Mesin dari kueri pertama dalam periode agregasi. |
client_addr | text | Alamat IP sumber (IP egress aplikasi, belum tentu IP aplikasi sebenarnya). | Alamat sumber dari kueri pertama dalam periode agregasi. |
table_write | text | Tabel tempat data ditulis. | Target penulisan dari kueri pertama dalam periode agregasi. |
table_read | text[] | Tabel dari mana data dibaca. | Sumber pembacaan dari kueri pertama dalam periode agregasi. |
session_id | text | ID sesi. | ID sesi dari kueri pertama dalam periode agregasi. |
session_start | timestamptz | Waktu koneksi dibuat. | Waktu mulai sesi dari semua kueri dalam periode agregasi. |
command_id | text | ID perintah atau pernyataan. | ID perintah dari semua kueri dalam periode agregasi. |
optimization_cost | integer | Waktu untuk menghasilkan rencana eksekusi kueri (ms). Nilai tinggi menunjukkan pernyataan SQL yang kompleks. | Waktu pembuatan rencana dari semua kueri dalam periode agregasi. |
start_query_cost | integer | Waktu startup kueri (ms). Nilai tinggi menunjukkan kueri sedang menunggu lock atau sumber daya. | Waktu startup dari semua kueri dalam periode agregasi. |
get_next_cost | integer | Waktu eksekusi kueri (ms). Nilai tinggi menunjukkan komputasi besar dan eksekusi memakan waktu lama. | Waktu eksekusi dari semua kueri dalam periode agregasi. |
extended_cost | text | Detail waktu lainnya, termasuk: build_dag (waktu untuk membangun grafik asiklik terarah (DAG) komputasi; nilai tinggi menunjukkan akses metadata lambat untuk tabel eksternal), prepare_reqs (waktu untuk menyiapkan permintaan bagi mesin eksekusi; nilai tinggi menunjukkan resolusi alamat shard lambat), dan bidang khusus Serverless (serverless_allocated_cores, serverless_allocated_workers, serverless_resource_used_time_ms). | Biaya tambahan dari kueri pertama dalam periode agregasi. |
plan | text | Rencana eksekusi kueri. Maksimal 102.400 karakter; rencana yang lebih panjang dipotong. Dikontrol oleh log_min_duration_query_plan. | Rencana eksekusi dari kueri pertama dalam periode agregasi. |
statistics | text | Statistik eksekusi kueri. Maksimal 102.400 karakter. Dikontrol oleh log_min_duration_query_stats. | Statistik eksekusi dari kueri pertama dalam periode agregasi. |
visualization_info | text | Data visualisasi rencana kueri. | Data visualisasi dari kueri pertama dalam periode agregasi. |
query_detail | text | Informasi kueri tambahan dalam format JSON. Maksimal 10.240 karakter; nilai yang lebih panjang dipotong. | Info tambahan dari kueri pertama dalam periode agregasi. |
query_extinfo | text[] | Info kueri tambahan dalam format array. Termasuk serverless_computing untuk kueri Serverless. Mulai dari V2.0.29, juga menangkap ID AccessKey akun. Catatan: ID AccessKey tidak direkam untuk akun lokal, Service-Linked Roles (SLR), atau login Layanan Token Keamanan (STS). Untuk akun sementara, hanya ID AccessKey sementara yang direkam. | Info tambahan dari kueri pertama dalam periode agregasi. |
calls | INT | Selalu 1 untuk catatan rinci (tanpa agregasi). Ditambahkan di V3.0.2. | Jumlah kueri dengan kunci agregasi yang sama dalam periode agregasi. |
agg_stats | JSONB | Kosong. Ditambahkan di V3.0.2. | Statistik MIN, MAX, dan AVG untuk bidang numerik (duration, memory_bytes, cpu_time_ms, physical_reads, optimization_cost, start_query_cost, get_next_cost). |
extended_info | JSONB | Informasi tambahan tentang Antrian Kueri dan Komputasi Serverless. Lihat nilai extended_info. | Kosong. |
Memahami rincian `duration`:
Bidang duration merepresentasikan total waktu kueri dan terdiri dari tiga tahap:
| Tahap | Bidang | Makna | Kapan nilainya tinggi |
|---|---|---|---|
| Pembuatan rencana | optimization_cost | Waktu untuk mengompilasi rencana eksekusi | Pernyataan SQL kompleks |
| Startup | start_query_cost | Waktu sebelum eksekusi dimulai | Menunggu lock atau sumber daya |
| Eksekusi | get_next_cost | Waktu untuk menjalankan kueri | Komputasi besar dan eksekusi memakan waktu lama |
Gunakan extended_cost untuk detail waktu tambahan di luar ketiga tahap tersebut.
Nilai application_name
| Sumber | Format |
|---|---|
| Realtime Compute for Apache Flink (VVR) | {client_version}_ververica-connector-hologres |
| Flink open source | {client_version}_hologres-connector-flink |
| Sinkronisasi offline DataWorks | datax_{jobId} |
| Sinkronisasi tulis offline DataWorks | {client_version}_datax_{jobId} |
| Sinkronisasi real-time DataWorks | {client_version}_streamx_{jobId} |
| HoloWeb | holoweb |
| Akses tabel eksternal MaxCompute | MaxCompute |
| Auto Analyze | AutoAnalyze |
| Quick BI | QuickBI_public_{version} |
| Penjadwalan DataWorks | {client_version}_dwscheduler_{tenant_id}_{scheduler_id}_{scheduler_task_id}_{bizdate}_{cyctime}_{scheduler_alisa_id} |
| Penjaga Keamanan Data | dsg |
Untuk aplikasi lainnya, atur application_name secara eksplisit dalam string koneksi.
Jenis mesin
| Mesin | Deskripsi |
|---|---|
| HQE | Mesin proprietary asli Hologres. Sebagian besar kueri menggunakan HQE untuk efisiensi eksekusi tinggi. |
| PQE | Mesin PostgreSQL. Saat PQE muncul, beberapa operator SQL tidak didukung secara native oleh HQE. Menulis ulang seperti yang dijelaskan dalam Optimalkan performa kueri dapat meningkatkan performa. |
| FixedQE | Mesin eksekusi untuk Fixed Plan. Secara efisien menangani SQL tipe serving seperti point reads, point writes, dan PrefixScan. Sebelumnya disebut SDK (diganti nama di V2.2). Untuk informasi selengkapnya, lihat Percepat eksekusi SQL dengan Fixed Plan. |
| PG | Komputasi lokal frontend untuk kueri metadata pada tabel sistem. Tidak membaca data tabel pengguna. Pernyataan DDL juga menggunakan PG. |
Nilai extended_info
Bidang extended_info mencatat sumber eksekusi Komputasi Serverless:
Nilai serverless_computing_source | Makna |
|---|---|
user_submit | Kueri diajukan secara manual untuk dijalankan pada sumber daya Serverless, terlepas dari Antrian Kueri. |
query_queue | Semua kueri dalam antrian kueri tertentu dijalankan pada sumber daya Serverless. Lihat Gunakan sumber daya Komputasi Serverless untuk mengeksekusi kueri dalam antrian kueri. |
query_queue_rerun | Kueri dijalankan ulang secara otomatis pada sumber daya Serverless oleh fitur kontrol kueri besar dari Antrian Kueri. Lihat Kontrol kueri besar. |
Ketika serverless_computing_source bernilai query_queue_rerun, bidang query_id_of_triggered_rerun juga muncul, menampilkan ID kueri asli dari pernyataan yang dijalankan ulang.
Prasyarat
Untuk melihat log kueri lambat, Anda memerlukan salah satu izin berikut:
View logs for all databases in an instance:
Superuser: Jalankan perintah berikut. Ganti
ID akun Alibaba Clouddengan username aktual. Untuk Pengguna RAM, gunakanp4_AccountID(ID akun, bukan nama Pengguna RAM).ALTER USER "ID akun Alibaba Cloud" SUPERUSER;Grup pg_read_all_stats (untuk non-superuser): Hubungi superuser untuk menambahkan Anda ke grup ini.
-- Otorisasi PostgreSQL standar GRANT pg_read_all_stats TO "ID akun Alibaba Cloud"; -- Model izin sederhana (SPM) CALL spm_grant('pg_read_all_stats', 'ID akun Alibaba Cloud'); -- Model izin tingkat skema (SLPM) CALL slpm_grant('pg_read_all_stats', 'ID akun Alibaba Cloud');
View logs for current database only:
Aktifkan SPM atau SLPM dan tambahkan pengguna ke peran db_admin.
-- SPM
CALL spm_grant('<db_name>_admin', 'ID akun Alibaba Cloud');
-- SLPM
CALL slpm_grant('<db_name>.admin', 'ID akun Alibaba Cloud');Pengguna biasa hanya dapat melihat kueri mereka sendiri di database saat ini, tanpa pengaturan tambahan.
Lihat log kueri lambat
Hologres menyediakan dua cara untuk melihat log kueri lambat. Gunakan HoloWeb untuk eksplorasi visual — gunakan SQL untuk filter kustom, rentang waktu, dan ekspor.
| Metode | Paling cocok untuk | Batasan |
|---|---|---|
| HoloWeb | Eksplorasi visual dan analisis tren | Hanya superuser; hanya 7 hari terakhir |
SQL (hg_query_log table) | Rentang waktu kustom, penyaringan, dan ekspor | Memerlukan izin yang sesuai |
Lihat di HoloWeb
Login ke Konsol HoloWeb.
Di bilah navigasi atas, klik Diagnostics and Optimization.
Di panel navigasi kiri, klik Historical Slow Query.
Atur kondisi kueri di bagian atas halaman Historical Slow Query. Untuk deskripsi parameter, lihat Historical Slow Queries.
Klik Search. Hasil muncul di dua area:
Query Trend Analysis: menunjukkan frekuensi kueri lambat dan gagal dari waktu ke waktu, membantu Anda mengidentifikasi periode bermasalah.
Queries: mencantumkan informasi rinci untuk setiap kueri lambat atau gagal. Klik Customize Columns untuk memilih kolom yang akan ditampilkan.
Kueri dengan SQL
Lakukan kueri langsung pada tabel hologres.hg_query_log untuk fleksibilitas penuh. Lihat Diagnosa kueri untuk contoh SQL siap pakai.
Sidik jari SQL
Mulai dari V2.2, kolom digest dalam hg_query_log menyimpan sidik jari SQL untuk setiap kueri. Untuk SELECT, INSERT, DELETE, dan UPDATE, Hologres menghitung hash MD5 sebagai sidik jari.
Kapan menggunakan `digest` vs `query_id`:
Gunakan
digestuntuk mengelompokkan dan menganalisis kueri dengan pola yang sama — misalnya, untuk menemukan pola kueri mana yang paling banyak mengonsumsi CPU rata-rata.Gunakan
query_iduntuk melacak eksekusi kueri tertentu — misalnya, untuk mengambil detail lengkap dari kueri gagal tertentu.
Cara menghitung sidik jari:
Sidik jari hanya dikumpulkan untuk SELECT, INSERT, DELETE, dan UPDATE.
Spasi diabaikan (spasi, jeda baris, tab).
Nilai konstan diabaikan:
SELECT * FROM t WHERE a > 1danSELECT * FROM t WHERE a > 2menghasilkan sidik jari yang sama.Jumlah elemen array diabaikan:
WHERE a IN (1, 2)danWHERE a IN (3, 4, 5)menghasilkan sidik jari yang sama.Untuk INSERT dengan data konstan, sidik jari tidak dipengaruhi oleh jumlah baris yang dimasukkan.
Huruf besar/kecil mengikuti aturan kueri Hologres.
Sidik jari mencakup nama database dan skema fully qualified, sehingga
SELECT * FROM tdanSELECT * FROM public.tmemiliki sidik jari yang sama hanya jikatberada di skemapublicdan kedua kueri merujuk ke tabel yang sama.
Diagnosa kueri
Contoh SQL berikut mencakup skenario diagnostik paling umum. Semua kueri menargetkan hologres.hg_query_log.
Hitung semua kueri dalam log (default: bulan lalu):
SELECT count(*) FROM hologres.hg_query_log;Contoh output — 44 kueri lambat dalam sebulan terakhir:
count
-------
44
(1 row)Hitung kueri lambat per pengguna:
SELECT usename AS "User",
count(1) AS "Query count"
FROM hologres.hg_query_log
GROUP BY usename
ORDER BY count(1) DESC;Contoh output:
User | Query count
---------------------+-------------
1111111111111111 | 27
2222222222222222 | 11
3333333333333333 | 4
4444444444444444 | 2
(4 rows)Cari kueri tertentu berdasarkan ID:
SELECT * FROM hologres.hg_query_log WHERE query_id = '13001450118416xxxx';Untuk deskripsi bidang yang dikembalikan, lihat Tabel hg_query_log.
Temukan kueri intensif sumber daya dalam 10 menit terakhir:
Sesuaikan interval agar sesuai dengan jendela waktu target Anda.
SELECT status AS "Status",
duration AS "Duration (ms)",
query_start AS "Start time",
(read_bytes / 1048576)::text || ' MB' AS "Data read",
(memory_bytes / 1048576)::text || ' MB' AS "Memory",
(shuffle_bytes / 1048576)::text || ' MB' AS "Shuffle",
(cpu_time_ms / 1000)::text || ' s' AS "CPU time",
physical_reads AS "Disk reads",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
read_bytes DESC,
shuffle_bytes DESC,
memory_bytes DESC,
cpu_time_ms DESC,
physical_reads DESC
LIMIT 100;Contoh output:
Status | Duration (ms) | Start time | Data read | Memory | Shuffle | CPU time | Disk reads | Query ID | query
---------+---------------+------------------------+-----------+--------+---------+----------+------------+--------------------+--------------------------------
SUCCESS | 149 | 2021-03-30 23:45:01+08 | 0 MB | 25 MB | 454 MB | 321 s | 0 | 13001450118416xxxx | explain analyze SELECT * FROM
SUCCESS | 137 | 2021-03-30 23:49:18+08 | 247 MB | 21 MB | 213 MB | 803 s | 7771 | 13001491818416xxxx | explain analyze SELECT * FROM
FAILED | 53 | 2021-03-30 23:48:43+08 | 0 MB | 0 MB | 0 MB | 0 s | 0 | 13001484318416xxxx | SELECT ds::bigint / 0 FROM pub
(3 rows)Skenario: Diagnosa penggunaan CPU atau memori tinggi setelah peningkatan versi instans
Kueri ini sangat berguna ketika penggunaan CPU atau memori melonjak setelah Anda meningkatkan instans Hologres ke versi baru. Untuk mengidentifikasi kueri yang menyebabkan konsumsi sumber daya tinggi:
Sesuaikan rentang waktu dalam klausa
WHEREagar mencakup periode ketika penggunaan CPU atau memori tidak normal. Misalnya, gantiinterval '10 min'dengan rentang yang sesuai dengan jendela lonjakan tersebut.Tambahkan
ORDER BY cpu_time_ms DESCuntuk menemukan kueri intensif CPU, atauORDER BY memory_bytes DESCuntuk menemukan kueri intensif memori.Periksa kolom
query_id,usename, danquerydalam hasil untuk mengidentifikasi kueri spesifik dan pemiliknya, lalu analisis dan optimalkan kueri tersebut.
Rincian durasi berdasarkan tahap:
Gunakan ini untuk mengidentifikasi tahap mana (optimization_cost, start_query_cost, atau get_next_cost) yang paling banyak menyumbang keterlambatan. Lihat tabel rincian durasi di bagian tabel hg_query_log untuk detail setiap tahap.
SELECT status AS "Status",
duration AS "Duration (ms)",
optimization_cost AS "Optimization cost (ms)",
start_query_cost AS "Startup cost (ms)",
get_next_cost AS "Execution cost (ms)",
duration - optimization_cost - start_query_cost - get_next_cost AS "Other cost (ms)",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
start_query_cost DESC,
optimization_cost,
get_next_cost DESC,
duration - optimization_cost - start_query_cost - get_next_cost DESC
LIMIT 100;Contoh output:
Status | Duration (ms) | Optimization cost (ms) | Startup cost (ms) | Execution cost (ms) | Other cost (ms) | Query ID | query
---------+---------------+------------------------+-------------------+---------------------+-----------------+--------------------+--------------------------------
SUCCESS | 4572 | 521 | 320 | 3726 | 5 | 6000260625679xxxx | -- /* user: wang ip: xxx.xx.x
SUCCESS | 1490 | 538 | 98 | 846 | 8 | 12000250867886xxxx | -- /* user: lisa ip: xxx.xx.x
SUCCESS | 1230 | 502 | 95 | 625 | 8 | 26000512070295xxxx | -- /* user: zhang ip: xxx.xx.
(3 rows)Lihat volume kueri dan data yang dibaca per jam (3 jam terakhir):
SELECT date_trunc('hour', query_start) AS query_start,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY 1;Bandingkan trafik dengan jendela yang sama kemarin:
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY query_date
UNION ALL
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1d 3h'
AND query_start <= now() - interval '1d'
GROUP BY query_date;Temukan kueri gagal pertama dalam jendela waktu:
SELECT status AS "Status",
regexp_replace(message, '\n', ' ')::char(150) AS "Error message",
duration AS "Duration (ms)",
query_start AS "Start time",
query_id AS "Query ID",
query::char(100) AS "Query"
FROM hologres.hg_query_log
WHERE query_start BETWEEN '2021-03-25 17:00:00'::timestamptz
AND '2021-03-25 17:42:00'::timestamptz + interval '2 min'
AND status = 'FAILED'
ORDER BY query_start ASC
LIMIT 100;Contoh output:
Status | Error message | Duration (ms) | Start time | Query ID | Query
--------+--------------------------------------------------------------+---------------+------------------------+--------------------+-------
FAILED | Query:[1070285448673xxxx] code: kActorInvokeError msg: "..." | 1460 | 2021-03-25 17:28:54+08 | 1070285448673xxxx | S...
FAILED | Query:[1016285560553xxxx] code: kActorInvokeError msg: "..." | 131 | 2021-03-25 17:28:55+08 | 1016285560553xxxx | S...
(2 rows)Temukan pola kueri baru dari kemarin (jumlah total):
Kueri yang muncul untuk pertama kalinya dibandingkan dengan hari sebelum kemarin, dikelompokkan berdasarkan sidik jari.
SELECT COUNT(1)
FROM (
SELECT DISTINCT t1.digest
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND digest IS NOT NULL
) AS a;Contoh output — 10 pola kueri baru kemarin:
count
-------
10
(1 row)Temukan pola kueri baru dari kemarin (berdasarkan jenis):
SELECT a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1
ORDER BY 2 DESC;Contoh output:
command_tag | count
-------------+-------
INSERT | 8
SELECT | 2
(2 rows)Temukan pola kueri baru dari kemarin (dengan detail):
SELECT a.usename, a.status, a.query_id, a.digest,
a.datname, a.command_tag, a.query, a.cpu_time_ms, a.memory_bytes
FROM (
SELECT DISTINCT
t1.usename, t1.status, t1.query_id, t1.digest,
t1.datname, t1.command_tag, t1.query, t1.cpu_time_ms, t1.memory_bytes
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a;Temukan pola kueri baru dari kemarin (berdasarkan jam):
SELECT to_char(a.query_start, 'HH24') AS query_start_hour,
a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.query_start, t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1, 2
ORDER BY 3 DESC;Contoh output — pada pukul 21:00 kemarin, 8 pola INSERT; pada pukul 11:00 dan 13:00, masing-masing 1 pola SELECT:
query_start_hour | command_tag | count
------------------+-------------+-------
21 | INSERT | 8
11 | SELECT | 1
13 | SELECT | 1
(3 rows)Hitung kueri lambat berdasarkan sidik jari (kemarin):
SELECT digest,
command_tag,
count(1)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
GROUP BY 1, 2
ORDER BY 3 DESC;Temukan 10 pola kueri dengan rata-rata waktu CPU tertinggi (hari terakhir):
SELECT digest,
avg(cpu_time_ms)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND usename != 'system'
AND cpu_time_ms IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;Temukan 10 pola kueri dengan rata-rata penggunaan memori tertinggi (minggu terakhir):
SELECT digest,
avg(memory_bytes)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '7 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND memory_bytes IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;Parameter konfigurasi
Gunakan parameter GUC berikut untuk mengontrol apa yang dicatat dan seberapa detail informasi yang diambil.
log_min_duration_statement
Mengontrol durasi minimum kueri untuk pencatatan log.
Default: 100 ms (mulai dari V2.2.7; versi sebelumnya default 1.000 ms).
Nilai minimum: 100 ms.
Atur ke `-1` untuk menonaktifkan pencatatan log kueri lambat sepenuhnya.
Hanya superuser yang dapat mengubahnya di tingkat database. Pengguna biasa dapat mengubahnya di tingkat sesi.
Perubahan hanya berlaku untuk kueri baru.
-- Tingkat database (hanya superuser)
ALTER DATABASE dbname SET log_min_duration_statement = '250ms';
-- Tingkat sesi
SET log_min_duration_statement = '250ms';log_min_duration_query_stats
Mengontrol apakah statistik eksekusi diambil untuk suatu kueri.
Default: mencatat statistik untuk kueri yang berjalan lebih dari 10 detik.
Atur ke `-1` untuk menonaktifkan pengumpulan statistik.
Statistik menggunakan ruang penyimpanan signifikan. Turunkan nilai ini hanya untuk troubleshooting terarah; kembalikan setelah selesai.
Perubahan hanya berlaku untuk kueri baru.
-- Tingkat database (hanya superuser)
ALTER DATABASE dbname SET log_min_duration_query_stats = '20s';
-- Tingkat sesi
SET log_min_duration_query_stats = '20s';log_min_duration_query_plan
Mengontrol apakah rencana eksekusi diambil untuk suatu kueri.
Default: mencatat rencana untuk kueri yang berjalan lebih dari 10 detik.
Atur ke `-1` untuk menonaktifkan pengambilan rencana.
Untuk troubleshooting ad hoc, gunakan
EXPLAINsebagai gantinya — ini mengembalikan rencana secara instan tanpa mencatat log.Perubahan hanya berlaku untuk kueri baru.
-- Tingkat database (hanya superuser)
ALTER DATABASE dbname SET log_min_duration_query_plan = '10s';
-- Tingkat sesi
SET log_min_duration_query_plan = '10s';Ubah retensi log
Mulai dari V3.0.27, Anda dapat mengubah berapa lama log kueri lambat disimpan di tingkat database.
ALTER DATABASE <db_name> SET hg_query_log_retention_time_sec = 2592000;| Aspek | Detail |
|---|---|
| Satuan | Detik |
| Rentang | 3–30 hari (259.200–2.592.000 detik) |
| Cakupan | Hanya log baru (log yang sudah ada tetap menggunakan retensi aslinya) |
| Berlaku untuk | Hanya koneksi baru |
| Pembersihan | Log yang kedaluwarsa dihapus segera, bukan secara asinkron |
Ekspor log kueri lambat
Ekspor data dari hg_query_log ke tabel internal Hologres, tabel eksternal MaxCompute, atau OSS untuk penyimpanan atau analisis jangka panjang.
Sebelum mengekspor, perhatikan:
Akun yang menjalankan perintah
INSERT INTO ... SELECT ... FROM hologres.hg_query_logharus memiliki akses kehg_query_log. Untuk ekspor seluruh instans, diperlukan izin superuser ataupg_read_all_stats— jika tidak, data yang diekspor akan tidak lengkap.query_startadalah kolom terindeks. Selalu sertakan dalam klausa WHERE Anda untuk meningkatkan performa dan mengurangi penggunaan sumber daya.Jangan menerapkan fungsi pada
query_startdalam klausa WHERE — ini mencegah penggunaan indeks.-- Benar: gunakan kondisi rentang langsung pada query_start WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04' -- Salah: membungkus query_start dalam fungsi melewati indeks WHERE to_char(query_start, 'yyyymmdd') = '20220101'
Ekspor ke tabel internal Hologres
-- Langkah 1: Buat tabel target
CREATE TABLE query_log_download (
usename text,
status text,
query_id text,
datname text,
command_tag text,
duration integer,
message text,
query_start timestamp with time zone,
query_date text,
query text,
result_rows bigint,
result_bytes bigint,
read_rows bigint,
read_bytes bigint,
affected_rows bigint,
affected_bytes bigint,
memory_bytes bigint,
shuffle_bytes bigint,
cpu_time_ms bigint,
physical_reads bigint,
pid integer,
application_name text,
engine_type text[],
client_addr text,
table_write text,
table_read text[],
session_id text,
session_start timestamp with time zone,
trans_id text,
command_id text,
optimization_cost integer,
start_query_cost integer,
get_next_cost integer,
extended_cost text,
plan text,
statistics text,
visualization_info text,
query_detail text,
query_extinfo text[]
);
-- Langkah 2: Ekspor log untuk tanggal tertentu
INSERT INTO query_log_download
SELECT
usename, status, query_id, datname, command_tag, duration, message,
query_start, query_date, query, result_rows, result_bytes, read_rows,
read_bytes, affected_rows, affected_bytes, memory_bytes, shuffle_bytes,
cpu_time_ms, physical_reads, pid, application_name, engine_type,
client_addr, table_write, table_read, session_id, session_start,
trans_id, command_id, optimization_cost, start_query_cost, get_next_cost,
extended_cost, plan, statistics, visualization_info, query_detail, query_extinfo
FROM hologres.hg_query_log
WHERE query_start >= '2022-08-03'
AND query_start < '2022-08-04';Ekspor ke tabel eksternal MaxCompute
Di MaxCompute, buat tabel partisi untuk menerima data:
CREATE TABLE IF NOT EXISTS mc_holo_query_log ( username STRING COMMENT 'Username untuk kueri', status STRING COMMENT 'Status akhir kueri: success atau failed', query_id STRING COMMENT 'ID kueri', datname STRING COMMENT 'Nama database untuk kueri', command_tag STRING COMMENT 'Jenis kueri', duration BIGINT COMMENT 'Durasi kueri dalam milidetik (ms)', message STRING COMMENT 'Pesan kesalahan', query STRING COMMENT 'Isi teks kueri', read_rows BIGINT COMMENT 'Jumlah baris yang dibaca oleh kueri', read_bytes BIGINT COMMENT 'Jumlah byte yang dibaca oleh kueri', memory_bytes BIGINT COMMENT 'Konsumsi memori puncak pada satu node (tidak eksak)', shuffle_bytes BIGINT COMMENT 'Perkiraan jumlah byte untuk shuffle data (tidak eksak)', cpu_time_ms BIGINT COMMENT 'Total waktu CPU dalam milidetik (tidak eksak)', physical_reads BIGINT COMMENT 'Jumlah pembacaan fisik', application_name STRING COMMENT 'Jenis aplikasi kueri', engine_type ARRAY<STRING> COMMENT 'Mesin yang digunakan untuk kueri', table_write STRING COMMENT 'Tabel tempat pernyataan SQL menulis data', table_read ARRAY<STRING> COMMENT 'Tabel dari mana pernyataan SQL membaca data', plan STRING COMMENT 'Rencana eksekusi untuk kueri', optimization_cost BIGINT COMMENT 'Waktu untuk menghasilkan rencana eksekusi kueri', start_query_cost BIGINT COMMENT 'Waktu startup kueri', get_next_cost BIGINT COMMENT 'Durasi eksekusi kueri', extended_cost STRING COMMENT 'Biaya detail lainnya dari kueri', query_detail STRING COMMENT 'Informasi tambahan lainnya tentang kueri (format JSON)', query_extinfo ARRAY<STRING> COMMENT 'Informasi tambahan lainnya tentang kueri (format ARRAY)', query_start STRING COMMENT 'Waktu mulai kueri', query_date STRING COMMENT 'Tanggal mulai kueri' ) COMMENT 'Log kueri instans Hologres' PARTITIONED BY (ds STRING COMMENT 'tanggal stat') LIFECYCLE 365; ALTER TABLE mc_holo_query_log ADD PARTITION (ds=20220803);Di Hologres, impor tabel MaxCompute sebagai tabel eksternal dan ekspor log:
IMPORT FOREIGN SCHEMA project_name LIMIT TO (mc_holo_query_log) FROM SERVER odps_server INTO public; INSERT INTO mc_holo_query_log SELECT usename AS username, status, query_id, datname, command_tag, duration, message, query, read_rows, read_bytes, memory_bytes, shuffle_bytes, cpu_time_ms, physical_reads, application_name, engine_type, table_write, table_read, plan, optimization_cost, start_query_cost, get_next_cost, extended_cost, query_detail, query_extinfo, query_start, query_date, '20220803' FROM hologres.hg_query_log WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04';
FAQ
Baris yang dikembalikan kueri dan baris yang dibaca tidak muncul di Hologres V1.1.
Hal ini terjadi karena pengumpulan log kueri lambat tidak lengkap di versi V1.1 yang terpengaruh. Di V1.1.36 hingga V1.1.49, aktifkan parameter GUC berikut untuk mengumpulkan statistik lengkap:
-- Tingkat database (disarankan — atur sekali per database)
ALTER DATABASE <db_name> SET hg_experimental_force_sync_collect_execution_statistics = ON;
-- Tingkat sesi
SET hg_experimental_force_sync_collect_execution_statistics = ON;Ganti <db_name> dengan nama database Anda.
Jika instans Anda lebih awal dari V1.1.36, lihat Kesalahan umum persiapan peningkatan atau hubungi dukungan Hologres. Untuk informasi selengkapnya, lihat Bagaimana cara mendapatkan dukungan online tambahan?.
Perilaku ini telah diperbaiki secara default di V1.1.49 dan versi setelahnya.
Apakah durasi dalam log kueri lambat mencakup waktu Fetching?
Tidak. Bidang duration dalam log kueri lambat Hologres hanya mengukur waktu eksekusi di sisi server, yang terdiri dari pembuatan rencana (optimization_cost), startup (start_query_cost), dan komputasi (get_next_cost). Bidang ini tidak mencakup waktu yang dihabiskan klien untuk mengambil data hasil (fase Fetching).
Jika kueri dari tool BI seperti Quick BI memakan waktu jauh lebih lama daripada pernyataan SQL yang sama yang dijalankan di HoloWeb atau dari command line, penyebab umumnya adalah:
Tool BI mengirim beberapa kueri secara konkuren, yang meningkatkan waktu respons keseluruhan di bawah paralelisme tinggi.
Bidang
get_next_costmencakup waktu transfer jaringan untuk mengirim data hasil dari server ke klien. Nilaiget_next_costyang tinggi mungkin mencerminkan latensi pengambilan data di sisi klien, bukan komputasi lambat di sisi server.
Untuk membedakan antara keterlambatan sisi server dan sisi klien, jalankan kueri dengan EXPLAIN ANALYZE dan periksa bidang get_next_cost. Nilai get_next_cost yang tinggi dikombinasikan dengan nilai optimization_cost dan start_query_cost yang rendah biasanya menunjukkan bahwa waktu tersebut dihabiskan untuk transfer data, bukan eksekusi kueri.
Langkah selanjutnya
Untuk memantau dan mengelola kueri aktif di instans Anda, lihat Kelola kueri.