Älteste aktive Abfragen, auch als Abfragen mit längster Ausführungszeit bezeichnet, ist eine Liste der in Ihrer Datenbank aktiven Abfragen, sortiert nach ihrer Laufzeit. Einblicke in diese Abfragen können helfen, die Ursachen von Systemlatenzen und hoher CPU-Auslastung während deren Auftreten zu erkennen.
Spanner bietet die integrierte Tabelle SPANNER_SYS.OLDEST_ACTIVE_QUERIES
, in der die laufenden Abfragen, einschließlich Abfragen mit DML-Anweisungen, in aufsteigender Reihenfolge nach Beginn sortiert sind. Änderungsstreamabfragen sind darin nicht enthalten.
Wenn eine große Anzahl von Abfragen ausgeführt wird, können die Ergebnisse aufgrund von Arbeitsspeicherbeschränkungen, die das System für die Erfassung dieser Daten erzwingt, auf eine Teilmenge der gesamten Abfragen begrenzt sein. Daher stellt Spanner die zusätzliche Tabelle SPANNER_SYS.ACTIVE_QUERIES_SUMMARY
bereit, die zusammenfassende Statistiken für alle aktiven Abfragen (außer für Änderungsstreamabfragen) anzeigt.
Sie können mithilfe von SQL-Anweisungen Informationen aus diesen beiden integrierten Tabellen abrufen.
Auf dieser Seite werden beide Tabellen beschrieben, einige Beispielabfragen gezeigt, in denen diese Tabellen verwendet werden, und schließlich zeigen, wie Sie sie verwenden, um Probleme zu minimieren, die durch aktive Abfragen verursacht werden.
Verfügbarkeit
SPANNER_SYS
-Daten sind nur über SQL-Schnittstellen verfügbar. Beispiel:
Die Seite Spanner Studio einer Datenbank in der Google Cloud Console
Mit der
executeQuery
API
Andere von Spanner bereitgestellte Methoden für einzelne Leseaufrufe unterstützen SPANNER_SYS
nicht.
OLDEST_ACTIVE_QUERIES
SPANNER_SYS.OLDEST_ACTIVE_QUERIES
gibt eine Liste aktiver Abfragen zurück, nach Startzeit sortiert. Wenn eine große Anzahl von Abfragen ausgeführt wird, können die Ergebnisse aufgrund der Speichereinschränkungen, die Spanner für die Erfassung dieser Daten erzwingt, auf eine Teilmenge der gesamten Abfragen beschränkt sein.
Für alle Spalten in der Tabelle sind Nullwerte zulässig. Informationen zum Aufrufen zusammenfassender Statistiken für alle aktiven Abfragen finden Sie unter ACTIVE_QUERIES_SUMMARY
.
Tabellenschema
Spaltenname | Typ | Beschreibung |
---|---|---|
START_TIME |
TIMESTAMP |
Startzeit der Abfrage. |
TEXT_FINGERPRINT |
INT64 |
Der Fingerabdruck ist ein Hash der an der Transaktion beteiligten Vorgänge. |
TEXT |
STRING |
Der Text der Abfrageanweisung. |
TEXT_TRUNCATED |
BOOL |
"True", wenn der Abfragetext im Feld TEXT beschnitten ist. Andernfalls "false". |
SESSION_ID |
STRING |
Die ID der Sitzung, in der die Abfrage ausgeführt wird. Durch Löschen der Sitzungs-ID wird die Abfrage abgebrochen. |
Beispielabfragen
Sie können die folgenden Beispiel-SQL-Anweisungen mit den Clientbibliotheken, der Google Cloud CLI oder der Google Cloud Console ausführen.
Am längsten laufende Abfragen auflisten
Die folgende Abfrage gibt eine Liste der ältesten laufenden Abfragen zurück, nach Startzeit der Abfrage sortiert.
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 | text | 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; | Falsch | ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw |
2020-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; | False | ACjbPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ |
2020-07-18T07:54:08.631744Z | -105437553161169030 | 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 > 7 LIMIT 1000000; | Falsch | 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 Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; | Falsch | ACjbPvYIE2QHkhnmMXuAGpB4inK7yMnQjmYgQ9FoygKNaB5KCXu7Sf7f9aghYw |
2020-07-18T07:54:08.731006Z | 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; | Falsch | ACjbPvYNZ06N2YyvwV0YMlSRBNDtXBqZEK-iAAyPFnFcTmshPvzWkhr034ud7w |
Die beiden am längsten laufenden Abfragen auflisten
Als geringfügige Variation der vorhergehenden Abfrage gibt dieses Beispiel die zwei am längsten laufenden Abfragen zurück, nach Startzeit der Abfrage sortiert.
SELECT start_time,
text_fingerprint,
text,
text_truncated,
session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 2;
Ausgabe der Abfrage
start_time | text_fingerprint | text | 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; | Falsch | ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw |
2020-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; | False | ACjbPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ |
ACTIVE_QUERIES_SUMMARY
Wie der Name verrät, zeigt die integrierte Tabelle SPANNER_SYS.ACTIVE_QUERIES_SUMMARY
eine Zusammenfassungsstatistik für alle aktiven Abfragen an. Wie im folgenden Schema gezeigt, werden Abfragen nach Alter in drei Buckets oder Zähler gruppiert, die älter als eine Sekunde, älter als 10 Sekunden und älter als 100 Sekunden sind.
Tabellenschema
Spaltenname | Typ | Beschreibung |
---|---|---|
ACTIVE_COUNT |
INT64 |
Die Gesamtzahl der aktuell ausgeführten Abfragen. |
OLDEST_START_TIME |
TIMESTAMP |
Obergrenze für die Startzeit der am längsten laufenden Abfrage. |
COUNT_OLDER_THAN_1S |
INT64 |
Die Anzahl der Abfragen, die älter als 1 Sekunde sind. |
COUNT_OLDER_THAN_10S |
INT64 |
Die Anzahl der Abfragen, die älter als 10 Sekunden sind. |
COUNT_OLDER_THAN_100S |
INT64 |
Die Anzahl der Abfragen, die älter als 100 Sekunden sind. |
Abfragen können in mehr als einem dieser Buckets gezählt werden. Beispiel: Wurde eine Abfrage 12 Sekunden lang ausgeführt, so wird sie in COUNT_OLDER_THAN_1S
und COUNT_OLDER_THAN_10S
gezählt, da sie beide Kriterien erfüllt.
Beispielabfragen
Sie können die folgenden Beispiel-SQL-Anweisungen mit den Clientbibliotheken, dem gcloud spanner oder der Google Cloud Console ausführen.
Zusammenfassung aktiver Abfragen abrufen
Folgende Abfrage gibt eine Zusammenfassung der Statistiken zur Abfragenausführung zurück.
SELECT active_count,
oldest_start_time,
count_older_than_1s,
count_older_than_10s,
count_older_than_100s
FROM spanner_sys.active_queries_summary;
Ausgabe der Abfrage
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 |
Beschränkungen
Das Ziel ist es, Ihnen möglichst umfassende Einblicke zu liefern. Es gibt jedoch einige Umstände, unter denen Abfragen nicht in den Daten dieser Tabellen enthalten sind.
DML-Abfragen (UPDATE/INSERT/DELETE) werden nicht berücksichtigt, wenn sie sich in der Phase Mutationen anwenden befinden.
Eine Abfrage ist nicht enthalten, wenn sie aufgrund eines vorübergehenden Fehlers gerade neu startet.
Abfragen von überlasteten oder nicht reagierenden Servern sind nicht enthalten.
OLDEST_ACTIVE_QUERIES
kann in Lese-Schreib-Transaktionen nicht verwendet werden. Selbst in schreibgeschützten Transaktionen wird der Transaktionszeitstempel ignoriert und es werden immer aktuelle Daten bei der Ausführung zurückgegeben. In seltenen Fällen kann der FehlerABORTED
mit Teilergebnissen zurückgegeben werden. Verwerfen Sie in diesem Fall die Teilergebnisse und versuchen Sie anschließend, die Abfrage noch einmal auszuführen.
Aktive Abfragedaten zur Fehlerbehebung bei hoher CPU-Auslastung verwenden
Abfragestatistiken und Transaktionsstatistiken bieten nützliche Informationen für die Fehlerbehebung bei der Latenz in einer Spanner-Datenbank. Diese Tools liefern Informationen über die bereits abgeschlossenen Abfragen. Manchmal müssen Sie jedoch wissen, was derzeit im System ausgeführt wird. Stellen Sie sich beispielsweise ein Szenario vor, in dem die CPU-Auslastung sehr hoch ist und Sie die folgenden Fragen beantworten möchten.
- Wie viele Abfragen werden aktuell ausgeführt?
- Was sind diese Abfragen?
- Wie viele Abfragen werden für eine lange Zeit ausgeführt, d. h. länger als 100 Sekunden?
- In welcher Sitzung wird die Abfrage ausgeführt?
Aufgrund der Antworten auf vorhergehende Fragen können Sie folgende Maßnahme ergreifen.
- Löschen Sie die Sitzung, in der die Abfrage ausgeführt wird, um eine sofortige Lösung zu erhalten.
- Um die Abfrageleistung zu steigern können Sie einen Index hinzufügen.
- Reduzieren Sie die Häufigkeit der Abfrage, wenn sie einer regelmäßigen Hintergrundaufgabe zugeordnet ist.
- Identifizieren Sie den Nutzer oder die Komponente, die die Abfrage ausgibt und die möglicherweise nicht zum Ausführen der Abfrage autorisiert ist.
In dieser Schritt-für-Schritt-Anleitung untersuchen wir unsere aktiven Abfragen und bestimmen gegebenenfalls, welche Aktion ausgeführt werden soll.
Zusammenfassung der derzeit aktiven Abfragen abrufen
In unserem Beispielszenario bemerken wir eine überdurchschnittliche CPU-Auslastung. Daher führen wir die folgende Abfrage aus, um eine Zusammenfassung der aktiven Abfragen zu erhalten.
SELECT active_count,
oldest_start_time,
count_older_than_1s,
count_older_than_10s,
count_older_than_100s
FROM spanner_sys.active_queries_summary;
Die Abfrage liefert folgende Ergebnisse.
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 |
Wie sich herausstellt wird aktuell eine Abfrage ausgeführt, die bereits mehr als 100 Sekunden läuft. Dies ist ungewöhnlich für unsere Datenbank, weshalb wir es genauer untersuchen wollen.
Liste der aktiven Abfragen abrufen
Im vorherigen Schritt haben wir eine Abfrage ausgeführt, die länger als 100 Sekunden lief. Zur weiteren Untersuchung führen wir folgende Abfrage aus, um mehr Informationen zu den fünf am längsten ausgeführten Abfragen zu erhalten.
SELECT start_time,
text_fingerprint,
text,
text_truncated,
session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 5;
In diesem Beispiel haben wir die Abfrage am 18. Juli 2020 um 12:54:18 Uhr PDT ausgeführt und die folgenden Ergebnisse geliefert. (Möglicherweise müssen Sie horizontal scrollen, um die gesamte Ausgabe zu sehen.)
start_time | text_fingerprint | text | 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 Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; | False | ACjbPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ |
2020-07-18T07:54:08.631744Z | -105437553161169030 | 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 > 7 LIMIT 1000000; | Falsch | 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 Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; | Falsch | ACjbPvYIE2QHkhnmMXuAGpB4inK7yMnQjmYgQ9FoygKNaB5KCXu7Sf7f9aghYw |
2020-07-18T07:54:08.731006Z | 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; | Falsch | ACjbPvYNZ06N2YyvwV0YMlSRBNDtXBqZEK-iAAyPFnFcTmshPvzWkhr034ud7w |
Die älteste Abfrage (fingerprint = -3426560921851907385
) wird in der Tabelle hervorgehoben. Es ist ein teurer CROSS JOIN
. Wir entscheiden uns, einzugreifen.
Teure Abfragen abbrechen
Wir haben eine Abfrage gefunden, die eine teure CROSS JOIN
ausgeführt hat, daher brechen wir die Abfrage ab. Die Abfrage im vorherigen Schritt enthielt einen session_id
. Dies ist die ID der Sitzung, in der die Abfrage ausgeführt wird. Mit dem folgenden gcloud spanner databases sessions delete
-Befehl können Sie die Sitzung mit dieser ID löschen, um die Abfrage abzubrechen.
gcloud spanner databases sessions delete\
ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw \
--database=singer_db --instance=test-instance
In dieser Schritt-für-Schritt-Anleitung wird gezeigt, wie Sie mit SPANNER_SYS.OLDEST_ACTIVE_QUERIES
und SPANNER_SYS.ACTIVE_QUERIES_SUMMARY
laufende Abfragen analysieren und bei Bedarf bei Abfragen, die eine hohe CPU-Auslastung bedingen, Schritte ergreifen. Natürlich ist es immer günstiger, teure Vorgänge zu vermeiden und das richtige Schema für den jeweiligen Anwendungsfall zu entwerfen. Weitere Informationen zum Erstellen effizienter SQL-Anweisungen finden sich unter Best Practices für SQL.
Nächste Schritte
- Weitere Informationen zu Tools zur Selbstbeobachtung
- Weitere Informationen, die Spanner für jede Datenbank in den Informationsschematabellen der Datenbank speichert.
- Weitere Informationen zu Best Practices für SQL für Spanner.