Statistiques de verrouillage

Spanner fournit des statistiques de verrouillage qui vous permettent d'identifier la clé de ligne et les colonnes de table qui étaient les principales sources de conflits de verrouillage des transactions dans votre base de données pendant une période donnée. Vous pouvez récupérer ces statistiques à partir des tables système SPANNER_SYS.LOCK_STATS* à l'aide d'instructions SQL.

Disponibilité

Les données SPANNER_SYS ne sont disponibles que via des interfaces SQL. Exemple :

Les autres méthodes de lecture unique fournies par Spanner ne sont pas compatibles avec SPANNER_SYS.

Verrouiller les statistiques par clé de ligne

Les tableaux ci-dessous suivent la clé de ligne présentant le temps d'attente le plus élevé :

  • SPANNER_SYS.LOCK_STATS_TOP_MINUTE: clés de ligne avec le temps d'attente de verrouillage le plus élevé pendant des intervalles d'une minute.

  • SPANNER_SYS.LOCK_STATS_TOP_10MINUTE : clés de ligne avec les temps d'attente de verrouillage les plus élevés pendant des intervalles de 10 minutes.

  • SPANNER_SYS.LOCK_STATS_TOP_HOUR : clés de ligne avec les temps d'attente de verrouillage les plus élevés pendant des intervalles d'une heure.

Ces tables ont les propriétés suivantes :

  • Chaque table contient des données pour des intervalles de temps sans chevauchement de la longueur spécifiée par le nom de la table.

  • Les intervalles sont définis selon l'heure réelle. Les intervalles d'une minute se terminent toutes les minutes, les intervalles de 10 minutes se terminent toutes les 10 minutes à partir de l'heure et les intervalles d'une heure se terminent toutes les heures. Après chaque intervalle, Spanner collecte les données de tous les serveurs, puis les met à disposition dans les tables SPANNER_SYS peu de temps après.

    Par exemple, à 11:59:30, les intervalles les plus récents disponibles pour les requêtes SQL sont les suivants :

    • 1 minute : 11:58:00 – 11:58:59
    • 10 minutes : 11:40:00 – 11:49:59
    • 1 heure : 10:00:00 – 10:59:59
  • Spanner regroupe les statistiques en commençant par une plage de clés de ligne.

  • Chaque ligne contient des statistiques sur le temps d'attente total de verrouillage d'une plage de clés de ligne de début particulière pour laquelle Spanner enregistre des statistiques pendant l'intervalle spécifié.

  • Si Spanner ne peut pas stocker d'informations sur chaque plage de clés de ligne pour les temps d'attente de verrouillage pendant l'intervalle, le système donne la priorité à la plage de clés de ligne ayant le temps d'attente de verrouillage le plus élevé au cours de l'intervalle spécifié.

Schéma de la table

Nom de la colonne Type Description
INTERVAL_END TIMESTAMP Fin de l'intervalle de temps au cours duquel les conflits de verrouillage inclus ont eu lieu.
ROW_RANGE_START_KEY BYTES(MAX) Clé de ligne où le conflit de verrouillage a eu lieu. Lorsque le conflit implique une plage de lignes, cette valeur représente la clé de départ de cette plage. Le signe plus (+) correspond à une plage. Pour plus d'informations, consultez la section Qu'est-ce qu'une clé de début de plage de lignes ?
LOCK_WAIT_SECONDS FLOAT64 Le temps d'attente de verrouillage cumulé des conflits de verrouillage enregistrés pour toutes les colonnes de la plage de clés de ligne est exprimé en secondes.
SAMPLE_LOCK_REQUESTS ARRAY<STRUCT<
  column STRING,
  lock_mode STRING,
   transaction_tag STRING>>
Chaque entrée de ce tableau correspond à un exemple de requête de verrouillage qui a contribué au conflit de verrouillage en attendant un verrou ou en empêchant d'autres transactions d'utiliser le verrou, sur la clé de ligne (plage) donnée. Le nombre maximal d'échantillons dans ce tableau est de 20.
Chaque exemple contient les trois champs suivants :
  • lock_mode : mode de verrouillage demandé. Pour en savoir plus, consultez la section Modes de verrouillage .
  • column : colonne ayant rencontré le conflit de verrouillage. Le format de cette valeur est tablename.columnname.
  • transaction_tag : tag de la transaction qui a émis la requête. Pour en savoir plus sur l'utilisation des tags, consultez la page Résoudre les problèmes liés aux tags de transaction.
