Statistik kueri aktif terlama

Kueri aktif terlama, juga dikenal sebagai kueri yang berjalan paling lama, adalah daftar kueri yang aktif di database Anda, yang diurutkan berdasarkan durasi berjalannya. Mendapatkan insight tentang kueri ini dapat membantu mengidentifikasi penyebab latensi sistem dan penggunaan CPU yang tinggi saat terjadi.

Spanner menyediakan tabel bawaan,SPANNER_SYS.OLDEST_ACTIVE_QUERIES, yang mencantumkan kueri yang sedang berjalan, termasuk kueri yang berisi pernyataan DML, yang diurutkan berdasarkan waktu mulai, dalam urutan menaik. Fitur ini tidak mencakup kueri aliran perubahan.

Jika ada banyak kueri yang sedang berjalan, hasilnya mungkin dibatasi hanya pada sebagian kueri karena batasan memori yang diterapkan sistem pada pengumpulan data ini. Oleh karena itu, Spanner menyediakan tabel tambahan, SPANNER_SYS.ACTIVE_QUERIES_SUMMARY, yang menampilkan statistik ringkasan untuk semua kueri aktif (kecuali kueri aliran perubahan). Anda dapat mengambil informasi dari kedua tabel bawaan ini menggunakan pernyataan SQL.

Dalam dokumen ini, kita akan menjelaskan kedua tabel, menunjukkan beberapa contoh kueri yang menggunakan tabel ini, dan terakhir, mendemonstrasikan cara menggunakannya untuk membantu mengurangi masalah yang disebabkan oleh kueri aktif.

Mengakses statistik kueri aktif terlama

Data SPANNER_SYS hanya tersedia melalui antarmuka SQL; misalnya:

Spanner tidak mendukung SPANNER_SYS dengan metode baca tunggal berikut:

  • Melakukan pembacaan yang kuat dari satu baris atau beberapa baris dalam tabel.
  • Melakukan pembacaan basi dari satu baris atau beberapa baris dalam tabel.
  • Membaca dari satu baris atau beberapa baris dalam indeks sekunder.

Statistik OLDEST_ACTIVE_QUERIES

SPANNER_SYS.OLDEST_ACTIVE_QUERIES menampilkan daftar kueri aktif yang diurutkan berdasarkan waktu mulai. Jika ada banyak kueri yang berjalan, hasilnya mungkin dibatasi hanya pada sebagian kueri karena batasan memori yang diterapkan Spanner pada pengumpulan data ini. Untuk melihat statistik ringkasan untuk semua kueri aktif, lihat ACTIVE_QUERIES_SUMMARY.

Skema untuk semua tabel statistik kueri aktif terlama

Nama kolom Jenis Deskripsi
START_TIME TIMESTAMP Waktu mulai kueri.
TEXT_FINGERPRINT INT64 Sidik jari adalah hash tag permintaan, atau jika tag tidak ada, hash teks kueri.
TEXT STRING Teks pernyataan kueri.
TEXT_TRUNCATED BOOL Jika teks kueri di kolom TEXT dipangkas, nilai ini adalah TRUE. Jika teks kueri tidak dipangkas, nilai ini adalah FALSE.
SESSION_ID STRING ID sesi yang menjalankan kueri.
QUERY_ID STRING ID kueri. Anda dapat menggunakan ID ini dengan CALL cancel_query(query_id) untuk membatalkan kueri.
CLIENT_IP_ADDRESS STRING Alamat IP klien yang meminta kueri. Terkadang, alamat IP klien mungkin disamarkan. Alamat IP yang ditampilkan di sini konsisten dengan log audit dan mengikuti pedoman penyensoran yang sama. Untuk mengetahui informasi selengkapnya, lihat Alamat IP pemanggil di log audit. Sebaiknya minta alamat IP klien hanya jika alamat IP klien diperlukan, karena permintaan alamat IP klien dapat menimbulkan latensi tambahan.
API_CLIENT_HEADER STRING Header api_client dari klien.
USER_AGENT_HEADER STRING Header user_agent yang diterima Spanner dari klien.
SERVER_REGION STRING Region tempat server root Spanner memproses kueri. Untuk mengetahui informasi selengkapnya, lihat Siklus proses kueri.
PRIORITY STRING Prioritas kueri. Untuk melihat prioritas yang tersedia, lihat RequestOptions.
TRANSACTION_TYPE STRING Jenis transaksi kueri. Nilai yang mungkin adalah READ_ONLY, READ_WRITE, dan NONE.

Contoh kueri

Anda dapat menjalankan pernyataan SQL contoh berikut menggunakan library klien, Google Cloud CLI, atau konsolGoogle Cloud .

Mencantumkan kueri aktif yang berjalan paling lama

