Cet article explique comment écrire un code temporel de commit pour chaque insertion et mise à jour
que vous effectuez avec Spanner. Pour utiliser cette fonctionnalité, définissez l'option allow_commit_timestamp
sur une colonne TIMESTAMP
, puis écrivez l'horodatage dans le cadre de chaque transaction.
Présentation
L'horodatage de commit, basé sur la technologie TrueTime, est l'heure à laquelle une transaction est reçue dans la base de données. L'option de colonne allow_commit_timestamp
permet de stocker de manière atomique l'horodatage de commit dans une colonne.
À l'aide des horodatages de commit stockés dans les tables, vous pouvez déterminer l'ordre exact des mutations et créer des fonctionnalités telles que les journaux des modifications.
Pour insérer des horodatages de commit dans votre base de données, procédez comme suit :
Créez une colonne de type
TIMESTAMP
avec l'option de colonneallow_commit_timestamp
définie surtrue
dans la définition de schéma. Exemple :CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Si vous effectuez des insertions ou des mises à jour en langage LMD, utilisez la fonction
PENDING_COMMIT_TIMESTAMP
pour écrire l'horodatage de commit.Si vous effectuez des insertions ou des mises à jour avec des mutations, Utilisez la chaîne d'espace réservé
spanner.commit_timestamp()
sur les insertions ou les mises à jour de votre commit code temporel. Vous pouvez également utiliser la constante de code temporel de validation fournie par la bibliothèque cliente. Par exemple, cette constante dans le client Java estValue.COMMIT_TIMESTAMP
.
Lorsque Spanner reçoit la transaction en utilisant ces espaces réservés comme valeurs de colonne, l'horodatage de commit réel est écrit dans la colonne spécifiée (par exemple, la colonne LastUpdateTime
). Vous pouvez ensuite utiliser cette valeur de colonne pour créer un historique des mises à jour de la table.
Le caractère unique des valeurs d'horodatage de commit n'est pas garanti. Les transactions qui écrivent dans des ensembles de champs ne se chevauchant pas peuvent avoir le même horodatage. Les transactions qui écrivent dans des ensembles de champs qui se chevauchent ont des horodatages uniques.
Les horodatages de commit Spanner sont d'une précision qui s'exprime en microsecondes et sont convertis en nanosecondes lorsqu'ils sont stockés dans des colonnes TIMESTAMP
.
Créer et supprimer une colonne d'horodatage de commit
Utilisez l'option de colonne allow_commit_timestamp
pour ajouter et supprimer la compatibilité avec les horodatages de commit :
- Lors de la création d'une table, pour spécifier qu'une colonne accepte les horodatages de commit.
- Lors de la modification d'une table existante :
- pour ajouter une nouvelle colonne acceptant les horodatages de commit ;
- pour modifier une colonne
TIMESTAMP
existante afin d'accepter les horodatages de commit ; - pour modifier une colonne
TIMESTAMP
existante afin de supprimer la compatibilité avec l'horodatage de commit.
Clés et index
Vous pouvez utiliser une colonne d'horodatage de commit en tant que colonne de clé primaire ou en tant que colonne non clé. Les clés primaires peuvent être définies comme ASC
ou DESC
.
ASC
(valeur par défaut) : les clés croissantes sont idéales pour répondre aux requêtes à partir d'une heure spécifique.DESC
: les clés décroissantes conservent les dernières lignes en haut de la table. Elles fournissent un accès rapide aux derniers enregistrements.
L'option allow_commit_timestamp
doit être cohérente entre les clés primaires des tables parents et enfants. Dans le cas contraire, Spanner renvoie une erreur. Le seul moment où l'option peut être incohérente est lorsque vous créez ou mettez à jour le schéma.
L'utilisation d'horodatages de commit dans les scénarios suivants engendre des problèmes de hotspotting et réduit les performances de traitement des données :
Colonne d'horodatage de commit en tant que première partie de la clé primaire d'une table :
CREATE TABLE Users ( LastAccess TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... ) PRIMARY KEY (LastAccess, UserId);
Première partie de la clé primaire d'un index secondaire :
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
ou
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Les hotspots réduisent les performances de traitement des données, même avec des vitesses d'écriture faibles. L'activation de l'horodatage de commit sur des colonnes non clés non indexées n'impacte pas les performances.
Créer une colonne d'horodatage de commit
Le LDD suivant crée une table avec une colonne compatible avec les horodatages de commit.
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE
L'ajout de l'option modifie la colonne d'horodatage comme suit :
- Vous pouvez utiliser la chaîne d'espace réservé
spanner.commit_timestamp()
(ou une constante fournie par la bibliothèque cliente) pour les insertions et les mises à jour. - La colonne ne peut contenir que des valeurs antérieures au moment actuel. Pour plus d'informations, consultez la section Fournir votre propre valeur pour la colonne d'horodatage.
L'option allow_commit_timestamp
est sensible à la casse.
Ajouter une colonne d'horodatage de commit à une table existante
Pour ajouter une colonne d'horodatage de commit à une table existante, utilisez l'instruction ALTER TABLE
. Par exemple, pour ajouter une colonne LastUpdateTime
à la table Performances
, utilisez l'instruction suivante :
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Convertir une colonne d'horodatage en une colonne d'horodatage de commit
Vous pouvez convertir une colonne d'horodatage existante en colonne d'horodatage de commit. Toutefois, pour ce faire, Spanner doit valider l'état les valeurs de code temporel sont passées. Exemple :
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=true)
Vous ne pouvez pas modifier le type de données ou l'annotation NULL
d'une colonne dans une instruction ALTER TABLE
incluant SET OPTIONS
. Pour plus d'informations, consultez la page Langage de définition de données.
Supprimer l'option d'horodatage de commit
Si vous souhaitez supprimer la compatibilité d'une colonne avec l'horodatage de commit, utilisez l'option allow_commit_timestamp=null
dans une instruction ALTER TABLE
. Le comportement lié à l'horodatage de commit est supprimé, mais la colonne reste toujours un horodatage. La modification de cette option n'altère pas les autres caractéristiques de la colonne, telles que le type ou l'option de valeur vide (NOT NULL
). Par exemple :
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Écrire un horodatage de commit à l'aide d'une instruction LMD
Pour écrire l'horodatage de commit dans une instruction LMD, utilisez la fonction PENDING_COMMIT_TIMESTAMP
. Spanner sélectionne le code temporel de commit lorsque la transaction
des commits.
L'instruction LMD suivante met à jour la colonne LastUpdateTime
dans le fichier
Table Performances
avec le code temporel de commit:
UPDATE Performances SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
L'exemple de code suivant utilise la fonction PENDING_COMMIT_TIMESTAMP
pour écrire l'horodatage de commit dans la colonne LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
Les horodatages de commit ne peuvent être écrits que dans des colonnes annotées avec l'option allow_commit_timestamp=true
.
Si des mutations sont présentes sur des lignes dans plusieurs tables, vous devez spécifier spanner.commit_timestamp()
(ou la constante de la bibliothèque cliente) pour la colonne d'horodatage de commit de chaque table.
Interroger une colonne d'horodatage de commit
L'exemple suivant interroge la colonne d'horodatage de commit de la table.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Indiquez votre propre valeur pour la colonne d'horodatage de commit
Vous pouvez fournir votre propre valeur pour la colonne d'horodatage de commit au lieu de transmettre spanner.commit_timestamp()
(ou la constante de la bibliothèque cliente) en tant que valeur de colonne. La valeur doit être un horodatage antérieur au moment actuel. Cette restriction garantit que l'écriture d'horodatages est une opération rapide et peu coûteuse. Le serveur
La fonction renvoie une erreur FailedPrecondition
si un horodatage futur est spécifié.
Créer un journal de modifications
Supposons que vous souhaitiez créer un journal des modifications pour chaque mutation qui se produit dans une table, puis l'utiliser pour un audit. Prenons l'exemple d'une table qui stocke l'historique des modifications apportées aux documents de traitement de texte. L'horodatage de commit facilite la création du journal des modifications, car les horodatages peuvent imposer le classement des modifications des entrées. Vous pouvez créer un journal des modifications qui stocke l'historique des modifications apportées à un document donné à l'aide d'un schéma semblable à l'exemple suivant :
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Contents STRING(MAX) NOT NULL,
) PRIMARY KEY (UserId, DocumentId);
CREATE TABLE DocumentHistory (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
Delta STRING(MAX),
) PRIMARY KEY (UserId, DocumentId, Ts),
INTERLEAVE IN PARENT Documents ON DELETE NO ACTION;
Pour créer un journal des modifications, insérez une nouvelle ligne dans la table DocumentHistory
, dans la même transaction que celle dans laquelle vous insérez ou mettez à jour une ligne dans la table Document
. Lors de l'insertion de la nouvelle ligne dans la table DocumentHistory
, utilisez l'espace réservé spanner.commit_timestamp()
(ou la constante de la bibliothèque cliente) pour indiquer à Spanner d'écrire l'horodatage de commit dans la colonne Ts
. Si vous entrelacez la table DocumentsHistory
avec la table Documents
, la localité des données, les insertions et les mises à jour seront plus efficaces. Cependant, ce procédé ajoute également une contrainte : les lignes parents et enfants doivent être supprimées ensemble. Pour garder les lignes dans la table DocumentHistory
après la suppression des lignes de la table Documents
, n'entrelacez pas les tables.
Optimiser les requêtes de données récentes avec des horodatages de commit
Les horodatages de commit permettent d'optimiser Spanner permet de réduire les E/S de requête lors de la récupération de données écrites après un en temps réel.
Pour activer cette optimisation, la clause WHERE
d'une requête doit inclure un
Comparaison entre la colonne d'horodatage de commit d'une table et une heure spécifique
que vous fournissez, avec les attributs suivants:
Indiquez l'heure spécifique en tant qu'expression constante: un littéral, une ou une fonction dont les arguments sont évalués sur des constantes.
Déterminez si l'horodatage de commit est plus récent que le code temporel à un moment donné, via les opérateurs
>
ou>=
.Vous pouvez également ajouter d'autres restrictions à la clause
WHERE
avecAND
. L'extension de la clause avecOR
disqualifie la requête de cette optimisation.
Prenons l'exemple de la table Performances
suivante, qui inclut une colonne d'horodatage de commit :
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate DATE,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate);
Cette requête bénéficie de l'optimisation de l'horodatage de validation décrite précédemment, car elle comporte une comparaison "supérieur ou égal à" entre la colonne d'horodatage de validation de la table et une expression constante (dans ce cas, un littéral) :
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
La requête suivante est également éligible à l'optimisation, car elle comporte une comparaison "supérieur à" entre le code temporel du commit et une fonction dont tous les arguments sont évalués à des constantes lors de l'exécution de la requête :
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
Étape suivante
- Utilisez les horodatages de commit pour créer un journal des modifications avec Go.