Toutes les requêtes de verrouillage qui ont contribué à des conflits de verrouillage sont échantillonnées de manière uniforme et aléatoire. Il est donc possible que seule la moitié d'un conflit (le conteneur ou le service de veille) soit enregistrée dans ce tableau.

Modes de verrouillage

Les opérations Spanner acquièrent des verrous lorsqu'elles font partie d'une transaction en lecture/écriture. Les transactions en lecture seule n'acquièrent pas de verrou. Spanner utilise différents modes de verrouillage pour maximiser le nombre de transactions ayant accès à une cellule de données particulière à un moment donné. Les verrous présentent des caractéristiques différentes. Par exemple, certains verrous peuvent être partagés entre plusieurs transactions, tandis que d'autres ne le peuvent pas.

Un conflit de verrouillage peut se produire lorsque vous tentez d'acquérir l'un des modes de verrouillage suivants dans une transaction.

  • ReaderShared Verrou : verrou qui permet à d'autres lectures de continuer à accéder aux données jusqu'à ce que la transaction soit prête à être validée. Ce verrou partagé est acquis lorsqu'une transaction en lecture-écriture lit des données.

  • Verrou WriterShared : ce verrou est acquis lorsqu'une transaction en lecture-écriture tente de valider une écriture.

  • Verrou Exclusive : un verrou exclusif est acquis lorsqu'une transaction en lecture-écriture, qui a déjà acquis un verrou ReaderShared, tente d'écrire des données une fois la lecture terminée. Un verrouillage exclusif est une mise à niveau d'un verrou ReaderShared. Un verrou exclusif est un cas particulier d'une transaction contenant à la fois les verrous ReaderShared et WriterShared. Aucune autre transaction ne peut acquérir de verrou sur la même cellule.

  • Verrou WriterSharedTimestamp : type spécial de verrou WriterShared obtenu lors de l'insertion de nouvelles lignes dans une table dont la clé primaire contient un horodatage de commit. Ce type de verrouillage empêche les participants à la transaction de créer exactement la même ligne et, par conséquent, d'entrer en conflit. Spanner met à jour la clé de la ligne insérée pour qu'elle corresponde à l'horodatage de commit de la transaction qui a effectué l'insertion.

Pour plus d'informations sur les types de transactions et les types de verrous disponibles, consultez la page Transactions.

Conflits de mode de verrouillage

Le tableau suivant présente les conflits possibles entre les différents modes de verrouillage.

Modes de verrouillage ReaderShared WriterShared Exclusive WriterSharedTimestamp
ReaderShared Non Oui Oui Oui
WriterShared Oui Non Oui Non applicable
Exclusive Oui Oui Oui Non applicable
WriterSharedTimestamp Oui Non applicable Non applicable Oui

Les verrous WriterSharedTimestamp ne sont utilisés que lorsque vous insérez de nouvelles lignes dont la clé primaire contient un horodatage. Les verrous WriterShared et Exclusive sont utilisés lors de l'écriture dans des cellules existantes ou de l'insertion de nouvelles lignes sans horodatage. Par conséquent, WriterSharedTimestamp ne peut pas entrer en conflit avec d'autres types de verrous, et ces scénarios sont désignés comme Non applicables dans le tableau précédent.

La seule exception est ReaderShared, qui peut être appliqué aux lignes qui n'existent pas encore et peut donc entrer en conflit avec WriterSharedTimestamp. Par exemple, une analyse complète de la table verrouille l'intégralité de la table même pour les lignes qui n'ont pas été créées. Il est donc possible que ReaderShared entre en conflit avec WriterSharedTimestamp.

Qu'est-ce qu'une clé de début de plage de lignes ?

La colonne ROW_RANGE_START_KEY identifie la clé primaire composite, ou clé de départ d'une plage de lignes, qui présente des conflits de verrouillage. Le schéma suivant permet d'illustrer un exemple.

