Gestire la conservazione dei dati con TTL

Questa pagina spiega come utilizzare la durata (TTL) nelle tabelle Spanner. Per approfondire, consulta la sezione Informazioni sul TTL.

Prima di iniziare

Prima di iniziare, segui queste best practice.

Abilita il backup e il recupero point-in-time

Prima di aggiungere TTL alla tabella, ti consigliamo di attivare il backup e il ripristino di Spanner. In questo modo, puoi ripristinare completamente un database nel caso in cui elimini accidentalmente i dati con la norma TTL.

Se hai attivato il recupero in un determinato momento, puoi visualizzare e ripristinare i dati eliminati, senza un ripristino completo dal backup, se rientrano nel periodo di conservazione della versione configurato. Per informazioni sulla lettura dei dati passati, consulta Eseguire una lettura non aggiornata.

Eliminare i dati vecchi

Se è la prima volta che utilizzi TTL e prevedi che la prima esecuzione elimini molte righe, ti consigliamo di ripulire prima i vecchi dati manualmente utilizzando la DML partizionata. In questo modo hai un maggiore controllo sull'utilizzo delle risorse, anziché lasciarlo al processo in background TTL. TTL viene eseguito con una priorità bassa, ideale per la pulizia incrementale. Tuttavia, è probabile che il tempo necessario per eliminare l'insieme iniziale di righe in un database occupato aumenti perché lo schedulatore dei lavori interno di Spanner darà la priorità ad altri lavori, come le query degli utenti.

Verifica le condizioni

Per le tabelle GoogleSQL, se vuoi verificare i dati a cui si applicherà il criterio di eliminazione delle righe prima di attivare il TTL, puoi eseguire query sulla tabella utilizzando le stesse condizioni. Ad esempio:

GoogleSQL

  SELECT COUNT(*)
  FROM CalculatedRoutes
  WHERE TIMESTAMP_ADD(CreatedAt, INTERVAL 30 DAY) < CURRENT_TIMESTAMP();

Autorizzazioni obbligatorie

Per modificare lo schema del database, devi disporre dell'autorizzazione spanner.databases.updateDdl. Per maggiori dettagli, consulta Controllo dell'accesso per Spanner.

Crea un criterio di eliminazione delle righe

GoogleSQL

Per creare un criterio di eliminazione delle righe utilizzando GoogleSQL, puoi definire una clausola ROW DELETION POLICY quando crei una nuova tabella o aggiungere un criterio a una tabella esistente. Questa clausola contiene un'espressione di una colonna e un intervallo.

Per aggiungere un criterio al momento della creazione della tabella:

CREATE TABLE MyTable(
Key INT64,
CreatedAt TIMESTAMP,
) PRIMARY KEY (Key),
ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

Dove:

  • timestamp_column deve essere una colonna esistente con tipo TIMESTAMP. Le colonne con timestamp dei commit sono valide, così come le colonne generate. Tuttavia, non puoi specificare una colonna generata che fa riferimento a una colonna timestamp del commit.

  • num_days è il numero di giorni trascorsi dal timestamp in timestamp_column in cui la riga è contrassegnata per la eliminazione. Il valore deve essere un numero intero non negativo e DAY è l'unica unità supportata.

Per aggiungere un criterio a una tabella esistente, utilizza l'istruzione ALTER TABLE. Una tabella può avere al massimo un criterio di eliminazione delle righe. L'aggiunta di un criterio di eliminazione delle righe a una tabella con un criterio esistente non va a buon fine a causa di un errore. Consulta TTL nelle colonne generate per specificare una logica di eliminazione delle righe più evoluta.

ALTER TABLE Albums
ADD ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

PostgreSQL

Per creare un criterio di eliminazione delle righe utilizzando PostgreSQL, puoi definire una clausola TTL INTERVAL quando crei una nuova tabella o aggiungere un criterio a una tabella esistente.

Per aggiungere un criterio al momento della creazione della tabella:

CREATE TABLE mytable (
  key bigint NOT NULL,
  timestamp_column_name TIMESTAMPTZ,
  PRIMARY KEY(key)
) TTL INTERVAL interval_spec ON timestamp_column_name;

