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:
Halaman Spanner Studio database di konsol Google Cloud
Perintah
gcloud spanner databases execute-sqlMetode
executeSqlatauexecuteStreamingSql
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_QUERIEStidak 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 errorABORTEDdengan hasil parsial; dalam kasus tersebut, hapus hasil parsial dan coba kueri lagi.Jika kolom
CLIENT_IP_ADDRESSmenampilkan 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
- Pelajari alat Introspeksi lainnya.
- Pelajari informasi lain yang disimpan Spanner untuk setiap database di tabel skema informasi database.
- Pelajari lebih lanjut praktik terbaik SQL untuk Spanner.