

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Utilizzo delle estensioni PostgreSQL con Amazon RDS for PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions"></a>

È possibile estendere la funzionalità di PostgreSQL installando un'ampia serie di estensioni e moduli. Ad esempio, per lavorare con i dati spaziali è possibile installare e utilizzare l'estensione PostGIS. Per ulteriori informazioni, consulta [Gestione dei dati spaziali con estensione PostGIS](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md). Come altro esempio, per migliorare l'immissione dei dati per tabelle molto grandi, è possibile prendere in considerazione il partizionamento dei dati utilizzando l’estensione `pg_partman`. Per ulteriori informazioni, consulta [Gestione delle partizioni PostgreSQL con l'estensione pg\$1partman](PostgreSQL_Partitions.md).

**Nota**  
RDS per PostgreSQL supporta Trusted Language Extensions per PostgreSQL tramite l’estensione `pg_tle` che puoi aggiungere all’istanza database. Con questa estensione, gli sviluppatori possono creare le proprie estensioni di PostgreSQL in un ambiente sicuro che semplifica i requisiti di impostazione e configurazione. Per ulteriori informazioni sulle versioni di RDS per PostgreSQL che supportano l’estensione `pg_tle` e per ulteriori informazioni, consulta [Utilizzo di Trusted Language Extensions per PostgreSQL](PostgreSQL_trusted_language_extension.md).