Kueri berikut menampilkan daftar kueri terlama yang sedang berjalan, yang diurutkan berdasarkan waktu mulai kueri.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id,
       query_id,
       api_client_header,
       server_region,
       priority,
       transaction_type
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC;
Output kueri

Tabel berikut menunjukkan output untuk menjalankan kueri yang disebutkan sebelumnya:

start_time text_fingerprint teks biasa text_truncated session_id query_id api_client_header server_region priority transaction_type
2025-05-20T03:29:54.287255Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; FALSE AG46FS6K3adF 9023439241169932454 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_HIGH READ_ONLY
2025-05-20T03:31:52.40808Z 1688332608621812214 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; FALSE AG46FS6paJPKDOb 2729381896189388167 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_HIGH READ_WRITE
2025-05-20T03:31:52.591212Z 6561582859583559006 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 10 LIMIT 1000000; FALSE AG46FS7Pb_9H6J6p 9125776389780080794 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_LOW READ_ONLY

Mencantumkan 2 kueri terlama yang sedang berjalan

Sedikit berbeda dengan kueri sebelumnya, contoh ini menampilkan 2 kueri yang berjalan paling lama yang diurutkan berdasarkan waktu mulai kueri.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 2;
Output kueri

Tabel berikut menunjukkan output untuk menjalankan kueri yang disebutkan sebelumnya:

start_time text_fingerprint teks biasa text_truncated session_id
2039-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; Salah ACjbPvYsuRt
2039-07-18T07:54:08.622081Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; Salah ACjbPvaF3yK

ACTIVE_QUERIES_SUMMARY

Tabel statistik SPANNER_SYS.ACTIVE_QUERIES_SUMMARY menampilkan statistik ringkasan untuk semua kueri aktif. Kueri dikelompokkan ke dalam bucket berikut:

  • lebih lama dari 1 detik
  • lebih lama dari 10 detik
  • lebih lama dari 100 detik

Skema tabel untuk ACTIVE_QUERIES_SUMMARY

Nama kolom Jenis Deskripsi
ACTIVE_COUNT INT64 Jumlah total kueri yang sedang berjalan.
OLDEST_START_TIME TIMESTAMP Batas atas pada waktu mulai kueri yang berjalan paling lama.
COUNT_OLDER_THAN_1S INT64 Jumlah kueri yang lebih lama dari 1 detik.
COUNT_OLDER_THAN_10S INT64 Jumlah kueri yang lebih lama dari 10 detik.
COUNT_OLDER_THAN_100S INT64 Jumlah kueri yang lebih lama dari 100 detik.

Kueri dapat dihitung di lebih dari satu bucket ini. Misalnya, jika kueri telah berjalan selama 12 detik, kueri tersebut akan dihitung dalam COUNT_OLDER_THAN_1S dan COUNT_OLDER_THAN_10S karena memenuhi kedua kriteria.

Contoh kueri

Anda dapat menjalankan pernyataan SQL contoh berikut menggunakan library klien, gcloud spanner, atau Google Cloud konsol.

Mengambil ringkasan kueri aktif

Kueri berikut menampilkan statistik ringkasan tentang kueri yang sedang berjalan.

SELECT active_count,
       oldest_start_time,
       count_older_than_1s,
       count_older_than_10s,
       count_older_than_100s
FROM spanner_sys.active_queries_summary;
Output kueri
active_count oldest_start_time count_older_than_1s count_older_than_10s count_older_than_100s
22 2039-07-18T07:52:28.225877Z 21 21 1

Batasan

Meskipun tujuannya adalah memberi Anda insight yang paling komprehensif, ada beberapa kondisi yang menyebabkan kueri tidak disertakan dalam data yang ditampilkan di tabel ini.

  • Kueri DML (UPDATE, INSERT, DELETE) tidak disertakan jika berada dalam fase Terapkan mutasi.

  • Kueri tidak disertakan jika sedang dalam proses memulai ulang karena error sementara.

  • Kueri dari server yang kelebihan beban atau tidak responsif tidak disertakan.

  • Membaca atau membuat kueri dari tabel OLDEST_ACTIVE_QUERIES tidak dapat dilakukan dalam transaksi baca-tulis. Bahkan dalam transaksi hanya baca, perintah ini mengabaikan stempel waktu transaksi dan selalu menampilkan data saat ini pada saat eksekusinya. Dalam kasus yang jarang terjadi, API ini dapat menampilkan error ABORTED dengan hasil parsial; dalam kasus tersebut, hapus hasil parsial dan coba kueri lagi.

  • Jika kolom CLIENT_IP_ADDRESS menampilkan string <error>, hal ini menunjukkan masalah sementara yang tidak akan memengaruhi kueri lainnya. Coba lagi kueri untuk mengambil alamat IP klien.

Menggunakan data kueri aktif untuk memecahkan masalah pemakaian CPU yang tinggi