CREATE TABLE Singers (
  SingerId   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

CREATE TABLE Songs (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  TrackId      INT64 NOT NULL,
  SongName     STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId, TrackId),
  INTERLEAVE IN PARENT Albums ON DELETE CASCADE;

CREATE TABLE Users (
  UserId     INT64 NOT NULL,
  LastAccess TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
  ...
) PRIMARY KEY (UserId, LastAccess);

Comme le montre le tableau suivant qui regroupe des de clés de ligne et des plages de clés de ligne, une plage est représentée par un signe plus (+) dans la clé. Dans ce cas, la clé représente la clé de départ d'une plage de clés dans laquelle un conflit de verrouillage est survenu.

ROW_RANGE_START_KEY Explication
singers(2) Table "Singers" à la clé SingerId=2
albums(2,1) Table "Albums" à la clé SingerId=2, AlbumId=1
songs(2,1,5) Table "Songs" à la clé SingerId=2, AlbumId=1, trackId=5
songs(2,1,5+) Plage de clés de la table "Songs" commençant par SingerId=2, AlbumId=1, trackId=5
albums(2,1+) Plage de clés de la table "Albums" commençant par SingerId=2, AlbumId=1
users(3, 2020-11-01 12:34:56.426426+00:00) Table "Users" à la clé KeyId=3, LastAccess=commit_timestamp

Statistiques globales

SPANNER_SYS contient également des tables permettant de stocker les données globales des statistiques de verrouillage capturées par Spanner sur une période spécifique:

  • SPANNER_SYS.LOCK_STATS_TOTAL_MINUTE: statistiques agrégées pour tous les verrouillages pendant des intervalles d'une minute.

  • SPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE: statistiques globales pour tous les temps d'attente de verrouillage pendant des intervalles de 10 minutes.

  • SPANNER_SYS.LOCK_STATS_TOTAL_HOUR : statistiques globales pour tous les temps d'attente de verrouillage pendant des intervalles d'une heure.

Les tableaux de statistiques globales présentent les propriétés suivantes :

  • Chaque table contient des données pour des intervalles de temps sans chevauchement de la longueur spécifiée par le nom de la table.

  • Les intervalles sont définis selon l'heure réelle. Les intervalles d'une minute se terminent toutes les minutes, les intervalles de 10 minutes se terminent toutes les 10 minutes à partir de l'heure et les intervalles d'une heure se terminent toutes les heures.

    Par exemple, à 11:59:30, les intervalles les plus récents disponibles pour les requêtes SQL sur les statistiques de verrouillage globales sont les suivants :

    • 1 minute : 11:58:00 – 11:58:59
    • 10 minutes : 11:40:00 – 11:49:59
    • 1 heure : 10:00:00 – 10:59:59
  • Chaque ligne contient des statistiques agrégées relatives à toutes les attentes de verrouillage sur la base de données pendant l'intervalle spécifié. Il n'y a par conséquent qu'une seule ligne par intervalle de temps.

  • Les statistiques capturées dans les tables SPANNER_SYS.LOCK_STATS_TOTAL_* incluent les temps de verrouillage que Spanner n'a pas capturés dans les tables SPANNER_SYS.LOCK_STATS_TOP_*.

  • Certaines colonnes de ces tables sont exposées sous forme de métriques dans Cloud Monitoring. Les métriques exposées sont les suivantes:

    • Temps d'attente pour le verrouillage

    Pour en savoir plus, consultez la page Métriques Spanner.

Schéma de la table

Nom de la colonne Type Description
INTERVAL_END TIMESTAMP Fin de l'intervalle de temps au cours duquel le conflit de verrouillage s'est produit.
TOTAL_LOCK_WAIT_SECONDS FLOAT64 Temps d'attente total pour les conflits de verrouillage enregistrés pour l'ensemble de la base de données, en secondes.

Exemples de requêtes

Voici un exemple d'instruction SQL que vous pouvez utiliser pour récupérer des statistiques de verrouillage. Vous pouvez exécuter ces instructions SQL à l'aide des bibliothèques clientes, de gcloud spanner ou de la console Google Cloud.

Lister les statistiques de verrouillage pour l'intervalle d'une minute précédent

La requête suivante renvoie les informations d'attente de verrouillage pour chaque clé de ligne en conflit de verrouillage, en incluant la fraction du nombre total de conflits de verrouillage, au cours du dernier intervalle de temps d'une minute.

La fonction CAST() convertit le champ BYTES "row_range_start_key" en valeur de type STRING.

SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
       t.total_lock_wait_seconds,
       s.lock_wait_seconds,
       s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
       s.sample_lock_requests
FROM spanner_sys.lock_stats_total_minute t, spanner_sys.lock_stats_top_minute s
WHERE t.interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.lock_stats_total_minute)
AND s.interval_end = t.interval_end
ORDER BY s.lock_wait_seconds DESC;
Sortie de la requête
row_range_start_key total_lock_wait_seconds lock_wait_seconds frac_of_total sample_lock_requests
Songs(2,1,1) 2,37 1,76 0.7426 LOCK_MODE: ReaderShared

COLUMN: Singers.SingerInfo