Dove:

  • timestamp_column_name deve essere una colonna con tipo di dati TIMESTAMPTZ. Devi creare questa colonna nell'istruzione CREATE TABLE. Le colonne con timestamp dei commit sono valide, così come le colonne generate. Tuttavia, non puoi specificare una colonna generata che fa riferimento a una colonna timestamp del commit.

  • interval_spec è il numero di giorni trascorsi dal timestamp in timestamp_column_name in cui la riga è contrassegnata per la eliminazione. Il valore deve essere un numero intero non negativo e deve essere valutato come un numero intero di giorni. Ad esempio, '3 days' è consentito, ma '3 days - 2 minutes' restituisce un errore.

Per aggiungere un criterio a una tabella esistente, utilizza l'istruzione ALTER TABLE. Una tabella può avere al massimo un criterio TTL. L'aggiunta di un criterio TTL a una tabella con un criterio esistente non va a buon fine e viene visualizzato un errore. Consulta TTL nelle colonne generate per specificare una logica TTL più sofisticata.

Per aggiungere un criterio a una tabella esistente:

ALTER TABLE albums
ADD COLUMN timestampcolumn TIMESTAMPTZ;

ALTER TABLE albums
ADD TTL INTERVAL '5 days' ON timestampcolumn;

Limitazioni

I criteri di eliminazione delle righe presentano le seguenti limitazioni.

TTL nelle tabelle a cui fa riferimento una chiave esterna

Non puoi creare un criterio di eliminazione delle righe:

  • In una tabella a cui fa riferimento una chiave esterna che non include la condizione di riga ON DELETE CASCADE.
  • Nella tabella principale a cui fa riferimento una chiave esterna che non include l'azione di referenza ON DELETE CASCADE.

Nell'esempio seguente, non puoi aggiungere un criterio di eliminazione delle righe alla tabella Customers perché viene fatto riferimento a una chiave esterna nella tabella Orders, che non ha la clausola ON DELETE CASCADE. L'eliminazione dei clienti potrebbe violare questa limitazione della chiave esterna. Inoltre, non puoi aggiungere una norma di eliminazione delle righe alla tabella Districts. L'eliminazione di una riga da Districts potrebbe causare eliminazioni in cascata nella tabella figlio Customers, il che potrebbe violare il vincolo della chiave esterna nella tabella Orders.

GoogleSQL

CREATE TABLE Districts (
  DistrictID INT64
) PRIMARY KEY (DistrictID);

CREATE TABLE Customers (
  DistrictID INT64,
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE;

CREATE TABLE Orders (
  OrderID INT64,
  DistrictID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID)
) PRIMARY KEY (OrderID);

PostgreSQL

CREATE TABLE districts (
  districtid   bigint NOT NULL,
  PRIMARY KEY(districtid)
);

CREATE TABLE customers (
  districtid   bigint NOT NULL,
  customerid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE;

CREATE TABLE orders (
  orderid bigint NOT NULL,
  districtid   bigint,
  customerid bigint,
  PRIMARY KEY(orderid),
  CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid)
);

Puoi creare un criterio di eliminazione delle righe in una tabella a cui fa riferimento un vincolo di chiave esterna che utilizza ON DELETE CASCADE. Nell'esempio seguente, puoi creare un criterio di eliminazione delle righe nella tabella Customers a cui fa riferimento la limitazione della chiave esterna CustomerOrder, definita nella tabella Orders. Quando il TTL elimina le righe in Customers, l'eliminazione si applica alle righe corrispondenti nella tabella Orders.

GoogleSQL

 CREATE TABLE Districts (
  DistrictID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID),
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));

CREATE TABLE Customers (
  DistrictID INT64,
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE,
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));

CREATE TABLE Orders (
  OrderID INT64,
  DistrictID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID) ON DELETE CASCADE
) PRIMARY KEY (OrderID);

PostgreSQL

CREATE TABLE districts (
  districtid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid)
) TTL INTERVAL '1 day' ON createdat;

CREATE TABLE customers (
  districtid   bigint NOT NULL,
  customerid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE
TTL INTERVAL '1 day' ON createdat;

CREATE TABLE orders (
  orderid bigint NOT NULL,
  districtid bigint,
  customerid bigint,
  PRIMARY KEY(orderid),
  CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid) ON DELETE CASCADE
);

