Statistiche meno recenti sulle query attive

Le query attive meno recenti, note anche come query con esecuzione più lunga, sono un elenco delle query attive nel database, ordinate in base alla durata di esecuzione. Ottenere insight su queste query può aiutare a identificare le cause della latenza di sistema e dell'elevato utilizzo della CPU mentre si verificano.

Spanner fornisce una tabella integrata,SPANNER_SYS.OLDEST_ACTIVE_QUERIES, che elenca le query in esecuzione, incluse quelle contenenti istruzioni DML, ordinate per ora di inizio, in ordine crescente. Non include le query di modifiche in tempo reale.

Se hai un numero elevato di query in esecuzione, i risultati potrebbero essere limitati a un sottoinsieme di query totali a causa dei vincoli di memoria che il sistema applica alla raccolta di questi dati. Di conseguenza, Spanner fornisce una tabella aggiuntiva, SPANNER_SYS.ACTIVE_QUERIES_SUMMARY, che mostra le statistiche di riepilogo per tutte le query attive (ad eccezione delle query di modifiche in tempo reale). Puoi recuperare le informazioni da entrambe le tabelle integrate utilizzando le istruzioni SQL.

In questa pagina, descriveremo entrambe le tabelle, mostreremo alcuni esempi di query che le utilizzano e, infine, dimostreremo come utilizzarle per mitigare i problemi causati dalle query attive.

Disponibilità

I dati di SPANNER_SYS sono disponibili solo tramite le interfacce SQL, ad esempio:

Altri metodi di lettura singoli forniti da Spanner non supportano SPANNER_SYS.

OLDEST_ACTIVE_QUERIES

SPANNER_SYS.OLDEST_ACTIVE_QUERIES restituisce un elenco di query attive ordinate in base all'ora di inizio. Se hai un numero elevato di query in esecuzione, i risultati potrebbero essere limitati a un sottoinsieme di query totali a causa dei vincoli di memoria che Spanner applica alla raccolta di questi dati. Tutte le colonne della tabella sono nulli. Per visualizzare le statistiche riepilogative per tutte le query attive, vedi ACTIVE_QUERIES_SUMMARY.

Schema tabella

Nome colonna Tipo Descrizione
START_TIME TIMESTAMP Ora di inizio della query.
TEXT_FINGERPRINT INT64 L'impronta è un hash delle operazioni coinvolte nella transazione.
TEXT STRING Il testo dell'istruzione della query.
TEXT_TRUNCATED BOOL True se il testo della query nel campo TEXT è troncato; in caso contrario, è falso.
SESSION_ID STRING L'ID della sessione che sta eseguendo la query. Se elimini l'ID sessione, la query verrà annullata.

Esempi di query

Puoi eseguire le seguenti istruzioni SQL di esempio utilizzando le librerie client, Google Cloud CLI o la console Google Cloud.

Elenco delle query in esecuzione meno recenti

La seguente query restituisce un elenco delle query in esecuzione meno recenti ordinate in base all'ora di inizio della query.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC;
start_time text_fingerprint testo text_truncated session_id
2020-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId come b_id, b.AlbumId come b_albumid, b.TrackId come b_trackId FROM Brani come CROSS JOIN Brani come b; False AC3PvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw
2020-07-18T07:54:08.622081Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; False ACFBPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ
2020-07-18T07:54:08.631744Z -105437553161169030 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 7 LIMIT 1000000; False ACjbPvanq3MesDNT98t64KdKAz3TlDZoCC-zgW-FJn91cJHuczQ_cOFN_Hdflw
2020-07-18T07:54:08.720011Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; False AC3PvYIE2QHkhnmMXuAGpB4inK7yMnQjmYgQ9FoygKNaB5KCXu7Sf7f9aghYw
2020-07-18T07:54:08.731006Z 6561582859583559006 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 10 LIMIT 1000000; False AC3PvYNZ06N2YyvwV0YMlSRBNDtXBqZEK-iAAyPFnFcTmshPvzWkhr034ud7w

Elenco delle prime 2 query meno recenti in esecuzione

Una leggera variazione rispetto alla query precedente, questo esempio restituisce le prime 2 query in esecuzione meno recenti ordinate in base all'ora di inizio della query.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 2;
Output query
start_time text_fingerprint testo text_truncated session_id
2020-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId come b_id, b.AlbumId come b_albumid, b.TrackId come b_trackId FROM Brani come CROSS JOIN Brani come b; False AC3PvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw
2020-07-18T07:54:08.622081Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; False ACFBPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ

ACTIVE_QUERIES_SUMMARY

Come suggerisce il nome, la tabella integrata SPANNER_SYS.ACTIVE_QUERIES_SUMMARY mostra le statistiche di riepilogo per tutte le query attive. Come mostrato nello schema seguente, le query vengono raggruppate per età in tre bucket, o contatori, più vecchi di un secondo, più vecchi di 10 secondi e più vecchi di 100 secondi.

Schema tabella

Nome colonna Tipo Descrizione
ACTIVE_COUNT INT64 Il numero totale di query attualmente in esecuzione.
OLDEST_START_TIME TIMESTAMP Un limite superiore all'ora di inizio della query in esecuzione meno recente.
COUNT_OLDER_THAN_1S INT64 Il numero di query precedenti a un secondo.
COUNT_OLDER_THAN_10S INT64 Il numero di query precedenti a 10 secondi.
COUNT_OLDER_THAN_100S INT64 Il numero di query precedenti a 100 secondi.

Una query può essere conteggiata in più di uno di questi bucket. Ad esempio, se una query è stata eseguita per 12 secondi, verrà conteggiata in COUNT_OLDER_THAN_1S e COUNT_OLDER_THAN_10S perché soddisfa entrambi i criteri.