LOCK_MODE: WriterShared

COLUMN: Singers.SingerInfo
Users(3, 2020-11-01 12:34:56.426426+00:00) 2,37 0.61 0.2573 LOCK_MODE: ReaderShared

COLUMN: users._exists1

LOCK_MODE: WriterShared

COLUMN: users._exists1

1 _exists est un champ interne utilisé pour vérifier si une ligne existe ou non.

Conservation des données

Spanner conserve au minimum les données de chaque table pour les périodes suivantes:

  • SPANNER_SYS.LOCK_STATS_TOP_MINUTE et SPANNER_SYS.LOCK_STATS_TOTAL_MINUTE : intervalles couvrant les six heures précédentes

  • SPANNER_SYS.LOCK_STATS_TOP_10MINUTE et SPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE : intervalles couvrant les quatre derniers jours.

  • SPANNER_SYS.LOCK_STATS_TOP_HOUR et SPANNER_SYS.LOCK_STATS_TOTAL_HOUR : intervalles couvrant les 30 derniers jours

Résoudre les conflits de verrouillage dans votre base de données à l'aide des statistiques de verrouillage

Vous pouvez utiliser SQL ou le tableau de bord Lock insights pour afficher les conflits de verrouillage dans votre base de données.

Les rubriques suivantes expliquent comment examiner ces conflits de verrouillage à l'aide du code SQL.

Sélectionnez une période à examiner

Vous examinez les métriques de latence de votre base de données Spanner et découvrez une période au cours de laquelle votre application rencontre une latence et une utilisation du processeur élevées. Par exemple, le problème a commencé vers 22h50 le 12 novembre 2020.

Déterminer si la latence du commit des transactions a augmenté en même temps que le temps d'attente du verrouillage au cours de la période sélectionnée

Les verrous sont acquis par des transactions. Ainsi, en cas de conflits de verrouillage entraînant de longs temps d'attente, nous devrions constater une augmentation de la latence de commit des transactions ainsi qu'une augmentation du temps d'attente de verrouillage.

Après avoir sélectionné une période pour démarrer notre enquête, nous regroupons les statistiques de transaction TXN_STATS_TOTAL_10MINUTE et les statistiques de verrouillage LOCK_STATS_TOTAL_10MINUTE autour de cette période pour nous aider à mieux comprendre si l'augmentation de la latence de commit moyenne est due à l'augmentation du temps d'attente.

SELECT t.interval_end, t.avg_commit_latency_seconds, l.total_lock_wait_seconds
FROM spanner_sys.txn_stats_total_10minute t
LEFT JOIN spanner_sys.lock_stats_total_10minute l
ON t.interval_end = l.interval_end
WHERE
  t.interval_end >= "2020-11-12T21:50:00Z"
  AND t.interval_end <= "2020-11-12T23:50:00Z"
ORDER BY interval_end;

Prenons les données suivantes en guise d'exemple de résultats générés par notre requête.

interval_end avg_commit_latency_seconds total_lock_wait_seconds
2020-11-12 21:40:00-07:00 0.002 0.090
2020-11-12 21:50:00-07:00 0.003 0.110
2020-11-12 22:00:00-07:00 0.002 0.100
2020-11-12 22:10:00-07:00 0.002 0.080
2020-11-12 22:20:00-07:00 0.030 0.240
2020-11-12 22:30:00-07:00 0.034 0.220
2020-11-12 22:40:00-07:00 0.034 0.218
2020-11-12 22:50:00-07:00 3.741 780.193
2020-11-12 23:00:00-07:00 0.042 0.240
2020-11-12 23:10:00-07:00 0.038 0.129
2020-11-12 23:20:00-07:00 0.021 0.128
2020-11-12 23:30:00-07:00 0.038 0.231

Les résultats précédents montrent une augmentation spectaculaire de avg_commit_latency_seconds et total_lock_wait_seconds sur la même période, du 22:40:00 au 2020-11-12 22:50:00, avant d'avoir diminué. Notez que avg_commit_latency_seconds correspond au temps moyen consacré uniquement à l'étape de commit. En revanche, total_lock_wait_seconds correspond au temps de verrouillage cumulé pour la période. Le temps semble donc beaucoup plus long que le temps de commit de la transaction.

Maintenant que nous avons confirmé que le temps d'attente pour le verrouillage est étroitement lié à l'augmentation de la latence en écriture, nous allons déterminer, à l'étape suivante, quelles lignes et colonnes provoquent une longue attente.