Analogamente, puoi creare un criterio di eliminazione delle righe in una tabella principale a cui viene fatto riferimento da un vincolo di chiave esterna ON DELETE CASCADE.

TTL nelle colonne con valori predefiniti

Un criterio di eliminazione delle righe può utilizzare una colonna di timestamp con un valore predefinito. Un valore predefinito tipico è CURRENT_TIMESTAMP. Se non viene assegnato esplicitamente alcun valore alla colonna o se la colonna è impostata sul valore predefinito da un'istruzione INSERT o UPDATE, nel calcolo della regola viene utilizzato il valore predefinito.

Nell'esempio seguente, il valore predefinito per la colonna CreatedAt nella tabella Customers è il timestamp in cui viene creata la riga.

GoogleSQL

CREATE TABLE Customers (
  CustomerID INT64,
  CreatedAt TIMESTAMP DEFAULT (CURRENT_TIMESTAMP())
) PRIMARY KEY (CustomerID);

Per ulteriori informazioni, consulta VALORE_IMPLICITO (espressione) nel "linguaggio di definizione dei dati GoogleSQL".

PostgreSQL

CREATE TABLE customers (
  customerid bigint NOT NULL,
  createdat timestamptz DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY(customerid)
  );

Per ulteriori informazioni, consulta CREATE TABLE in "PostgreSQL Data Definition Language".

TTL nelle colonne generate

I criteri di eliminazione delle righe possono utilizzare le colonne generate per esprimere regole più sofisticate. Ad esempio, puoi definire un criterio di eliminazione delle righe in base al timestamp greatest (GoogleSQL o PostgreSQL) di più colonne o mappare un altro valore a un timestamp.

GoogleSQL

La tabella seguente denominata Orders monitora gli ordini di vendita. Il proprietario della tabella vuole configurare un criterio di eliminazione delle righe che elimini gli ordini annullati dopo 30 giorni e gli ordini non annullati dopo 180 giorni.

TTL di Spanner consente un solo criterio di eliminazione delle righe per tabella. Per esprimere i due criteri in una singola colonna, puoi utilizzare una colonna generata con un'istruzione IF:

CREATE TABLE Orders (
  OrderId INT64 NOT NULL,
  OrderStatus STRING(30) NOT NULL,
  LastModifiedDate TIMESTAMP NOT NULL,
  ExpiredDate TIMESTAMP AS (IF(OrderStatus = 'Cancelled',
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 30 DAY),
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 180 DAY))) STORED,
) PRIMARY KEY(OrderId),
ROW DELETION POLICY (OLDER_THAN(ExpiredDate, INTERVAL 0 DAY));

L'istruzione crea una colonna denominata ExpiredDate che aggiunge 30 o 180 giorni a LastModifiedDate a seconda dello stato dell'ordine. Poi, definisce il criterio di eliminazione delle righe per far scadere le righe il giorno memorizzato nella colonna ExpiredDate specificando INTERVAL 0 day.

PostgreSQL

La tabella seguente denominata Orders monitora gli ordini di vendita. Il proprietario della tabella vuole configurare un criterio di eliminazione delle righe che elimini le righe dopo 30 giorni di inattività.

TTL di Spanner consente un solo criterio di eliminazione delle righe per tabella. Per esprimere i due criteri in una singola colonna, puoi creare una colonna generata:

CREATE TABLE orders (
    orderid bigint NOT NULL,
    orderstatus varchar(30) NOT NULL,
    createdate timestamptz NOT NULL,
    lastmodifieddate timestamptz,
    expireddate timestamptz GENERATED ALWAYS AS (GREATEST(createdate, lastmodifieddate)) STORED,
    PRIMARY KEY(orderid)
) TTL INTERVAL '30 days' ON expireddate;

L'istruzione crea una colonna generata denominata ExpiredDate che valuta la data più recente delle due (LastModifiedDate o CreateDate). Poi, definisce il criterio di eliminazione delle righe in modo che le righe scadano 30 giorni dopo la creazione dell'ordine oppure, se l'ordine è stato modificato entro questi 30 giorni, prolungherà l'eliminazione di altri 30 giorni.