Esempi di query

Puoi eseguire le seguenti istruzioni SQL di esempio utilizzando le librerie client, gcloud spanner o la console Google Cloud.

Recupero di un riepilogo delle query attive

La seguente query restituisce le statistiche di riepilogo sulle query in esecuzione.

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 query
active_count oldest_start_time count_older_than_1s count_older_than_10s count_older_than_100s
22 2020-07-18T07:52:28.225877Z 21 21 1

Limitazioni

Sebbene l'obiettivo sia fornire gli insight più completi possibili, in alcuni casi le query non vengono incluse nei dati restituiti in queste tabelle.

  • Le query DML (UPDATE/INSERT/DELETE) non vengono incluse se sono nella fase Applica mutazioni.

  • Una query non viene inclusa se è nel bel mezzo di un riavvio a causa di un errore temporaneo.

  • Non sono incluse le query provenienti da server sovraccarichi o che non rispondono.

  • Impossibile utilizzare OLDEST_ACTIVE_QUERIES in una transazione di lettura/scrittura. Anche in una transazione di sola lettura, ignora il timestamp della transazione e restituisce sempre i dati correnti al momento dell'esecuzione. In rari casi, potrebbe restituire un errore ABORTED con risultati parziali; in questo caso, ignora questi risultati e riprova a eseguire la query.

Utilizzo dei dati delle query attive per risolvere i problemi di utilizzo elevato della CPU

Le statistiche sulle query e le statistiche sulle transazioni forniscono informazioni utili per la risoluzione dei problemi di latenza in un database Spanner. Questi strumenti forniscono informazioni sulle query già completate. Tuttavia, a volte è necessario sapere cosa è attualmente in esecuzione nel sistema. Considera ad esempio lo scenario in cui l'utilizzo della CPU è piuttosto elevato e vuoi rispondere alle seguenti domande.

  • Quante query sono in esecuzione al momento?
  • Quali sono queste query?
  • Quante query vengono eseguite per molto tempo, ovvero superiori a 100 secondi?
  • In quale sessione è in esecuzione la query?

Rispondendo alle domande precedenti, puoi decidere di intraprendere le seguenti azioni.

  • Elimina la sessione che esegue la query per una risoluzione immediata.
  • Migliora le prestazioni delle query aggiungendo un indice.
  • Riduci la frequenza della query se è associata a un'attività in background periodica.
  • Identifica l'utente o il componente che invia la query che potrebbe non essere autorizzato a eseguire la query.

In questa procedura dettagliata, esaminiamo le query attive e determiniamo quali azioni intraprendere.

Recupero di un riepilogo delle query attualmente attive

Nel nostro scenario di esempio, notiamo un utilizzo della CPU superiore al normale, quindi decidiamo di eseguire la seguente query per restituire un riepilogo delle query attive.

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

La query restituisce i seguenti risultati.

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

Si è scoperto che attualmente una query è in esecuzione per più di 100 secondi. Si tratta di un caso insolito per il nostro database, quindi vogliamo effettuare ulteriori accertamenti.

Recupero di un elenco di query attive

Nel passaggio precedente abbiamo stabilito che una query è in esecuzione per oltre 100 secondi.Per ulteriori indagini, eseguiamo la seguente query per restituire maggiori informazioni sulle prime 5 query in esecuzione meno recenti.

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

In questo esempio, abbiamo eseguito la query il 18 luglio 2020 alle 00:54:18 circa PDT circa e ha restituito i seguenti risultati. Potrebbe essere necessario scorrere in orizzontale per vedere l'intero output.

start_time text_fingerprint testo text_truncated session_id
2020-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 ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw
2020-07-18T07:54:08.622081Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; False ACFBPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ
2020-07-18T07:54:08.631744Z -105437553161169030 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 7 LIMIT 1000000; False ACjbPvanq3MesDNT98t64KdKAz3TlDZoCC-zgW-FJn91cJHuczQ_cOFN_Hdflw
2020-07-18T07:54:08.720011Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; False AC3PvYIE2QHkhnmMXuAGpB4inK7yMnQjmYgQ9FoygKNaB5KCXu7Sf7f9aghYw
2020-07-18T07:54:08.731006Z 6561582859583559006 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Canzoni come JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 10 LIMIT 1000000; False AC3PvYNZ06N2YyvwV0YMlSRBNDtXBqZEK-iAAyPFnFcTmshPvzWkhr034ud7w

La query meno recente (impronta = -3426560921851907385) è evidenziata nella tabella. È un CROSS JOIN costoso. Decidiamo quindi di agire.

Annullare una query costosa

Abbiamo trovato una query che stava eseguendo una costosa CROSS JOIN, quindi abbiamo deciso di annullarla. I risultati della query nel passaggio precedente includevano un session_id, ovvero l'ID della sessione che sta eseguendo la query. Possiamo quindi eseguire questo comando gcloud spanner databases sessions delete per eliminare la sessione utilizzando quell'ID, il che a sua volta annulla la query.

gcloud spanner databases sessions delete\
   ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw \
    --database=singer_db --instance=test-instance

Questa procedura dettagliata illustra come utilizzare SPANNER_SYS.OLDEST_ACTIVE_QUERIES e SPANNER_SYS.ACTIVE_QUERIES_SUMMARY per analizzare le nostre query in esecuzione e, se necessario, intervenire su tutte le query che contribuiscono a un utilizzo elevato della CPU. Naturalmente, è sempre più economico evitare operazioni costose e progettare lo schema giusto per i tuoi casi d'uso. Per saperne di più sulla creazione di istruzioni SQL eseguite in modo efficiente, vedi le best practice per SQL.

Passaggi successivi