Découvrez quelles clés de ligne et colonnes ont subi de longs temps d'attente de verrouillage pendant la période sélectionnée

Pour déterminer quelles clés de ligne et colonnes ont souffert d'un temps d'attente de verrouillage élevé au cours de la période examinée, nous interrogeons LOCK_STAT_TOP_10MINUTE qui répertorie les clés de ligne et les colonnes contribuant le plus au temps d'attente de verrouillage.

La fonction CAST() de la requête suivante convertit le champ BYTES "row_range_start_key" en valeur de type STRING.

SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
       t.total_lock_wait_seconds,
       s.lock_wait_seconds,
       s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
       s.sample_lock_requests
FROM spanner_sys.lock_stats_total_10minute t, spanner_sys.lock_stats_top_10minute s
WHERE
  t.interval_end = "2020-11-12T22:50:00Z" and s.interval_end = t.interval_end;
row_range_start_key total_lock_wait_seconds lock_wait_seconds frac_of_total sample_lock_requests
Singers(32) 780.193 780.193 1 LOCK_MODE: WriterShared

COLUMN: Singers.SingerInfo

LOCK_MODE: ReaderShared

COLUMN: Singers.SingerInfo

À partir de cette table de résultats, nous pouvons constater le conflit dans la table Singers à la clé SingerId=32. Singers.SingerInfo est la colonne où le conflit de verrouillage s'est produit entre ReaderShared et WriterShared.

Il s'agit d'un type de conflit courant lorsqu'une transaction tente de lire une cellule et que l'autre transaction tente d'écrire dans la même cellule. Nous connaissons maintenant la cellule de données exacte pour laquelle les transactions rivalisent avec le verrou. À l'étape suivante, nous allons donc identifier les transactions qui se disputent les verrous.

Identifier les transactions qui accèdent aux colonnes impliquées dans le conflit de verrouillage

Pour identifier les transactions qui connaissent une latence de commit importante dans un intervalle de temps spécifique en raison de conflits de verrouillage, vous devez interroger les colonnes suivantes de la table SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE:

  • fprint
  • read_columns
  • write_constructive_columns
  • avg_commit_latency_seconds

Vous devez filtrer les colonnes verrouillées identifiées dans la table SPANNER_SYS.LOCK_STATS_TOP_10MINUTE:

  • Transactions qui lisent une colonne ayant entraîné un conflit de verrouillage lors de la tentative d'obtention du verrou ReaderShared.

  • Transactions qui écrivent dans une colonne ayant entraîné un conflit de verrouillage lors de la tentative d'obtention d'un verrou WriterShared.

SELECT
  fprint,
  read_columns,
  write_constructive_columns,
  avg_commit_latency_seconds
FROM spanner_sys.txn_stats_top_10minute t2
WHERE (
  EXISTS (
    SELECT * FROM t2.read_columns columns WHERE columns IN (
      SELECT DISTINCT(req.COLUMN)
      FROM spanner_sys.lock_stats_top_10minute t, t.SAMPLE_LOCK_REQUESTS req
      WHERE req.LOCK_MODE = "ReaderShared" AND t.interval_end ="2020-11-12T23:50:00Z"))
OR
  EXISTS (
    SELECT * FROM t2.write_constructive_columns columns WHERE columns IN (
      SELECT DISTINCT(req.COLUMN)
      FROM spanner_sys.lock_stats_top_10minute t, t.SAMPLE_LOCK_REQUESTS req
      WHERE req.LOCK_MODE = "WriterShared" AND t.interval_end ="2020-11-12T23:50:00Z"))
)
AND t2.interval_end ="2020-11-12T23:50:00Z"
ORDER BY avg_commit_latency_seconds DESC;

Le résultat de la requête est trié en fonction de la colonne avg_commit_latency_seconds de sorte que la transaction présente d'abord la latence de commit la plus élevée.

fprint read_columns write_constructive_columns avg_commit_latency_seconds
1866043996151916800


['Singers.SingerInfo',
'Singers.FirstName',
'Singers.LastName',
'Singers._exists']
['Singers.SingerInfo'] 4.89
4168578515815911936 [] ['Singers.SingerInfo'] 3.65

Les résultats de la requête montrent que deux transactions ont tenté d'accéder à la colonne Singers.SingerInfo, qui est celle qui a présenté des conflits de verrouillage au cours de la période. Une fois que vous avez identifié les transactions à l'origine des conflits de verrouillage, vous pouvez les analyser à l'aide de leur empreinte, fprint, pour identifier les problèmes potentiels qui ont contribué au conflit de verrouillage.