In alcuni casi, anziché installare un'estensione, è possibile aggiungere un modulo specifico all'elenco di `shared_preload_libraries` nel gruppo di parametri database personalizzato dell'istanza database RDS per PostgreSQL. In genere, il gruppo di parametri cluster di database predefinito carica solo `pg_stat_statements`, ma sono disponibili diversi altri moduli da aggiungere all'elenco. Ad esempio, è possibile aggiungere funzionalità di pianificazione aggiungendo il modulo `pg_cron`, come descritto in [Pianificazione della manutenzione con l'estensione PostgreSQL pg\$1cron](PostgreSQL_pg_cron.md). Come altro esempio, è possibile registrare i piani di esecuzione delle query caricando il modulo `auto_explain`. Per ulteriori informazioni, consulta [Registrazione dei piani di esecuzione delle query](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#) nel AWS Knowledge Center.

A seconda della versione di RDS per PostgreSQL, l'installazione di un'estensione potrebbe richiedere autorizzazioni `rds_superuser`, come segue: 
+ Per RDS per PostgreSQL versione 12 e versioni precedenti, l'installazione delle estensioni richiede i privilegi `rds_superuser`.
+ Per RDS per PostgreSQL versione 13 e versioni successive, gli utenti (ruoli) con autorizzazioni di creazione su una determinata istanza database possono installare e utilizzare qualsiasi *estensione attendibile*. Per un elenco di estensioni attendibili, consulta [Estensioni attendibili di PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.Extensions.Trusted). 

È inoltre possibile specificare con precisione le estensioni che possono essere installate sull'istanza database RDS per PostgreSQL, elencandole nel parametro `rds.allowed_extensions`. Per ulteriori informazioni, consulta [Limitazione dell'installazione delle estensioni PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

Per ulteriori informazioni sul ruolo `rds_superuser`, consulta [Informazioni su ruoli e autorizzazioni di PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Roles.md).

**Topics**
+ [

# Utilizzo delle funzioni dall’estenzione orafce
](Appendix.PostgreSQL.CommonDBATasks.orafce.md)
+ [

# Utilizzo del supporto delle estensioni delegate di Amazon RDS per PostgreSQL
](RDS_delegated_ext.md)
+ [

# Gestione delle partizioni PostgreSQL con l'estensione pg\$1partman
](PostgreSQL_Partitions.md)
+ [

# Utilizzo di pgAudit per registrare l'attività del database
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)
+ [

# Pianificazione della manutenzione con l'estensione PostgreSQL pg\$1cron
](PostgreSQL_pg_cron.md)
+ [

# Utilizzo di pglogical per sincronizzare i dati tra le istanze
](Appendix.PostgreSQL.CommonDBATasks.pglogical.md)
+ [

# Utilizzo di pgactive per supportare la replica active-active
](Appendix.PostgreSQL.CommonDBATasks.pgactive.md)
+ [

# Riduzione della dimensione nelle tabelle e negli indici con l’estensione pg\$1repack
](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md)
+ [

# Aggiornamento e utilizzo dell'estensione PLV8
](PostgreSQL.Concepts.General.UpgradingPLv8.md)
+ [

# Utilizzo PL/Rust per scrivere funzioni PostgreSQL nel linguaggio Rust
](PostgreSQL.Concepts.General.Using.PL_Rust.md)
+ [

# Gestione dei dati spaziali con estensione PostGIS
](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md)

# Utilizzo delle funzioni dall’estenzione orafce
<a name="Appendix.PostgreSQL.CommonDBATasks.orafce"></a>

L'estensione orafce fornisce funzioni e operatori che emulano un sottoinsieme di funzioni e pacchetti da un database Oracle. L'estensione orafce consente di portare più facilmente un'applicazione Oracle su PostgreSQL. RDS for PostgreSQL versioni 9.6.6 e successive supportano questa estensione. Per ulteriori informazioni su orafce, vedere [orafce](https://github.com/orafce/orafce) on. GitHub

**Nota**  
RDS for PostgreSQL non supporta il pacchetto `utl_file`, che fa parte dell'estensione orafce. Ciò avviene perché le funzioni dello schema `utl_file` offrono operazioni di lettura e scrittura sui file di testo del sistema operativo, il che richiede che il superuser acceda all'host sottostante. Come servizio gestito, RDS for PostgreSQL non fornisce accesso host.

**Utilizzare l'estensione orafce**

1. Connettiti all'istanza database con il nome utente primario che hai utilizzato per creare l'istanza database. 

   Se si desidera attivare orafce per un database diverso nella stessa istanza database, utilizzare il comando psql `/c dbname`. Utilizzando questo comando, si passa dal database primario dopo aver avviato la connessione.

1. Attivare l'estensione orafce con l'istruzione `CREATE EXTENSION`.

   ```
   CREATE EXTENSION orafce;
   ```

1. Trasferire la proprietà dello schema oracle al ruolo rds\$1superuser con l'istruzione `ALTER SCHEMA`.

   ```
   ALTER SCHEMA oracle OWNER TO rds_superuser;
   ```

   Se si desidera visualizzare l'elenco dei proprietari per lo schema di Oracle, utilizzare il comando `\dn` psql.

# Utilizzo del supporto delle estensioni delegate di Amazon RDS per PostgreSQL
<a name="RDS_delegated_ext"></a>

Utilizzando il supporto delle estensioni delegate di Amazon RDS per PostgreSQL, è possibile delegare la gestione delle estensioni a un utente che non deve essere un `rds_superuser`. Con questo supporto delle estensioni delegate, viene creato un nuovo ruolo denominato `rds_extension` che è necessario assegnare a un utente per gestire altre estensioni. Questo ruolo può creare, aggiornare ed eliminare estensioni.

È possibile specificare le estensioni che possono essere installate sull’istanza database RDS, elencandole nel parametro `rds.allowed_extensions`. Per ulteriori informazioni, consulta [Utilizzo delle estensioni PostgreSQL con Amazon RDS per PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Extensions.html).

È possibile limitare l’elenco delle estensioni disponibili che possono essere gestite dall’utente con il ruolo `rds_extension` utilizzando il parametro `rds.allowed_delegated_extensions`.

Il supporto delle estensioni delegate è disponibile nelle seguenti versioni:
+ Tutte le versioni successive
+ 16.4 e versioni successive alla 16
+ 15.8 e versioni successive
+ 14.13 e versioni successive alla 14
+ 13.16 e versioni successive alla 13
+ 12.20 e versioni successive 12

**Topics**
+ [

## Attivazione del supporto delle estensioni delegate per un utente
](#RDSPostgreSQL.delegated_ext_mgmt)
+ [

## Configurazione utilizzata nel supporto delle estensioni delegate RDS
](#RDSPostgreSQL.delegated_ext_config)
+ [

## Disattivazione del supporto per l’estensione delegata
](#RDSPostgreSQL.delegated_ext_disable)
+ [

## Vantaggi dell’utilizzo del supporto delle estensioni delegate di Amazon RDS
](#RDSPostgreSQL.delegated_ext_benefits)
+ [

## Limitazione del supporto delle estensioni delegate di Amazon RDS per PostgreSQL
](#RDSPostgreSQL.delegated_ext_limit)
+ [

## Autorizzazioni necessarie per determinate estensioni
](#RDSPostgreSQL.delegated_ext_perm)
+ [

## Considerazioni sulla sicurezza
](#RDSPostgreSQL.delegated_ext_sec)
+ [

## Disabilitazione dell’eliminazione delle estensioni con l’opzione cascade
](#RDSPostgreSQL.delegated_ext_drop)
+ [

## Estensioni di esempio che possono essere aggiunte utilizzando il supporto delle estensioni delegate
](#RDSPostgreSQL.delegated_ext_support)

## Attivazione del supporto delle estensioni delegate per un utente
<a name="RDSPostgreSQL.delegated_ext_mgmt"></a>

È necessario eseguire le seguenti operazioni per abilitare il supporto delle estensioni delegate per un utente:

1. **Concedere il ruolo `rds_extension` a un utente**: connettersi al database come `rds_superuser` ed esegui il seguente comando:

   ```
   Postgres => grant rds_extension to user_name;
   ```

1. **Impostare l’elenco delle estensioni disponibili per la gestione degli utenti delegati**: `rds.allowed_delegated_extensions` consente di specificare un sottoinsieme delle estensioni disponibili utilizzando `rds.allowed_extensions` nel parametro del cluster di database. È possibile eseguire questa operazione a uno dei seguenti livelli:
   + Nel cluster o nel gruppo di parametri dell’istanza, tramite la Console di gestione AWS o l’API. Per ulteriori informazioni, consulta [Gruppi di parametri per Amazon RDS](USER_WorkingWithParamGroups.md).
   + Utilizzare il seguente comando a livello di database:

     ```
     alter database database_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
   + Utilizzare il seguente comando a livello di utente:

     ```
     alter user user_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
**Nota**  
Non è necessario riavviare il database dopo aver modificato il parametro dinamico `rds.allowed_delegated_extensions`.

1. **Consentire l’accesso all’utente delegato agli oggetti creati durante il processo di creazione dell’estensione**: alcune estensioni creano oggetti che richiedono la concessione di autorizzazioni aggiuntive prima che l’utente con il ruolo `rds_extension` possa accedervi. `rds_superuser` deve concedere all’utente delegato l’accesso a tali oggetti. Una delle opzioni consiste nell’utilizzare un trigger di evento per concedere automaticamente l’autorizzazione all’utente delegato.

   **Esempio di attivazione di un evento**

   Se si desidera consentire a un utente delegato con `rds_extension` di utilizzare estensioni che richiedono l’impostazione delle autorizzazioni sugli oggetti creati durante la creazione dell’estensione, è possibile personalizzare l’esempio seguente di trigger di evento e aggiungere solo le estensioni per le quali si desidera che gli utenti delegati abbiano accesso alla funzionalità completa. Questo trigger di evento può essere creato su template1 (il modello predefinito), pertanto tutti i database creati da template1 avranno tale trigger di evento. Quando un utente delegato installa l’estensione, questo trigger garantirà automaticamente la proprietà degli oggetti creati dall’estensione.

   ```
   CREATE OR REPLACE FUNCTION create_ext()
   
     RETURNS event_trigger AS $$
   
   DECLARE
   
     schemaname TEXT;
     databaseowner TEXT;
   
     r RECORD;
   
   BEGIN
   
     IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN
       RAISE NOTICE 'SECURITY INVOKER';
       RAISE NOTICE 'user: %', current_user;
       FOR r IN SELECT * FROM pg_catalog.pg_event_trigger_ddl_commands()
       LOOP
           CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension';
   
           schemaname = (
               SELECT n.nspname
               FROM pg_catalog.pg_extension AS e
               INNER JOIN pg_catalog.pg_namespace AS n
               ON e.extnamespace = n.oid
               WHERE e.oid = r.objid
           );
   
           databaseowner = (
               SELECT pg_catalog.pg_get_userbyid(d.datdba)
               FROM pg_catalog.pg_database d
               WHERE d.datname = current_database()
           );
           RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner;
           IF r.object_identity = 'address_standardizer_data_us' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'dict_int' THEN
               EXECUTE pg_catalog.format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner);
           ELSIF r.object_identity = 'pg_partman' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'postgis_topology' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
           END IF;
       END LOOP;
     END IF;
   END;
   $$ LANGUAGE plpgsql SECURITY DEFINER;
   
   CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
   ```

## Configurazione utilizzata nel supporto delle estensioni delegate RDS
<a name="RDSPostgreSQL.delegated_ext_config"></a>


| Nome configurazione | Description | Valore predefinito | Note | Chi può modificare o concedere l’autorizzazione | 
| --- | --- | --- | --- | --- | 
| `rds.allowed_delegated_extensions` | Questo parametro limita le estensioni che un ruolo rds\$1extension può gestire in un database. Deve essere un sottoinsieme di rds.allowed\$1extensions. | Stringa vuota | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/RDS_delegated_ext.html) Per ulteriori informazioni sulla configurazione di questo parametro, consulta [Attivazione del supporto delle estensioni delegate per un utente](#RDSPostgreSQL.delegated_ext_mgmt). | rds\$1superuser | 
| `rds.allowed_extensions` | Questo parametro consente all’utente di limitare le estensioni che possono essere installate nell’istanza database RDS. Per ulteriori informazioni, consulta [Limitazione dell’installazione delle estensioni PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction). | "\$1" | Per impostazione predefinita, questo parametro è impostato su “\$1”, il che significa che tutte le estensioni supportate su RDS per PostgreSQL e Aurora PostgreSQL possono essere create da utenti con i privilegi necessari. Vuoto significa che non è possibile installare estensioni nell’istanza database RDS. | administrator | 
| `rds-delegated_extension_allow_drop_cascade` | Questo parametro controlla la possibilità per l’utente con `rds_extension` di eliminare l’estensione utilizzando un’opzione cascade. | off | Per impostazione predefinita, `rds-delegated_extension_allow_drop_cascade` è impostato su `off`. Ciò significa che gli utenti con `rds_extension` non sono autorizzati a eliminare un’estensione utilizzando l’opzione cascade. Per consentire tale funzionalità, il parametro `rds.delegated_extension_allow_drop_cascade` deve essere impostato su `on`. | rds\$1superuser | 

## Disattivazione del supporto per l’estensione delegata
<a name="RDSPostgreSQL.delegated_ext_disable"></a>

**Disattivazione parziale**  
Gli utenti delegati non possono creare nuove estensioni ma possono comunque aggiornare le estensioni esistenti.
+ Ripristinare `rds.allowed_delegated_extensions` sul valore predefinito nel gruppo di parametri del cluster di database.
+ Utilizzare il seguente comando a livello di database:

  ```
  alter database database_name reset rds.allowed_delegated_extensions;
  ```
+ Utilizzare il seguente comando a livello di utente:

  ```
  alter user user_name reset rds.allowed_delegated_extensions;
  ```

**Disattivazione completa**  
La revoca del ruolo `rds_extension` a un utente ripristinerà le autorizzazioni standard per l’utente. L’utente non può più creare, aggiornare o eliminare le estensioni. 

```
postgres => revoke rds_extension from user_name;
```

## Vantaggi dell’utilizzo del supporto delle estensioni delegate di Amazon RDS
<a name="RDSPostgreSQL.delegated_ext_benefits"></a>

Utilizzando il supporto delle estensioni delegate di Amazon RDS per PostgreSQL, è possibile delegare in modo sicuro la gestione delle estensioni agli utenti che non dispongono del ruolo `rds_superuser`. Questa funzionalità fornisce i seguenti vantaggi:
+ È possibile delegare facilmente la gestione delle estensioni agli utenti desiderati.
+ Non è richiesto il ruolo `rds_superuser`.
+ Offre la possibilità di supportare diversi set di estensioni per diversi database nello stesso cluster di database.

## Limitazione del supporto delle estensioni delegate di Amazon RDS per PostgreSQL
<a name="RDSPostgreSQL.delegated_ext_limit"></a>
+ Gli oggetti creati durante il processo di creazione dell’estensione possono richiedere privilegi aggiuntivi per il corretto funzionamento dell’estensione.
+ Per impostazione predefinita, alcune estensioni non possono essere gestite dall’utente delegato dell’estensione, tra cui: `log_fdw`, `pg_cron`, `pg_tle`, `pgactive`, `pglogical`, `postgis_raster`, `postgis_tiger_geocoder`, `postgis_topology`.

## Autorizzazioni necessarie per determinate estensioni
<a name="RDSPostgreSQL.delegated_ext_perm"></a>

Per creare, utilizzare o aggiornare le seguenti estensioni, l’utente delegato deve disporre dei privilegi necessari sulle seguenti funzioni, tabelle e schemi.


| Estensioni che richiedono proprietà o autorizzazioni | Funzione | Tabelle | Schema | Dizionario di ricerca testuale | Comment | 
| --- | --- | --- | --- | --- | --- | 
| address\$1standardizer\$1data\$1us | nessuno | us\$1gaz, us\$1lex, us\$1lex, I.us\$1rules | nessuno | nessuno | nessuno | 
| amcheck | bt\$1index\$1check, bt\$1index\$1parent\$1check | nessuno | nessuno | nessuno | nessuno | 
| dict\$1int | nessuno | nessuno | nessuno | intdict | nessuno | 
| pg\$1partman | nessuno | custom\$1time\$1partitions, part\$1config, part\$1config\$1sub | nessuno | nessuno | nessuno | 
| pg\$1stat\$1statements | nessuno | nessuno | nessuno | nessuno | nessuno | 
| PostGIS | st\$1tileenvelope | spatial\$1ref\$1sys | nessuno | nessuno | nessuno | 
| postgis\$1raster | nessuno | nessuno | nessuno | nessuno | nessuno | 
| postgis\$1topology | nessuno | topology, layer | topology | nessuno | L’utente delegato deve essere il proprietario del database | 
| log\$1fdw | create\$1foreign\$1table\$1for\$1log\$1file | nessuno | nessuno | nessuno | nessuno | 
| rds\$1tools | role\$1password\$1encryption\$1type | nessuno | nessuno | nessuno | nessuno | 
| postgis\$1tiger\$1geocoder | nessuno | geocode\$1settings\$1default, geocode\$1settings | tiger | nessuno | nessuno | 
| pg\$1freespacemap | pg\$1freespace | nessuno | nessuno | nessuno | nessuno | 
| pg\$1visibility | pg\$1visibility | nessuno | nessuno | nessuno | nessuno | 

## Considerazioni sulla sicurezza
<a name="RDSPostgreSQL.delegated_ext_sec"></a>

 Tenere presente che un utente con il ruolo `rds_extension` sarà in grado di gestire le estensioni su tutti i database su cui ha il privilegio di connessione. Se l’intenzione è fare in modo che un utente delegato gestisca l’estensione su un singolo database, è buona norma revocare tutti i privilegi al pubblico su ciascun database, quindi concedere esplicitamente il privilegio di connessione per tale database specifico all’utente delegato. 

 Esistono diverse estensioni che possono consentire a un utente di accedere alle informazioni da più database. Prima di aggiungere queste estensioni a `rds.allowed_delegated_extensions`, assicurarsi che gli utenti a cui si concede `rds_extension` dispongano di funzionalità su più database. Ad esempio, `postgres_fdw` e `dblink` forniscono funzionalità per eseguire query su più database sulla stessa istanza o su istanze remote. `log_fdw` legge i file di log del motore postgres, che riguardano tutti i database dell’istanza, potenzialmente contenenti query lente o messaggi di errore provenienti da più database. `pg_cron` consente l’esecuzione di processi pianificati in background sull’istanza database e può configurare i processi per l’esecuzione in un database diverso. 

## Disabilitazione dell’eliminazione delle estensioni con l’opzione cascade
<a name="RDSPostgreSQL.delegated_ext_drop"></a>

 La possibilità di eliminare l’estensione con l’opzione cascade da parte di un utente con il ruolo `rds_extension` è controllata dal parametro `rds.delegated_extension_allow_drop_cascade`. Per impostazione predefinita, `rds-delegated_extension_allow_drop_cascade` è impostato su `off`. Ciò significa che agli utenti con il ruolo `rds_extension` non è consentito eliminare un’estensione utilizzando l’opzione cascade, come mostrato nella query seguente. 

```
DROP EXTENSION CASCADE;
```

In questo modo verranno eliminati automaticamente gli oggetti che dipendono dall’estensione e, di conseguenza, tutti gli oggetti che dipendono da tali oggetti. Il tentativo di utilizzare l’opzione cascade genererà un errore.

 Per consentire tale funzionalità, il parametro `rds.delegated_extension_allow_drop_cascade` deve essere impostato su `on`. 

 La modifica del parametro dinamico `rds.delegated_extension_allow_drop_cascade` non richiede il riavvio del database. È possibile eseguire questa operazione a uno dei seguenti livelli: 
+ Nel cluster o nel gruppo di parametri dell'istanza, tramite l'API Console di gestione AWS o.
+ Utilizzando il seguente comando a livello di database:

  ```
  alter database database_name set rds.delegated_extension_allow_drop_cascade = 'on';
  ```
+ Utilizzando il seguente comando a livello di utente:

  ```
  alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
  ```

## Estensioni di esempio che possono essere aggiunte utilizzando il supporto delle estensioni delegate
<a name="RDSPostgreSQL.delegated_ext_support"></a>
+ `rds_tools`

  ```
  extension_test_db=> create extension rds_tools;
  CREATE EXTENSION
  extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files';
  ERROR: permission denied for function role_password_encryption_type
  ```
+ `amcheck`

  ```
  extension_test_db=> CREATE TABLE amcheck_test (id int);
  CREATE TABLE
  extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000));
  INSERT 0 100000
  extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id);
  CREATE INDEX
  extension_test_db=> create extension amcheck;
  CREATE EXTENSION
  extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_check
  extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_parent_check
  ```
+ `pg_freespacemap`

  ```
  extension_test_db=> create extension pg_freespacemap;
  CREATE EXTENSION
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid');
  ERROR: permission denied for function pg_freespace
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0);
  ERROR: permission denied for function pg_freespace
  ```
+ `pg_visibility`

  ```
  extension_test_db=> create extension pg_visibility;
  CREATE EXTENSION
  extension_test_db=> select * from pg_visibility('pg_database'::regclass);
  ERROR: permission denied for function pg_visibility
  ```
+ `postgres_fdw`

  ```
  extension_test_db=> create extension postgres_fdw;
  CREATE EXTENSION
  extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432');
  ERROR: permission denied for foreign-data wrapper postgres_fdw
  ```

# Gestione delle partizioni PostgreSQL con l'estensione pg\$1partman
<a name="PostgreSQL_Partitions"></a>

Il partizionamento delle tabelle PostgreSQL fornisce un framework per la gestione ad alte prestazioni di input e reporting dei dati. Utilizzare il partizionamento per database che richiedono un input molto veloce di grandi quantità di dati. Il partizionamento fornisce anche query di tabelle di grandi dimensioni più veloci. Il partizionamento consente di conservare i dati senza influire sull'istanza del database perché richiede meno risorse I/O.

Utilizzando il partizionamento, è possibile suddividere i dati in blocchi di dimensioni personalizzate per l'elaborazione. Ad esempio, è possibile partizionare i dati delle serie temporali per intervalli quali orario, giornaliero, settimanale, mensile, trimestrale, annuale, personalizzato o qualsiasi combinazione di questi. Per un esempio di dati di serie temporali, se la tabella è stata partizionata per ora, ogni partizione conterrà un'ora di dati. Se si partiziona la tabella delle serie temporali per giorno, le partizioni conterranno i dati di un giorno e così via. La chiave di partizione controlla le dimensioni di una partizione. 

Quando si utilizza un comando SQL `INSERT` o `UPDATE` in una tabella partizionata, il motore database indirizza i dati alla partizione appropriata. Le partizioni di tabella PostgreSQL che memorizzano i dati sono tabelle figlio della tabella principale. 

Durante le letture delle query di database, l'ottimizzatore PostgreSQL esamina la clausola `WHERE` della query e, se possibile, indirizza la scansione del database solo alle partizioni pertinenti.

A partire dalla versione 10, PostgreSQL utilizza il partizionamento dichiarativo per implementare il partizionamento delle tabelle. Questo è noto anche come partizionamento PostgreSQL nativo. Prima di PostgreSQL versione 10, per implementare le partizioni venivano utilizzati i trigger. 

Il partizionamento delle tabelle PostgreSQL fornisce le seguenti funzionalità:
+ Creazione di nuove partizioni in qualsiasi momento.
+ Intervalli di partizione variabili.
+ Partizioni scollegabili e ricollegabili utilizzando istruzioni DDL (Data Definition Language).

  Ad esempio, le partizioni scollegabili sono utili per rimuovere i dati storici dalla partizione principale, conservando i dati storici per l'analisi.
+ Le nuove partizioni ereditano le proprietà della tabella di database padre, tra cui:
  + Indici
  + Chiavi primarie, che devono includere la colonna delle chiavi di partizione
  + Chiavi esterne
  + Vincoli check
  + Riferimenti
+ Creazione di indici per la tabella completa o per ogni partizione specifica.

Non è possibile modificare lo schema per una singola partizione. Tuttavia, è possibile modificare la tabella padre (ad esempio, aggiungendo una nuova colonna), che si propaga alle partizioni. 

**Topics**
+ [

## Panoramica dell'estensione PostgreSQL pg\$1partman
](#PostgreSQL_Partitions.pg_partman)
+ [

## Abilitazione dell'estensione pg\$1partman
](#PostgreSQL_Partitions.enable)
+ [

## Configurazione delle partizioni utilizzando la funzione create\$1parent
](#PostgreSQL_Partitions.create_parent)
+ [

## Configurazione della manutenzione delle partizioni utilizzando la funzione run\$1maintenance ance\$1proc
](#PostgreSQL_Partitions.run_maintenance_proc)

## Panoramica dell'estensione PostgreSQL pg\$1partman
<a name="PostgreSQL_Partitions.pg_partman"></a>

È possibile utilizzare l'estensione `pg_partman` PostgreSQL per automatizzare la creazione e la manutenzione delle partizioni di tabella. Per informazioni più generali, consulta [PG Partition Manager](https://github.com/pgpartman/pg_partman) nella documentazione di `pg_partman`.

**Nota**  
L'estensione `pg_partman` è supportata sul motore Amazon RDS for PostgreSQL versioni 12.5 e successive.

Invece di dover creare manualmente ogni partizione, è possibile configurare `pg_partman` con le seguenti impostazioni: 
+ Tabella da partizionare
+ Tipo di partizione
+ Chiave di partizione
+ Granularità delle partizioni
+ Opzioni di pre-creazione e gestione delle partizioni

Dopo aver creato una tabella con partizioni PostgreSQL, la si registra con `pg_partman` chiamando la funzione `create_parent`. In questo modo vengono create le partizioni necessarie in base ai parametri passati alla funzione.

L'estensione `pg_partman` fornisce anche la funzione `run_maintenance_proc`, che è possibile chiamare su base pianificata per gestire automaticamente le partizioni. Per pianificare la creazione delle partizioni appropriate in base alle esigenze, puoi pianificare questa funzione in modo che venga eseguita periodicamente (ad esempio, ogni ora). È inoltre possibile assicurarsi che le partizioni vengano eliminate automaticamente.

## Abilitazione dell'estensione pg\$1partman
<a name="PostgreSQL_Partitions.enable"></a>

Se disponi di più database all'interno della stessa istanza database per cui desideri gestire le partizioni, è necessario abilitare l'estensione `pg_partman` separatamente per ogni database. Per abilitare l'estensione `pg_partman` per un database specifico, crea lo schema di manutenzione delle partizioni, quindi crea l'estensione `pg_partman` nel modo seguente:

```
CREATE SCHEMA partman;
CREATE EXTENSION pg_partman WITH SCHEMA partman;
```

**Nota**  
Per creare l'estensione `pg_partman`, assicurati di disporre dei privilegi `rds_superuser`. 

Se viene restituito un errore come il seguente, concedi i privilegi `rds_superuser` all'account o utilizza l'account utente avanzato. 

```
ERROR: permission denied to create extension "pg_partman"
HINT: Must be superuser to create this extension.
```

Per concedere i privilegi `rds_superuser`, collegati con l'account utente avanzato ed emetti il seguente comando:

```
GRANT rds_superuser TO user-or-role;
```

Per gli esempi che mostrano l’uso dell’estensione pg\$1partman, si utilizza la tabella di database e la partizione di esempio seguenti. Questo database utilizza una tabella partizionata basata su un timestamp. Uno schema `data_mart` contiene una tabella denominata `events` con una colonna denominata `created_at`. Nella tabella `events` sono incluse le seguenti impostazioni:
+  Chiavi primarie `event_id` e `created_at`, che devono avere la colonna utilizzata per guidare la partizione.
+ Un vincolo di controllo `ck_valid_operation` per applicare i valori per una colonna della tabella `operation` .
+ Due chiavi esterne, dove una (`fk_orga_membership)`) punta alla tabella esterna `organization` e l'altra (`fk_parent_event_id`) è una chiave esterna autoreferenziata. 
+ Due indici, dove uno (`idx_org_id`) è per la chiave esterna e l'altro (`idx_event_type`) è per il tipo di evento.

Le seguenti istruzioni DDL creano questi oggetti, che verranno inclusi automaticamente in ogni partizione.

```
CREATE SCHEMA data_mart;
CREATE TABLE data_mart.organization ( org_id BIGSERIAL,
        org_name TEXT,
        CONSTRAINT pk_organization PRIMARY KEY (org_id)  
    );

CREATE TABLE data_mart.events(
        event_id        BIGSERIAL, 
        operation       CHAR(1), 
        value           FLOAT(24), 
        parent_event_id BIGINT, 
        event_type      VARCHAR(25), 
        org_id          BIGSERIAL, 
        created_at      timestamp, 
        CONSTRAINT pk_data_mart_event PRIMARY KEY (event_id, created_at), 
        CONSTRAINT ck_valid_operation CHECK (operation = 'C' OR operation = 'D'), 
        CONSTRAINT fk_orga_membership 
            FOREIGN KEY(org_id) 
            REFERENCES data_mart.organization (org_id),
        CONSTRAINT fk_parent_event_id 
            FOREIGN KEY(parent_event_id, created_at) 
            REFERENCES data_mart.events (event_id,created_at)
    ) PARTITION BY RANGE (created_at);

CREATE INDEX idx_org_id     ON  data_mart.events(org_id);
CREATE INDEX idx_event_type ON  data_mart.events(event_type);
```



## Configurazione delle partizioni utilizzando la funzione create\$1parent
<a name="PostgreSQL_Partitions.create_parent"></a>

Dopo aver abilitato l'estensione `pg_partman`, utilizza la funzione `create_parent` per configurare le partizioni all'interno dello schema di manutenzione delle partizioni. In questo esempio viene utilizzato l’esempio della tabella `events` creato in [Abilitazione dell'estensione pg\$1partmanConfigurazione della manutenzione delle partizioni utilizzando la funzione run\$1maintenance ance\$1proc](#PostgreSQL_Partitions.enable). Richiama la funzione `create_parent` come segue:

```
SELECT partman.create_parent( 
 p_parent_table => 'data_mart.events',
 p_control      => 'created_at',
 p_type         => 'range',
 p_interval     => '1 day',
 p_premake      => 30);
```

I parametri sono i seguenti:
+ `p_parent_table` – La tabella partizionata padre. Questa tabella deve già esistere ed essere completa, deve ovvero includere lo schema. 
+ `p_control` – Colonna su cui basare il partizionamento. Il tipo di dati deve essere intero o basato sul tempo.
+ `p_type`: il tipo è `'range'` o `'list'`.
+ `p_interval` – Intervallo di tempo o intervallo intero per ogni partizione. I valori di esempio includono `1 day`, `1 hour` e così via.
+ `p_premake` – Il numero di partizioni da creare in anticipo per supportare nuovi inserimenti.

Per una descrizione completa della funzione `create_parent`, consulta [Funzioni di creazione](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#user-content-creation-functions) nella documentazione `pg_partman`.

## Configurazione della manutenzione delle partizioni utilizzando la funzione run\$1maintenance ance\$1proc
<a name="PostgreSQL_Partitions.run_maintenance_proc"></a>

È possibile eseguire operazioni di manutenzione delle partizioni per creare automaticamente nuove partizioni, scollegare partizioni o rimuovere partizioni obsolete. La manutenzione delle partizioni si basa sulla funzione `run_maintenance_proc` dell'estensione `pg_partman` e dell'estensione `pg_cron`, che avvia un pianificatore interno. Lo scheduler `pg_cron` esegue automaticamente le istruzioni SQL, le funzioni e le procedure definite nei database. 

Nell'esempio seguente viene utilizzato l'esempio della tabella `events` creata in [Abilitazione dell'estensione pg\$1partmanConfigurazione della manutenzione delle partizioni utilizzando la funzione run\$1maintenance ance\$1proc](#PostgreSQL_Partitions.enable) per impostare l'esecuzione automatica delle operazioni di manutenzione delle partizioni. Come prerequisito, aggiungere `pg_cron` al parametro `shared_preload_libraries` nel gruppo di parametri dell'istanza database.

```
CREATE EXTENSION pg_cron;

UPDATE partman.part_config 
SET infinite_time_partitions = true,
    retention = '3 months', 
    retention_keep_table=true 
WHERE parent_table = 'data_mart.events';
SELECT cron.schedule('@hourly', $$CALL partman.run_maintenance_proc()$$);
```

Di seguito, puoi trovare una step-by-step spiegazione dell'esempio precedente: 

1. Modifica il gruppo di parametri associato all'istanza database e aggiungi `pg_cron` al valore del parametro `shared_preload_libraries`. Perché questa modifica abbia effetto, è necessario riavviare l'istanza database. Per ulteriori informazioni, consulta [Modifica dei parametri in un gruppo di parametri database in Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Emettere il comando `CREATE EXTENSION pg_cron;` utilizzando un account con le autorizzazioni `rds_superuser`. In questo modo, viene abilitata l’estensione `pg_cron`. Per ulteriori informazioni, consulta [Pianificazione della manutenzione con l'estensione PostgreSQL pg\$1cron](PostgreSQL_pg_cron.md).

1. Emettere il comando `UPDATE partman.part_config` per regolare le impostazioni `pg_partman` per la tabella `data_mart.events`. 

1. Eseguire il comando `SET` . . . per configurare la tabella `data_mart.events`, con le seguenti clausole:

   1. `infinite_time_partitions = true,` – Configura la tabella in modo da poter creare automaticamente nuove partizioni senza limiti.

   1. `retention = '3 months',` – Configura la tabella in modo che venga conservata per un massimo di tre mesi. 

   1. `retention_keep_table=true `– Configura la tabella in modo che quando il periodo di conservazione è scaduto, la tabella non venga eliminata automaticamente. Le partizioni precedenti al periodo di conservazione vengono invece scollegate dalla tabella padre.

1. Eseguire il comando `SELECT cron.schedule` . . . per creare una chiamata di funzione `pg_cron`. Questa chiamata definisce la frequenza con cui lo scheduler esegue la procedura di manutenzione `pg_partman`, `partman.run_maintenance_proc`. Per questo esempio, la procedura viene eseguita ogni ora. 

Per una descrizione completa della funzione `run_maintenance_proc`, consulta [Funzioni di manutenzione](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#maintenance-functions) nella documentazione di `pg_partman`. 

# Utilizzo di pgAudit per registrare l'attività del database
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit"></a>

Gli istituti finanziari, gli enti governativi e molti settori devono conservare i *log di audit* per soddisfare i requisiti normativi. L'utilizzo dell'estensione PostgreSQL Audit (pgAudit) con l'istanza database RDS per PostgreSQL consente di acquisire i record dettagliati richiesti in genere dai revisori o di soddisfare requisiti normativi. Ad esempio, è possibile impostare l'estensione pgAudit per tenere traccia delle modifiche apportate a database e tabelle specifici, per registrare l'utente che ha apportato la modifica e molti altri dettagli.

L'estensione pgAudit si basa sulla funzionalità dell'infrastruttura di registrazione PostgreSQL nativa estendendo i messaggi di registro con maggiori dettagli. In altre parole, l'approccio utilizzato per visualizzare il registro di audit è lo stesso utilizzato per visualizzare i messaggi di registro. Per ulteriori informazioni sulla registrazione PostgreSQL, consulta [](USER_LogAccess.Concepts.PostgreSQL.md). 

L'estensione pgAudit consente di oscurare i dati sensibili, come le password in chiaro, dai registri. Se il l'istanza database RDS per PostgreSQL è configurata per registrare le istruzioni DML (Data Manipulation Language) come descritto in [Attivazione della registrazione delle query per l'](USER_LogAccess.Concepts.PostgreSQL.Query_Logging.md), il problema delle password in chiaro può essere evitato utilizzando l'estensione PostgreSQL Audit. 

È possibile configurare l'audit sulle istanze database con un elevato grado di specificità. Puoi eseguire l'audit di tutti i database e di tutti gli utenti. In alternativa, è possibile scegliere di eseguire l'audit solo di determinati database, utenti e altri oggetti. È inoltre possibile escludere esplicitamente determinati utenti e database dall'audit. Per ulteriori informazioni, consulta [Esclusione di utenti o database dalla registrazione di audit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md). 

Data la quantità di dettagli che è possibile acquisire, ti consigliamo di monitorare il consumo di archiviazione se utilizzi pgAudit. 

L'estensione pgAudit è supportata su tutte le Versioni RDS per PostgreSQL. Per un elenco delle versioni di pgAudit supportate dalle versioni di RDS per PostgreSQL disponibili, consulta [Extension versions for Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) (Versioni delle estensioni per Amazon RDS per PostgreSQL) in *Amazon RDS for PostgreSQL Release Notes* (Note di rilascio di Amazon RDS per PostgreSQL). 

**Topics**
+ [

# Configurazione dell'estensione pgAudit
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md)
+ [

# Audit di oggetti di database
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing.md)
+ [

# Esclusione di utenti o database dalla registrazione di audit
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md)
+ [

# Riferimento per l'estensione pgAudit
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md)

# Configurazione dell'estensione pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup"></a>

Per configurare l'estensione pgAudit sull'istanza database RDS per PostgreSQL , aggiungi innanzitutto pgAudit alle librerie condivise nel gruppo di parametri database personalizzato per l'istanza database RDS per PostgreSQL Per informazioni sulla creazione di un gruppo di parametri database personalizzato, consulta [Gruppi di parametri per Amazon RDS](USER_WorkingWithParamGroups.md). Quindi, installa l'estensione pgAudit. Infine, specifica i database e gli oggetti di cui eseguire l'audit. Le procedure in questa sezione mostrano come fare. Puoi utilizzare la Console di gestione AWS o l'AWS CLI. 

Per eseguire tutte queste attività, sono richieste autorizzazioni come il ruolo `rds_superuser`.

Le fasi seguenti si basano sull'ipotesi che l'istanza database RDS per PostgreSQL sia associata a un gruppo di parametri database personalizzato. 

## Console
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CON"></a>

**Per impostare l'estensione pgAudit**

1. Accedi alla Console di gestione AWS e apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Nel riquadro di navigazione, scegli l' istanza database RDS per PostgreSQL.

1. Apri la scheda **Configurazione** per l' l'istanza database RDS per PostgreSQL. Tra i dettagli dell'istanza, individua il collegamento **Parameter group** (Gruppo di parametri). 

1. Scegli il collegamento per aprire i parametri personalizzati associati l'istanza database RDS per PostgreSQL. 

1. Nel campo di ricerca **Parametri**, digita `shared_pre` per trovare il parametro `shared_preload_libraries`.

1. Scegli **Edit parameters** (Modifica parametri) per accedere ai valori delle proprietà.

1. Aggiungi `pgaudit` all'elenco nel campo **Values** (Valori). Utilizza una virgola per separare gli elementi nell'elenco di valori.   
![\[Immagine del parametro shared_preload_libaries con pgAudit aggiunto.\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pgaudit.png)

1. Riavvia l'istanza database RDS per PostgreSQL in modo che la modifica al parametro `shared_preload_libraries` diventi effettiva. 

1. Quando l'istanza è disponibile, verifica che pgAudit sia stato inizializzato. Utilizza `psql` per connetterti all'istanza database RDS per PostgreSQL, quindi esegui il comando seguente.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

1. Con pgAudit inizializzato, puoi ora creare l'estensione. L'estensione deve essere creata dopo aver inizializzato la libreria perché l'estensione `pgaudit` installa i trigger evento per l'audit delle istruzioni DDL (Data Definition Language). 

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Chiudi la sessione `psql`.

   ```
   labdb=> \q
   ```

1. Accedi alla Console di gestione AWS e apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Trova il parametro `pgaudit.log` nell'elenco e impostalo sul valore appropriato per il caso d'uso. Ad esempio, se si imposta il parametro `pgaudit.log` su `write` come mostrato nell'immagine seguente, gli inserimenti, gli aggiornamenti, le eliminazioni e alcuni altri tipi di modifiche vengono acquisiti nel registro.   
![\[Immagine del parametro pgaudit.log con l'impostazione.\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/images/rpg_set_pgaudit-log-level.png)

   Puoi anche scegliere uno dei seguenti valori per il parametro `pgaudit.log`.
   + none: valore predefinito. Non viene registrata alcuna modifica al database. 
   + all: registra tutto (read, write, function, role, ddl, misc). 
   + ddl: registra tutte le istruzioni DDL (Data Definition Language) non incluse nella classe `ROLE`.
   + function: registra le chiamate di funzione e blocchi `DO`.
   + misc: registra vari comandi come `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`.
   + read: registra `SELECT` e `COPY` quando l'origine è una relazione (ad esempio una tabella) o una query.
   + role: registra le istruzioni correlate a ruoli e privilegi, ad esempio `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando la destinazione è una relazione (tabella).

1. Seleziona **Save changes** (Salva modifiche).

1. Apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Nell’elenco Database, scegli l’istanza database RDS per PostgreSQL.

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CLI"></a>

**Per configurare pgAudit**

Per configurare pgAudit utilizzando AWS CLI, chiama l'operazione [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) per modificare i parametri del registro di audit nel gruppo di parametri personalizzati, come illustrato nella procedura seguente.

1. Utilizza il seguente comando AWS CLI per aggiungere `pgaudit` al parametro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilizza il comando AWS CLI seguente per riavviare istanza database RDS per PostgreSQL in modo che la libreria pgaudit venga inizializzata.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando l'istanza è disponibile, verifica che `pgaudit` sia stato inizializzato. Utilizza `psql` per connetterti all'istanza database RDS per PostgreSQL, quindi esegui il comando seguente.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

   Con pgAudit inizializzato, puoi ora creare l'estensione.

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Chiudi la sessione `psql` in modo da poter utilizzare AWS CLI.

   ```
   labdb=> \q
   ```

1. Utilizza il comando AWS CLI seguente per specificare le classi di istruzioni che desideri registrare mediante la registrazione di audit della sessione. L'esempio imposta il parametro `pgaudit.log` su `write`, che acquisisce inserimenti, aggiornamenti ed eliminazioni nel registro.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.log,ParameterValue=write,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

   Puoi anche scegliere uno dei seguenti valori per il parametro `pgaudit.log`.
   + none: valore predefinito. Non viene registrata alcuna modifica al database. 
   + all: registra tutto (read, write, function, role, ddl, misc). 
   + ddl: registra tutte le istruzioni DDL (Data Definition Language) non incluse nella classe `ROLE`.
   + function: registra le chiamate di funzione e blocchi `DO`.
   + misc: registra vari comandi come `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`.
   + read: registra `SELECT` e `COPY` quando l'origine è una relazione (ad esempio una tabella) o una query.
   + role: registra le istruzioni correlate a ruoli e privilegi, ad esempio `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando la destinazione è una relazione (tabella).

   Riavvia l'istanza database RDS per PostgreSQL utilizzando il comando AWS CLI seguente.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Audit di oggetti di database
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing"></a>

Con pgAudit impostata sull'istanza database RDS per PostgreSQL e configurata per i requisiti, informazioni più dettagliate vengono acquisite nel registro PostgreSQL. Ad esempio, sebbene la configurazione della registrazione PostgreSQL predefinita consenta di identificare la data e l'ora della modifica apportata a una tabella di database, con l'estensione pgAudit la voce di registro può includere lo schema, l'utente che ha apportato la modifica e altri dettagli a seconda della configurazione dei parametri dell'estensione. È possibile configurare l'audit per tenere traccia delle modifiche nei modi seguenti.
+ Per ogni sessione, per utente. Per il livello di sessione, è possibile acquisire il testo del comando completo.
+ Per ogni oggetto, per utente e per database. 

La funzionalità di audit degli oggetti viene attivata quando il ruolo `rds_pgaudit` viene creato nel sistema e quindi aggiunto al parametro `pgaudit.role` nel gruppo di parametri personalizzati. Per impostazione predefinita, l'impostazione del parametro `pgaudit.role` viene annullata e l'unico valore consentito è `rds_pgaudit`. Nelle fasi seguenti si presume che `pgaudit` sia stato inizializzato e che l'estensione `pgaudit` sia stata creata seguendo la procedura in [Configurazione dell'estensione pgAudit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md). 

![\[Immagine del file di registro di PostgreSQL dopo la configurazione di pgAudit.\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/images/pgaudit-log-example.png)


Come mostrato in questo esempio, la riga "LOG: AUDIT: SESSION" fornisce informazioni sulla tabella e il relativo schema, insieme ad altri dettagli. 

**Per configurare l'audit degli oggetti**

1. Utilizza `psql` per connetterti all'istanza database RDS per PostgreSQL.

   ```
   psql --host=your-instance-name.aws-region.rds.amazonaws.com --port=5432 --username=postgrespostgres --password --dbname=labdb
   ```

1. Crea un ruolo del database denominato `rds_pgaudit` utilizzando il comando seguente.

   ```
   labdb=> CREATE ROLE rds_pgaudit;
   CREATE ROLE
   labdb=>
   ```

1. Chiudi la sessione `psql`.

   ```
   labdb=> \q
   ```

   Nei passaggi successivi, utilizza AWS CLI per modificare i parametri del registro di audit nel gruppo di parametri personalizzati. 

1. Utilizza il seguente comando AWS CLI per impostare il parametro `pgaudit.role` su `rds_pgaudit`. Per impostazione predefinita, questo parametro è vuoto e `rds_pgaudit` è l'unico valore consentito.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.role,ParameterValue=rds_pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilizza il seguente comando AWS CLI per riavviare l'istanza database RDS per PostgreSQL in modo da rendere effettive le modifiche apportate ai parametri.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Esegui il comando seguente per verificare che `pgaudit.role` sia impostato su `rds_pgaudit`.

   ```
   SHOW pgaudit.role;
   pgaudit.role 
   ------------------
   rds_pgaudit
   ```

Per testare la registrazione di pgAudit, è possibile eseguire diversi comandi di esempio da controllare. Ad esempio, si potrebbero eseguire i comandi seguenti.

```
CREATE TABLE t1 (id int);
GRANT SELECT ON t1 TO rds_pgaudit;
SELECT * FROM t1;
id 
----
(0 rows)
```

I registri del database devono contenere una voce simile alla seguente:

```
...
2017-06-12 19:09:49 UTC:...:rds_test@postgres:[11701]:LOG: AUDIT:
OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1;
...
```

Per informazioni sulla visualizzazione dei registri, consulta [Monitoraggio dei file di log di Amazon RDS](USER_LogAccess.md).

Per ulteriori informazioni sull'estensione pgAudit, consulta [pgAudit](https://github.com/pgaudit/pgaudit/blob/master/README.md) su GitHub.

# Esclusione di utenti o database dalla registrazione di audit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db"></a>

Come illustrato in [](USER_LogAccess.Concepts.PostgreSQL.md), i registri di PostgreSQL consumano spazio di archiviazione. L'uso dell'estensione pgAudit consente di aumentare il volume di dati raccolti nei registri in misura diversa, a seconda delle modifiche che vengono monitorate. Potrebbe non essere necessario eseguire l'audit di ogni utente o database l'istanza database RDS per PostgreSQL.

Per ridurre al minimo l'impatto sull'archiviazione ed evitare di acquisire inutilmente i record di audit, è possibile escludere utenti e database dall'audit. È anche possibile modificare la registrazione all'interno di una determinata sessione. Negli esempi seguenti viene mostrato come fare. 

**Nota**  
Le impostazioni dei parametri a livello di sessione hanno la precedenza sulle impostazioni nel gruppo di parametri database personalizzato per l'istanza database RDS per PostgreSQL. Per evitare che gli utenti del database ignorino le impostazioni di configurazione della registrazione di audit, accertati di modificare le loro autorizzazioni. 

Supponi che l'istanza database RDS per PostgreSQL sia configurata per eseguire l'audit dello stesso livello di attività per tutti gli utenti e i database. Decidi quindi di non voler eseguire l'audit dell'utente `myuser`. Puoi disattivare l'audit per `myuser` con il comando SQL seguente.

```
ALTER USER myuser SET pgaudit.log TO 'NONE';
```

Quindi, puoi utilizzare la seguente query per controllare la colonna `user_specific_settings` per `pgaudit.log` per verificare che sia impostata su `NONE`.

```
SELECT
    usename AS user_name,
    useconfig AS user_specific_settings
FROM
    pg_user
WHERE
    usename = 'myuser';
```

Viene visualizzato l'output riportato di seguito.

```
 user_name | user_specific_settings
-----------+------------------------
 myuser    | {pgaudit.log=NONE}
(1 row)
```

Puoi disattivare la registrazione per un determinato utente durante la sessione con il database con il seguente comando.

```
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'none';
```

Utilizza la seguente query per controllare la colonna delle impostazioni per pgaudit.log per una combinazione specifica di utente e database. 

```
SELECT
    usename AS "user_name",
    datname AS "database_name",
    pg_catalog.array_to_string(setconfig, E'\n') AS "settings"
FROM
    pg_catalog.pg_db_role_setting s
    LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase
    LEFT JOIN pg_catalog.pg_user r ON r.usesysid = setrole
WHERE
    usename = 'myuser'
    AND datname = 'mydatabase'
ORDER BY
    1,
    2;
```

L'output visualizzato è simile al seguente.

```
  user_name | database_name |     settings
-----------+---------------+------------------
 myuser    | mydatabase    | pgaudit.log=none
(1 row)
```

Dopo aver disattivato l'audit per `myuser`, decidi di non voler tenere traccia delle modifiche apportate a `mydatabase`. Puoi disattivare l'audit per il database specifico utilizzando il comando seguente.

```
ALTER DATABASE mydatabase SET pgaudit.log to 'NONE';
```

Quindi, utilizza la seguente query per controllare la colonna database\$1specific\$1settings per verificare che pgaudit.log sia impostato su NONE.

```
SELECT
a.datname AS database_name,
b.setconfig AS database_specific_settings
FROM
pg_database a
FULL JOIN pg_db_role_setting b ON a.oid = b.setdatabase
WHERE
a.datname = 'mydatabase';
```

Viene visualizzato l'output riportato di seguito.

```
 database_name | database_specific_settings
---------------+----------------------------
 mydatabase    | {pgaudit.log=NONE}
(1 row)
```

Per ripristinare le impostazioni predefinite di myuser, utilizza il comando seguente:

```
ALTER USER myuser RESET pgaudit.log;
```

Per ripristinare i valori predefiniti delle impostazioni di un database, utilizza il comando seguente.

```
ALTER DATABASE mydatabase RESET pgaudit.log;
```

Per ripristinare l'impostazione predefinita di utente e database, utilizza il comando seguente.

```
ALTER USER myuser IN DATABASE mydatabase RESET pgaudit.log;
```

Puoi anche acquisire eventi specifici nel registro impostando `pgaudit.log` su uno degli altri valori consentiti per il parametro `pgaudit.log`. Per ulteriori informazioni, consulta [Elenco delle impostazioni consentite per il parametro `pgaudit.log`](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).

```
ALTER USER myuser SET pgaudit.log TO 'read';
ALTER DATABASE mydatabase SET pgaudit.log TO 'function';
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'read,function'
```

# Riferimento per l'estensione pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference"></a>

Puoi specificare il livello di dettaglio desiderato per il registro di audit modificando uno o più dei parametri elencati in questa sezione. 

## Controllo del comportamento di pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.basic-setup.parameters"></a>

Puoi controllare la registrazione di audit modificando uno o più dei parametri elencati nella tabella seguente. 


| Parametro | Description | 
| --- | --- | 
| `pgaudit.log`  | Specifica quali classi di istruzioni verranno registrate per registrazione di audit della sessione. I valori consentiti includono ddl, function, misc, read, role, write, none, all. Per ulteriori informazioni, consulta [Elenco delle impostazioni consentite per il parametro `pgaudit.log`](#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).  | 
| `pgaudit.log_catalog` | Quando è attivato (impostato su 1), aggiunge istruzioni all'audit trail se tutte le relazioni in un'istruzione si trovano in pg\$1catalog. | 
| `pgaudit.log_level` | Specifica il livello di registro che verrà utilizzato per le voci di registro. Valori consentiti: debug5, debug4, debug3, debug2, debug1, info, notice, warning, log | 
| `pgaudit.log_parameter` | Quando è attivato (impostato su 1), i parametri passati con l'istruzione vengono acquisiti nel registro di audit. | 
| `pgaudit.log_relation` | Quando è attivato (impostato su 1), il registro di audit della sessione crea una voce di registro separata per ogni relazione (TABLE, VIEW e così via) a cui si fa riferimento in un'istruzione SELECT o DML. | 
| `pgaudit.log_statement_once` | Specificate se la registrazione includerà il testo e i parametri dell'istruzione con la prima voce di registro per una statement/substatement combinazione o con ogni voce. | 
| `pgaudit.role` | Specifica il ruolo principale da utilizzare per la registrazione di verifica degli oggetti. L'unica voce consentita è `rds_pgaudit`. | 

## Elenco delle impostazioni consentite per il parametro `pgaudit.log`
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings"></a>

 


| Valore | Description | 
| --- | --- | 
| nessuno | Questa è l’impostazione predefinita. Non viene registrata alcuna modifica al database.  | 
| tutto | Registra tutto (read, write, function, role, ddl, misc).  | 
| ddl | Registra tutte le istruzioni DDL (Data Definition Language) non incluse nella classe `ROLE`. | 
| funzione | Registra le chiamate di funzione e i blocchi `DO`. | 
| misc | Registra vari comandi, ad esempio `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`. | 
| read | Registra `SELECT` e `COPY` quando l'origine è una relazione (ad esempio una tabella) o una query. | 
| role | Registra le istruzioni relative a ruoli e privilegi, ad esempio `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`. | 
| write | Registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando la destinazione è una relazione (tabella). | 

Per registrare più tipi di eventi con controllo di sessioni, utilizzare un elenco separato da virgole. Per registrare tutti i tipi di eventi, impostare `pgaudit.log` su `ALL`. Riavviare l'istanza database per applicare le modifiche.

Con il controllo dell'oggetto, è possibile perfezionare la registrazione di controllo per lavorare con relazioni specifiche. Ad esempio, è possibile richiedere la registrazione di audit per le operazioni `READ` su una o più tabelle.

# Pianificazione della manutenzione con l'estensione PostgreSQL pg\$1cron
<a name="PostgreSQL_pg_cron"></a>

Puoi utilizzare l'estensione PostgreSQL `pg_cron` per pianificare i comandi di manutenzione all'interno di un database PostgreSQL. Per ulteriori informazioni sull'estensione, consulta [Che cos'è pg\$1cron?](https://github.com/citusdata/pg_cron) nella documentazione di pg\$1cron. 

L'estensione `pg_cron` è supportata sul motore RDS for PostgreSQL versioni 12.5 e successive.

Per ulteriori informazioni sull'uso di `pg_cron`, consulta [Schedule jobs with pg\$1cron on your RDS for PostgreSQL or your Aurora PostgreSQL-Compatible Edition databases](https://aws.amazon.com/blogs/database/schedule-jobs-with-pg_cron-on-your-amazon-rds-for-postgresql-or-amazon-aurora-for-postgresql-databases/) (Pianificazione dei processi con pg\$1cron sui database RDS per PostgreSQL o Aurora edizione compatibile con PostgreSQL).

**Nota**  
La versione dell’estensione `pg_cron` viene visualizzata come versione a due cifre, ad esempio 1.6, nella vista pg\$1available\$1extensions. Sebbene in alcuni contesti possano essere elencate versioni a tre cifre, ad esempio 1.6.4 o 1.6.5, è necessario specificare la versione a due cifre quando si esegue un aggiornamento dell’estensione.

**Topics**
+ [

## Configurazione dell'estensione pg\$1cron
](#PostgreSQL_pg_cron.enable)
+ [

## Concessione delle autorizzazioni per utilizzare pg\$1cron agli utenti del database
](#PostgreSQL_pg_cron.permissions)
+ [

## Programmazione di processi pg\$1cron
](#PostgreSQL_pg_cron.examples)
+ [

## Riferimento per l'estensione pg\$1cron
](#PostgreSQL_pg_cron.reference)

## Configurazione dell'estensione pg\$1cron
<a name="PostgreSQL_pg_cron.enable"></a>

Configura l'estensione `pg_cron` come riportato di seguito:

1. Modifica il gruppo di parametri personalizzati associato all'istanza database PostgreSQL aggiungendo `pg_cron` al valore del parametro `shared_preload_libraries`.
   + Se l'istanza database RDS per PostgreSQL utilizza il parametro `rds.allowed_extensions` per elencare in maniera esplicita le estensioni che possono essere installate, è necessario aggiungere l'estensione `pg_cron` all'elenco. Solo alcune versioni di RDS per PostgreSQL supportano il parametro `rds.allowed_extensions`. Per impostazione predefinita, tutte le estensioni disponibili sono consentite. Per ulteriori informazioni, consulta [Limitazione dell'installazione delle estensioni PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

   Per rendere effettive le modifiche apportate al gruppo di parametri, riavvia l'istanza database PostgreSQL. Per ulteriori informazioni sull'utilizzo dei gruppi di parametri, consulta [Modifica dei parametri in un gruppo di parametri database in Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Dopo il riavvio dell'istanza database PostgreSQL, esegui il comando riportato di seguito utilizzando un account che dispone delle autorizzazioni `rds_superuser`. Ad esempio, se hai utilizzato le impostazioni di default quando hai creato l'istanza database RDS for PostgreSQL, connettiti come utente `postgres` e crea l'estensione. 

   ```
   CREATE EXTENSION pg_cron;
   ```

   Lo scheduler `pg_cron` è impostato nel database PostgreSQL predefinito denominato `postgres`. Gli oggetti `pg_cron` vengono creati in questo database `postgres` e tutte le azioni di pianificazione vengono eseguite in questo database.

1. Puoi usare le impostazioni predefinite oppure puoi pianificare i processi da eseguire in altri database all'interno dell'istanza database di PostgreSQL. Per pianificare i processi per altri database all'interno dell'istanza database di PostgreSQL, consulta l'esempio in [Pianificazione di un processo cron per un database diverso da quello predefinito](#PostgreSQL_pg_cron.otherDB).

## Concessione delle autorizzazioni per utilizzare pg\$1cron agli utenti del database
<a name="PostgreSQL_pg_cron.permissions"></a>

L'installazione dell'estensione `pg_cron` richiede privilegi `rds_superuser`. Tuttavia, le autorizzazioni per utilizzare `pg_cron` possono essere concesse (da un membro del gruppo/ruolo `rds_superuser`) ad altri utenti del database, in modo che possano pianificare i propri lavori. Ti consigliamo di concedere le autorizzazioni allo schema `cron` solo se in base alle esigenze se migliora le operazioni nell'ambiente di produzione. 

Per concedere a un database l'autorizzazione utente nello schema `cron`, esegui il seguente comando:

```
postgres=> GRANT USAGE ON SCHEMA cron TO db-user;
```

Questo dà *db-user* il permesso di accedere allo `cron` schema per pianificare i cron job per gli oggetti a cui hanno i permessi di accesso. Se l'utente del database non dispone di autorizzazioni, il processo non va a buon fine dopo aver pubblicato il messaggio di errore nel file `postgresql.log`, come mostrato di seguito:

```
2020-12-08 16:41:00 UTC::@:[30647]:ERROR: permission denied for table table-name
2020-12-08 16:41:00 UTC::@:[27071]:LOG: background worker "pg_cron" (PID 30647) exited with exit code 1
```

In altre parole, assicurarsi che gli utenti del database a cui sono concesse autorizzazioni per lo schema `cron`, dispongano anche di autorizzazioni sugli oggetti (tabelle, schemi e così via) che intendono pianificare.

I dettagli del processo cron e l’esito positivo o negativo sono anche acquisiti nella tabella `cron.job_run_details`. Per ulteriori informazioni, consulta [Tabelle per la pianificazione dei processi e l'acquisizione dello stato](#PostgreSQL_pg_cron.tables).

## Programmazione di processi pg\$1cron
<a name="PostgreSQL_pg_cron.examples"></a>

Nelle sezioni seguenti viene illustrato come è possibile pianificare varie attività di gestione utilizzando le attività `pg_cron`.

**Nota**  
Quando crei processi `pg_cron`, controlla che l'impostazione `max_worker_processes` sia maggiore del numero di `cron.max_running_jobs`. Un processo `pg_cron` non riesce se i processi worker in background vengono esauriti. Il numero predefinito di processi `pg_cron` è `5`. Per ulteriori informazioni, consulta [Parametri per la gestione dell'estensione pg\$1cron](#PostgreSQL_pg_cron.parameters).

**Topics**
+ [

### Vacuum di una tabella
](#PostgreSQL_pg_cron.vacuum)
+ [

### Eliminazione della tabella della cronologia di pg\$1cron
](#PostgreSQL_pg_cron.job_run_details)
+ [

### Registrazione degli errori solo nel file postgresql.log
](#PostgreSQL_pg_cron.log_run)
+ [

### Pianificazione di un processo cron per un database diverso da quello predefinito
](#PostgreSQL_pg_cron.otherDB)

### Vacuum di una tabella
<a name="PostgreSQL_pg_cron.vacuum"></a>

Autovacuum gestisce la manutenzione del vacuum per la maggior parte dei casi. Tuttavia, potresti voler programmare un vacuum di una tabella specifica in un momento di tua scelta. 

Consulta anche, [Utilizzo della funzionalità di autovacuum di PostgreSQL in Amazon RDS per PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

Di seguito è riportato un esempio di utilizzo della funzione `cron.schedule` per impostare un processo in modo da utilizzare `VACUUM FREEZE` su una tabella specifica ogni giorno alle 22:00 (GMT).

```
SELECT cron.schedule('manual vacuum', '0 22 * * *', 'VACUUM FREEZE pgbench_accounts');
 schedule
----------
1
(1 row)
```

Dopo l'esecuzione dell'esempio precedente, è possibile controllare la cronologia nella tabella `cron.job_run_details` come riportato di seguito.

```
postgres=> SELECT * FROM cron.job_run_details;
jobid  | runid | job_pid | database | username | command                        | status    | return_message | start_time                    | end_time
-------+-------+---------+----------+----------+--------------------------------+-----------+----------------+-------------------------------+-------------------------------
 1     | 1     | 3395    | postgres | adminuser| vacuum freeze pgbench_accounts | succeeded | VACUUM         | 2020-12-04 21:10:00.050386+00 | 2020-12-04 21:10:00.072028+00
(1 row)
```

Di seguito è riportata una query della tabella `cron.job_run_details` per visualizzare i processi non riusciti.

```
postgres=> SELECT * FROM cron.job_run_details WHERE status = 'failed';
jobid | runid | job_pid | database | username | command                       | status | return_message                                   | start_time                    | end_time
------+-------+---------+----------+----------+-------------------------------+--------+--------------------------------------------------+-------------------------------+------------------------------
 5    | 4     | 30339   | postgres | adminuser| vacuum freeze pgbench_account | failed | ERROR: relation "pgbench_account" does not exist | 2020-12-04 21:48:00.015145+00 | 2020-12-04 21:48:00.029567+00
(1 row)
```

Per ulteriori informazioni, consulta [Tabelle per la pianificazione dei processi e l'acquisizione dello stato](#PostgreSQL_pg_cron.tables).

### Eliminazione della tabella della cronologia di pg\$1cron
<a name="PostgreSQL_pg_cron.job_run_details"></a>

La tabella `cron.job_run_details` contiene una cronologia di processi cron che può crescere a dismisura nel tempo. Si consiglia di pianificare un processo che elimini questa tabella. Ad esempio, conservare una settimana di voci può essere sufficiente per la risoluzione dei problemi. 

Nell'esempio seguente viene utilizzata la funzione [cron.schedule](#PostgreSQL_pg_cron.schedule) per pianificare un processo che viene eseguito ogni giorno a mezzanotte per rimuovere la tabella `cron.job_run_details`. Il processo conserva solo gli ultimi sette giorni. Utilizza l'account `rds_superuser` per pianificare il processo come riportato di seguito.

```
SELECT cron.schedule('0 0 * * *', $$DELETE 
    FROM cron.job_run_details 
    WHERE end_time < now() - interval '7 days'$$);
```

Per ulteriori informazioni, consulta [Tabelle per la pianificazione dei processi e l'acquisizione dello stato](#PostgreSQL_pg_cron.tables).

### Registrazione degli errori solo nel file postgresql.log
<a name="PostgreSQL_pg_cron.log_run"></a>

Per disattivare la scrittura nella tabella `cron.job_run_details`, modifica il gruppo di parametri associato all'istanza database PostgreSQL e disattiva il parametro `cron.log_run`. L'estensione `pg_cron` non scrive più nella tabella e acquisisce gli errori solo nel file `postgresql.log`. Per ulteriori informazioni, consulta [Modifica dei parametri in un gruppo di parametri database in Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

Utilizza il seguente comando per controllare il valore del parametro `cron.log_run`.

```
postgres=> SHOW cron.log_run;
```

Per ulteriori informazioni, consulta [Parametri per la gestione dell'estensione pg\$1cron](#PostgreSQL_pg_cron.parameters).

### Pianificazione di un processo cron per un database diverso da quello predefinito
<a name="PostgreSQL_pg_cron.otherDB"></a>

I metadati per `pg_cron` sono tutti contenuti nel database predefinito PostgreSQL denominato `postgres`. Poiché i worker in background vengono utilizzati per l'esecuzione dei processi cron di manutenzione, puoi pianificare un processo in uno qualsiasi dei database all'interno dell'istanza database PostgreSQL.

**Nota**  
Solo gli utenti con il ruolo `rds_superuser` o i privilegi `rds_superuser` possono elencare tutti i processi cron nel database. Gli altri utenti possono visualizzare solo i propri processi nella tabella `cron.job`.

1. Nel database cron, pianifica il processo come si farebbe normalmente utilizzando [cron.schedule](#PostgreSQL_pg_cron.schedule).

   ```
   postgres=> SELECT cron.schedule('database1 manual vacuum', '29 03 * * *', 'vacuum freeze test_table');
   ```

1. Con il ruolo `rds_superuser`, aggiorna la colonna del database per il processo appena creato in modo che venga eseguito in un altro database all'interno dell'istanza database PostgreSQL.

   ```
   postgres=> UPDATE cron.job SET database = 'database1' WHERE jobid = 106;
   ```

1.  Verifica eseguendo una query sulla tabella `cron.job`.

   ```
   postgres=> SELECT * FROM cron.job;
   jobid | schedule    | command                        | nodename  | nodeport | database | username  | active | jobname
   ------+-------------+--------------------------------+-----------+----------+----------+-----------+--------+-------------------------
   106   | 29 03 * * * | vacuum freeze test_table       | localhost | 8192     | database1| adminuser | t      | database1 manual vacuum
     1   | 59 23 * * * | vacuum freeze pgbench_accounts | localhost | 8192     | postgres | adminuser | t      | manual vacuum
   (2 rows)
   ```

**Nota**  
In alcune situazioni, è possibile aggiungere un processo cron che si intende eseguire in un database diverso. In questi casi, il processo potrebbe essere eseguito nel database predefinito (`postgres`) prima di aggiornare la colonna del database corretta. Se il nome utente dispone delle autorizzazioni, il processo viene eseguito correttamente nel database predefinito.

## Riferimento per l'estensione pg\$1cron
<a name="PostgreSQL_pg_cron.reference"></a>

È possibile utilizzare i seguenti parametri, funzioni e tabelle con l'estensione `pg_cron`. Per ulteriori informazioni, consultare [Che cos'è pg\$1cron?](https://github.com/citusdata/pg_cron) nella documentazione di pg\$1cron.

**Topics**
+ [

### Parametri per la gestione dell'estensione pg\$1cron
](#PostgreSQL_pg_cron.parameters)
+ [

### Riferimento alla funzione: cron.schedule
](#PostgreSQL_pg_cron.schedule)
+ [

### Riferimento alla funzione: cron.unschedule
](#PostgreSQL_pg_cron.unschedule)
+ [

### Tabelle per la pianificazione dei processi e l'acquisizione dello stato
](#PostgreSQL_pg_cron.tables)

### Parametri per la gestione dell'estensione pg\$1cron
<a name="PostgreSQL_pg_cron.parameters"></a>

Di seguito è riportato l'elenco dei parametri che consentono di controllare il comportamento dell'estensione `pg_cron`. 


| Parametro | Description | 
| --- | --- | 
| cron.database\$1name |  Il database in cui vengono conservati i metadati `pg_cron`.  | 
| cron.host |  Il nome host per connettersi a PostgressQL. Non è possibile modificare questo valore.  | 
| cron.log\$1run |  Registra tutti i processi eseguiti nella tabella `job_run_details`. I valori sono `on` o `off`. Per ulteriori informazioni, consulta [Tabelle per la pianificazione dei processi e l'acquisizione dello stato](#PostgreSQL_pg_cron.tables).  | 
| cron.log\$1statement |  Registra tutte le istruzioni cron prima di eseguirle. I valori sono `on` o `off`.  | 
| cron.max\$1running\$1jobs |  Numero massimo di processi che possono essere eseguiti contemporaneamente.  | 
| cron.use\$1background\$1workers |  Utilizza i worker in background anziché le sessioni client. Non è possibile modificare questo valore.  | 

Puoi utilizzare il comando SQL seguente per visualizzare questi parametri e i relativi valori.

```
postgres=> SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE 'cron.%' ORDER BY name;
```

### Riferimento alla funzione: cron.schedule
<a name="PostgreSQL_pg_cron.schedule"></a>

Questa funzione pianifica un processo cron. Il processo viene inizialmente pianificato nel database `postgres` predefinito. La funzione restituisce un valore `bigint` che rappresenta l'identificativo del processo. Per pianificare l'esecuzione di processi in altri database all'interno dell'istanza database di PostgreSQL, consulta l'esempio in [Pianificazione di un processo cron per un database diverso da quello predefinito](#PostgreSQL_pg_cron.otherDB).

La funzione ha due diverse sintassi.

**Sintassi**  

```
cron.schedule (job_name,
    schedule,
    command
);

cron.schedule (schedule,
    command
);
```

**Parametri**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Esempi**  

```
postgres=> SELECT cron.schedule ('test','0 10 * * *', 'VACUUM pgbench_history');
 schedule
----------
      145
(1 row)

postgres=> SELECT cron.schedule ('0 15 * * *', 'VACUUM pgbench_accounts');
 schedule
----------
      146
(1 row)
```

### Riferimento alla funzione: cron.unschedule
<a name="PostgreSQL_pg_cron.unschedule"></a>

Questa funzione elimina un processo cron. Puoi specificare `job_name` o `job_id`. Una policy assicura che l'utente sia il proprietario e possa rimuovere la pianificazione per il processo. La funzione restituisce un valore Booleano che indica la riuscita o l'errore.

La funzione ha la seguente sintassi.

**Sintassi**  

```
cron.unschedule (job_id);

cron.unschedule (job_name);
```

**Parametri**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Esempi**  

```
postgres=> SELECT cron.unschedule(108);
 unschedule
------------
 t
(1 row)

postgres=> SELECT cron.unschedule('test');
 unschedule
------------
 t
(1 row)
```

### Tabelle per la pianificazione dei processi e l'acquisizione dello stato
<a name="PostgreSQL_pg_cron.tables"></a>

Le seguenti tabelle vengono create e utilizzate per pianificare i processi cron e registrare il modo in cui i processi vengono completati. 


| Tabella | Descrizione | 
| --- | --- | 
| cron.job |  Contiene i metadati relativi a ciascun processo pianificato. La maggior parte delle interazioni con questa tabella dovrebbe essere eseguita tramite le funzioni `cron.schedule` e `cron.unschedule`.  Si sconsiglia di concedere privilegi di aggiornamento/inserimento direttamente a questa tabella. In questo modo, si consente all'utente di aggiornare la colonna `username` da eseguire come `rds-superuser`.   | 
| cron.job\$1run\$1details |  Contiene informazioni cronologiche sulle esecuzioni precedenti dei processi pianificati. Ciò è utile per analizzare lo stato, i messaggi restituiti e l'ora di inizio e di fine dall'esecuzione del processo.  Per evitare che questa tabella cresca in maniera indefinita, è necessario eliminarla su base regolare. Per un esempio, consulta [Eliminazione della tabella della cronologia di pg\$1cron](#PostgreSQL_pg_cron.job_run_details).   | 

# Utilizzo di pglogical per sincronizzare i dati tra le istanze
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical"></a>

Tutte le versioni di RDS per PostgreSQL attualmente disponibili supportano l'estensione `pglogical`, che precede la funzionalità di replica logica funzionalmente simile introdotta nella versione 10 di PostgreSQL. Per ulteriori informazioni, consulta [Esecuzione della replica logica per Amazon RDS for PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md).

L'estensione `pglogical` supporta la replica logica tra due o più istanze database RDS per PostgreSQL. Supporta anche la replica tra diverse versioni di PostgreSQL e tra database in esecuzione in istanze database RDS per PostgreSQL e cluster database Aurora PostgreSQL. L'estensione `pglogical` utilizza un modello publish-subscribe per replicare le modifiche apportate alle tabelle e ad altri oggetti, come le sequenze, da un publisher in un subscriber. Si basa su uno slot di replica per garantire la sincronizzazione delle modifiche da un nodo publisher a un nodo subscriber, definiti come indicato di seguito. 
+ Il *nodo publisher* è l'istanza database RDS per PostgreSQL che costituisce l'origine dei dati da replicare in altri nodi. Il nodo publisher definisce le tabelle da replicare in un set di pubblicazione. 
+ Il *nodo subscriber* è l'istanza database RDS per PostgreSQL che riceve gli aggiornamenti WAL dal publisher. Il subscriber crea una sottoscrizione per connettersi al publisher e ottenere i dati WAL decodificati e contemporaneamente nel nodo publisher viene creato lo slot di replica. 

Di seguito sono riportati gli argomenti sull'impostazione dell'estensione `pglogical`. 

**Topics**
+ [

## Requisiti e limitazioni dell'estensione pglogical
](#Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations)
+ [

# Impostazione dell'estensione pglogical
](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md)
+ [

# Impostazione della replica logica per l'istanza database RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication.md)
+ [

# Riconnessione della replica logica dopo un aggiornamento principale
](Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.md)
+ [

# Gestione degli slot di replica logica per PostgreSQL RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)
+ [

# Riferimento sui parametri dell'estensione pglogical
](Appendix.PostgreSQL.CommonDBATasks.pglogical.reference.md)

## Requisiti e limitazioni dell'estensione pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations"></a>

Tutte le versioni attualmente disponibili di RDS per PostgreSQL supportano l'estensione `pglogical`. 

Sia il nodo publisher che il nodo subscriber devono essere impostati per la replica logica.

Le tabelle da replicare da un nodo publisher a un nodo subscriber devono avere gli stessi nomi e lo stesso schema. Inoltre devono contenere le stesse colonne e le colonne devono utilizzare gli stessi tipi di dati. Le tabelle del publisher e del subscriber devono avere le stesse chiavi primarie. Si consiglia di utilizzare solo la CHIAVE PRIMARIA come vincolo univoco.

Le tabelle del nodo subscriber possono avere vincoli più permissivi rispetto ai vincoli CHECK e NOT NULL delle tabelle del nodo publisher. 

L'estensione `pglogical` fornisce funzionalità, come la replica bidirezionale, che non sono supportate dalla funzionalità di replica logica integrata in PostgreSQL 10 e versioni successive. Per ulteriori informazioni, consulta [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replica bidirezionale di PostgreSQL utilizzando pglogical).

# Impostazione dell'estensione pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup"></a>

Per impostare l'estensione `pglogical` per l'istanza database RDS per PostgreSQL, aggiungi `pglogical` alle librerie condivise nel gruppo di parametri database personalizzato per l'istanza database RDS per PostgreSQL. È inoltre necessario impostare il valore del parametro `rds.logical_replication` su `1` per attivare la decodifica logica. Infine, crei l'estensione nel database. È possibile utilizzare Console di gestione AWS o AWS CLI per queste attività. 

Per eseguire queste attività sono richieste le autorizzazioni del ruolo `rds_superuser`.

Le fasi seguenti si basano sull'ipotesi che l'istanza database RDS per PostgreSQL sia associata a un gruppo di parametri database personalizzato. Per informazioni sulla creazione di un gruppo di parametri database personalizzato, consulta [Gruppi di parametri per Amazon RDS](USER_WorkingWithParamGroups.md).

## Console
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CON"></a>

**Per impostare l'estensione pglogical**

1. Accedi a Console di gestione AWS e apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Nel riquadro di navigazione, scegli l' istanza database RDS per PostgreSQL.

1. Apri la scheda **Configurazione** per l' l’istanza database RDS per PostgreSQL. Tra i dettagli dell'istanza, individua il collegamento **Parameter group** (Gruppo di parametri). 

1. Scegli il collegamento per aprire i parametri personalizzati associati l’istanza database RDS per PostgreSQL. 

1. Nel campo di ricerca **Parametri**, digita `shared_pre` per trovare il parametro `shared_preload_libraries`.

1. Scegli **Edit parameters** (Modifica parametri) per accedere ai valori delle proprietà.

1. Aggiungi `pglogical` all’elenco nel campo **Values** (Valori). Utilizza una virgola per separare gli elementi nell’elenco di valori.   
![\[Immagine del parametro shared_preload_libraries con l'estensione pglogical aggiunta.\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pglogical.png)

1. Individua il parametro `rds.logical_replication` e impostalo su `1` per attivare la replica logica.

1. Riavvia l'istanza database RDS per PostgreSQL per rendere effettive le modifiche. 

1. Quando l'istanza è disponibile, puoi utilizzare `psql` (o pgAdmin) per connetterti all'istanza database RDS per PostgreSQL. 

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Per verificare che l'estensione pglogical sia inizializzata, esegui il seguente comando.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pglogical
   (1 row)
   ```

1. Verifica l'impostazione che abilita la decodifica logica, come indicato di seguito.

   ```
   SHOW wal_level;
   wal_level
   -----------
    logical
   (1 row)
   ```

1. Crea l'estensione, come indicato di seguito.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. Scegli **Save changes** (Salva modifiche).

1. Aprire la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Scegli istanza database RDS per PostgreSQL dall'elenco di database per selezionarla, quindi scegli **Reboot** (Riavvia) dal menu Actions (Operazioni).

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CLI"></a>

**Per impostare l'estensione pglogical**

Per configurare pglogical utilizzando AWS CLI, richiama l'[modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html)operazione per modificare determinati parametri nel gruppo di parametri personalizzato, come illustrato nella procedura seguente.

1. Utilizzate il AWS CLI comando seguente per aggiungere `pglogical` al parametro. `shared_preload_libraries`

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Usa il AWS CLI comando seguente `rds.logical_replication` `1` per impostare l'attivazione della funzionalità di decodifica logica per l' DB. l’istanza database RDS per PostgreSQL.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Usa il AWS CLI comando seguente per riavviare l' in modo da inizializzare la libreria pglogical.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando l'istanza è disponibile, utilizza `psql` per connetterti all'istanza database RDS per PostgreSQL. 

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Crea l'estensione, come indicato di seguito.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. Riavviare l' utilizzando il comando seguente. AWS CLI 

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Impostazione della replica logica per l'istanza database RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication"></a>

La seguente procedura mostra come avviare la replica logica tra due istanze database RDS per PostgreSQL. I passaggi presuppongono che sia l'origine (publisher) che la destinazione (subscriber) abbiano l'estensione `pglogical` impostata come descritto dettagliatamente in [Impostazione dell'estensione pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

**Nota**  
`node_name` di un nodo subscriber non può iniziare con `rds`.

**Per creare il nodo publisher e definire le tabelle da replicare**

Questi passaggi presuppongono che l'istanza database RDS per PostgreSQL abbia un database contenente una o più tabelle che desideri replicare in un altro nodo. È necessario ricreare la struttura delle tabelle dal publisher nel subscriber, quindi prima, se occorre, recupera la struttura delle tabelle. Puoi farlo utilizzando il metacomando `psql` `\d tablename` e quindi creando la stessa tabella nell'istanza subscriber. Nella procedura seguente viene illustrato come creare una tabella di esempio nel publisher (origine) a scopo dimostrativo.

1. Utilizza `psql` per connetterti all'istanza che include la tabella da usare come origine per i subscriber. 

   ```
   psql --host=source-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

   Se non hai una tabella esistente da replicare, puoi creare una tabella di esempio come indicato di seguito.

   1. Crea una tabella di esempio utilizzando la seguente istruzione SQL.

      ```
      CREATE TABLE docs_lab_table (a int PRIMARY KEY);
      ```

   1. Popola la tabella con i dati generati utilizzando la seguente istruzione SQL.

      ```
      INSERT INTO docs_lab_table VALUES (generate_series(1,5000));
      INSERT 0 5000
      ```

   1. Verifica che i dati siano presenti nella tabella utilizzando la seguente istruzione SQL.

      ```
      SELECT count(*) FROM docs_lab_table;
      ```

1. Identifica l'istanza database RDS per PostgreSQL come nodo publisher, come indicato di seguito.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_provider',
       dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 dbname=labdb');
    create_node
   -------------
      3410995529
   (1 row)
   ```

1. Aggiungi la tabella da replicare al set di replica predefinito. Per ulteriori informazioni sui set di replica, consulta [Replication sets](https://github.com/2ndQuadrant/pglogical/tree/REL2_x_STABLE/docs#replication-sets) (Set di replica) nella documentazione di pglogical. 

   ```
   SELECT pglogical.replication_set_add_table('default', 'docs_lab_table', 'true', NULL, NULL);
    replication_set_add_table
     ---------------------------
     t
     (1 row)
   ```

L'impostazione del nodo publisher è completata. Ora puoi impostare il nodo subscriber per ricevere gli aggiornamenti dal publisher.

**Per impostare il nodo subscriber e creare una sottoscrizione per ricevere gli aggiornamenti**

Questi passaggi presuppongono che sia stata eseguita l'impostazione dell'istanza database RDS per PostgreSQL con l'estensione `pglogical`. Per ulteriori informazioni, consulta [Impostazione dell'estensione pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

1. Utilizza `psql` per connetterti all'istanza per cui vuoi ricevere gli aggiornamenti dal publisher.

   ```
   psql --host=target-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Nell'istanza database RDS per PostgreSQL del subscriber crea la stessa tabella presente nel publisher. In questo esempio, la tabella è `docs_lab_table`. È possibile creare la tabella come indicato di seguito.

   ```
   CREATE TABLE docs_lab_table (a int PRIMARY KEY);
   ```

1. Verifica che questa tabella sia vuota.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     0
   (1 row)
   ```

1. Identifica l'istanza database RDS per PostgreSQL come nodo subscriber, come indicato di seguito.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_target',
       dsn := 'host=target-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=********');
    create_node
   -------------
      2182738256
   (1 row)
   ```

1. Crea la sottoscrizione. 

   ```
   SELECT pglogical.create_subscription(
      subscription_name := 'docs_lab_subscription',
      provider_dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=*******',
      replication_sets := ARRAY['default'],
      synchronize_data := true,
      forward_origins := '{}' );  
    create_subscription
   ---------------------
   1038357190
   (1 row)
   ```

   Una volta completato questo passaggio, i dati della tabella del publisher vengono creati nella tabella del subscriber. È possibile verificare questa operazione utilizzando la seguente query SQL.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     5000
   (1 row)
   ```

Da questo momento in poi, le modifiche apportate alla tabella del publisher vengono replicate nella tabella del subscriber.

# Riconnessione della replica logica dopo un aggiornamento principale
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

Prima di poter eseguire un aggiornamento della versione principale di un'istanza database RDS per PostgreSQL impostata come nodo publisher per la replica logica, è necessario rimuovere tutti gli slot di replica, anche quelli non attivi. Si consiglia di deviare temporaneamente le transazioni del database dal nodo publisher, rimuovere gli slot di replica, aggiornare l'istanza database RDS per PostgreSQL e quindi riconnettere e riavviare la replica.

Gli slot di replica sono ospitati solo nel nodo publisher. Il nodo subscriber RDS per PostgreSQL in uno scenario di replica logica non ha slot da rimuovere, ma non può essere aggiornato a una versione principale finché è designato come nodo subscriber con una sottoscrizione al publisher. Prima di aggiornare il nodo subscriber RDS per PostgreSQL, rimuovi la sottoscrizione e il nodo. Per ulteriori informazioni, consulta [Gestione degli slot di replica logica per PostgreSQL RDS per PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md).  

## Determinazione della replica logica interrotta
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.identifying-the-issue"></a>

È possibile determinare che il processo di replica è stato interrotto eseguendo una query sul nodo publisher o sul nodo subscriber, come indicato di seguito.

**Per controllare il nodo publisher**
+ Utilizza `psql` per connetterti al nodo publisher e quindi esegui la query sulla funzione `pg_replication_slots`. Osserva il valore nella colonna attiva. Normalmente, la query restituisce `t` (true) per indicare che la replica è attiva. Se restituisce `f` (false), indica che la replica nel subscriber è stata interrotta. 

  ```
  SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
                      slot_name              |      plugin      | slot_type | active
  -------------------------------------------+------------------+-----------+--------
   pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical   | f
  (1 row)
  ```

**Per controllare il nodo subscriber**

Nel nodo subscriber è possibile verificare lo stato della replica in tre modi diversi.
+ Esamina i log di PostgreSQL sul nodo subscriber per trovare i messaggi di errore. Il log identifica gli errori nei messaggi che includono il codice di uscita 1, come illustrato di seguito.

  ```
  2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1
  2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  ```
+ Esegui la query sulla funzione `pg_replication_origin`. Connettiti al database sul nodo subscriber utilizzando `psql` ed esegui la query sulla funzione `pg_replication_origin`, come indicato di seguito.

  ```
  SELECT * FROM pg_replication_origin;
   roident | roname
  ---------+--------
  (0 rows)
  ```

  Se il set di risultati è vuoto, la replica è stata interrotta. Normalmente, viene restituito l'output riportato di seguito.

  ```
     roident |                       roname
    ---------+----------------------------------------------------
           1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
    (1 row)
  ```
+ Esegui la query sulla funzione `pglogical.show_subscription_status` come illustrato nell'esempio seguente.

  ```
  SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
       subscription_name | status |              slot_name
  ---====----------------+--------+-------------------------------------
   docs_lab_subscription | down   | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
  (1 row)
  ```

  Questo output mostra che la replica è stata interrotta. Lo stato è `down` e normalmente l'output mostra lo stato `replicating`.

Se il processo di replica logica è stato interrotto, è possibile riconnettere la replica seguendo questi passaggi.

**Per riconnettere la replica logica tra i nodi publisher e subscriber**

Per riconnettere la replica, devi prima disconnettere il subscriber dal nodo publisher e quindi riconnettere la sottoscrizione, come descritto in questi passaggi. 

1. Connettiti al nodo subscriber utilizzando `psql`, come indicato di seguito.

   ```
   psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Disattiva la sottoscrizione utilizzando la funzione `pglogical.alter_subscription_disable`.

   ```
   SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
    alter_subscription_disable
   ----------------------------
    t
   (1 row)
   ```

1. Ottieni l'identificatore del nodo publisher eseguendo la query su `pg_replication_origin`, come indicato di seguito.

   ```
   SELECT * FROM pg_replication_origin;
    roident |               roname
   ---------+-------------------------------------
          1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
   (1 row)
   ```

1. Utilizza la risposta restituita dal passaggio precedente con il comando `pg_replication_origin_create` per assegnare l'identificatore che può essere usato dalla sottoscrizione una volta riconnessa. 

   ```
   SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
     pg_replication_origin_create
   ------------------------------
                               1
   (1 row)
   ```

1. Attiva la sottoscrizione specificando il nome con lo stato `true`, come illustrato nell'esempio seguente.

   ```
   SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
     alter_subscription_enable
   ---------------------------
    t
   (1 row)
   ```

Controlla lo stato del nodo. Lo stato deve essere `replicating` come mostrato nell'esempio.

```
SELECT subscription_name,status,slot_name
  FROM pglogical.show_subscription_status();
             subscription_name |   status    |              slot_name
-------------------------------+-------------+-------------------------------------
 docs_lab_subscription         | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c
(1 row)
```

Verifica lo stato dello slot di replica del subscriber sul nodo publisher. La colonna `active` dello slot deve restituire `t` (true) per indicare che la replica è stata riconnessa.

```
SELECT slot_name,plugin,slot_type,active
  FROM pg_replication_slots;
                    slot_name              |      plugin      | slot_type | active
-------------------------------------------+------------------+-----------+--------
 pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical   | t
(1 row)
```

# Gestione degli slot di replica logica per PostgreSQL RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots"></a>

Prima di poter eseguire un aggiornamento alla versione principale su un'istanza database RDS per PostgreSQL che funge da nodo publisher in uno scenario di replica logica, è necessario rimuovere gli slot di replica nell'istanza. Il processo di verifica preliminare dell'aggiornamento alla versione principale avvisa che l'aggiornamento non può procedere fino a quando gli slot non vengono rimossi.

Per rimuovere gli slot dall'istanza database RDS per PostgreSQL, è necessario prima rimuovere la sottoscrizione e quindi gli slot. 

Per identificare gli slot di replica creati utilizzando l'estensione `pglogical`, accedi a ciascun database e recupera il nome dei nodi. Quando esegui la query sul nodo subscriber, nell'output viene restituito sia il nodo publisher che il nodo subscriber, come mostrato nell'esempio seguente. 

```
SELECT * FROM pglogical.node;
node_id   |     node_name
------------+-------------------
 2182738256 | docs_lab_target
 3410995529 | docs_lab_provider
(2 rows)
```

Puoi ottenere i dettagli sulla sottoscrizione con la seguente query.

```
SELECT sub_name,sub_slot_name,sub_target
  FROM pglogical.subscription;
 sub_name |         sub_slot_name          | sub_target
----------+--------------------------------+------------
  docs_lab_subscription     | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256
(1 row)
```

A questo punto puoi rimuovere la sottoscrizione, come indicato di seguito.

```
SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription');
 drop_subscription
-------------------
                 1
(1 row)
```

Dopo aver rimosso la sottoscrizione, puoi eliminare il nodo.

```
SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber');
 drop_node
-----------
 t
(1 row)
```

Puoi verificare che il nodo sia stato eliminato, come indicato di seguito.

```
SELECT * FROM pglogical.node;
 node_id | node_name
---------+-----------
(0 rows)
```

# Riferimento sui parametri dell'estensione pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.reference"></a>

Nella tabella sono illustrati i parametri associati all'estensione `pglogical`. Parametri come `pglogical.conflict_log_level` e `pglogical.conflict_resolution` vengono utilizzati per gestire i conflitti di aggiornamento. I conflitti possono emergere quando vengono apportate modifiche localmente alle stesse tabelle che hanno una sottoscrizione con il publisher. I conflitti possono verificarsi anche in altri scenari, ad esempio la replica bidirezionale o quando più subscriber eseguono la replica dallo stesso publisher. Per ulteriori informazioni, consulta [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replica bidirezionale di PostgreSQL utilizzando pglogical). 


| Parametro | Description | 
| --- | --- | 
| pglogical.batch\$1inserts | Esegue inserimenti batch, se possibile. Non impostato per impostazione predefinita. Imposta "1" per attivarlo, "0" per disattivarlo. | 
| pglogical.conflict\$1log\$1level | Imposta il livello di log da utilizzare per la registrazione dei conflitti risolti. I valori di stringa supportati sono debug5, debug4, debug3, debug2, debug1, info, notice, warning, error, log, fatal, panic. | 
| pglogical.conflict\$1resolution | Imposta il metodo da utilizzare per risolvere i conflitti quando sono risolvibili. I valori di stringa supportati sono error, apply\$1remote, keep\$1local, last\$1update\$1wins, first\$1update\$1wins. | 
| pglogical.extra\$1connection\$1options | Specifica le opzioni di connessione da aggiungere a tutte le connessioni dei nodi peer. | 
| pglogical.synchronous\$1commit | Valore di commit sincrono specifico pglogical | 
| pglogical.use\$1spi | Utilizza la SPI (Server Programming Interface) invece dell'API di basso livello per applicare le modifiche. Imposta "1" per attivarlo, "0" per disattivarlo. Per ulteriori informazioni sulla SPI, consulta [Server Programming Interface](https://www.postgresql.org/docs/current/spi.html) nella documentazione PostgreSQL.  | 

# Utilizzo di pgactive per supportare la replica active-active
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive"></a>

L'estensione `pgactive` utilizza la replica active-active per supportare e coordinare le operazioni di scrittura su più database RDS per PostgreSQL. Amazon RDS per PostgreSQL supporta l’estensione `pgactive` sulle seguenti versioni: 
+ RDS per PostgreSQL 17.0 e tutte le versioni successive
+ RDS per PostgreSQL 16.1 e versioni successive 16
+ RDS per PostgreSQL 15.4-R2 e versioni successive 15
+ RDS per PostgreSQL 14.10 e versioni successive (14)
+ RDS per PostgreSQL 13.13 e versioni successive (13)
+ RDS per PostgreSQL 12.17 e versioni successive (12)
+ RDS per PostgreSQL 11.22

**Nota**  
Quando sono presenti operazioni di scrittura su più di un database in una configurazione di replica, sono possibili conflitti. Per ulteriori informazioni, consulta [Gestione dei conflitti nella replica active-active](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)

**Topics**
+ [

## Limitazioni per l'estensione pgactive
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations)
+ [

# Inizializzazione della funzionalità di estensione pgactive
](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)
+ [

# Configurazione della replica active-active per istanze database RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication.md)
+ [

# Misurazione del ritardo di replica tra i membri pgactive
](Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag.md)
+ [

# Configurazione delle impostazioni dei parametri per l’estensione pgactive
](Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.md)
+ [

# Comprensione dei conflitti in modalità attivo-attivo
](Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication.md)
+ [

# Informazioni sullo schema pgactive
](Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.md)
+ [

# Informazioni di riferimento sulle funzioni pgactive
](pgactive-functions-reference.md)
+ [

# Gestione dei conflitti nella replica active-active
](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)
+ [

# Gestione delle sequenze nella replica active-active
](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)

## Limitazioni per l'estensione pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations"></a>
+ Tutte le tabelle richiedono una chiave primaria, altrimenti le opzioni di aggiornamento ed eliminazione non sono consentite. I valori nella colonna Chiave primaria non devono essere aggiornati.
+ Le sequenze possono presentare delle lacune e talvolta potrebbero non seguire un ordine. Le sequenze non vengono replicate. Per ulteriori informazioni, consulta [Gestione delle sequenze nella replica active-active](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md).
+ DDL e oggetti di grandi dimensioni non vengono replicati.
+ Gli indici univoci secondari possono causare divergenze tra i dati.
+ Le regole di confronto devono essere identiche su tutti i nodi del gruppo.
+ Il bilanciamento del carico tra i nodi è un anti-pattern.
+ Le transazioni di grandi dimensioni possono causare ritardi nella replica.

# Inizializzazione della funzionalità di estensione pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup"></a>

Per inizializzare la funzionalità dell'estensione `pgactive` sull'istanza database RDS per PostgreSQL, imposta il valore del parametro `rds.enable_pgactive` su `1` e quindi crea l'estensione nel database. In questo modo si attivano automaticamente i parametri `rds.logical_replication` e `track_commit_timestamp` e il valore `wal_level` viene impostato su `logical`. 

Per eseguire queste attività sono richieste le autorizzazioni del ruolo `rds_superuser`.

È possibile utilizzare Console di gestione AWS o the AWS CLI per creare l'RDS richiesto per le istanze DB PostgreSQL. I passaggi seguenti si basano sull'ipotesi che l'istanza database Amazon RDS per PostgreSQL sia associata a un gruppo di parametri di database personalizzato. Per ulteriori informazioni sulla creazione di un gruppo di parametri personalizzato, consulta [Gruppi di parametri per Amazon RDS](USER_WorkingWithParamGroups.md).

## Console
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CON"></a>

**Inizializzazione della funzionalità di estensione pgactive**

1. Accedi a Console di gestione AWS e apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Nel riquadro di navigazione, scegli l'istanza database RDS per PostgreSQL.

1. Apri la scheda **Configurazione** per l'istanza database RDS per PostgreSQL. Nei dettagli dell'istanza, trova il link **Gruppo di parametri dell'istanza database**. 

1. Scegli il link per aprire i parametri personalizzati associati all'istanza database RDS per PostgreSQL. 

1. Trova il parametro `rds.enable_pgactive` e impostalo su `1` per inizializzare la funzionalità `pgactive`.

1. Scegli **Save changes** (Salva modifiche).

1. Nel pannello di navigazione della console di Amazon RDS, scegli **Database**.

1. Seleziona l'istanza database RDS per PostgreSQL, quindi scegli **Riavvia** dal menu **Operazioni**.

1. Conferma il riavvio dell'istanza database per applicare le modifiche. 

1. Quando l'istanza database è disponibile, puoi usare `psql` o qualsiasi altro client PostgreSQL per connetterti all'istanza database RDS per PostgreSQL. 

   L'esempio seguente presuppone che l'istanza DB RDS per PostgreSQL abbia un database predefinito denominato. *postgres*

   ```
   psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. Per verificare che l'estensione pgactive sia inizializzata, esegui il seguente comando.

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   Se `pgactive` è presente in `shared_preload_libraries`, il comando precedente restituirà quanto segue:

   ```
   ?column? 
   ----------
    t
   ```

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CLI"></a>

**Inizializzazione della funzionalità di estensione pgactive**

Per inizializzare l'`pgactive`utilizzo di AWS CLI, richiamate l'[modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html)operazione per modificare determinati parametri nel gruppo di parametri personalizzato, come illustrato nella procedura seguente.

1. Utilizzare il AWS CLI comando seguente `rds.enable_pgactive` per `1` impostare l'inizializzazione della `pgactive` funzionalità per l'istanza DB RDS for PostgreSQL.

   ```
   postgres=>aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilizzare il AWS CLI comando seguente per riavviare l'istanza DB RDS for PostgreSQL in modo che la libreria venga inizializzata. `pgactive`

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando l'istanza è disponibile, utilizza `psql` per connetterti all'istanza database RDS per PostgreSQL. 

   ```
   psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master user --password=PASSWORD --dbname=postgres
   ```

1. Per verificare che l'estensione pgactive sia inizializzata, esegui il seguente comando.

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   Se `pgactive` è presente in `shared_preload_libraries`, il comando precedente restituirà quanto segue:

   ```
   ?column? 
   ----------
    t
   ```

# Configurazione della replica active-active per istanze database RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

La seguente procedura mostra come avviare la replica attiva-attiva istanze database RDS per PostgreSQL in cui è disponibile `pgactive`. Per eseguire l'esempio di elevata disponibilità multiregionale, devi distribuire istanze Amazon RDS per PostgreSQL in due regioni diverse e configurare il peering VPC. Per ulteriori informazioni, consulta [Peering VPC](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html).

**Nota**  
L'invio di traffico tra più regioni può comportare costi aggiuntivi.

Questi passaggi presuppongono che l’istanza database RDS per PostgreSQL sia stata abilitata con l’estensione `pgactive`. Per ulteriori informazioni, consulta [Inizializzazione della funzionalità di estensione pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

**Configurazione della prima istanza database RDS per PostgreSQL con l'estensione `pgactive`**

L'esempio seguente illustra come viene creato il gruppo `pgactive`, insieme ad altri passaggi necessari per creare l'estensione `pgactive`sull'istanza database RDS per PostgreSQL.

1. Usa `psql` o un altro strumento client per connetterti alla tua prima istanza database RDS per PostgreSQL.

   ```
   psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. Crea un database sull'istanza RDS per PostgreSQL utilizzando il seguente comando:

   ```
   postgres=> CREATE DATABASE app;
   ```

1. Passa alla connessione al nuovo database utilizzando il seguente comando:

   ```
   \c app
   ```

1. Crea e popola una tabella di esempio utilizzando le seguenti istruzioni SQL:

   1. Crea una tabella di esempio utilizzando la seguente istruzione SQL.

      ```
      app=> CREATE SCHEMA inventory;
      CREATE TABLE inventory.products (
      id int PRIMARY KEY, product_name text NOT NULL,
      created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);
      ```

   1. Popola la tabella con alcuni dati di esempio utilizzando la seguente istruzione SQL.

      ```
      app=> INSERT INTO inventory.products (id, product_name)
      VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
      ```

   1. Verifica che i dati siano presenti nella tabella utilizzando la seguente istruzione SQL.

      ```
       app=>SELECT count(*) FROM inventory.products;
      
       count
      -------
       3
      ```

1. Crea l'estensione `pgactive` database esistente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Per creare e inizializzare il gruppo pgactive in modo sicuro, utilizza i seguenti comandi:

   ```
   app=>
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
         -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   Ora puoi inizializzare il gruppo di replica e aggiungere questa prima istanza:

   ```
   SELECT pgactive.pgactive_create_group(
       node_name := 'endpoint1-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   
   );
   ```

   Utilizza i seguenti comandi come metodo alternativo, ma meno sicuro, per creare e inizializzare il gruppo pgactive:

   ```
   app=> SELECT pgactive.pgactive_create_group(
       node_name := 'node1-app',
       node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node1-app è il nome che assegni per identificare in modo univoco un nodo nel gruppo `pgactive`.
**Nota**  
Per eseguire correttamente questo passaggio su un'istanza database accessibile pubblicamente, è necessario attivare il parametro `rds.custom_dns_resolution` impostandolo su `1`.

1. Per verificare se l'istanza database è pronta, usa il seguente comando:

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready();
   ```

   Se il comando viene eseguito correttamente, verrà visualizzato il seguente output:

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

**Configurazione della seconda istanza RDS per PostgreSQL e collegamento al gruppo `pgactive`**

L'esempio seguente illustra come puoi collegare un'istanza database RDS per PostgreSQL al gruppo `pgactive`, insieme ad altri passaggi necessari per creare l'estensione `pgactive` sull'istanza database.

Questi passaggi presuppongono che sia stata eseguita la configurazione di un ulteriore istanza database RDS per PostgreSQL con l'estensione `pgactive`. Per ulteriori informazioni, consulta [Inizializzazione della funzionalità di estensione pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

1. Utilizza `psql` per connetterti all'istanza per cui vuoi ricevere gli aggiornamenti dal publisher.

   ```
   psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. Crea un database sulla seconda istanza database RDS per PostgreSQL utilizzando il seguente comando:

   ```
   postgres=> CREATE DATABASE app;
   ```

1. Passa alla connessione al nuovo database utilizzando il seguente comando:

   ```
   \c app
   ```

1. Crea l'estensione `pgactive` database esistente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Unisci la seconda istanza database RDS per PostgreSQL al gruppo `pgactive` in modo più sicuro utilizzando i seguenti comandi:

   ```
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
   
   -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   ```
   SELECT pgactive.pgactive_join_group(
       node_name := 'endpoint2-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint2',
       join_using_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   );
   ```

   Utilizza i comandi indicati di seguito come metodo alternativo, ma meno sicuro, per unire la seconda istanza database RDS per PostgreSQL al gruppo `pgactive`

   ```
   app=> SELECT pgactive.pgactive_join_group(
   node_name := 'node2-app',
   node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD',
   join_using_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node2-app è il nome che assegni per identificare in modo univoco un nodo nel gruppo `pgactive`.

1. Per verificare se l'istanza database è pronta, usa il seguente comando:

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready(); 
   ```

   Se il comando viene eseguito correttamente, verrà visualizzato il seguente output:

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   Se il primo database RDS per PostgreSQL è relativamente grande, puoi vedere l'emissione di `pgactive.pgactive_wait_for_node_ready()` del report sullo stato di avanzamento dell'operazione di ripristino. L'esito si presenta in maniera analoga all'immagine riportata di seguito.

   ```
   NOTICE:  restoring database 'app', 6% of 7483 MB complete
   NOTICE:  restoring database 'app', 42% of 7483 MB complete
   NOTICE:  restoring database 'app', 77% of 7483 MB complete
   NOTICE:  restoring database 'app', 98% of 7483 MB complete
   NOTICE:  successfully restored database 'app' from node node1-app in 00:04:12.274956
    pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   Da questo momento in poi, `pgactive` sincronizza i dati tra le due istanze database.

1. Puoi utilizzare il comando seguente per verificare se il database della seconda istanza database contiene i dati:

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   Se i dati vengono sincronizzati correttamente, verrà visualizzato il seguente output:

   ```
    count
   -------
    3
   ```

1. Esegui il seguente comando per inserire nuovi valori:

   ```
   app=> INSERT INTO inventory.products (id, product_name) VALUES (4, 'lotion');
   ```

1. Connettiti al database della prima istanza database ed esegui la seguente query:

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   Se la replica active-active è inizializzata, l'output è simile al seguente:

   ```
   count
   -------
    4
   ```

**Scollegamento e rimozione di un'istanza database dal gruppo `pgactive`**

Puoi scollegare e rimuovere un'istanza database dal gruppo `pgactive` utilizzando la procedura seguente:

1. Puoi scollegare la seconda istanza database dalla prima istanza database utilizzando il seguente comando:

   ```
   app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
   ```

1. Rimuovi l'estensione `pgactive` dalla seconda istanza database utilizzando il seguente comando:

   ```
   app=> SELECT * FROM pgactive.pgactive_remove();
   ```

   Per rimuovere forzatamente l'estensione:

   ```
   app=> SELECT * FROM pgactive.pgactive_remove(true);
   ```

1. Elimina l'estensione usando il seguente comando:

   ```
   app=> DROP EXTENSION pgactive;
   ```

# Misurazione del ritardo di replica tra i membri pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag"></a>

È possibile utilizzare la seguente query per visualizzare il ritardo di replica tra i membri `pgactive`. Esegui questa query su ogni nodo `pgactive` per ottenere il quadro completo.

```
    
app=> SELECT * FROM pgactive.pgactive_get_replication_lag_info();
│-[ RECORD 1 ]--------+---------------------------------------------
│node_name            | node2-app
│node_sysid           | 7481018224801653637
│application_name     | pgactive:7481018224801653637:send
│slot_name            | pgactive_16385_7481018224801653637_0_16385__
│active               | t
│active_pid           | 783486
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/2108150
│confirmed_flush_lsn  | 0/2154690
│sent_lsn             | 0/2154690
│write_lsn            | 0/2154690
│flush_lsn            | 0/2154690
│replay_lsn           | 0/2154690
│-[ RECORD 2 ]--------+---------------------------------------------
│node_name            | node1-app
│node_sysid           | 7481018033434600853
│application_name     | pgactive:7481018033434600853:send
│slot_name            | pgactive_16385_7481018033434600853_0_16385__
│active               | t
│active_pid           | 783488
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/20F5AD0
│confirmed_flush_lsn  | 0/214EF68
│sent_lsn             | 0/214EF68
│write_lsn            | 0/214EF68
│flush_lsn            | 0/214EF68
│replay_lsn           | 0/214EF68
```

Monitora almeno la seguente diagnostica:

attiva  
Imposta avvisi quando active è false, il che indica che lo slot non è al momento in uso (l’istanza subscriber si è disconnessa dal publisher).

pending\$1wal\$1decoding  
Nella replica logica di PostgreSQL, i file WAL vengono archiviati in formato binario. Il publisher deve decodificare queste modifiche WAL e convertirle in modifiche logiche (come operazioni di inserimento, aggiornamento o eliminazione).  
La metrica pending\$1wal\$1decoding mostra il numero di file WAL in attesa di essere decodificati sul lato del publisher.  
Questo numero può aumentare a causa di questi fattori:  
+ Quando il subscriber non è connesso, lo stato active sarà false e pending\$1wal\$1decoding aumenterà
+ Lo slot è attivo, ma il publisher non riesce a tenere il passo con il volume delle modifiche WAL

pending\$1wal\$1to\$1apply  
La metrica pending\$1wal\$1apply indica il numero di file WAL in attesa di essere applicati sul lato del subscriber.  
Diversi fattori possono impedire al subscriber di applicare le modifiche e potenzialmente causare uno scenario di disco pieno:  
+ Differenze nello schema: ad esempio, quando si apportano modifiche nel flusso WAL per una tabella denominata sample, ma tale tabella non esiste sul lato del subscriber
+ I valori nelle colonne chiave primaria erano stati aggiornati
+ Gli indici univoci secondari possono causare divergenze tra i dati.

# Configurazione delle impostazioni dei parametri per l’estensione pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters"></a>

È possibile utilizzare la seguente query per visualizzare tutti i parametri associati all’estensione `pgactive`.

```
app=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
```

Puoi configurare l’estensione `pgactive` utilizzando vari parametri. Questi parametri possono essere impostati tramite l'interfaccia CLI Console di gestione AWS o l' AWS interfaccia CLI.

## Principali parametri dell’estensione pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.mainparams"></a>

La tabella seguente fornisce un riferimento per i parametri principali dell’estensione `pgactive`:


| Parametro | Unità | Predefinita | Description | 
| --- | --- | --- | --- | 
| pgactive.conflict\$1logging\$1include\$1tuples | `boolean` | –  | Registra le informazioni complete sulla tupla per l’estensione `pgactive`.  Per rendere effettive le modifiche apportate, è necessario riavviare il server.  | 
| pgactive.log\$1conflicts\$1to\$1table | `boolean` | –  | Determina se l’estensione `pgactive` registra i conflitti rilevati nella tabella `pgactive.pgactive_conflict_history`. Per ulteriori informazioni, consulta la sezione relativa alla registrazione di log dei conflitti per maggiori dettagli.  Per rendere effettive le modifiche apportate, è necessario riavviare il server.  | 
| pgactive.log\$1conflicts\$1to\$1logfile | `boolean` | –  | Determina se l’estensione `pgactive` registra i conflitti rilevati nel file di log PostgreSQL. Per ulteriori informazioni, consulta la sezione relativa alla registrazione di log dei conflitti per maggiori dettagli.  Per rendere effettive le modifiche apportate, è necessario riavviare il server.  | 
| pgactive.synchronous\$1commit | `boolean` | off | Determina il comportamento di commit per i worker apply pgactive. Se sono disabilitati (off), i worker apply eseguono commit asincroni. Ciò migliora il throughput di PostgreSQL durante le operazioni apply, ma ritarda le conferme di riproduzione all’upstream. Impostarli su `off` è sempre sicuro ed eviterà che le transazioni vengano perse o ignorate. Questa impostazione influisce solo sulla tempistica del flush su disco sul nodo downstream e sull’invio delle conferme upstream. Il sistema ritarda l’invio delle conferme di replay flush finché non viene eseguito il flush dei commit su disco tramite operazioni non correlate come checkpoint o operazioni periodiche. Tuttavia, se nel nodo upstream il nodo downstream è elencato in `synchronous_standby_names`, impostando il parametro su `off` i commit sincroni del nodo upstream impiegheranno più tempo a segnalare l’esito positivo al client. In tal caso, imposta il parametro su `on`.  Anche quando questo parametro è impostato su `on` con nodi elencati in `synchronous_standby_names`, è comunque possibile che si verifichino conflitti di replica nelle configurazioni attive-attive. Questo accade perché il sistema non dispone del blocco tra i nodi e della gestione globale delle snapshot, il che consente alle transazioni simultanee su nodi diversi di modificare la stessa tupla. Inoltre, le transazioni iniziano la replica solo dopo il commit sul nodo upstream. L’abilitazione del commit sincrono non trasforma l’estensione pgactive in un sistema sempre coerente.  | 
| pgactive.temp\$1dump\$1directory | `string` | – | Definisce il percorso di archiviazione temporaneo richiesto per le operazioni di clonazione del database durante la configurazione iniziale. Questa directory deve essere scrivibile dall’utente postgres e deve disporre di spazio di archiviazione sufficiente per contenere un dump completo del database. Il sistema utilizza questa posizione solo durante la configurazione iniziale del database con operazioni di copia logica. Questo parametro non viene utilizzato da `pgactive_init_copy command`. | 
| pgactive.max\$1ddl\$1lock\$1delay | `milliseconds` | `-1` | Specifica il tempo di attesa massimo per il blocco DDL prima dell’interruzione forzata delle transazioni di scrittura simultanee. Il valore predefinito è `-1`, che adotta il valore impostato in `max_standby_streaming_delay`. Questo parametro accetta unità temporali. Ad esempio, puoi impostarlo su 10 secondi per 10 secondi. Durante questo periodo di attesa, il sistema tenta di acquisire blocchi DDL in attesa del commit o del rollback delle transazioni di scrittura in corso. Per ulteriori informazioni, consulta la sezione sul blocco DDL. | 
| pgactive.ddl\$1lock\$1timeout | `milliseconds` | `-1` | Specifica il lasso di tempo che un tentativo di blocco DDL attende per ottenere il blocco. Il valore predefinito è `-1`, che utilizza il valore specificato in lock\$1timeout. Puoi impostare questo parametro utilizzando unità di tempo come 10s per 10 secondi. Questo timer controlla solo il periodo di attesa per ottenere un blocco DDL. Una volta che il sistema ottiene il blocco e inizia l’operazione DDL, il timer si arresta. Questo parametro non limita la durata totale di mantenimento di un blocco DDL né il tempo complessivo dell’operazione DDL. Per controllare la durata totale dell’operazione, usa `statement_timeout` invece. Per ulteriori informazioni, consulta la sezione sul blocco DDL. | 
| pgactive.debug\$1trace\$1ddl\$1locks\$1level | `boolean` | –  | Sostituisce il livello di log di debug predefinito per le operazioni di blocco DDL nell’estensione `pgactive`. Se configurata, questa impostazione fa sì che i messaggi relativi al blocco DDL vengano emessi al livello di debug del LOG anziché al livello predefinito. Utilizza questo parametro per monitorare l’attività di blocco DDL senza abilitare i livelli di log `DEBUG1` `DEBUG2` dettagliati sull’intero server.  Livelli di log disponibili, in ordine crescente di dettaglio: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Per ulteriori informazioni sulle opzioni di monitoraggio, consulta la sezione sul monitoraggio dei blocchi DDL globali.  Le modifiche a questa impostazione vengono eseguite quando ricarichi la configurazione. Non è necessario riavviare il server.   | 

## Parametri aggiuntivi dell’estensione pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.addparams"></a>

La tabella seguente presenta le opzioni di configurazione interne e utilizzate meno di frequente disponibili per l’estensione `pgactive`.


| Parametro | Unità | Predefinita | Description | 
| --- | --- | --- | --- | 
| pgactive.debug\$1apply\$1delay | `integer` | – |  Imposta un ritardo di applicazione (in millisecondi) per le connessioni configurate che non hanno un ritardo di applicazione esplicito nella voce `pgactive.pgactive_connections`. Questo ritardo viene impostato durante la creazione del nodo o al momento del join e pgactive non riprodurrà una transazione sui nodi peer finché non sarà trascorso almeno il numero di millisecondi specificato dal momento in cui è stato eseguito il commit. Utilizzato principalmente per simulare reti ad alta latenza in ambienti di test per facilitare la creazione di conflitti. Ad esempio, con un ritardo di 500 ms sui nodi A e B, hai almeno 500 ms per eseguire un inserimento in conflitto sul nodo B dopo aver inserito un valore sul nodo A.  Per rendere effettivi i worker apply, è necessario ricaricare o riavviare il server.  | 
| pgactive.connectability\$1check\$1duration | `integer` | –  | Specifica la durata (in secondi) del tempo che un worker del database attende per stabilire connessioni durante i tentativi falliti. Il worker effettua un tentativo di connessione al secondo finché non riesce o non raggiunge questo valore di timeout. Questa impostazione è utile quando il motore del database si avvia prima che il worker sia pronto a stabilire delle connessioni. | 
| pgactive.skip\$1ddl\$1replication | `boolean` | `on` | Controlla il modo in cui le modifiche DDL vengono replicate o gestite in Amazon RDS con il parametro `pgactive` abilitato. Se impostato su `on`, il nodo elabora le modifiche DDL come un nodo non-pgactive. Quando si lavora con questo parametro, vengono applicati i seguenti requisiti: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Puoi modificare questo parametro in due modi con i privilegi di super utente: globalmente e localmente (a livello di sessione).  Modificare questo parametro in modo errato può comportare l’interruzione delle configurazioni di replica.  | 
| pgactive.do\$1not\$1replicate | `boolean` | – | Questo parametro è solo per l’uso interno. Quando imposti questo parametro in una transazione, le modifiche non vengono replicate su altri nodi del cluster di database.   Modificare questo parametro in modo errato può comportare l’interruzione delle configurazioni di replica.  | 
| pgactive.discard\$1mismatched\$1row\$1attributes | `boolean` | –  | Questo parametro è destinato esclusivamente all’uso da parte di specialisti. Si consiglia di utilizzare questo parametro solo per la risoluzione di problemi di replica specifici. Utilizza questo parametro quando: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Questa impostazione sovrascrive il messaggio di errore seguente e consente la divergenza dei dati per fare in modo che la replica continui: `cannot right-pad mismatched attributes; attno %u is missing in local table and remote row has non-null, non-dropped value for this attribute`  Modificare questo parametro in modo errato può comportare l’interruzione delle configurazioni di replica.   | 
| pgactive.debug\$1trace\$1replay | `boolean` | – | Se impostato su `on`, emette un messaggio di log per ogni azione remota che i worker apply downstream elaborano. I log includono: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) I log registrano anche i comandi DDL in coda e le eliminazioni di tabelle.para> Per impostazione predefinita, i log non includono il contenuto dei campi riga. Per includere i valori delle righe nei log, è necessario eseguire di nuovo la compilazione con i seguenti flag abilitati: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html)  L’attivazione di questa impostazione di log può influire sulle prestazioni. Si consiglia di abilitarla solo se necessario per la risoluzione dei problemi. Le modifiche a questa impostazione vengono eseguite quando ricarichi la configurazione. Non è necessario riavviare il server.   | 
| pgactive.extra\$1apply\$1connection\$1options |  | – | Puoi configurare i parametri di connessione per tutte le connessioni tra nodi peer con nodi pgactive. Questi parametri controllano impostazioni quali keepalives e modalità SSL. Per impostazione predefinita, pgactive utilizza i seguenti parametri di connessione: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Per sovrascrivere i parametri predefiniti, utilizza il seguente comando simile: pgactive.extra\$1apply\$1connection\$1options = 'keepalives=0' Le stringhe di connessione dei singoli nodi hanno la precedenza su entrambe queste impostazioni e sulle opzioni di connessione integrate di pgactive. Per ulteriori informazioni sui formati delle stringhe di connessione, consulta la sezione sulle [stringhe di connessione libpq](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING). Consigliamo di mantenere abilitate le impostazioni keepalive predefinite. Disabilita keepalive solo se riscontri problemi con il completamento di transazioni di grandi dimensioni su reti inaffidabili.   Consigliamo di mantenere abilitate le impostazioni keepalive predefinite. Disabilita keepalive solo se riscontri problemi con il completamento di transazioni di grandi dimensioni su reti inaffidabili. Le modifiche a questa impostazione vengono eseguite quando ricarichi la configurazione. Non è necessario riavviare il server.  | 
| pgactive.init\$1node\$1parallel\$1jobs (int) |  | – | Specifica il numero di lavori paralleli che `pg_dump` e `pg_restore` possono utilizzare durante l’unione del nodo logico con la funzione `pgactive.pgactive_join_group`. Le modifiche a questa impostazione vengono eseguite quando ricarichi la configurazione. Non è necessario riavviare il server. | 
| pgactive.max\$1nodes | `int` | 4 |  Specifica il numero massimo di nodi permessi in un gruppo di estensioni pgactive. Il valore predefinito è 4 nodi. È necessario considerare quanto segue quando si imposta il valore di questo parametro: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Puoi impostare questo parametro in due modi: nel file di configurazione, utilizzando il comando `ALTER SYSTEM SET` Il valore predefinito per questo parametro è `4`, il che significa che possono essere consentiti al massimo 4 nodi nel gruppo di estensioni `pgactive` in qualsiasi momento.  La modifica ha effetto dopo il riavvio del server.  | 
| pgactive.permit\$1node\$1identifier\$1getter\$1function\$1creation | `boolean` | – | Questo parametro è destinato esclusivamente all’uso interno. Se abilitata, l’estensione `pgactive` consente la creazione della funzione getter dell’identificatore del nodo pgactive. | 

# Comprensione dei conflitti in modalità attivo-attivo
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication"></a>

Quando utilizzi pgactive in modalità attivo-attivo, la scrittura da più nodi sulle stesse tabelle può creare conflitti di dati. Anche se alcuni sistemi di clustering utilizzano blocchi distribuiti per impedire l’accesso simultaneo, pgactive adotta un approccio ottimistico più adatto per applicazioni distribuite geograficamente.

Alcuni sistemi di clustering di database impediscono l’accesso simultaneo ai dati utilizzando blocchi distribuiti. Sebbene sia efficace quando i server sono nelle immediate vicinanze, questo approccio non supporta applicazioni distribuite geograficamente, perché per offrire buone prestazioni richiede una latenza estremamente bassa. Anziché ricorrere a blocchi distribuiti (approccio pessimistico), l’estensione pgactive utilizza un approccio ottimistico. Questo significa che:
+ Contribuisce a evitare i conflitti quando possibile.
+ Consente il verificarsi di determinati tipi di conflitti.
+ Fornisce la risoluzione dei conflitti quando questi si verificano.

Questo approccio offre una maggiore flessibilità durante la creazione di applicazioni distribuite.

## Come avvengono i conflitti
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.howconflicts"></a>

I conflitti tra nodi derivano da sequenze di eventi che non potrebbero verificarsi se tutte le transazioni coinvolte avvenissero contemporaneamente sullo stesso nodo. Poiché i nodi scambiano le modifiche solo dopo il completamento delle transazioni, ogni transazione è valida individualmente sul nodo su cui è stata effettuata, ma non lo sarebbe se eseguita su un altro nodo che nel frattempo ha svolto altre operazioni. Poiché, essenzialmente, pgactive apply riproduce la transazione sugli altri nodi, in caso di conflitto tra una transazione applicata e una transazione che è stata effettuata sul nodo ricevente, l’operazione di riproduzione può fallire.

 Il motivo per cui la maggior parte dei conflitti non può verificarsi quando tutte le transazioni vengono eseguite su un singolo nodo è che PostgreSQL dispone di meccanismi di comunicazione tra transazioni che ne consentono la prevenzione, tra cui:
+ Indici UNIQUE
+ SEQUENCEs
+ Blocco di righe e relazioni
+ Tracciamento delle dipendenze in modalità SERIALIZABLE

Tutti questi meccanismi consentono la comunicazione tra le transazioni per prevenire problemi di concorrenza indesiderati

pgactive raggiunge una bassa latenza e gestisce correttamente le partizioni di rete, perché non utilizza un gestore di transazioni distribuito o un gestore di blocchi. Questo significa, tuttavia, che le transazioni su nodi diversi vengono eseguite in completo isolamento l’una dall’altra. Sebbene in genere l’isolamento migliori la coerenza del database, in questo caso è necessario ridurlo per prevenire i conflitti.

## Tipi di conflitti
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes"></a>

I conflitti che possono verificarsi includono:

**Topics**
+ [

### Conflitti con vincoli PRIMARY KEY o UNIQUE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1)
+ [

### Conflitti INSERT/INSERT
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2)
+ [

### INSERTs che violano più vincoli UNIQUE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3)
+ [

### Conflitti UPDATE/UPDATE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4)
+ [

### Conflitti UPDATE sulla PRIMARY KEY
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)
+ [

### UPDATEs che violano più vincoli UNIQUE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6)
+ [

### Conflitti UPDATE/DELETE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)
+ [

### Conflitti INSERT/UPDATE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8)
+ [

### Conflitti DELETE/DELETE
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9)
+ [

### Conflitti con vincoli di chiave esterna
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10)
+ [

### Conflitti con vincoli di esclusione
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11)
+ [

### Conflitti di dati globali
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12)
+ [

### Conflitti di blocco e interruzioni per deadlock
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13)
+ [

### Conflitti divergenti
](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)

### Conflitti con vincoli PRIMARY KEY o UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1"></a>

I conflitti di riga si verificano quando più operazioni tentano di modificare la stessa chiave di riga in modi che non sarebbero consentiti su un singolo nodo. Questi conflitti rappresentano il tipo di conflitti sui dati più comune.

pgactive risolve i conflitti rilevati tramite la last-update-wins gestione o il tuo gestore di conflitti personalizzato.

I conflitti di riga includono:
+ INSERT/INSERT
+ INSERT/UPDATE
+ UPDATE/DELETE
+ INSERT/DELETE
+ DELETE/DELETE
+ INSERT/DELETE

### Conflitti INSERT/INSERT
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2"></a>

Questo conflitto più comune si verifica quando INSERTs su due nodi diversi si crea una tupla con gli stessi valori PRIMARY KEY (o valori di vincolo UNIQUE identici quando non esiste una CHIAVE PRIMARIA).

pgactivelink risolve i conflitti INSERT utilizzando il timestamp dell’host di origine per mantenere la tupla più recente. Puoi sovrascrivere questo comportamento predefinito con il tuo gestore di conflitti personalizzato. Sebbene questo processo non richieda alcuna azione speciale da parte dell’amministratore, tieni presente che pgactivelink scarta una delle operazioni INSERT su tutti i nodi. Non si verifica alcuna unione automatica dei dati, a meno che il gestore personalizzato non la implementi.

pgactivelink può risolvere solo i conflitti che coinvolgono la violazione di un solo vincolo. Se un INSERT viola più vincoli UNIQUE, è necessario implementare ulteriori strategie di risoluzione dei conflitti.

### INSERTs che violano più vincoli UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3"></a>

Un INSERT/INSERT conflitto può violare più vincoli UNIQUE, inclusa la CHIAVE PRIMARIA. pgactivelink può gestire solo i conflitti che coinvolgono un singolo vincolo UNIQUE. Quando i conflitti violano più vincoli UNIQUE, il worker di applicazione fallisce e restituisce il seguente errore:

`multiple unique constraints violated by remotely INSERTed tuple.`

Nelle versioni precedenti, questa situazione generava invece un errore di conflitto di unicità divergente. 

Per risolvere questi conflitti, è necessario intraprendere un’azione manuale. Esegui operazioni DELETE per le tuple locali in conflitto o operazioni UPDATE per rimuovere i conflitti con la nuova tupla remota. Tieni presente che potresti dover risolvere conflitti tra più tuple. Attualmente, pgactivelink non fornisce alcuna funzionalità integrata per ignorare, scartare o unire le tuple che violano più vincoli unici.

**Nota**  
Per ulteriori informazioni, vedi che violano più vincoli UNIQUE. UPDATEs 

### Conflitti UPDATE/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4"></a>

Questo conflitto si verifica quando due nodi modificano contemporaneamente la stessa tupla senza cambiarne la CHIAVE PRIMARIA. pgactivelink risolve questi conflitti utilizzando la logica o il gestore dei conflitti personalizzato, se definito. last-update-wins Una PRIMARY KEY è essenziale per la corrispondenza delle tuple e la risoluzione dei conflitti. Per quanto riguarda le tabelle senza PRIMARY KEY, pgactivelink rifiuta le operazioni UPDATE restituendo il seguente errore:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

### Conflitti UPDATE sulla PRIMARY KEY
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5"></a>

pgactive presenta delle limitazioni nella gestione degli aggiornamenti della PRIMARY KEY. Sebbene sia possibile eseguire l'operazione UPDATE su una CHIAVE PRIMARIA, pgactive non può risolvere automaticamente i conflitti utilizzando la logica per queste operazioni. last-update-wins È necessario assicurarsi che gli aggiornamenti della PRIMARY KEY non siano in conflitto con i valori esistenti. Se si verificano conflitti durante gli aggiornamenti della PRIMARY KEY, questi diventano conflitti divergenti, che richiedono l’intervento manuale dell’utente. Per ulteriori informazioni sulla gestione di queste situazioni, consulta [Conflitti divergenti](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### UPDATEs che violano più vincoli UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6"></a>

pgactivelink non può applicare la risoluzione dei last-update-wins conflitti quando un UPDATE in entrata viola più vincoli UNIQUE o valori PRIMARY KEY. Questo funzionamento è simile alle operazioni INSERT con violazioni di più vincoli. Tali situazioni creano conflitti divergenti che richiedono l’intervento manuale dell’utente. Per ulteriori informazioni, consulta [Conflitti divergenti](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### Conflitti UPDATE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7"></a>

Questi conflitti si verificano quando un nodo è una riga e un altro nodo contemporaneamente UPDATEs . DELETEs In questo caso si verifica un UPDATE/DELETE conflitto durante la riproduzione. La soluzione consiste nell’eliminare qualsiasi operazione UPDATE successiva a un’operazione DELETE, a meno che il gestore dei conflitti personalizzato non specifichi diversamente.

pgactivelink richiede una PRIMARY KEY per abbinare le tuple e risolvere i conflitti. Per quanto riguarda le tabelle senza PRIMARY KEY, pgactivelink rifiuta le operazioni DELETE restituendo il seguente errore:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

**Nota**  
pgactivelink non è in grado di distinguere tra e conflitti. UPDATE/DELETE INSERT/UPDATE In entrambi i casi, un’operazione UPDATE influisce su una riga inesistente. A causa della replica asincrona e della mancanza di un ordine di riproduzione tra i nodi, pgactivelink non è in grado di determinare se l’operazione UPDATE si riferisce a una nuova riga (operazione INSERT non ancora ricevuta) o a una riga eliminata. In entrambi gli scenari, pgactivelink elimina l’operazione UPDATE.

### Conflitti INSERT/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8"></a>

Questo conflitto può verificarsi in ambienti con più nodi. Succede quando INSERTs un nodo una riga, un secondo nodo e un terzo nodo UPDATEs ricevono l'UPDATE prima dell'INSERT originale. Per impostazione predefinita, pgactivelink risolve questi conflitti eliminando l’operazione UPDATE, a meno che il trigger per la gestione dei conflitti personalizzato non specifichi diversamente. Tieni presente che questo metodo di risoluzione può causare incongruenze nei dati tra i nodi. Per ulteriori informazioni su scenari simili e su come gestirli, consulta [Conflitti UPDATE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7).

### Conflitti DELETE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9"></a>

Questo conflitto si verifica quando due nodi diversi eliminano contemporaneamente la stessa tupla. pgactivelink considera questi conflitti innocui, perché entrambe le operazioni DELETE hanno lo stesso risultato finale. In questo scenario, pgactivelink ignora in modo sicuro una delle operazioni DELETE senza influire sulla coerenza dei dati. 

### Conflitti con vincoli di chiave esterna
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10"></a>

I vincoli FOREIGN KEY possono causare conflitti quando si applicano transazioni remote a dati locali esistenti. Questi conflitti si verificano, in genere, quando le transazioni vengono applicate in una sequenza diversa rispetto al loro ordine logico sui nodi di origine.

Per impostazione predefinita, pgactive applica le modifiche con session\$1replication\$1role come `replica`, che ignora i controlli delle chiavi esterne durante la replica. Nelle configurazioni in modalità attivo-attivo, questo può portare a violazioni delle chiavi esterne. La maggior parte delle violazioni è temporanea e si risolve una volta ripristinata la replica. Tuttavia, possono verificarsi chiavi esterne non valide perché pgactive non supporta il blocco delle righe tra nodi.

Questo comportamento è inerente ai sistemi in modalità attivo-attivo asincroni con tolleranza della partizione. Ad esempio, il nodo A potrebbe inserire una nuova riga secondaria mentre il nodo B elimina contemporaneamente la riga principale. Il sistema non può impedire questo tipo di modifica simultanea tra i nodi.

Per ridurre al minimo i conflitti tra chiavi esterne, è consigliabile:
+ Limitare le relazioni con chiave esterna a entità strettamente correlate.
+ Modificare le entità correlate da un singolo nodo, quando possibile.
+ Scegliere entità che raramente richiedono modifiche.
+ Implementare il controllo della concorrenza a livello di applicazione per le modifiche.

### Conflitti con vincoli di esclusione
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11"></a>

 pgactive link non supporta i vincoli di esclusione e ne limita la creazione.

**Nota**  
Se converti un database autonomo esistente in un database pgactivelink, elimina manualmente tutti i vincoli di esclusione.

In un sistema asincrono distribuito, non è possibile garantire che nessun insieme di righe violi il vincolo. Questo perché tutte le transazioni su nodi diversi sono completamente isolate. I vincoli di esclusione possono portare a deadlock della riproduzione, che le impediscono di passare da un nodo all’altro a causa delle violazioni dei vincoli di esclusione.

Se forzi pgactive Link a creare un vincolo di esclusione o se non elimini quelli esistenti durante la conversione di un database autonomo in pgactive Link, è probabile che la replica si interrompa. Per ripristinare l’avanzamento della replica, rimuovi o modifica le tuple locali in conflitto con una tupla remota in entrata, in modo da poter applicare la transazione remota.

### Conflitti di dati globali
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12"></a>

Quando utilizzi pgactivelink, possono verificarsi conflitti se i nodi hanno dati globali diversi a livello di sistema PostgreSQL, ad esempio i ruoli. Questi conflitti possono determinare il successo e il commit delle operazioni, soprattutto quelle di tipo DDL, su un nodo, impedendone tuttavia l’applicazione sugli altri nodi.

Se un utente esiste su un nodo ma non su un altro, possono verificarsi problemi di replica:
+ Su Node1 è presente un utente denominato `fred`, che risulta però inesistente su Node2
+ Quando `fred` crea una tabella su Node1, questa viene replicata con `fred` come nome di proprietario
+ Quando questo comando DDL viene applicato a Node2, l’esito è negativo, perché l’utente `fred` non esiste
+ Questo errore genera un’operazione ERROR nei log PostgreSQL su Node2 e incrementa il conteggio di `pgactive.pgactive_stats.nr_rollbacks`

**Risoluzione:** creazione dell’utente `fred` su Node2. L’utente non necessita di autorizzazioni identiche, ma deve esistere su entrambi i nodi.

Se una tabella esiste su un nodo ma non su un altro, le operazioni di modifica dei dati non riusciranno:
+ In Node1 è presente una tabella denominata `foo` che risulta inesistente in Node2
+ Qualsiasi operazione DML sulla tabella `foo` su Node1 avrà esito negativo se replicata su Node2

**Risoluzione:** creazione della tabella `foo` su Node2 con la stessa struttura.

**Nota**  
pgactivelink attualmente non replica i comandi CREATE USER o le operazioni DDL. La replica DDL verrà introdotta in versioni future.

### Conflitti di blocco e interruzioni per deadlock
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13"></a>

Poiché funzionano come normali sessioni utente, i processi di applicazione di pgactive seguono le regole standard di blocco delle righe e delle tabelle. È quindi possibile che i processi di applicazione di pgactivelink restino bloccati dalle transazioni degli utenti o da altri processi di applicazione.

I seguenti tipi di blocchi possono influire sui processi di applicazione:
+ Blocco esplicito a livello di tabella (LOCK TABLE...) da parte delle sessioni utente
+ Blocco esplicito a livello di riga (SELECT... FOR UPDATE/FOR SHARE) per sessioni utente
+ Blocco da chiavi esterne
+ Blocco implicito dovuto alla riga UPDATEs o DELETEs all'attività locale o applicato da altri server INSERTs

I deadlock possono verificarsi tra:
+ Un processo di applicazione di pgactivelink e una transazione utente
+ Due processi di applicazione

Quando si verifica un deadlock, il rilevatore di deadlock di PostgreSQL interrompe una delle transazioni che causa problemi. Se il processo del worker di applicazione di pgactivelink viene terminato, esegue automaticamente un nuovo tentativo che, in genere, ha esito positivo.

**Nota**  
Questi problemi sono temporanei e di norma non richiedono l’intervento dell’amministratore. Se un processo di applicazione viene bloccato per un periodo prolungato a causa del blocco di una sessione utente inattiva, è possibile interrompere tale sessione per riprendere la replica. Questa situazione è simile a quando un utente mantiene un blocco prolungato che influisce su un’altra sessione utente.
Per identificare i ritardi di riproduzione legati ai blocchi, abilita la funzionalità `log_lock_waits` in PostgreSQL.

### Conflitti divergenti
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14"></a>

I conflitti divergenti si verificano quando i dati che dovrebbero essere identici tra i nodi differiscono inaspettatamente. Questi conflitti non dovrebbero verificarsi, ma nell’implementazione attuale non è possibile evitarli tutti in modo affidabile.

**Nota**  
 La modifica della PRIMARY KEY di una riga può causare conflitti divergenti se un altro nodo cambia la chiave della stessa riga prima che tutti i nodi elaborino la modifica. Evita di modificare le chiavi primarie o limita le modifiche a un nodo designato. Per ulteriori informazioni, consulta [Conflitti UPDATE sulla PRIMARY KEY](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5).

I conflitti divergenti che coinvolgono i dati delle righe richiedono, in genere, l’intervento dell’amministratore. Per risolvere tali conflitti, è necessario modificare manualmente i dati su un nodo in modo che corrispondano a quelli di un altro, disabilitando temporaneamente la replica ricorrendo a `pgactive.pgactive_do_not_replicate`. Questi conflitti non dovrebbero verificarsi quando si utilizza pgactive come prescritto e si evitano impostazioni o funzioni contrassegnate come non sicure.

 In qualità di amministratore, devi risolvere questi conflitti manualmente. A seconda del tipo di conflitto, è necessario utilizzare opzioni avanzate come `pgactive.pgactive_do_not_replicate`. Utilizza queste opzioni con cautela, poiché un uso improprio può peggiorare la situazione. A causa della varietà dei possibili conflitti, non possiamo fornire istruzioni universalmente valide per la risoluzione.

I conflitti divergenti si verificano quando i dati che dovrebbero essere identici tra i nodi differiscono inaspettatamente. Questi conflitti non dovrebbero verificarsi, ma nell’implementazione attuale non è possibile evitarli tutti in modo affidabile.

## Come evitare o tollerare i conflitti
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.avoidconflicts"></a>

 Nella maggior parte dei casi, per evitare conflitti è possibile utilizzare un design appropriato dell’applicazione o rendere l’applicazione tollerante nei confronti dei conflitti.

 I conflitti si verificano solo quando operazioni simultanee avvengono su più nodi. Per evitare conflitti:
+ Scrivi su un solo nodo
+ Scrivi su sottoinsiemi di database indipendenti su ogni nodo (ad esempio, assegna a ogni nodo uno schema separato)

Per i conflitti INSERT/INSERT, utilizza le sequenze Global che prevengono completamente i conflitti.

 Se i conflitti non sono accettabili per il tuo caso d’uso, prendi in considerazione l’implementazione del blocco distribuito a livello di applicazione. Spesso, l’approccio migliore è progettare l’applicazione in modo che funzioni con i meccanismi di risoluzione dei conflitti di pgactive piuttosto che cercare di prevenire tutti i conflitti. Per ulteriori informazioni, consulta [Tipi di conflitti](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes). 

## Registrazione di log dei conflitti
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflictlogging"></a>

pgactivelink registra gli incidenti di conflitto nella tabella `pgactive.pgactive_conflict_history` per aiutarti a diagnosticare e gestire i conflitti in modalità attivo-attivo. La registrazione di log dei conflitti in questa tabella si verifica solo se `pgactive.log_conflicts_to_table` è impostato su true. L’estensione pgactive registra i conflitti anche nel file di log di PostgreSQL quando log\$1min\$1messages è impostato su `LOG` o `lower`, indipendentemente dall’impostazione `pgactive.log_conflicts_to_table`.

 Utilizza la tabella della cronologia dei conflitti per:
+ Misurare la frequenza con cui l’applicazione crea conflitti
+ Identificare dove si verificano i conflitti
+ Migliorare l’applicazione per ridurre i tassi di conflitto
+ Rilevare i casi in cui la risoluzione dei conflitti non produce i risultati desiderati
+ Stabilire dove è necessario utilizzare i trigger per la gestione dei conflitti definiti dall’utente o modificare la progettazione delle applicazioni

 Per i conflitti di riga, puoi facoltativamente registrare i valori di riga. Questa operazione è controllata dall’impostazione `pgactive.log_conflicts_to_table`. Note:
+ Questa è un’opzione globale per l’intero database
+ Non esiste un controllo per tabella sulla registrazione di log dei valori di riga
+ Ai numeri di campo, agli elementi dell’array o alla lunghezza dei campi non viene applicato alcun limite
+ L’attivazione di questa funzionalità potrebbe non essere consigliabile se si lavora con righe da più megabyte che potrebbero causare conflitti

 Poiché la tabella della cronologia dei conflitti contiene i dati di ogni tabella del database (ognuna con schemi potenzialmente diversi), i valori delle righe registrati vengono archiviati come campi JSON. Il file JSON viene creato utilizzando `row_to_json`, in modo simile a una chiamata diretta da SQL. PostgreSQL non fornisce `json_to_row` una funzione, quindi avrai bisogno di codice specifico per la tabella (PL/pgSQL, PL/Python, PL/Perlin, ecc.) per ricostruire una tupla di tipo composito dal JSON registrato.

**Nota**  
Il supporto dei conflitti definiti dall’utente verrà introdotto come funzionalità di estensione futura.

# Informazioni sullo schema pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema"></a>

Lo schema pgactive gestisce la replica attiva-attiva in RDS per PostgreSQL. Questo schema contiene tabelle che memorizzano le informazioni sullo stato e sulla configurazione della replica.

**Nota**  
Lo schema pgactive è in evoluzione ed è soggetto a modifica. Non modificare i dati direttamente in queste tabelle.

Le tabelle chiave dello schema pgactive includono:
+ `pgactive_nodes`: memorizza le informazioni sui nodi nel gruppo di replica attiva-attiva.
+ `pgactive_connections`: memorizza i dettagli di connessione per ogni nodo.

## pgactive\$1nodes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.nodes"></a>

Il pgactive\$1nodes memorizza le informazioni sui nodi che partecipano al gruppo di replica attiva-attiva. 


| Colonna | Tipo | Collation (Regola di confronto) | Nullable | Default | 
| --- | --- | --- | --- | --- | 
| node\$1sysid | testo | – | Non null | – | 
| node\$1timeline | oid | – | non null | – | 
| node\$1dboid | oid | – | non null | – | 
| node\$1status | char | – | non null | – | 
| node\$1name | testo | – | non null | – | 
| node\$1dsn | testo | – | non null | – | 
| node\$1init\$1from\$1dsn | testo | – | non null | – | 
| node\$1read\$1only | booleano | – | – | false | 
| node\$1seq\$1id | smallint | – | non null | – | 

**node\$1sysid**  
ID univoco per un nodo, generato durante `pgactive_create_group` o `pgactive_join_group`

**node\$1status**  
Disponibilità del nodo:  
+ **b** - beginning setup (avvio della configurazione)
+ **i** - initializing (inizializzazione)
+ **c** - catchup (recupero)
+ **o** - creating outbound slots (creazione di slot in uscita)
+ **r** - ready (pronto)
+ **k** - killed (terminato)
Questa colonna non indica se un nodo è connesso o disconnesso.

**node\$1name**  
Nome del nodo univoco fornito dall’utente.

**node\$1dsn**  
Stringa di connessione o nome della mappatura utente

**node\$1init\$1from\$1dsn**  
DSN da cui è stato creato questo nodo.

## pgactive\$1connection
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.connection"></a>

Il pgactive\$1connections memorizza i dettagli di connessione per ogni nodo.


| Colonna | Tipo | Collation (Regola di confronto) | Nullable | Default | 
| --- | --- | --- | --- | --- | 
| conn\$1sysid | testo | nessuno | non null | nessuno | 
| conn\$1timeline | oid | nessuno | non null | nessuno | 
| conn\$1dboid | oid | nessuno | non null | nessuno | 
| conn\$1dsn | testo | nessuno | non null | nessuno | 
| conn\$1apply\$1delay | intero | nessuno | nessuno | nessuno | 
| conn\$1replication\$1sets | testo | nessuno | nessuno | nessuno | 

conn\$1sysid  
Identificatore del nodo per il nodo a cui si riferisce questa voce.

conn\$1dsn  
Uguale a pgactive.pgactive\$1nodes `node_dsn`.

conn\$1apply\$1delay  
Se impostato, mostra i millisecondi di attesa prima di applicare ogni transazione dal nodo remoto. Principalmente per il debug. Se null, si applica l’impostazione predefinita globale.

## Utilizzo delle dei set di replica
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replication"></a>

I set di replica determinano quali tabelle includere o escludere dalle operazioni di replica. Per impostazione predefinita, tutte le tabelle vengono replicate, a meno che non venga specificato diversamente, utilizzando le seguenti funzioni:
+ `pgactive_exclude_table_replication_set()`: esclude le tabelle specificate dalla replica
+ `pgactive_include_table_replication_set()`: include le tabelle specificate nella replica

**Nota**  
Prima di configurare i set di replica, valuta quanto segue:  
È possibile configurare l’inclusione o l’esclusione delle tabelle solo dopo aver eseguito `pgactive_create_group()`, ma prima di `pgactive_join_group()`.
Dopo aver utilizzato `pgactive_exclude_table_replication_set()`, non è possibile utilizzare `pgactive_include_table_replication_set()`.
Dopo aver utilizzato `pgactive_include_table_replication_set()`, non è possibile utilizzare `pgactive_exclude_table_replication_set()`.

Il sistema gestisce le tabelle appena create in modo diverso in base alla configurazione iniziale:
+ Se hai escluso le tabelle: tutte le nuove tabelle create dopo `pgactive_join_group()` vengono automaticamente incluse nella replica
+ Se sono state incluse tabelle: tutte le nuove tabelle create dopo `pgactive_join_group()` vengono automaticamente escluse dalla replica.

Per visualizzare la configurazione del set di repliche per una tabella specifica, utilizza la funzione `pgactive.pgactive_get_table_replication_sets()`.

# Informazioni di riferimento sulle funzioni pgactive
<a name="pgactive-functions-reference"></a>

Di seguito è riportato un elenco di funzioni pgactive con i relativi parametri, valori restituiti e note pratiche per facilitarne l’utilizzo efficace:

## get\$1last\$1applied\$1xact\$1info
<a name="get-last-applied-xact-info"></a>

Recupera le informazioni sull’ultima transazione applicata per un nodo specificato.

**Argomenti**  
+ sysid (text) – OID della timeline
+ dboid (OID)

**Tipo restituito**  
Registra quanto segue:  
+ last\$1applied\$1xact\$1id (OID)
+ last\$1applied\$1xact\$1committs (timestamp con fuso orario)
+ last\$1applied\$1xact\$1at (timestamp con fuso orario)

**Note per l'utilizzo**  
Utilizza questa funzione per recuperare le informazioni sull’ultima transazione applicata per un nodo specificato.

## pgactive\$1apply\$1pause
<a name="pgactive-apply-pause"></a>

Sospende il processo di applicazione della replica.

**Argomenti**  
Nessuno

**Tipo restituito**  
booleano

**Note per l'utilizzo**  
Chiama questa funzione per sospendere il processo di applicazione della replica.

## pgactive\$1apply\$1resume
<a name="pgactive-apply-resume"></a>

Riprende il processo di applicazione della replica.

**Argomenti**  
Nessuno

**Tipo restituito**  
void

**Note per l'utilizzo**  
Chiama questa funzione per riprendere il processo di applicazione della replica.

## pgactive\$1is\$1apply\$1paused
<a name="pgactive-is-apply-paused"></a>

Verifica se l’applicazione della replica è attualmente sospesa.

**Argomenti**  
Nessuno

**Tipo restituito**  
booleano

**Note per l'utilizzo**  
Utilizza questa funzione per verificare se l’applicazione della replica è attualmente sospesa.

## pgactive\$1create\$1group
<a name="pgactive-create-group"></a>

Crea un gruppo pgactive convertendo un database autonomo nel nodo iniziale.



**Argomenti**  
+ node\$1name (text)
+ node\$1dsn (text)
+ apply\$1delay integer DEFAULT NULL::integer - replication\$1sets text[] DEFAULT ARRAY[‘default’::text]

**Tipo restituito**  
void

**Note per l'utilizzo**  
Crea un gruppo pgactive convertendo un database autonomo nel nodo iniziale. La funzione esegue controlli di integrità prima di trasformare il nodo in un nodo pgactive. Prima di utilizzare questa funzione, assicurati che il cluster PostgreSQL abbia una quantità di `max_worker_processes` sufficiente per supportare i processi worker in background.

## pgactive\$1detach\$1nodes
<a name="pgactive-detach-nodes"></a>

Rimuove i nodi specificati dal gruppo pgactive.

**Argomenti**  
+ p\$1nodes (text[])

**Tipo restituito**  
void

**Note per l'utilizzo**  
Utilizza questa funzione per rimuovere i nodi specificati dal gruppo pgactive.

## pgactive\$1exclude\$1table\$1replication\$1set
<a name="pgactive-exclude-table-replication-set"></a>

Esclude una tabella specifica dalla replica.

**Argomenti**  
+ p\$1relation (regclass)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Utilizza questa funzione per escludere una tabella specifica dalla replica.

## pgactive\$1get\$1replication\$1lag\$1info
<a name="pgactive-get-replication-lag-info"></a>

Recupera informazioni dettagliate sul ritardo di replica, inclusi i dettagli dei nodi, lo stato WAL e i valori LSN.

**Argomenti**  
Nessuno

**Tipo restituito**  
SETOF record - node\$1name text - node\$1sysid text - application\$1name text - slot\$1name text - active boolean - active\$1pid integer - pending\$1wal\$1decoding bigint - Dimensione approssimativa di WAL in byte da decodificare sul nodo mittente - pending\$1wal\$1to\$1apply bigint - Dimensione approssimativa di WAL in byte da applicare sul nodo ricevente - restart\$1lsn pg\$1lsn - confirmed\$1flush\$1lsn pg\$1lsn - sent\$1lsn pg\$1lsn - write\$1lsn pg\$1lsn - flush\$1lsn pg\$1lsn - replay\$1lsn pg\$1lsn

**Note per l'utilizzo**  
Chiama questa funzione per recuperare le informazioni sul ritardo di replica, inclusi i dettagli dei nodi, lo stato WAL e i valori LSN.

## pgactive\$1get\$1stats
<a name="pgactive-get-stats"></a>

Recupera le statistiche di replica pgactive.

**Argomenti**  
Nessuno

**Tipo restituito**  
SETOF record - rep\$1node\$1id id - rilocalid oid - riremoteid text - nr\$1commit bigint - nr\$1rollback bigint - nr\$1insert bigint - nr\$1insert\$1conflict bigint - nr\$1update bigint - nr\$1update\$1conflict bigint - nr\$1delete bigint - nr\$1delete\$1conflict bigint - nr\$1disconnect bigint

**Note per l'utilizzo**  
Utilizza questa funzione per recuperare le statistiche di replica pgactive.

## pgactive\$1get\$1table\$1replication\$1sets
<a name="pgactive-get-table-replication-sets"></a>

Ottiene la configurazione del set di replica per una relazione specifica.

**Argomenti**  
+ relation (regclass)

**Tipo restituito**  
Record SETOF

**Note per l'utilizzo**  
Chiama questa funzione per ottenere la configurazione del set di replica per una relazione specifica.

## pgactive\$1include\$1table\$1replication\$1set
<a name="pgactive-include-table-replication-set"></a>

Include una tabella specifica nella replica.

**Argomenti**  
+ p\$1relation (regclass)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Utilizza questa funzione per includere una tabella specifica nella replica.

## pgactive\$1join\$1group
<a name="pgactive-join-group"></a>

Aggiunge un nodo a un gruppo pgactive esistente.

**Argomenti**  
+ node\$1name (text)
+ node\$1dsn (text)
+ join\$1using\$1dsn (text)
+ apply\$1delay (integer, opzionale)
+ replication\$1sets (text[], valore predefinito: ['default'])
+ bypass\$1collation\$1check (boolean, valore predefinito: false)
+ bypass\$1node\$1identifier\$1creation (boolean, valore predefinito: false)
+ bypass\$1user\$1tables\$1check (boolean, valore predefinito: false)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Chiama questa funzione per aggiungere un nodo a un gruppo pgactive esistente. Assicurati che il cluster PostgreSQL abbia max\$1worker\$1processes sufficienti per i processi worker in background pgactive.

## pgactive\$1remove
<a name="pgactive-remove"></a>

Rimuove tutti i componenti pgactive dal nodo locale.

**Argomenti**  
+ force (boolean, valore predefinito: false)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Chiama questa funzione per rimuovere tutti i componenti pgactive dal nodo locale.

## pgactive\$1snowflake\$1id\$1nextval
<a name="pgactive-snowflake-id-nextval"></a>

Genera valori di sequenza univoci specifici del nodo.

**Argomenti**  
+ regclass

**Tipo restituito**  
bigint

**Note per l'utilizzo**  
Utilizza questa funzione per generare valori di sequenza univoci specifici del nodo.

## pgactive\$1update\$1node\$1conninfo
<a name="pgactive-update-node-conninfo"></a>

Aggiorna le informazioni di connessione per un nodo pgactive.

**Argomenti**  
+ node\$1name\$1to\$1update (text)
+ node\$1dsn\$1to\$1update (text)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Utilizza questa funzione per aggiornare le informazioni di connessione per un nodo pgactive.

## pgactive\$1wait\$1for\$1node\$1ready
<a name="pgactive-wait-for-node-ready"></a>

Monitora lo stato di avanzamento delle operazioni di creazione o unione dei gruppi.

**Argomenti**  
+ timeout (integer, valore predefinito: 0)
+ progress\$1interval (integer, valore predefinito: 60)

**Tipo restituito**  
void

**Note per l'utilizzo**  
Chiama questa funzione per monitorare l’avanzamento delle operazioni di creazione o unione dei gruppi.

# Gestione dei conflitti nella replica active-active
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts"></a>

L'estensione `pgactive` funziona per database e non per cluster. Ogni istanza database che utilizza `pgactive` è un'istanza indipendente e può accettare modifiche ai dati da qualsiasi origine. Quando viene inviata una modifica a un'istanza database, PostgreSQL la esegue localmente e quindi utilizza `pgactive` per replicare la modifica in modo asincrono su altre istanze database. Quando due istanze database PostgreSQL aggiornano lo stesso record quasi contemporaneamente, può verificarsi un conflitto.

L'estensione `pgactive` fornisce meccanismi per il rilevamento dei conflitti e la risoluzione automatica. Tiene traccia del timestamp in cui è stata effettuata la transazione su entrambe le istanze database e applica automaticamente la modifica con il timestamp più recente. L'estensione `pgactive` registra anche quando si verifica un conflitto nella tabella `pgactive.pgactive_conflict_history`.

`pgactive.pgactive_conflict_history` continuerà a crescere. Potresti voler definire una policy di eliminazione. A tal fine, puoi cancellare alcuni record su base regolare o definire uno schema di partizionamento per questa relazione (e successivamente scollegare, rimuovere e troncare le partizioni di interesse). Per implementare la policy di eliminazione su base regolare, un’opzione è utilizzare l’estensione `pg_cron`. Consulta le seguenti informazioni di un esempio per la tabella della cronologia `pg_cron`, [Pianificazione della manutenzione con l’estensione PostgreSQL pg\$1cron](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html).

# Gestione delle sequenze nella replica active-active
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences"></a>

Un'istanza database RDS per PostgreSQL con l'estensione `pgactive` utilizza due diversi meccanismi di sequenza per generare valori univoci.

**Sequenze globali**  
Per utilizzare una sequenza globale, crea una sequenza locale con l'istruzione `CREATE SEQUENCE`. Utilizza `pgactive.pgactive_snowflake_id_nextval(seqname)` invece di `usingnextval(seqname)` per ottenere il valore univoco successivo della sequenza.

L'esempio seguente crea una sequenza globale:

```
app=> CREATE TABLE gstest (
      id bigint primary key,
      parrot text
    );
```

```
app=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
```

```
app=> ALTER TABLE gstest \
      ALTER COLUMN id SET DEFAULT \
      pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
```

**Sequenze partizionate**  
Nelle sequenze suddivise o partizionate, viene utilizzata una normale sequenza PostgreSQL su ciascun nodo. Ogni sequenza incrementa della stessa quantità e inizia con offset diversi. Ad esempio, con il passaggio 100, il nodo 1 genera una sequenza come 101, 201, 301 e così via e il nodo 2 genera una sequenza come 102, 202, 302 e così via. Questo schema funziona bene anche se i nodi non possono comunicare per periodi prolungati, ma richiede che il progettista specifichi un numero massimo di nodi al momento di stabilire lo schema e richiede una configurazione per nodo. Gli errori possono facilmente portare alla sovrapposizione di sequenze.

È relativamente semplice configurare questo approccio con `pgactive` creando la sequenza desiderata su un nodo nel modo seguente:

```
CREATE TABLE some_table (generated_value bigint primary key);
```

```
app=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
```

```
app=> ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');
```

Quindi richiama `setval` su ogni nodo per assegnare un valore iniziale di offset diverso nel modo seguente.

```
app=>
-- On node 1
SELECT setval('some_seq', 1);

-- On node 2
SELECT setval('some_seq', 2);
```

# Riduzione della dimensione nelle tabelle e negli indici con l’estensione pg\$1repack
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack"></a>

Puoi utilizzare l’estensione `pg_repack` per rimuovere dimensioni da tabelle e indici come alternativa a `VACUUM FULL`. Questa estensione è supportata sul motore Amazon RDS for PostgreSQL versioni 9.6.3 e successive. Per ulteriori informazioni sull'`pg_repack`estensione e sul repack completo della tabella, consulta la [documentazione del GitHub progetto](https://reorg.github.io/pg_repack/).

Al contrario`VACUUM FULL`, l'`pg_repack`estensione richiede un lock (AccessExclusiveLock) esclusivo solo per un breve periodo di tempo durante l'operazione di ricostruzione della tabella nei seguenti casi:
+ Creazione iniziale della tabella di log: viene creata una tabella di log per registrare le modifiche che si verificano durante la copia iniziale dei dati, come illustrato nell’esempio seguente: 

  ```
  postgres=>\dt+ repack.log_*
  List of relations
  -[ RECORD 1 ]-+----------
  Schema        | repack
  Name          | log_16490
  Type          | table
  Owner         | postgres
  Persistence   | permanent
  Access method | heap
  Size          | 65 MB
  Description   |
  ```
+  swap-and-dropFase finale.

Per il resto dell’operazione di ricostruzione, è sufficiente solo un blocco `ACCESS SHARE` sulla tabella originale per copiare le righe da questa tabella a quella nuova. Ciò consente alle operazioni INSERT, UPDATE e DELETE di procedere come di consueto.

## Raccomandazioni
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Recommen"></a>

I consigli indicato di seguito si applicano quando rimuovi le dimensioni dalle tabelle e dagli indici utilizzando l’estensione `pg_repack`:
+ Per minimizzarne l’impatto sulle prestazioni di altre attività del database, esegui la nuova compressione durante le ore non lavorative o durante una finestra di manutenzione.
+ Monitora attentamente le sessioni di blocco durante l'attività di ricostruzione e assicurati che sulla tabella originale non vi siano attività potenzialmente bloccabili`pg_repack`, in particolare durante la swap-and-drop fase finale, quando è necessario un blocco esclusivo sulla tabella originale. Per ulteriori informazioni, consulta l’articolo su come [identificare gli elementi che bloccano una query](https://repost.aws/knowledge-center/rds-aurora-postgresql-query-blocked). 

  Quando viene visualizzata una sessione di blocco, puoi interromperla utilizzando il seguente comando dopo un’attenta valutazione. Ciò consente di continuare `pg_repack` per completare la ricostruzione:

  ```
  SELECT pg_terminate_backend(pid);
  ```
+ Durante l’applicazione delle modifiche accumulate dalla tabella di log di `pg_repack's` sui sistemi con un tasso di transazione molto elevato, il processo di applicazione potrebbe non essere in grado di tenere il passo con la frequenza delle modifiche. In questi casi, `pg_repack` potrebbe non essere in grado di completare la procedura di applicazione. Per ulteriori informazioni, consulta [Monitoraggio della nuova tabella durante la nuova compressione](#Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring). Se gli indici sono aumentati molto in dimensioni, una soluzione alternativa consiste nell’eseguire una nuova compressione solo dell’indice. Ciò aiuta anche a completare più velocemente i cicli di pulizia degli indici di VACUUM.

  Puoi saltare la fase di pulizia dell’indice utilizzando VACUUM manuale dalla versione 12 di PostgreSQL. In questo modo, la fase di pulizia viene saltata automaticamente durante l’autovacuum di emergenza da PostgreSQL versione 14. Ciò consente al comando VACUUM di completare più rapidamente il processo senza rimuovere le dimensioni dell’indice. Tale soluzione è pensata solo per le situazioni di emergenza, ad esempio per evitare che si verifichi un processo di vacuum per wraparound. Per ulteriori informazioni, consulta [Impedimento dell’aumento delle dimensioni negli indici](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html#AuroraPostgreSQL.diag-table-ind-bloat.AvoidinginIndexes) nella Guida per l’utente di Amazon Aurora.

## Prerequisiti
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Prereq"></a>
+ La tabella deve avere un vincolo CHIAVE PRIMARIA o un vincolo UNIVOCO non nullo.
+ La versione dell’estensione deve essere la stessa per il client e per il server.
+ Assicurati che l’istanza RDS abbia una dimensione `FreeStorageSpace` superiore alla dimensione totale della tabella senza aumento delle dimensioni. Ad esempio, se la dimensione totale della tabella, compresi TOAST e indici, è pari a 2 TB e l’aumento delle dimensioni totali nella tabella è pari a 1 TB, la dimensione di `FreeStorageSpace` richiesto deve essere superiore al valore risultante dal seguente calcolo:

   `2TB (Table size)` - `1TB (Table bloat)` = `1TB`

  Puoi utilizzare la seguente query per verificare la dimensione totale della tabella e puoi utilizzare `pgstattuple` per individuare l’aumento delle dimensioni. Per ulteriori informazioni, consulta la sezione [Diagnosi delle dimensioni della tabella e dell’indice](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html) nella Guida per l’utente di Amazon Aurora 

  ```
  SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;
  ```

  Questo spazio viene recuperato dopo il completamento dell’attività. 
+ Assicurati che l’istanza RDS abbia una capacità di elaborazione e IO sufficiente per gestire l’operazione di nuova compressione. Potresti prendere in considerazione l’idea di aumentare verticalmente la classe di istanze per raggiungere un equilibrio ottimale delle prestazioni. 

**Per utilizzare l’estensione `pg_repack`**

1. Installa l'estensione `pg_repack` nell'istanza database di Amazon RDS for PostgreSQL eseguendo il comando seguente.

   ```
   CREATE EXTENSION pg_repack;
   ```

1. Esegui i comandi riportati di seguito per concedere l’accesso in scrittura alle tabelle di log temporanee create da `pg_repack`.

   ```
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC;
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
   ```

1. Utilizza l’utility client `pg_repack` per connetterti al database. Usa un account con privilegi `rds_superuser`. Ad esempio, presumiamo che il ruolo `rds_test` abbia i privilegi `rds_superuser`. La sintassi indicata di seguito esegue `pg_repack` per le tabelle complete, inclusi tutti gli indici delle tabelle del database `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
   ```
**Nota**  
È necessario connettersi utilizzando l’opzione -k. L'opzione a non è supportata.

   La risposta del client `pg_repack` fornisce informazioni sulle tabelle che vengono compresse di nuovo sull’istanza database.

   ```
   INFO: repacking table "pgbench_tellers"
   INFO: repacking table "pgbench_accounts"
   INFO: repacking table "pgbench_branches"
   ```

1. La sintassi seguente comprime di nuovo una singola tabella `orders`, inclusi gli indici nel database `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres
   ```

   La sintassi seguente comprime di nuovo solo gli indici per la tabella `orders` nel database `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres
   ```

## Monitoraggio della nuova tabella durante la nuova compressione
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring"></a>
+ La dimensione del database viene aumentata della dimensione totale della tabella meno il bloat, fino alla swap-and-drop fase di repack. È possibile monitorare il tasso di crescita delle dimensioni del database, calcolare la velocità della nuova compressione e stimare approssimativamente il tempo necessario per completare il trasferimento iniziale dei dati.

  Ad esempio, considera la dimensione totale della tabella di 2 TB, la dimensione del database di 4 TB e il volume totale della tabella di 1 TB. Il valore della dimensione totale del database restituito dal calcolo al termine dell’operazione di nuova compressione è il seguente:

   `2TB (Table size)` \$1 `4 TB (Database size)` - `1TB (Table bloat)` = `5TB`

  Puoi stimare approssimativamente la velocità dell’operazione di nuova compressione campionando il tasso di crescita in byte tra due momenti nel tempo. Se il tasso di crescita è di 1 GB al minuto, possono essere necessari 1.000 minuti o 16,6 ore circa per completare l’operazione iniziale di creazione della tabella. Oltre alla creazione iniziale della tabella, `pg_repack` deve applicare anche le modifiche accumulate. Il tempo necessario per tale operazione dipende dalla velocità di applicazione delle modifiche che sono in corso e di quelle accumulate.
**Nota**  
È possibile utilizzare l’estensione `pgstattuple` per calcolare l’aumento della dimensione nella tabella. Per ulteriori informazioni, consulta [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html).
+ Il numero di righe nella tabella di log `pg_repack's`, secondo lo schema di nuova compressione, rappresenta il volume delle modifiche in sospeso da applicare alla nuova tabella dopo il caricamento iniziale.

  Puoi controllare la tabella di log `pg_repack's` in `pg_stat_all_tables` per monitorare le modifiche applicate alla nuova tabella. `pg_stat_all_tables.n_live_tup`indica il numero di record che attendono di essere applicati alla nuova tabella. Per ulteriori informazioni, vedi [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW). 

  ```
  postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%';
          
  -[ RECORD 1 ]---------
  relname    | log_16490
  n_live_tup | 2000000
  ```
+ Puoi utilizzare l’estensione `pg_stat_statements` per scoprire il tempo impiegato da ogni fase dell’operazione di nuova compressione. Ciò è utile in preparazione all’applicazione della stessa operazione di nuova compressione in un ambiente di produzione. Puoi modificare la clausola `LIMIT` per estendere ulteriormente l’output.

  ```
  postgres=>SELECT
       SUBSTR(query, 1, 100) query,
       round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes
   FROM
       pg_stat_statements
   WHERE
       query ILIKE '%repack%'
   ORDER BY
       total_exec_time DESC LIMIT 5;
          
   query                                                                 | total_exec_time_in_minutes
  -----------------------------------------------------------------------+----------------------------
   CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) |                     6.8627
   INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1           |                     6.4150
   SELECT repack.repack_apply($1, $2, $3, $4, $5, $6)                    |                     0.5395
   SELECT repack.repack_drop($1, $2)                                     |                     0.0004
   SELECT repack.repack_swap($1)                                         |                     0.0004
  (5 rows)
  ```

Il reimballaggio è completamente un' out-of-placeoperazione, quindi la tabella originale non ne risente e non prevediamo problemi imprevisti che richiedano il ripristino della tabella originale. Se la nuova compressione riporta un errore imprevisto, è necessario verificare la causa dell’errore e risolverlo.

Dopo aver risolto l’errore, rilascia e ricrea l’estensione `pg_repack` nel database in cui esiste la tabella e riprova il passaggio `pg_repack`. Inoltre, la disponibilità di risorse di calcolo e l’accessibilità simultanea della tabella svolgono un ruolo cruciale nel completamento tempestivo dell’operazione di nuova compressione.

# Aggiornamento e utilizzo dell'estensione PLV8
<a name="PostgreSQL.Concepts.General.UpgradingPLv8"></a>

PLV8 è un'estensione affidabile del linguaggio Javascript per PostgreSQL. Puoi utilizzarlo per le procedure archiviate, i trigger e altri codici procedurali richiamabili da SQL. Questa estensione della lingua è supportata da tutte le versioni correnti di PostgreSQL. 

Se usi [PLV8](https://plv8.github.io/)e aggiorni PostgreSQL a una PLV8 nuova versione, sfrutti immediatamente la nuova estensione. Segui i passaggi seguenti per sincronizzare i metadati del catalogo con la nuova versione di. PLV8 Queste fasi sono facoltative ma fortemente consigliate per evitare avvisi di mancata corrispondenza dei metadati.

Il processo di aggiornamento elimina tutte le funzioni esistenti PLV8 . Pertanto, consigliamo di creare uno snapshot dell’istanza database di RDS for PostgreSQL prima dell'aggiornamento. Per ulteriori informazioni, consulta [Creazione di uno snapshot del database per un’istanza database Single-AZ per Amazon RDS](USER_CreateSnapshot.md).

**Importante**  
A partire dalla versione 18 di PostgreSQL, Amazon RDS per PostgreSQL renderà obsolete le estensioni `plcoffee` e `plls` di PostgreSQL. Ti consigliamo di smettere di usare CoffeeScript e LiveScript nelle tue applicazioni per assicurarti di disporre di un percorso di aggiornamento per i futuri aggiornamenti delle versioni del motore.

**Per sincronizzare i metadati del catalogo con una nuova versione di PLV8**

1. Verificare la necessità dell'aggiornamento. Per procedere, eseguire il comando seguente durante la connessione alla propria istanza.

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
   ```

   Se i risultati contengono valori per una versione installata inferiore rispetto alla versione predefinita, continuare con la procedura per aggiornare le estensioni. Ad esempio, il seguente set di risultati indica che è necessario eseguire l'aggiornamento:

   ```
   name    | default_version | installed_version |                     comment
   --------+-----------------+-------------------+--------------------------------------------------
   plls    | 2.1.0           | 1.5.3             | PL/LiveScript (v8) trusted procedural language
   plcoffee| 2.1.0           | 1.5.3             | PL/CoffeeScript (v8) trusted procedural language
   plv8    | 2.1.0           | 1.5.3             | PL/JavaScript (v8) trusted procedural language
   (3 rows)
   ```

1. Crea uno snapshot della tua istanza database RDS for PostgreSQL se non lo hai ancora fatto. Puoi continuare con la seguente procedura una volta creata la snapshot. 

1. Ottieni un conteggio del numero di PLV8 funzioni nella tua istanza DB in modo da poter verificare che siano tutte disponibili dopo l'aggiornamento. Ad esempio, la seguente query SQL restituisce il numero di funzioni scritte in plv8, plcoffee e plls.

   ```
   SELECT proname, nspname, lanname 
   FROM pg_proc p, pg_language l, pg_namespace n
   WHERE p.prolang = l.oid
   AND n.oid = p.pronamespace
   AND lanname IN ('plv8','plcoffee','plls');
   ```

1. Utilizzare pg\$1dump per creare un file dump solo schema. Ad esempio, crea un file nel computer client nella directory `/tmp`.

   ```
   ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp
   ```

   In questo esempio vengono utilizzate le seguenti opzioni: 
   + `-Fc` – Formato personalizzato
   + --schema-only – Esecuzione del dump solo dei comandi necessari per creare lo schema (funzioni in questo caso)
   + `-U` – Nome utente principale di RDS
   + `database` – Nome del database nell'istanza database

   Per ulteriori informazioni su pg\$1dump, consulta [pg\$1dump](https://www.postgresql.org/docs/current/static/app-pgdump.html ) nella documentazione di PostgreSQL.

1. Estrarre l'istruzione DDL "CREATE FUNCTION" presente nel file dump. Gli esempi seguenti utilizzano il comando `grep` per estrarre l'istruzione DDL che crea le funzioni e salvarle in un file. Verrà utilizzata nelle fasi successive per ricreare le funzioni. 

   ```
   ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list
   ```

   Per ulteriori informazioni su pg\$1restore, consulta [pg\$1dump](https://www.postgresql.org/docs/current/static/app-pgrestore.html) nella documentazione di PostgreSQL. 

1. Eliminare le funzioni e le estensioni. L'esempio seguente elimina tutti gli oggetti PLV8 basati. L'opzione a cascata assicura l'eliminazione di ogni elemento dipendente.

   ```
   DROP EXTENSION plv8 CASCADE;
   ```

   Se l'istanza PostgreSQL contiene degli oggetti basati su plcoffee o plls, ripetere la procedura per quelle estensioni.

1. Creare le estensioni. Il seguente esempio crea le estensioni plv8, plcoffee e plls.

   ```
   CREATE EXTENSION plv8;
   CREATE EXTENSION plcoffee;
   CREATE EXTENSION plls;
   ```

1. Creare le funzioni utilizzando il file dump e il file "driver".

   Il seguente esempio ricrea le funzioni estratte in precedenza.

   ```
   ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
   ```

1. Verifica che tutte le funzioni siano state ricreate utilizzando la seguente query. 

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee'); 
   ```

   La PLV8 versione 2 aggiunge la seguente riga aggiuntiva al set di risultati:

   ```
       proname    |  nspname   | lanname
   ---------------+------------+----------
    plv8_version  | pg_catalog | plv8
   ```

# Utilizzo PL/Rust per scrivere funzioni PostgreSQL nel linguaggio Rust
<a name="PostgreSQL.Concepts.General.Using.PL_Rust"></a>

PL/Rust is a trusted Rust language extension for PostgreSQL. You can use it for stored procedures, functions, and other procedural code that's callable from SQL. The PL/Rustl'estensione del linguaggio è disponibile nelle seguenti versioni:
+ RDS per PostgreSQL 17.1 e versioni successive 17
+ RDS per PostgreSQL 16.1 e versioni successive 16
+ RDS per PostgreSQL 15.2-R2 e versioni successive alla 15
+ RDS per PostgreSQL 14.9 e versioni successive alla 14
+ RDS per PostgreSQL 13.12 e versioni successive alla 13

[Per ulteriori informazioni, vedere PL/Rust on.](https://github.com/tcdi/plrust#readme) GitHub

**Topics**
+ [

## Configurazione di PL/Rust
](#PL_Rust-setting-up)
+ [

## Creazione di funzioni con PL/Rust
](#PL_Rust-create-function)
+ [

## Utilizzo dei formati crate con PL/Rust
](#PL_Rust-crates)
+ [

## Limitazioni del linguaggio PL/Rust
](#PL_Rust-limitations)

## Configurazione di PL/Rust
<a name="PL_Rust-setting-up"></a>

Per installare l'estensione plrust sull'istanza database, aggiungere plrust al parametro `shared_preload_libraries` nel gruppo di parametri database associato all'istanza database. Dopo aver installato l'estensione plrust, è possibile creare funzioni. 

Per modificare il parametro `shared_preload_libraries`, l'istanza database deve essere associata a un gruppo di parametri personalizzato. Per ulteriori informazioni sulla creazione di un gruppo di parametri personalizzato, consulta [Gruppi di parametri per Amazon RDS](USER_WorkingWithParamGroups.md).

È possibile installare l'estensione plrust utilizzando o il Console di gestione AWS . AWS CLI

I passaggi seguenti si basano sull'ipotesi che l'istanza database sia associata a un gruppo di parametri personalizzato.

### Console
<a name="PL_Rust-setting-up.CON"></a>

**Installare l'estensione plrust nel parametro `shared_preload_libraries`**

Eseguire i seguenti passaggi utilizzando un account membro del gruppo `rds_superuser` (ruolo).

1. Accedi a Console di gestione AWS e apri la console Amazon RDS all'indirizzo [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Nel pannello di navigazione, seleziona **Database**.

1. Scegliere il nome dell'istanza database per visualizzarne i dettagli.

1. Aprire la scheda **Configurazione** dell'istanza database e trovare il link al gruppo di parametri dell'istanza database.

1. Scegliere il link per aprire i parametri personalizzati associati all'istanza database. 

1. Nel campo di ricerca **Parametri**, digita `shared_pre` per trovare il parametro **`shared_preload_libraries`**.

1. Scegli **Edit parameters** (Modifica parametri) per accedere ai valori delle proprietà.

1. Aggiungere plrust all'elenco nel campo **Valori**. Utilizza una virgola per separare gli elementi nell’elenco di valori.

1. Riavviare l'istanza database per applicare le modifiche al parametro `shared_preload_libraries`. Il completamento del riavvio iniziale potrebbe richiedere più tempo.

1. Quando l'istanza è disponibile, verificare che plrust sia stato inizializzato. Utilizzare `psql` per connettersi all'istanza database ed eseguire il comando riportato di seguito.

   ```
   SHOW shared_preload_libraries;
   ```

   L'aspetto dell'output sarà simile al seguente:

   ```
   shared_preload_libraries 
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

### AWS CLI
<a name="PL_Rust-setting-up-CLI"></a>

**Installare l'estensione plrust nel parametro shared\$1preload\$1libraries**

Eseguire i seguenti passaggi utilizzando un account membro del gruppo `rds_superuser` (ruolo).

1. Usa il [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) AWS CLI comando per aggiungere plrust al `shared_preload_libraries` parametro.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilizzate il [reboot-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/reboot-db-instance) AWS CLI comando per riavviare l'istanza DB e inizializzare la libreria plrust. Il completamento del riavvio iniziale potrebbe richiedere più tempo.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando l'istanza è disponibile, è possibile verificare se plrust è stato inizializzato. Utilizzare `psql` per connettersi all'istanza database ed eseguire il comando riportato di seguito.

   ```
   SHOW shared_preload_libraries;
   ```

   L'aspetto dell'output sarà simile al seguente:

   ```
   shared_preload_libraries
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

## Creazione di funzioni con PL/Rust
<a name="PL_Rust-create-function"></a>

PL/Rust compilerà la funzione come libreria dinamica, la caricherà e la eseguirà.

La seguente funzione Rust filtra i multipli da un array.

```
postgres=> CREATE LANGUAGE plrust;
CREATE EXTENSION
```

```
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[]
    IMMUTABLE STRICT
    LANGUAGE PLRUST AS
$$
    Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect()))
$$;
        
WITH gen_values AS (
SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr)
SELECT filter_multiples(arr, 3)
from gen_values;
```

## Utilizzo dei formati crate con PL/Rust
<a name="PL_Rust-crates"></a>

Nelle versioni 16.3-R2 e successive di RDS per PostgreSQL, 15.7-R2 e versioni successive 15, 14.12-R2 e 14 versioni successive e 13.15-R2 e 13 versioni successive, supporta casse aggiuntive: PL/Rust 
+ `url` 
+ `regex` 
+ `serde` 
+ `serde_json` 

Nelle versioni 15.5-R2 e successive di RDS per PostgreSQL, 14 versioni 14.10-R2 e successive e 13.13-R2 e versioni successive 13, supporta due casse aggiuntive: PL/Rust 
+ `croaring-rs` 
+ `num-bigint` 

A partire dalle versioni 15.4, 14.9 e 13.12 di Amazon RDS for PostgreSQL, supporta le seguenti casse: PL/Rust 
+ `aes` 
+ `ctr` 
+ `rand` 

Per questi formati sono supportate solo le funzionalità predefinite. Le nuove versioni di RDS per PostgreSQL potrebbero contenere versioni aggiornate di questi formati e le relative versioni precedenti potrebbero non essere più supportate.

Segui le best practice per eseguire un aggiornamento di una versione principale per verificare se le tue PL/Rust funzioni sono compatibili con la nuova versione principale. Per ulteriori informazioni, consulta il blog [Best practices for upgrading Amazon RDS to major and minor versions of PostgreSQL](https://aws.amazon.com/blogs/database/best-practices-for-upgrading-amazon-rds-to-major-and-minor-versions-of-postgresql/) (Best practice per l'aggiornamento di Amazon RDS alle versioni principali e secondarie di PostgreSQL) e [Aggiornamento del motore del database PostgreSQL per Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.PostgreSQL.html) nella Guida per l'utente Amazon RDS. 

Esempi di utilizzo delle dipendenze durante la creazione di una PL/Rust funzione sono disponibili in [Usa dipendenze](https://tcdi.github.io/plrust/use-plrust.html#use-dependencies).

## Limitazioni del linguaggio PL/Rust
<a name="PL_Rust-limitations"></a>

Per impostazione predefinita, gli utenti del database non possono utilizzarePL/Rust. To provide access to PL/Rust, connettersi come utente con il privilegio rds\$1superuser ed eseguire il comando seguente:

```
postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;
```

# Gestione dei dati spaziali con estensione PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS"></a>

PostGIS è un'estensione di PostgreSQL per l'archiviazione e la gestione delle informazioni spaziali. Per ulteriori informazioni su PostGIS, consulta [PostGIS.net](https://postgis.net/). 

A partire dalla versione 10.5, PostgreSQL supporta la libreria libprotobuf 1.3.0 utilizzata da PostGIS per lavorare con i dati delle tile vettoriali delle mappe.

La configurazione dell'estensione PostGIS richiede i privilegi `rds_superuser`. Ti consigliamo di creare un utente (ruolo) per gestire l'estensione PostGIS e i dati spaziali. L'estensione PostGIS e i relativi componenti aggiungono migliaia di funzioni a PostgreSQL. Considera la possibilità di creare l'estensione PostGIS nel proprio schema se ciò ha senso per il tuo caso d'uso. ‭Nell'esempio seguente viene illustrato come installare l'estensione nel proprio database, ma questa operazione non è necessaria.

**Topics**
+ [

## Passaggio 1: Creazione di un utente (ruolo) per gestire l'estensione PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect)
+ [

## Passaggio 2: Caricamento delle estensioni di PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions)
+ [

## Fase 3: trasferimento della proprietà degli schemi di estensione
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership)
+ [

## Fase 4: Trasferimento della proprietà delle tabelle PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects)
+ [

## Passaggio 5: Verificare le estensioni
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test)
+ [

## Passaggio 6: Aggiornamento dell'estensione PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)
+ [Versioni dell’estensione PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS)
+ [Aggiornamento di PostGIS 2 a PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)

## Passaggio 1: Creazione di un utente (ruolo) per gestire l'estensione PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect"></a>

Per prima cosa, esegui la connessione a un'istanza database RDS per PostgreSQL come utente con i privilegi `rds_superuser`. Se hai mantenuto il nome di default durante la configurazione dell'istanza, esegui la connessione come `postgres`. 

```
psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
```

Crea un ruolo separato (utente) per amministrare l'estensione PostGIS.

```
postgres=>  CREATE ROLE gis_admin LOGIN PASSWORD 'change_me';
CREATE ROLE
```

Concedi a questo ruolo i privilegi `rds_superuser` per consentire l'installazione dell'estensione.

```
postgres=> GRANT rds_superuser TO gis_admin;
GRANT
```

Crea un database da utilizzare per gli artefatti PostGIS. Questa fase è facoltativa. In alternativa, puoi creare uno schema nel database utente per le estensioni PostGIS, ma anche questa operazione non è necessaria.

```
postgres=> CREATE DATABASE lab_gis;
CREATE DATABASE
```

Concedi a `gis_admin` tutti i privilegi per il database `lab_gis`.

```
postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_gis TO gis_admin;
GRANT
```

Esci dalla sessione ed esegui nuovamente la connessione all'istanza database RDS per PostgreSQL come `gis_admin`.

```
postgres=> psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=gis_admin --password --dbname=lab_gis
Password for user gis_admin:...
lab_gis=>
```

Continua a configurare l'estensione come descritto nei passaggi successivi.

## Passaggio 2: Caricamento delle estensioni di PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions"></a>

L'estensione PostGIS include diverse estensioni correlate che interagiscono per fornire funzionalità geospaziali. A seconda del caso d'uso, è possibile che le estensioni create in questo passaggio non siano tutte necessarie. 

Utilizzare `CREATE EXTENSION` le istruzioni per caricare le estensioni PostGIS. 

```
CREATE EXTENSION postgis;
CREATE EXTENSION
CREATE EXTENSION postgis_raster;
CREATE EXTENSION
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION
CREATE EXTENSION postgis_topology;
CREATE EXTENSION
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION
```

È possibile verificare i risultati eseguendo la query SQL mostrata nel seguente esempio, che elenca le estensioni e i relativi proprietari. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;
List of schemas
     Name     |   Owner
--------------+-----------
 public       | postgres
 tiger        | rdsadmin
 tiger_data   | rdsadmin
 topology     | rdsadmin
(4 rows)
```

## Fase 3: trasferimento della proprietà degli schemi di estensione
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership"></a>

Usare le istruzioni ALTER SCHEMA per trasferire la proprietà degli schemi al ruolo `gis_admin`.

```
ALTER SCHEMA tiger OWNER TO gis_admin;
ALTER SCHEMA
ALTER SCHEMA tiger_data OWNER TO gis_admin; 
ALTER SCHEMA
ALTER SCHEMA topology OWNER TO gis_admin;
ALTER SCHEMA
```

È possibile confermare la modifica della proprietà eseguendo la seguente query SQL. Oppure è possibile utilizzare il meta-comando `\dn` dalla riga di comando psql. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;

       List of schemas
     Name     |     Owner
--------------+---------------
 public       | postgres
 tiger        | gis_admin
 tiger_data   | gis_admin
 topology     | gis_admin
(4 rows)
```

## Fase 4: Trasferimento della proprietà delle tabelle PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects"></a>

**Nota**  
Non modificare la proprietà delle funzioni PostGIS. Il corretto funzionamento e i futuri aggiornamenti di PostGIS richiedono che queste funzioni mantengano la proprietà originale. Per ulteriori informazioni sulle autorizzazioni PostGIS, consulta [PostgreSQL Security](https://postgis.net/workshops/postgis-intro/security.html).

Utilizza la funzione seguente per trasferire la proprietà delle tabelle PostGIS al ruolo `gis_admin`. Eseguire la seguente istruzione dal prompt di psql per creare la funzione.

```
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
CREATE FUNCTION
```

Successivamente, eseguire la seguente query per eseguire la funzione `exec` che a sua volta esegue le istruzioni e altera le autorizzazioni.

```
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO gis_admin;')
  FROM (
    SELECT nspname, relname
    FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
    WHERE nspname in ('tiger','topology') AND
    relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
```

## Passaggio 5: Verificare le estensioni
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test"></a>

Per evitare di dover specificare il nome dello schema, aggiungi lo schema `tiger` al percorso di ricerca usando il seguente comando.

```
SET search_path=public,tiger;
SET
```

Verifica lo schema `tiger` usando la seguente istruzione SELECT.

```
SELECT address, streetname, streettypeabbrev, zip
 FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;
address | streetname | streettypeabbrev |  zip
---------+------------+------------------+-------
       1 | Devonshire | Pl               | 02109
(1 row)
```

Per ulteriori informazioni su questa estensione, consulta [Tiger Geocoder](https://postgis.net/docs/Extras.html#Tiger_Geocoder) nella documentazione di PostGIS. 

Verifica lo schema `topology` usando la seguente istruzione `SELECT`. Questa richiama la funzione `createtopology` per registrare un nuovo oggetto topologia (my\$1new\$1topo) con l'identificatore di riferimento spaziale specificato (26986) e la tolleranza predefinita (0,5). Per saperne di più, consulta la [CreateTopology](https://postgis.net/docs/CreateTopology.html)documentazione di PostGIS. 

```
SELECT topology.createtopology('my_new_topo',26986,0.5);
 createtopology
----------------
              1
(1 row)
```

## Passaggio 6: Aggiornamento dell'estensione PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update"></a>

Ogni nuova versione di PostgreSQL supporta una o più versioni dell'estensione PostGIS compatibili con tale versione. L'aggiornamento del motore PostgreSQL a una nuova versione non aggiorna automaticamente l'estensione PostGIS. Prima di aggiornare il motore PostgreSQL, in genere si aggiorna PostGIS alla versione più recente disponibile per la versione di PostgreSQL corrente. Per informazioni dettagliate, vedi [Versioni dell’estensione PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS). 

Dopo l'aggiornamento del motore PostgreSQL, si aggiorna nuovamente l'estensione PostGIS alla versione supportata per la versione del motore PostgreSQL aggiornata. Per ulteriori informazioni sull'aggiornamento del motore PostgreSQL, consulta [Come eseguire l’aggiornamento a una versione principale per RDS per PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

Puoi verificare la disponibilità di aggiornamenti della versione dell'estensione PostGIS sull'istanza database RDS per PostgreSQL in qualsiasi momento. Per farlo, esegui il comando seguente. Questa funzione è disponibile con PostGIS 2.5.0 e versioni successive.

```
SELECT postGIS_extensions_upgrade();
```

Se l'applicazione non supporta la versione più recente di PostGIS, puoi installare una versione precedente di PostGIS disponibile nella versione principale, come indicato di seguito.

```
CREATE EXTENSION postgis VERSION "2.5.5";
```

Se desideri eseguire l'aggiornamento a una versione PostGIS specifica da una versione precedente, puoi anche utilizzare il seguente comando.

```
ALTER EXTENSION postgis UPDATE TO "2.5.5";
```

A seconda della versione da cui si esegue l'aggiornamento, potrebbe essere necessario utilizzare nuovamente questa funzione. Il risultato della prima esecuzione della funzione determina se è necessaria una funzione di aggiornamento aggiuntiva. Ad esempio, questo si verifica per l'aggiornamento da PostGIS 2 a PostGIS 3. Per ulteriori informazioni, consulta [Aggiornamento di PostGIS 2 a PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3).

Se l'estensione è stata aggiornata in preparazione a un aggiornamento della versione principale del motore PostgreSQL, puoi continuare con altre attività preliminari. Per ulteriori informazioni, consulta [Come eseguire l’aggiornamento a una versione principale per RDS per PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

## Versioni dell’estensione PostGIS
<a name="CHAP_PostgreSQL.Extensions.PostGIS"></a>

Ti consigliamo di installare le versioni di tutte le estensioni, ad esempio PostGIS, come elencato in [Versioni delle estensioni per Amazon RDS per PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) nelle *Note di rilascio di Amazon RDS per PostgreSQL.* Per ottenere un elenco delle versioni disponibili nella versione, utilizza il comando seguente.

```
SELECT * FROM pg_available_extension_versions WHERE name='postgis';
```

Puoi trovare le informazioni sulle versioni nelle sezioni seguenti delle *Note di rilascio di Amazon RDS per PostgreSQL*:
+ [Estensioni di PostgreSQL versione 16 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-16x)
+ [Estensioni di PostgreSQL versione 15 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-15x)
+ [Estensioni di PostgreSQL versione 14 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-14x)
+ [Estensioni di PostgreSQL versione 13 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-13x)
+ [Estensioni di PostgreSQL versione 12 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-12x)
+ [Estensioni di PostgreSQL versione 11 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-11x)
+ [Estensioni di PostgreSQL versione 10 supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-101x)
+ [Estensioni di PostgreSQL versione 9.6.x supportate su Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-96x)

## Aggiornamento di PostGIS 2 a PostGIS 3
<a name="PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3"></a>

A partire dalla versione 3.0, la funzionalità raster di PostGIS è ora un'estensione separata, `postgis_raster`. Questa estensione dispone di un proprio percorso di installazione e aggiornamento. Ciò rimuove dall'estensione `postgis` core dozzine di funzioni, tipi di dati e altri artefatti necessari per l'elaborazione di immagini raster. Ciò significa che se il caso d'uso non richiede l'elaborazione raster, non è necessario installare l'estensione `postgis_raster`.

Nel seguente esempio di aggiornamento, il primo comando di aggiornamento estrae la funzionalità raster nell'estensione `postgis_raster`. È quindi necessario un secondo comando di aggiornamento per eseguire l'aggiornamento di `postgis_raster` alla nuova versione.

**Per eseguire l'aggiornamento da PostGIS 2 a PostGIS 3**

1. Identifica la versione predefinita di PostGIS disponibile per la versione PostgreSQL sul l’istanza database RDS per PostgreSQL. A questo scopo, esegui la query seguente.

   ```
   SELECT * FROM pg_available_extensions
       WHERE default_version > installed_version;
     name   | default_version | installed_version |                          comment
   ---------+-----------------+-------------------+------------------------------------------------------------
    postgis | 3.1.4           | 2.3.7             | PostGIS geometry and geography spatial types and functions
   (1 row)
   ```

1. Identifica le versioni di PostGIS installate in ogni database sull'istanza database RDS per PostgreSQL. In altre parole, esegui la query su ogni database utente come riportato di seguito.

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
       AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
     Name   | Version | Schema |                             Description
   ---------+---------+--------+---------------------------------------------------------------------
    postgis | 2.3.7   | public | PostGIS geometry, geography, and raster spatial types and functions
   (1 row)
   ```

   Questa discrepanza tra la versione predefinita (PostGIS 3.1.4) e la versione installata (PostGIS 2.3.7) indica che è necessario aggiornare l'estensione PostGIS.

   ```
   ALTER EXTENSION postgis UPDATE;
   ALTER EXTENSION
   WARNING: unpackaging raster
   WARNING: PostGIS Raster functionality has been unpackaged
   ```

1. Esegui la seguente query per verificare che la funzionalità raster sia ora contenuta nel proprio pacchetto.

   ```
   SELECT
       probin,
       count(*)
   FROM
       pg_proc
   WHERE
       probin LIKE '%postgis%'
   GROUP BY
       probin;
             probin          | count
   --------------------------+-------
    $libdir/rtpostgis-2.3    | 107
    $libdir/postgis-3        | 487
   (2 rows)
   ```

   L'output mostra che c'è ancora una differenza tra le versioni. Le funzioni PostGIS sono versione 3 (postgis-3), mentre le funzioni raster (rtpostgis) sono versione 2 (rtpostgis-2.3). Per completare l'aggiornamento, esegui nuovamente il comando di aggiornamento, come riportato di seguito.

   ```
   postgres=> SELECT postgis_extensions_upgrade();
   ```

   Puoi ignorare i messaggi di avviso in sicurezza. Esegui nuovamente la seguente query per verificare che l'aggiornamento sia stato completato. L'aggiornamento è completato quando PostGIS e tutte le estensioni correlate non sono contrassegnate come necessarie di aggiornamento. 

   ```
   SELECT postgis_full_version();
   ```

1. Utilizza la seguente query per visualizzare il processo di aggiornamento completato e le estensioni impacchettate separatamente e verifica che le relative versioni corrispondano. 

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
           AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
         Name      | Version | Schema |                             Description
   ----------------+---------+--------+---------------------------------------------------------------------
    postgis        | 3.1.5   | public | PostGIS geometry, geography, and raster spatial types and functions
    postgis_raster | 3.1.5   | public | PostGIS raster types and functions
   (2 rows)
   ```

   L'output mostra che l'estensione PostGIS 2 è stata aggiornata a PostGIS 3 e che `postgis` e l'estensione `postgis_raster` ora separata sono entrambe versione 3.1.5.

Al termine dell'aggiornamento, se non prevedi di utilizzare la funzionalità raster, puoi rimuovere l'estensione come segue.

```
DROP EXTENSION postgis_raster;
```