Statistik kueri dan statistik transaksi memberikan informasi yang berguna saat memecahkan masalah latensi dalam database Spanner. Alat ini memberikan informasi tentang kueri yang sudah selesai. Namun, terkadang Anda perlu mengetahui apa yang berjalan di sistem. Misalnya, pertimbangkan skenario saat penggunaan CPU cukup tinggi dan Anda ingin menjawab pertanyaan berikut.

  • Berapa banyak kueri yang sedang berjalan saat ini?
  • Apa saja kueri tersebut?
  • Berapa banyak kueri yang berjalan dalam waktu lama, yaitu lebih dari 100 detik?
  • Sesi mana yang menjalankan kueri?

Dengan jawaban atas pertanyaan sebelumnya, Anda dapat memutuskan untuk mengambil tindakan berikut.

  • Hapus sesi yang menjalankan kueri untuk segera menyelesaikan masalah.
  • Tingkatkan performa kueri dengan menambahkan indeks.
  • Kurangi frekuensi kueri jika terkait dengan tugas latar belakang berkala.
  • Identifikasi pengguna atau komponen yang mengeluarkan kueri yang mungkin tidak memiliki otorisasi untuk menjalankan kueri.

Dalam panduan ini, kita akan memeriksa kueri aktif dan menentukan tindakan apa yang perlu diambil, jika ada.

Mengambil ringkasan kueri aktif

Dalam contoh skenario, kita melihat penggunaan CPU yang lebih tinggi dari biasanya, jadi kita memutuskan untuk menjalankan kueri berikut untuk menampilkan ringkasan kueri aktif.

SELECT active_count,
       oldest_start_time,
       count_older_than_1s,
       count_older_than_10s,
       count_older_than_100s
FROM spanner_sys.active_queries_summary;

Kueri akan menghasilkan hasil berikut.

active_count oldest_start_time count_older_than_1s count_older_than_10s count_older_than_100s
22 2039-07-18T07:52:28.225877Z 21 21 1

Ternyata ada satu kueri yang berjalan selama lebih dari 100 detik. Hal ini tidak biasa terjadi pada database kami, jadi kami ingin menyelidikinya lebih lanjut.

Mengambil daftar kueri aktif

Pada langkah sebelumnya, kita telah menentukan bahwa ada kueri yang berjalan selama lebih dari 100 detik.Untuk menyelidiki lebih lanjut, kita menjalankan kueri berikut untuk menampilkan informasi selengkapnya tentang 5 kueri terlama yang sedang berjalan.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id,
       query_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 5;

Dalam contoh ini, kami menjalankan kueri pada 28 Maret 2024 sekitar pukul 16.44.09 PM EDT dan kueri tersebut menampilkan hasil berikut. (Anda mungkin perlu men-scroll secara horizontal untuk melihat seluruh output.)

start_time text_fingerprint teks biasa text_truncated session_id query_id
2024-03-28 16:44:09.356939+00:00 -2833175298673875968 select * from spanner_sys.oldest_active_queries false ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw 37190103859320827
2039-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; false ACjbPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ 48946620525959556

Kueri terlama (sidik jari = -2833175298673875968) ditandai dalam tabel. Ini adalah CROSS JOIN yang mahal. Kami memutuskan untuk mengambil tindakan.

Membatalkan kueri yang mahal

Dalam contoh ini, kita menemukan kueri yang menjalankan CROSS JOIN mahal, jadi kita memutuskan untuk membatalkan kueri tersebut. Hasil kueri yang kami terima pada langkah sebelumnya menyertakan query_id. Kita dapat menjalankan perintah CALL cancel_query(query_id) berikut untuk GoogleSQL dan perintah spanner.cancel_query(query_id) untuk PostgreSQL untuk membatalkan kueri.

GoogleSQL

CALL cancel_query(query_id)

PostgreSQL

CALL spanner.cancel_query(query_id)

Misalnya, pada contoh berikut, pernyataan CALL membatalkan kueri dengan ID 37190103859320827:

CALL cancel_query('37190103859320827')

Anda perlu membuat kueri tabel spanner_sys.oldest_active_queries untuk memverifikasi bahwa kueri dibatalkan.

Panduan ini menunjukkan cara menggunakan SPANNER_SYS.OLDEST_ACTIVE_QUERIES dan SPANNER_SYS.ACTIVE_QUERIES_SUMMARY untuk menganalisis kueri yang sedang berjalan dan mengambil tindakan jika perlu pada kueri yang menyebabkan penggunaan CPU tinggi. Tentu saja, selalu lebih murah untuk menghindari operasi yang mahal dan mendesain skema yang tepat untuk kasus penggunaan Anda. Untuk mengetahui informasi selengkapnya tentang cara membuat pernyataan SQL yang berjalan secara efisien, lihat Praktik terbaik SQL.

Langkah berikutnya