

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Funktionen und Ansichten für Aurora PostgreSQL Limitless Database
<a name="limitless-monitoring-fns-views"></a>

Aurora PostgreSQL Limitless Database verfügt über hinzugefügte Funktionen und Ansichten. Sie basieren auf den entsprechenden Funktionen und Ansichten von Aurora PostgreSQL.

**Anmerkung**  
Einige Statistiken können uneinheitliche Ergebnisse zurückgeben, wenn Transaktionen im Gange sind.

**Topics**
+ [Funktionen für Aurora PostgreSQL Limitless Database](limitless-monitoring-functions.md)
+ [Ansichten für Aurora PostgreSQL Limitless Database](limitless-monitoring-views.md)

# Funktionen für Aurora PostgreSQL Limitless Database
<a name="limitless-monitoring-functions"></a>

In der folgenden Tabelle sehen Sie die neuen Funktionen für Aurora PostgreSQL Limitless Database.

**Anmerkung**  
Die in dieser Tabelle aufgeführten Funktionen befinden sich im Schema `rds_aurora`. Wenn Sie eine Limitless-Database-Funktion verwenden, stellen Sie sicher, dass Sie den vollqualifizierten Objektnamen angeben: `rds_aurora`.`object_name`.


| Funktion für Aurora PostgreSQL Limitless Database | Entsprechende Funktion für Aurora PostgreSQL | 
| --- | --- | 
| [limitless\$1backend\$1dsid](#limitless_backend_dsid) | pg\$1backend\$1pid | 
| [limitless\$1cancel\$1session](#limitless_cancel_session) | pg\$1cancel\$1backend | 
| [limitless\$1stat\$1clear\$1snapshot](#limitless_stat_clear_snapshot) | pg\$1stat\$1clear\$1snapshot | 
| [limitless\$1stat\$1database\$1size](#limitless_stat_database_size) | pg\$1database\$1size | 
| [limitless\$1stat\$1get\$1snapshot\$1timestamp](#limitless_stat_get_snapshot_timestamp) | pg\$1stat\$1get\$1snapshot\$1timestamp | 
| [limitless\$1stat\$1prepared\$1xacts](#limitless_stat_prepared_xacts) | pg\$1prepared\$1xacts | 
| [limitless\$1stat\$1relation\$1sizes](#limitless_stat_relation_sizes) | pg\$1indexes\$1size, pg\$1relation\$1size, pg\$1table\$1size, pg\$1total\$1relation\$1size | 
| [limitless\$1stat\$1reset](#limitless_stat_reset) | pg\$1stat\$1reset | 
| [limitless\$1stat\$1statements\$1reset](#limitless_stat_statements_reset) | pg\$1stat\$1statements\$1reset | 
| [limitless\$1stat\$1system\$1waits](#limitless_stat_system_waits) | aurora\$1stat\$1system\$1waits | 
| [limitless\$1terminate\$1session](#limitless_terminate_session) | pg\$1terminate\$1backend | 
| [limitless\$1wait\$1report](#limitless_wait_report) | aurora\$1wait\$1report | 

Die folgenden Beispiele enthalten Einzelheiten zu den Funktionen für Aurora PostgreSQL Limitless Database. Weitere Informationen zu PostgreSQL-Funktionen finden Sie unter [Funktionen und Operatoren](https://www.postgresql.org/docs/15/functions.html) in der PostgreSQL-Dokumentation.

**limitless\$1backend\$1dsid**  
Die Funktion `limitless_backend_dsid` gibt die ID der verteilten Sitzung zurück. Eine verteilte Sitzung wird auf einem Router in einer DB-Shard-Gruppe ausgeführt und umfasst Backend-Prozesse auf einem oder mehreren Shards in der DB-Shard-Gruppe.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_backend_dsid` verwendet werden kann.  

```
SELECT rds_aurora.limitless_backend_dsid();

limitless_backend_dsid
------------------------
8CACD7B04D0FC2A5
(1 row)
```

**limitless\$1cancel\$1session**  
Die Funktion `limitless_cancel_session` arbeitet ähnlich wie `pg_cancel_backend`, versucht aber, alle Backend-Prozesse im Zusammenhang mit der angegebenen ID einer verteilten Sitzung abzubrechen, indem sie ein `SIGINT` (Unterbrechungssignal) sendet.  
Es wird der folgende Eingabeparameter verwendet:  
+ `distributed_session_id` (Text): Die ID der verteilten Sitzung, die abgebrochen werden soll.
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `pid` (Text): Die ID des Backend-Prozesses.
+ `success` (Boolean): Ob der Abbruch erfolgreich war.
Das folgende Beispiel zeigt, wie die Funktion `limitless_cancel_session` verwendet werden kann.  

```
SELECT * FROM rds_aurora.limitless_cancel_session('940CD5C81E3C796B');

 subcluster_id |  pid  | success
---------------+-------+---------
             1 | 26920 | t
(1 row)
```

**limitless\$1stat\$1clear\$1snapshot**  
Die Funktion `limitless_stat_clear_snapshot` verwirft den aktuellen Statistik-Snapshot oder die zwischengespeicherten Informationen auf allen Knoten.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_clear_snapshot` verwendet werden kann.  

```
SELECT rds_aurora.limitless_stat_clear_snapshot();
```

**limitless\$1stat\$1database\$1size**  
Die Funktion `limitless_stat_database_size` gibt die Größen einer Datenbank in der DB-Shard-Gruppe zurück.  
Es wird der folgende Eingabeparameter verwendet:  
+ `dbname` (Name): Die Datenbank, für die die Größen abgerufen werden sollen.
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `db_size`: Die Größe der Datenbank in diesem Subcluster in Byte.
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_database_size` verwendet werden kann.  

```
SELECT * FROM rds_aurora.limitless_stat_database_size('postgres_limitless');

 subcluster_id | subcluster_type | db_size
---------------+-----------------+----------
             1 | router          |  8895919
             2 | router          |  8904111
             3 | shard           | 21929391
             4 | shard           | 21913007
             5 | shard           | 21831087
(5 rows)
```

**limitless\$1stat\$1get\$1snapshot\$1timestamp**  
Die Funktion `limitless_stat_get_snapshot_timestamp` gibt den Zeitstempel des aktuellen Statistik-Snapshots zurück, oder `NULL`, wenn kein Statistik-Snapshot erstellt wurde. Ein Snapshot wird erstellt, wenn in einer Transaktion zum ersten Mal auf kumulative Statistiken zugegriffen wird, sofern `stats_fetch_consistency` auf `snapshot` gesetzt ist. Gibt eine konsolidierte Ansicht der Snapshot-Zeitstempel von allen Knoten zurück. Die Spalten `subcluster_id` und `subcluster_type` zeigen, von welchem Knoten die Daten stammen.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_get_snapshot_timestamp` verwendet werden kann.  

```
SELECT * FROM rds_aurora.limitless_stat_get_snapshot_timestamp();

 subcluster_id | subcluster_type | snapshot_timestamp
---------------+-----------------+--------------------
             1 | router          | 
             2 | router          | 
             3 | shard           | 
             4 | shard           | 
             5 | shard           | 
(5 rows)
```

**limitless\$1stat\$1prepared\$1xacts**  
Die Funktion `limitless_stat_prepared_xacts` gibt Informationen über Transaktionen auf allen Knoten zurück, die derzeit für ein zweiphasiges Commit vorbereitet sind. Weitere Informationen finden Sie unter [pg\$1prepared\$1xacts](https://www.postgresql.org/docs/current/view-pg-prepared-xacts.html) in der PostgreSQL-Dokumentation.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_prepared_xacts` verwendet werden kann.  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_stat_prepared_xacts;

 subcluster_id | subcluster_type | transaction_id |             gid              |           prepared            |  owner_id  |    database_id
---------------+-----------------+----------------+------------------------------+-------------------------------+------------+--------------------
 8             | shard           |        5815978 | 7_4599899_postgres_limitless | 2024-09-03 15:51:17.659603+00 | auroraperf | postgres_limitless
 12            | shard           |        4599138 | 7_4599899_postgres_limitless | 2024-09-03 15:51:17.659637+00 | auroraperf | postgres_limitless
(2 rows)
```

**limitless\$1stat\$1relation\$1sizes**  
Die Funktion `limitless_stat_relation_sizes` gibt die verschiedenen Größen einer Tabelle in der DB-Shard-Gruppe zurück.  
Es werden folgende Eingabeparameter verwendet:  
+ `relnspname` (Name): Der Name des Schemas, das die Tabelle enthält.
+ `relname` (Name): Der Name der Tabelle.
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `main_size`: Die Größe der Haupt-Datenzweige in diesem Knoten in Byte.
+ `fsm_size`: Die Größe der Free-Space-Map für die Tabelle in diesem Knoten in Byte.
+ `vm_size`: Die Größe der Sichtbarkeits-Map für die Tabelle in diesem Knoten in Byte.
+ `init_size`: Die Größe der Initialisierung der Tabelle in diesem Knoten in Byte.
+ `toast_size`: Die Größe der Toast-Tabelle in Byte, die der Tabelle in diesem Zweig zugeordnet ist.
+ `index_size`: Die Größe aller Indizes für die Tabelle in diesem Knoten in Byte.
+ `total_size`: Die Größe aller Tabellensegmente in diesem Knoten in Byte.
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_relation_sizes` verwendet werden kann (einige Spalten wurden weggelassen).  

```
SELECT * FROM rds_aurora.limitless_stat_relation_sizes('public','customers');

 subcluster_id | subcluster_type | main_size | fsm_size | vm_size | toast_size | table_size | total_size
---------------+-----------------+-----------+----------+---------+------------+------------+------------
             1 | router          |         0 |        0 |       0 |          0 |          0 |          0
             2 | router          |         0 |        0 |       0 |          0 |          0 |          0
             3 | shard           |   4169728 |  4177920 | 1392640 |    1392640 |   11132928 |   11132928
             4 | shard           |   4169728 |  4177920 | 1392640 |    1392640 |   11132928 |   11132928
             5 | shard           |   3981312 |  4227072 | 1409024 |    1409024 |   11026432 |   11026432
(5 rows)
```

**limitless\$1stat\$1reset**  
Die Funktion `limitless_stat_reset` setzt alle Statistikzähler für die aktuelle Datenbank auf Null (0) zurück. Wenn `track_functions` aktiviert ist, zeigt die Spalte `stats_reset` in `limitless_stat_database` an, wann die Statistiken für die Datenbank zuletzt zurückgesetzt wurden. `limitless_stat_reset` kann standardmäßig nur von einem Superuser ausgeführt werden. Anderen Benutzern kann mithilfe des Privilegs `EXECUTE` eine entsprechende Berechtigung erteilt werden.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_reset` verwendet werden kann.  

```
SELECT tup_inserted, tup_deleted FROM pg_stat_database
WHERE datname = 'postgres_limitless';

 tup_inserted | tup_deleted
--------------+-------------
          896 |           0
(1 row)

SELECT rds_aurora.limitless_stat_reset();

limitless_stat_reset
---------------------
(1 row)

SELECT tup_inserted, tup_deleted FROM pg_stat_database
WHERE datname = 'postgres_limitless';

tup_inserted | tup_deleted
-------------+-------------
           0 |           0
(1 row)
```

**limitless\$1stat\$1statements\$1reset**  
Die Funktion `limitless_stat_statements_reset` verwirft Statistiken, die inzwischen von `limitless_stat_statements` erfasst wurden, für die festgelegten Parameter `username`, `dbname`, `distributed_query_id` und `queryid`. Wenn einer der Parameter nicht angegeben ist, wird für jeden Parameter der Standardwert `""` oder `0` (ungültig) verwendet, und die Statistiken, die mit anderen Parametern übereinstimmen, werden zurückgesetzt. Wenn kein Parameter angegeben ist oder alle angegebenen Parameter `""` oder `0` (ungültig) lauten, verwirft die Funktion alle Statistiken. Wenn alle Statistiken in der Ansicht `limitless_stat_statements` verworfen werden, setzt die Funktion auch die Statistiken in der Ansicht `limitless_stat_statements_info` zurück.  
Es werden folgende Eingabeparameter verwendet:  
+ `username` (Name): Der Benutzer, der die Anweisung abgefragt hat.
+ `dbname` (Name): Die Datenbank, in der die Abfrage ausgeführt wurde.
+ `distributed_query_id` (bigint): Die Abfrage-ID der übergeordneten Abfrage vom Koordinatorknoten. Diese Spalte lautet `NULL`, wenn es sich um die übergeordnete Abfrage handelt. Der Koordinatorknoten gibt die ID der verteilten Abfrage an die teilnehmenden Knoten weiter. Für die Teilnehmerknoten sind die Werte für die ID der verteilten Abfrage und die ID der Abfrage also unterschiedlich.
+ `queryid` (bigint): Die Abfrage-ID der Anweisung.
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_statements_reset` verwendet wird, um alle von `limitless_stat_statements` erfassten Statistiken zurückzusetzen.  

```
SELECT rds_aurora.limitless_stat_statements_reset();
```

**limitless\$1stat\$1system\$1waits**  
Die Funktion `limitless_stat_system_waits` gibt eine konsolidierte Ansicht der Warteereignisdaten aus `aurora_stat_system_waits` von allen Knoten zurück, die systemweite Warteaktivitäten in einer Instance meldet. Die Spalten `subcluster_id` und `subcluster_type` zeigen, von welchem Knoten die Daten stammen.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_stat_system_waits` verwendet werden kann.  

```
postgres_limitless=> SELECT *
FROM rds_aurora.limitless_stat_system_waits() lssw, pg_catalog.aurora_stat_wait_event() aswe
WHERE lssw.event_id=aswe.event_id and aswe.event_name='LimitlessTaskScheduler';

 subcluster_id | subcluster_type | type_id | event_id  | waits  |  wait_time   |        event_name
---------------+-----------------+---------+-----------+--------+--------------+------------------------
             1 | router          |      12 | 201326607 | 677068 | 616942216307 | LimitlessTaskScheduler
             2 | router          |      12 | 201326607 | 678586 | 616939897111 | LimitlessTaskScheduler
             3 | shard           |      12 | 201326607 | 756640 | 616965545172 | LimitlessTaskScheduler
             4 | shard           |      12 | 201326607 | 755184 | 616958057620 | LimitlessTaskScheduler
             5 | shard           |      12 | 201326607 | 757522 | 616963183539 | LimitlessTaskScheduler
(5 rows)
```

**limitless\$1terminate\$1session**  
Die Funktion `limitless_terminate_session` arbeitet ähnlich wie `pg_terminate_backend`, versucht aber, alle Backend-Prozesse im Zusammenhang mit der angegebenen ID einer verteilten Sitzung zu beenden, indem sie ein `SIGTERM` (Beendigungssignal) sendet.  
Es wird der folgende Eingabeparameter verwendet:  
+ `distributed_session_id` (Text): Die ID der verteilten Sitzung, die beendet werden soll.
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `pid` (Text): Die ID des Backend-Prozesses.
+ `success` (Boolean): Ob der Prozess erfolgreich beendet wurde.
Das folgende Beispiel zeigt, wie die Funktion `limitless_terminate_session` verwendet werden kann.  

```
SELECT * FROM rds_aurora.limitless_terminate_session('940CD5C81E3C796B');

 subcluster_id |  pid  | success
---------------+-------+---------
             1 | 26920 | t 
(1 row)
```

**limitless\$1wait\$1report**  
Die Funktion `limitless_wait_report` gibt die Aktivität „Warteereignis“ über einen bestimmten Zeitraum von allen Knoten zurück. Die Spalten `subcluster_id` und `subcluster_type` zeigen, von welchem Knoten die Daten stammen.  
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
Die restlichen Spalten sind dieselben wie in `aurora_wait_report`.  
Das folgende Beispiel zeigt, wie die Funktion `limitless_wait_report` verwendet werden kann.  

```
postgres_limitless=> select * from rds_aurora.limitless_wait_report();

 subcluster_id | subcluster_type | type_name | event_name | waits | wait_time | ms_per_wait | waits_per_xact | ms_per_xact
---------------+-----------------+-----------+------------+-------+-----------+-------------+--------------- +-------------
             1 | router          | Client    | ClientRead |    57 | 741550.14 |   13009.652 |           0.19 |    2505.237
             5 | shard           | Client    | ClientRead |    54 | 738897.68 |   13683.290 |           0.18 |    2496.276
             4 | shard           | Client    | ClientRead |    54 | 738859.53 |   13682.584 |           0.18 |    2496.147
             2 | router          | Client    | ClientRead |    53 | 719223.64 |   13570.257 |           0.18 |    2429.810
             3 | shard           | Client    | ClientRead |    54 | 461720.40 |    8550.378 |           0.18 |    1559.86
```

# Ansichten für Aurora PostgreSQL Limitless Database
<a name="limitless-monitoring-views"></a>

In der folgenden Tabelle sehen Sie die neuen Ansichten für Aurora PostgreSQL Limitless Database.

**Anmerkung**  
Die in dieser Tabelle aufgeführten Ansichten befinden sich im Schema `rds_aurora`. Wenn Sie eine Limitless-Database-Ansicht verwenden, stellen Sie sicher, dass Sie den vollqualifizierten Objektnamen angeben: `rds_aurora`.`object_name`.


| Ansicht für Aurora PostgreSQL Limitless Database | Entsprechende Ansicht für Aurora PostgreSQL | 
| --- | --- | 
| [limitless\$1database](#limitless_database) | pg\$1database | 
| [limitless\$1locks](#limitless_locks) | pg\$1locks | 
| [limitless\$1stat\$1activity](#limitless_stat_activity) | pg\$1stat\$1activity | 
| [limitless\$1stat\$1all\$1indexes](#limitless_stat_all_indexes) | pg\$1stat\$1all\$1indexes | 
| [limitless\$1stat\$1all\$1tables](#limitless_stat_all_tables) | pg\$1stat\$1all\$1tables | 
| [limitless\$1stat\$1database](#limitless_stat_database) | pg\$1stat\$1database | 
| [limitless\$1stat\$1progress\$1vacuum](#limitless_stat_progress_vacuum) | pg\$1stat\$1progress\$1vacuum | 
| [limitless\$1stat\$1statements](#limitless_stat_statements) | pg\$1stat\$1statements | 
| [limitless\$1stat\$1subclusters](#limitless_stat_subclusters) | Keine | 
| [limitless\$1stat\$1statements\$1info](#limitless_stat_statements_info) | pg\$1stat\$1statements\$1info | 
| [limitless\$1statio\$1all\$1indexes](#limitless_statio_all_indexes) | pg\$1statio\$1all\$1indexes | 
| [limitless\$1statio\$1all\$1tables](#limitless_statio_all_tables) | pg\$1statio\$1all\$1tables | 
| [limitless\$1tables](#limitless_tables) | pg\$1tables | 
| [limitless\$1table\$1collocations](#limitless_table_collocations) | Keine | 
| [limitless\$1table\$1collocation\$1distributions](#limitless_table_collocation_distributions) | Keine | 

Die folgenden Beispiele enthalten Einzelheiten zu den Ansichten für Aurora PostgreSQL Limitless Database. Weitere Informationen zu PostgreSQL-Ansichten finden Sie unter [Anzeigen von Statistiken](https://www.postgresql.org/docs/15/monitoring-stats.html#MONITORING-STATS-VIEWS) in der PostgreSQL-Dokumentation.

**Anmerkung**  
Einige Statistikansichten können uneinheitliche Ergebnisse liefern, wenn Transaktionen im Gange sind.

**limitless\$1database**  
Diese Ansicht enthält Informationen über die verfügbaren Datenbanken in der DB-Shard-Gruppe. Zum Beispiel:  

```
postgres_limitless=> SELECT subcluster_id, subcluster_type, oid, datname, datacl FROM rds_aurora.limitless_database;

 subcluster_id | subcluster_type |  oid  |      datname       |                                                         datacl                                                         
---------------+-----------------+-------+--------------------+------------------------------------------------------------------------------------------------------------------------
 2             | router          |     4 | template0          | {=c/rdsadmin,rdsadmin=CTc/rdsadmin}
 2             | router          |     5 | postgres           | 
 2             | router          | 16384 | rdsadmin           | {rdsadmin=CTc/rdsadmin,rds_aurora_limitless_metadata_admin=c/rdsadmin,rds_aurora_limitless_heat_mgmt_admin=c/rdsadmin}
 2             | router          | 16477 | postgres_limitless | 
 2             | router          |     1 | template1          | {=c/rdsadmin,rdsadmin=CTc/rdsadmin}
 6             | shard           |     4 | template0          | {=c/rdsadmin,rdsadmin=CTc/rdsadmin}
```
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters (Knoten)
+ `subcluster_type` (Text): Der Typ des Subclusters (Knoten), Router oder Shard
Die restlichen Spalten sind dieselben wie in `pg_database`.

**limitless\$1locks**  
Diese Ansicht enthält eine Zeile pro Prozess und Knoten. Sie bietet Zugriff auf Informationen über die Sperren, die aktive Prozesse im Datenbankserver aufrecht erhalten.  

**Example Beispiel für das Erstellen einer Sperre mit zwei Transaktionen**  
In diesem Beispiel führen wir zwei Transaktionen gleichzeitig auf zwei Routern aus.  

```
# Transaction 1 (run on router 1)
BEGIN;
SET search_path = public;
SELECT * FROM customers;
INSERT INTO customers VALUES (400,'foo','bar');

# Transaction 2 (run on router 2)
BEGIN;
SET search_path = public;
ALTER TABLE customers ADD COLUMN phone VARCHAR;
```
Die erste Transaktion wird ausgeführt. Nachfolgende Transaktionen müssen warten, bis die erste Transaktion abgeschlossen ist. Daher wird die zweite Transaktion durch eine Sperre blockiert. Um die Ursache dafür zu ermitteln, führen wir einen Befehl aus, indem wir `limitless_locks` mit `limitless_stat_activity` vereinen.  

```
# Run on router 2
SELECT distributed_session_id, state, usename, query, query_start
FROM rds_aurora.limitless_stat_activity
WHERE distributed_session_id in (
SELECT distributed_session_id
FROM rds_aurora.limitless_locks
WHERE relname = 'customers'
);

 distributed_session_id | state               | usename                 | query                                           | query_start
------------------------+---------------------+--------------------------+---------------------------------- -------------+-------------------------------
 47BDE66E9A5E8477       | idle in transaction | limitless_metadata_admin | INSERT INTO customers VALUES (400,'foo','bar'); | 2023-04-13 17:44:45.152244+00
 2AD7F370202D0FA9       | active              | limitless_metadata_admin | ALTER TABLE customers ADD COLUMN phone VARCHAR; | 2023-04-13 17:44:55.113388+00
 47BDE66E9A5E8477       |                     | limitless_auth_admin     | <insufficient privilege>                        |
 2AD7F370202D0FA9       |                     | limitless_auth_admin     | <insufficient privilege>                        |
 47BDE66E9A5E8477       |                     | limitless_auth_admin     | <insufficient privilege>                        |
 2AD7F370202D0FA9       |                     | limitless_auth_admin     | <insufficient privilege>                        |
(6 rows)
```

**Example Beispiel für das explizite Erstellen einer Sperre**  
In diesem Beispiel erstellen wir explizit eine Sperre und verwenden dann die Ansicht `limitless_locks`, um die Sperren zu sehen (einige Spalten werden weggelassen).  

```
BEGIN;
SET search_path = public;
LOCK TABLE customers IN ACCESS SHARE MODE;
SELECT * FROM rds_aurora.limitless_locks WHERE relname = 'customers';

 subcluster_id | subcluster_type | distributed_session_id | locktype |      datname       | relnspname |  relname  | virtualtransaction |  pid  |      mode
---------------+-----------------+------------------------+----------+--------------------+------------+ ----------+--------------------+-------+-----------------
             1 | router          | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 28/600787          | 59564 | AccessShareLock
             2 | router          | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 28/600405          | 67130 | AccessShareLock
             3 | shard           | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 15/473401          | 27735 | AccessShareLock
             4 | shard           | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 13/473524          | 27734 | AccessShareLock
             5 | shard           | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 13/472935          | 27737 | AccessShareLock
             6 | shard           | 7207702F862FC937       | relation | postgres_limitless | public     | customers | 13/473015          | 48660 | AccessShareLock
(6 rows)
```

**limitless\$1stat\$1activity**  
Diese Ansicht enthält eine Zeile pro Prozess und Knoten. Sie kann verwendet werden, um den Gesamtzustand des Systems zu verfolgen und lange dauernde Prozesse zu klassifizieren. Zum Beispiel:  

```
postgres=# SELECT
    subcluster_id,
    subcluster_type,
    distributed_session_id,
    distributed_session_state,
    datname,
    distributed_query_id,
    is_sso_query
FROM
    rds_aurora.limitless_stat_activity
WHERE
    distributed_session_id in ('D2470C97E3D07E06', '5A3CD7B8E5FD13FF') 
    order by  distributed_session_id;

 subcluster_id | subcluster_type | distributed_session_id | distributed_session_state |      datname       | distributed_query_id | is_sso_query
---------------+-----------------+------------------------+---------------------------+--------------------+----------------------+--------------
 2             | router          | 5A3CD7B8E5FD13FF       | coordinator               | postgres_limitless |                      | f
 3             | shard           | 5A3CD7B8E5FD13FF       | participant               | postgres_limitless |  6808291725541680947 |
 4             | shard           | 5A3CD7B8E5FD13FF       | participant               | postgres_limitless |  6808291725541680947 |
 2             | router          | D2470C97E3D07E06       | coordinator               | postgres_limitless |                      | t
 3             | shard           | D2470C97E3D07E06       | participant               | postgres_limitless |  4058400544464210222 |
(5 rows)
```
<a name="HOutput"></a>Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `distributed_session_id` (Text): Die ID der verteilten Sitzung, zu der dieser Prozess gehört.
+ `distributed_session_state` (Text): Ob es sich um einen Koordinator, einen Teilnehmer oder einen eigenständigen/nicht verteilten Prozess handelt (angezeigt als `NULL`).
+ `datname` (Text): Die Datenbank, mit der dieser Prozess verbunden ist.
+ `distributed_query_id` (bigint): Die Abfrage-ID der übergeordneten Abfrage vom Koordinatorknoten. Diese Spalte lautet `NULL`, wenn es sich um die übergeordnete Abfrage handelt. Der Koordinatorknoten gibt die ID der verteilten Abfrage an die teilnehmenden Knoten weiter. Für die Teilnehmerknoten sind die Werte für die ID der verteilten Abfrage und die ID der Abfrage also unterschiedlich.
+ `is_sso_query` (Text): Dadurch erfahren wir, ob die Abfrage für einen einzelnen Shard optimiert ist oder nicht.
Die restlichen Spalten sind dieselben wie in `pg_stat_activity`.

**limitless\$1stat\$1all\$1indexes**  
Diese Ansicht enthält Auslastungsstatistiken für Indizes in der DB-Shard-Gruppe. Zum Beispiel:  

```
postgres_limitless=> SELECT schemaname, relname, indexrelname, idx_scan
  FROM rds_aurora.limitless_stat_all_indexes
  WHERE relname LIKE 'orders_ts%' ORDER BY indexrelname LIMIT 10;

 schemaname |    relname     |    indexrelname     | idx_scan
------------+----------------+---------------------+----------
 ec_sample  | orders_ts00001 | orders_ts00001_pkey |   196801
 ec_sample  | orders_ts00002 | orders_ts00002_pkey |   196703
 ec_sample  | orders_ts00003 | orders_ts00003_pkey |   196376
 ec_sample  | orders_ts00004 | orders_ts00004_pkey |   197966
 ec_sample  | orders_ts00005 | orders_ts00005_pkey |   195301
 ec_sample  | orders_ts00006 | orders_ts00006_pkey |   195673
 ec_sample  | orders_ts00007 | orders_ts00007_pkey |   194475
 ec_sample  | orders_ts00008 | orders_ts00008_pkey |   191694
 ec_sample  | orders_ts00009 | orders_ts00009_pkey |   193744
 ec_sample  | orders_ts00010 | orders_ts00010_pkey |   195421
(10 rows)
```

**limitless\$1stat\$1all\$1tables**  
Diese Ansicht enthält Statistiken über alle Tabellen in der aktuellen Datenbank in der DB-Shard-Gruppe. Dies ist nützlich, wenn Sie Bereinigungsvorgänge und DML-Operationen (Data Manipulation Language) verfolgen möchten. Zum Beispiel:  

```
postgres_limitless=> SELECT subcluster_id, subcluster_type, relname, n_ins_since_vacuum, n_tup_ins, last_vacuum
  FROM rds_aurora.limitless_stat_all_tables
  WHERE relname LIKE 'orders_ts%' ORDER BY relname LIMIT 10;

 subcluster_id | subcluster_type |    relname     | n_ins_since_vacuum | n_tup_ins | last_vacuum
---------------+-----------------+----------------+--------------------+-----------+-------------
 5             | shard           | orders_ts00001 |              34779 |    196083 |
 5             | shard           | orders_ts00002 |              34632 |    194721 |
 5             | shard           | orders_ts00003 |              34950 |    195965 |
 5             | shard           | orders_ts00004 |              34745 |    197283 |
 5             | shard           | orders_ts00005 |              34879 |    195754 |
 5             | shard           | orders_ts00006 |              34340 |    194605 |
 5             | shard           | orders_ts00007 |              33779 |    192203 |
 5             | shard           | orders_ts00008 |              33826 |    191293 |
 5             | shard           | orders_ts00009 |              34660 |    194117 |
 5             | shard           | orders_ts00010 |              34569 |    195560 |
(10 rows)
```
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `relname` (Name): Der Name der Tabelle.
Die restlichen Spalten sind dieselben wie in `pg_stat_all_tables`.

**limitless\$1stat\$1database**  
Diese Ansicht enthält Statistiken über alle Datenbanken in der DB-Shard-Gruppe. Gibt eine Zeile pro Datenbank und Knoten zurück. Zum Beispiel:  

```
postgres_limitless=> SELECT
    subcluster_id,
    subcluster_type,
    datname,
    blks_read,
    blks_hit
FROM
    rds_aurora.limitless_stat_database
WHERE
    datname='postgres_limitless';
 subcluster_id | subcluster_type |      datname       | blks_read | blks_hit
---------------+-----------------+--------------------+-----------+----------
             1 | router          | postgres_limitless |       484 | 34371314
             2 | router          | postgres_limitless |       673 | 33859317
             3 | shard           | postgres_limitless |      1299 | 17749550
             4 | shard           | postgres_limitless |      1094 | 17492849
             5 | shard           | postgres_limitless |      1036 | 17485098
             6 | shard           | postgres_limitless |      1040 | 17437257
(6 rows)
```
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `datname` (Name): Der Name der Datenbank.
Die restlichen Spalten sind dieselben wie in `pg_stat_database`.

**limitless\$1stat\$1progress\$1vacuum**  
Diese Ansicht enthält Informationen zu laufenden Bereinigungsvorgängen. Zum Beispiel:  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_stat_progress_vacuum;

-[ RECORD 1 ]----------+------------------
subcluster_id          | 3
subcluster_type        | shard
distributed_session_id | A56D96E2A5C9F426
pid                    | 5270
datname                | postgres
nspname                | public
relname                | customer_ts2
phase                  | vacuuming heap
heap_blks_total        | 130500
heap_blks_scanned      | 100036
heap_blks_vacuumed     | 0
index_vacuum_count     | 0
max_dead_tuples        | 11184810
num_dead_tuples        | 0

-[ RECORD 2 ]----------+------------------
subcluster_id          | 3
subcluster_type        | shard
distributed_session_id | 56DF26A89EC23AB5
pid                    | 6854
datname                | postgres
nspname                | public
relname                | sales_ts1
phase                  | vacuuming heap
heap_blks_total        | 43058
heap_blks_scanned      | 24868
heap_blks_vacuumed     | 0
index_vacuum_count     | 0
max_dead_tuples        | 8569523
num_dead_tuples        | 0
```
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `distributed_session_id` (Text): Die ID der Sitzung, die den Bereinigungsvorgang initiiert hat.
+ `datname` (Name): Die Datenbank, in der die Bereinigung durchgeführt wird.
+ `nspname` (Name): Der Name des Schemas der Tabelle, die bereinigt wird. Der Wert lautet `null`, wenn sich die Tabelle, die bereinigt wird, nicht in derselben Datenbank befindet wie die, mit der der Benutzer verbunden ist.
+ `relname` (Name): Der Name der Tabelle, die bereinigt wird. Der Wert lautet `null`, wenn sich die Tabelle, die bereinigt wird, nicht in derselben Datenbank befindet wie die, mit der der Benutzer verbunden ist.
Die restlichen Spalten sind dieselben wie in `pg_stat_progress_vacuum`.

**limitless\$1stat\$1statements**  
Diese Ansicht bietet die Möglichkeit, Statistiken zur Planung und Ausführung aller SQL-Anweisungen zu verfolgen, die auf allen Knoten ausgeführt werden.  
Sie müssen die Erweiterung [pg\$1stat\$1statements](https://www.postgresql.org/docs/current/pgstatstatements.html) installieren, um die Ansicht `limitless_stat_statements` verwenden zu können.  

```
-- CREATE EXTENSION must be run by a superuser
CREATE EXTENSION pg_stat_statements;

-- Verify that the extension is created on all nodes in the DB shard group
SELECT distinct node_id
    FROM rds_aurora.limitless_stat_statements
    LIMIT 10;
```
Das folgende Beispiel veranschaulicht die Verwendung der Ansicht `limitless_stat_statements`.  

```
postgres_limitless=> SELECT
 subcluster_id,
 subcluster_type,
 distributedqueryid,
 username,
 dbname,
 sso_calls
FROM
 rds_aurora.limitless_stat_statements;

 subcluster_id | subcluster_type |  distributedqueryid  |              username               |       dbname       | sso_calls
---------------+-----------------+----------------------+-------------------------------------+--------------------+-----------
 2             | router          |                      | postgres                            | postgres_limitless |         0
 2             | router          |                      | postgres                            | postgres_limitless |         0
 2             | router          |                      | postgres                            | postgres_limitless |         0
 2             | router          |                      | postgres                            | postgres_limitless |         0
 2             | router          |                      | postgres                            | postgres_limitless |         0
 2             | router          |                      | postgres                            | postgres_limitless |         1
 3             | shard           | -7975178695405682176 | postgres                            | postgres_limitless |
[...]
```
Es werden folgende Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
+ `subcluster_type` (Text): Der Typ des Subclusters, zu dem dieser Prozess gehört: `router` oder `shard`.
+ `distributedqueryid` (bigint): Die Abfrage-ID der übergeordneten Abfrage vom Koordinatorknoten. Diese Spalte lautet `NULL`, wenn es sich um die übergeordnete Abfrage handelt. Der Koordinatorknoten gibt die ID der verteilten Abfrage an die teilnehmenden Knoten weiter. Für die Teilnehmerknoten sind die Werte für die ID der verteilten Abfrage und die ID der Abfrage also unterschiedlich.
+ `username` (Name): Der Benutzer, der die Anweisung abgefragt hat.
+ `dbname` (Name): Die Datenbank, in der die Abfrage ausgeführt wurde.
+ `sso_calls` (Name): Gibt an, wie oft die Anweisung für einen einzelnen Shard optimiert wurde.
Die restlichen Spalten sind dieselben wie in [pg\$1stat\$1statements](https://www.postgresql.org/docs/current/pgstatstatements.html).

**limitless\$1stat\$1statements\$1info**  
Diese Ansicht enthält Statistiken für die Ansicht `limitless_stat_statements`. Jede Zeile enthält Daten für die Ansicht [pg\$1stat\$1statements\$1info](https://www.postgresql.org/docs/current/pgstatstatements.html#id-1.11.7.41.7) von jedem Knoten. Die Spalte `subcluster_id` identifiziert jeden Knoten.  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_stat_statements_info;

 subcluster_id | subcluster_type | dealloc |          stats_reset
---------------+-----------------+---------+-------------------------------
             1 | router          |       0 | 2023-06-30 21:22:09.524781+00
             2 | router          |       0 | 2023-06-30 21:21:40.834111+00
             3 | shard           |       0 | 2023-06-30 21:22:10.709942+00
             4 | shard           |       0 | 2023-06-30 21:22:10.740179+00
             5 | shard           |       0 | 2023-06-30 21:22:10.774282+00
             6 | shard           |       0 | 2023-06-30 21:22:10.808267+00
(6 rows)
```
Es wird folgender Ausgabeparameter verwendet:  
+ `subcluster_id` (Text): Die ID des Subclusters, zu dem dieser Prozess gehört.
Die restlichen Spalten sind dieselben wie in [pg\$1stat\$1statements\$1info](https://www.postgresql.org/docs/current/pgstatstatements.html#id-1.11.7.41.7).

**limitless\$1stat\$1subclusters**  
Diese Ansicht enthält Netzwerkstatistiken zwischen Routern und anderen Knoten. Sie enthält eine Zeile pro Paar aus Router und anderem Knoten, zum Beispiel:  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_stat_subclusters;

 orig_subcluster | orig_instance_az | dest_subcluster | dest_instance_az | latency_us |       latest_collection       | failed_requests | received_bytes | sent_bytes | same_az_requests | cross_az_requests |     stat_reset_timestamp      
-----------------+------------------+-----------------+------------------+------------+-------------------------------+-----------------+----------------+------------+------------------+-------------------+-------------------------------
 3               | us-west-2b       | 2               | us-west-2a       |        847 | 2024-10-07 17:25:39.518617+00 |               0 |       35668633 |   92090171 |                0 |            302787 | 2024-10-05 12:39:55.239675+00
 3               | us-west-2b       | 4               | us-west-2b       |        419 | 2024-10-07 17:25:39.546376+00 |               0 |      101190464 |  248795719 |           883478 |                 0 | 2024-10-05 12:39:55.231218+00
 3               | us-west-2b       | 5               | us-west-2c       |       1396 | 2024-10-07 17:25:39.52122+00  |               0 |       72864849 |  172086292 |                0 |            557726 | 2024-10-05 12:39:55.196412+00
 3               | us-west-2b       | 6               | us-west-2c       |        729 | 2024-10-07 17:25:39.54828+00  |               0 |       35668584 |   92090171 |                0 |            302787 | 2024-10-05 12:39:55.247334+00
 3               | us-west-2b       | 7               | us-west-2a       |       1702 | 2024-10-07 17:25:39.545307+00 |               0 |       71699576 |  171634844 |                0 |            556278 | 2024-10-05 12:39:52.715168+00
 2               | us-west-2a       | 3               | us-west-2b       |        868 | 2024-10-07 17:25:40.293927+00 |               0 |       35659611 |   92011872 |                0 |            302817 | 2024-10-05 12:39:54.420758+00
 2               | us-west-2a       | 4               | us-west-2b       |        786 | 2024-10-07 17:25:40.296863+00 |               0 |      102437253 |  251838024 |                0 |            895060 | 2024-10-05 12:39:54.404081+00
 2               | us-west-2a       | 5               | us-west-2c       |       1232 | 2024-10-07 17:25:40.292021+00 |               0 |       71990027 |  168828110 |                0 |            545453 | 2024-10-05 12:39:36.769549+00
```
Es werden folgende Ausgabeparameter verwendet:  
+ `orig_subcluster` (Text): Die ID des Routers, der Absender der Kommunikation ist
+ `orig_subcluster_az` (Text): Die Availability Zone (AZ) des Absender-Routers
+ `dest_subcluster` (Text): Die ID des Zielknotens
+ `dest_subcluster_az` (Text): Die zuletzt erfasste AZ des Zielknotens
+ `latency_us` (bigint): Die zuletzt erfasste Netzwerklatenz zwischen Knoten in Mikrosekunden. Der Wert lautet `0`, wenn der Knoten nicht erreichbar ist.
+ `latest_collection` (Zeitstempel): Der Zeitstempel der letzten Erfassung von AZ und Latenz für den Zielknoten
+ `failed_requests` (bigint): Die Gesamtzahl der fehlgeschlagenen internen Anfragen
+ `received_bytes` (bigint): Die geschätzte kumulative Anzahl von Byte, die von diesem Knoten empfangen wurden
+ `sent_bytes` (bigint): Die geschätzte kumulative Anzahl von Byte, die an diesen Knoten gesendet wurden
+ `same_az_requests` (bigint): Die kumulative Anzahl interner DB-Anfragen an diesen Knoten, wenn er sich in derselben AZ wie der Absender-Router befindet
+ `cross_az_requests` (bigint): Die kumulative Anzahl interner DB-Anfragen an diesen Knoten, wenn er sich in einer anderen AZ als der Absender-Router befindet
+ `stat_reset_timestamp` (Zeitstempel): Der Zeitstempel des Zeitpunkts, zu dem die kumulativen Statistiken für diese Ansicht zuletzt zurückgesetzt wurden

**limitless\$1statio\$1all\$1indexes**  
Diese Ansicht enthält Ein/Ausgabe (I/O)-Statistiken für alle Indizes in der DB-Shard-Gruppe. Zum Beispiel:  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_statio_all_indexes WHERE relname like'customers_ts%';

 subcluster_id | subcluster_type | schemaname |      relname      |            indexrelname             | idx_blks_read | idx_blks_hit
---------------+-----------------+------------+-------------------+-------------------------------------+ --------------+--------------
             3 | shard           | public     | customers_ts00002 | customers_ts00002_customer_name_idx |             1 |            0
             3 | shard           | public     | customers_ts00001 | customers_ts00001_customer_name_idx |             1 |            0
             4 | shard           | public     | customers_ts00003 | customers_ts00003_customer_name_idx |             1 |            0
             4 | shard           | public     | customers_ts00004 | customers_ts00004_customer_name_idx |             1 |            0
             5 | shard           | public     | customers_ts00005 | customers_ts00005_customer_name_idx |             1 |            0
             5 | shard           | public     | customers_ts00006 | customers_ts00006_customer_name_idx |             1 |            0
             6 | shard           | public     | customers_ts00007 | customers_ts00007_customer_name_idx |             1 |            0
             6 | shard           | public     | customers_ts00008 | customers_ts00008_customer_name_idx |             1 |            0
(8 rows)
```

**limitless\$1statio\$1all\$1tables**  
Diese Ansicht enthält Ein/Ausgabe (I/O)-Statistiken für alle Tabellen in der DB-Shard-Gruppe. Zum Beispiel:  

```
postgres_limitless=> SELECT
    subcluster_id,
    subcluster_type,
    schemaname,
    relname,
    heap_blks_read,
    heap_blks_hit
FROM
    rds_aurora.limitless_statio_all_tables
WHERE
    relname LIKE 'customers_ts%';

 subcluster_id | subcluster_type | schemaname |      relname      | heap_blks_read | heap_blks_hit
---------------+-----------------+------------+-------------------+----------------+---------------
             3 | shard           | public     | customers_ts00002 |            305 |         57780
             3 | shard           | public     | customers_ts00001 |            300 |         56972
             4 | shard           | public     | customers_ts00004 |            302 |         57291
             4 | shard           | public     | customers_ts00003 |            302 |         57178
             5 | shard           | public     | customers_ts00006 |            300 |         56932
             5 | shard           | public     | customers_ts00005 |            302 |         57386
             6 | shard           | public     | customers_ts00008 |            300 |         56881
             6 | shard           | public     | customers_ts00007 |            304 |         57635
(8 rows)
```

**limitless\$1tables**  
Diese Ansicht enthält Informationen zu Tabellen in Aurora PostgreSQL Limitless Database.  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_tables;

 table_gid | local_oid | schema_name | table_name  | table_status | table_type  | distribution_key 
-----------+-----------+-------------+-------------+--------------+-------------+------------------
         5 |     18635 | public      | placeholder | active       | placeholder | 
         6 |     18641 | public      | ref         | active       | reference   | 
         7 |     18797 | public      | orders      | active       | sharded     | HASH (order_id)
         2 |     18579 | public      | customer    | active       | sharded     | HASH (cust_id)
(4 rows)
```

**limitless\$1table\$1collocations**  
Diese Ansicht enthält Informationen über zusammengefasste Sharded-Tabellen.  
Im folgenden Beispiel sind die Tabellen `orders` und `customers` zusammengefasst, und die Tabellen `users` und `followers` ebenso. Zusammengefasste Tabellen haben die gleiche `collocation_id`.  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_table_collocations ORDER BY collocation_id;

 collocation_id | schema_name | table_name 
----------------+-------------+------------
              2 | public      | orders
              2 | public      | customers
              5 | public      | users
              5 | public      | followers
(4 rows)
```

**limitless\$1table\$1collocation\$1distributions**  
Diese Ansicht zeigt die Schlüsselverteilung für jede Kollokation.  

```
postgres_limitless=> SELECT * FROM rds_aurora.limitless_table_collocation_distributions ORDER BY collocation_id, lower_bound;

 collocation_id | subcluster_id |     lower_bound      |     upper_bound      
----------------+---------------+----------------------+----------------------
              2 |             6 | -9223372036854775808 | -4611686018427387904
              2 |             5 | -4611686018427387904 |                    0
              2 |             4 |                    0 |  4611686018427387904
              2 |             3 |  4611686018427387904 |  9223372036854775807
              5 |             6 | -9223372036854775808 | -4611686018427387904
              5 |             5 | -4611686018427387904 |                    0
              5 |             4 |                    0 |  4611686018427387904
              5 |             3 |  4611686018427387904 |  9223372036854775807
(8 rows)
```