TTL e tabelle con interfoliazione

Le tabelle con interfoliazione sono un'ottimizzazione del rendimento che associa righe correlate in una tabella figlia con una riga in una tabella principale. Per aggiungere un criterio di eliminazione delle righe in una tabella principale, tutte le tabelle secondarie interlacciate devono specificare ON DELETE CASCADE, il che significa che le righe secondarie verranno eliminate in modo atomico con la riga principale. In questo modo viene garantita l'integrità referenziale, in modo che le eliminazioni nella tabella principale eliminino anche le righe figlio correlate nella stessa transazione. Il TTL di Spanner non supporta ON DELETE NO ACTION.

Dimensioni massime della transazione

Spanner ha un limite di dimensioni delle transazioni. Le eliminazioni in cascata in gerarchie principali-secondarie di grandi dimensioni con colonne indicizzate potrebbero superare questi limiti e causare il fallimento di una o più operazioni TTL. Per le operazioni non riuscite, TTL riproverà con batch più piccoli, fino a una singola riga principale. Tuttavia, gerarchie secondarie di grandi dimensioni anche per una singola riga principale potrebbero comunque superare il limite di mutazioni.

Le operazioni non riuscite vengono registrate nelle metriche TTL.

Se una singola riga e le relative righe secondarie interlacciate sono troppo grandi per essere eliminate, puoi collegare un criterio di eliminazione delle righe direttamente alle tabelle secondarie, oltre a quello nella tabella principale. Il criterio per le tabelle secondarie deve essere configurato in modo che le righe secondarie vengano eliminate prima delle righe principali.

Valuta la possibilità di associare un criterio di eliminazione delle righe alle tabelle secondarie quando si applicano le due seguenti affermazioni:

  • La tabella secondaria ha eventuali indici globali associati; e
  • Prevedi un numero elevato (> 100) di righe secondarie per riga principale.

Eliminare un criterio di eliminazione delle righe

Puoi eliminare un criterio di eliminazione delle righe esistente da una tabella. Viene restituito un errore se nella tabella non esiste un criterio di eliminazione delle righe.

GoogleSQL

ALTER TABLE MyTable
DROP ROW DELETION POLICY;

PostgreSQL

ALTER TABLE mytable
DROP TTL;

L'eliminazione di un criterio di eliminazione delle righe interrompe immediatamente tutti i processi TTL in esecuzione in background. Le righe già eliminate dalle procedure in corso rimangono eliminate.

Eliminare una colonna a cui fa riferimento un criterio di eliminazione delle righe

Spanner non ti consente di eliminare una colonna a cui fa riferimento un criterio di eliminazione delle righe. Prima di eliminare la colonna, devi eliminare il criterio di eliminazione delle righe.

Visualizzare il criterio di eliminazione delle righe di una tabella

Puoi visualizzare i criteri di eliminazione delle righe delle tabelle Spanner.

GoogleSQL

SELECT TABLE_NAME, ROW_DELETION_POLICY_EXPRESSION
FROM INFORMATION_SCHEMA.TABLES
WHERE ROW_DELETION_POLICY_EXPRESSION IS NOT NULL;

Per ulteriori informazioni, consulta Schema di informazioni per i database in dialetto GoogleSQL.

PostgreSQL

SELECT table_name, row_deletion_policy_expression
FROM information_schema.tables
WHERE row_deletion_policy_expression is not null;

Per ulteriori informazioni, consulta Schema di informazioni per i database in dialetto PostgreSQL.

Modificare un criterio di eliminazione delle righe

Puoi modificare la colonna o l'espressione dell'intervallo di un criterio di eliminazione delle righe esistente. L'esempio seguente passa dalla colonna CreatedAt a ModifiedAt ed estende l'intervallo da 1 DAY a 7 DAY. Viene restituito un errore se non esiste un criterio di eliminazione delle righe nella tabella.

GoogleSQL

ALTER TABLE MyTable
REPLACE ROW DELETION POLICY (OLDER_THAN(ModifiedAt, INTERVAL 7 DAY));

PostgreSQL

ALTER TABLE mytable
ALTER TTL INTERVAL '7 days' ON timestampcolumn;