Après avoir examiné la transaction avec fprint=1866043996151916800, vous pouvez utiliser les colonnes read_columns et write_constructive_columns pour identifier quelle partie du code d'application a déclenché la transaction. Vous pouvez ensuite afficher le LMD sous-jacent qui ne filtre pas la clé primaire, SingerId. Cela a entraîné une analyse complète de la table et a verrouillé la table jusqu'à ce que la transaction soit validée.

Pour résoudre le conflit de verrouillage, procédez comme suit:

  1. Utilisez une transaction en lecture seule pour identifier les valeurs SingerId requises.
  2. Utilisez une transaction en lecture-écriture distincte pour mettre à jour les lignes avec les valeurs SingerId requises.

Appliquer les bonnes pratiques pour réduire les conflits de verrouillage

Dans notre scénario d'exemple, nous avons pu utiliser les statistiques de verrouillage et les statistiques de transaction pour diagnostiquer notre problème jusqu'à identifier une transaction qui n'utilise pas la clé primaire de notre table lors des mises à jour. Nous avons trouvé des idées pour améliorer la transaction selon que nous connaissions ou non les clés des lignes à mettre à jour au préalable.

Lorsque vous examinez les problèmes potentiels liés à votre solution, ou même lors de la conception de votre solution, tenez compte de ces bonnes pratiques afin de réduire le nombre de conflits de verrouillage dans votre base de données.

  • Évitez les opérations de lecture de grande taille dans les transactions en lecture-écriture.

  • Dans la mesure du possible, utilisez des transactions en lecture seule, car elles n'obtiennent aucun verrouillage.

  • Évitez les analyses de table complète dans une transaction en lecture-écriture. Cela inclut l'écriture d'une instruction LMD conditionnelle sur la clé primaire ou l'attribution d'une plage de clés spécifique lors de l'utilisation de l'API de lecture.

  • Faites en sorte que la période de verrouillage soit courte en validant la modification dès que vous avez lu les données dans une transaction en lecture-écriture. Une transaction en lecture-écriture garantit que les données restent inchangées après leur lecture, jusqu'à ce que la modification soit validée. Pour ce faire, la transaction nécessite de verrouiller les cellules de données pendant la lecture et pendant le commit. Par conséquent, si vous pouvez raccourcir la période de verrouillage, les transactions sont moins susceptibles de rencontrer des conflits de verrouillage.

  • Privilégiez les petites transactions par rapport aux transactions volumineuses ou envisagez l'utilisation de LMD partitionné pour les transactions LMD de longue durée. Une transaction de longue durée acquiert un verrou pendant une longue période. Par conséquent, envisagez de scinder une transaction qui touche des milliers de lignes en plusieurs transactions plus petites qui mettent à jour des centaines de lignes dans la mesure du possible.

  • Si vous n'avez pas besoin de la garantie fournie par une transaction en lecture-écriture, évitez de lire les données dans la transaction de lecture-écriture avant de valider la modification. Pour ce faire, vous pouvez lire les données dans une transaction en lecture seule distincte. La plupart des conflits de verrouillage résultent de la garantie forte selon laquelle les données restent inchangées entre la lecture et le commit. Ainsi, si la transaction en lecture-écriture ne lit aucune donnée, elle n'a pas besoin de verrouiller les cellules pendant longtemps.

  • Spécifiez uniquement l'ensemble minimal de colonnes requis dans une transaction en lecture-écriture. Comme les verrous Spanner sont définis par cellule de données, lorsqu'une transaction en lecture/écriture lit un nombre excessif de colonnes, elle acquiert un verrou ReaderShared sur ces cellules. Cela peut entraîner des conflits de verrouillage lorsque d'autres transactions acquièrent un verrouillage WriterShared sur les écritures dans les colonnes en trop. Par exemple, envisagez de spécifier un ensemble de colonnes au lieu de * lors de la lecture.

  • Minimiser les appels d'API dans une transaction en lecture-écriture La latence des appels d'API peut entraîner des conflits de verrouillage dans Spanner, car les appels d'API sont soumis à des retards sur le réseau et côté service. Dans la mesure du possible, nous vous recommandons d'effectuer des appels d'API en dehors des transactions en lecture-écriture. Si vous devez exécuter des appels d'API dans une transaction en lecture-écriture, veillez à surveiller la latence de vos appels d'API afin de minimiser l'impact sur la période d'acquisition de verrouillage.

  • Suivez les bonnes pratiques de conception des schémas.

Étapes suivantes