Spanner proporciona estadísticas de bloqueo que te permiten identificar la clave de fila y
columnas de la tabla que eran las fuentes principales de conflictos de bloqueo de transacciones en tu
de la base de datos
durante un período determinado. Puedes recuperar estas estadísticas de
las tablas del sistema SPANNER_SYS.LOCK_STATS*
con instrucciones de SQL.
Disponibilidad
Los datos SPANNER_SYS
solo están disponibles a través de interfaces de SQL; por ejemplo:
La página Spanner Studio de una base de datos en la consola de Google Cloud
El comando
gcloud spanner databases execute-sql
La opción Bloquear estadísticas panel
La API de
executeQuery
Otros métodos de lectura única que proporciona Spanner no son compatibles.
SPANNER_SYS
Estadísticas de bloqueo por clave de fila
En las siguientes tablas, se realiza un seguimiento de la clave de fila con el tiempo de espera más alto:
SPANNER_SYS.LOCK_STATS_TOP_MINUTE
: Las claves de fila con el tiempo de espera de bloqueo más alto en intervalos de 1 minuto.SPANNER_SYS.LOCK_STATS_TOP_10MINUTE
: Las claves de fila con el tiempo de espera de bloqueo más alto en intervalos de 10 minutos.SPANNER_SYS.LOCK_STATS_TOP_HOUR
: Las claves de fila con los tiempos de espera de bloqueo más altos en intervalos de 1 hora
Estas tablas tienen las siguientes propiedades:
Cada tabla contiene datos de intervalos de tiempo no superpuestos de la longitud que se especifica en el nombre de la tabla.
Los intervalos se basan en tiempos de reloj. Los intervalos de 1 minuto finalizan en el minuto, los intervalos de 10 minutos finalizan cada 10 minutos a partir de la hora y los intervalos de 1 hora finalizan en la hora. Después de cada intervalo, Spanner recopila datos de todos los servidores y, luego, los pone a disposición en las tablas SPANNER_SYS poco después.
Por ejemplo, a las 11:59:30 a.m., los intervalos más recientes disponibles para las consultas de SQL son los siguientes:
- 1 minuto: de 11:58:00 a 11:58:59 a.m.
- 10 minutos: de 11:40:00 a 11:49:59 a.m.
- 1 hora: de 10:00:00 a 10:59:59 a.m.
Spanner agrupa las estadísticas por rango de clave de fila inicial.
Cada fila contiene estadísticas del tiempo total de espera de bloqueo de un determinado rango de clave de fila inicial para el que Spanner captura estadísticas durante el intervalo especificado.
Si Spanner no puede almacenar información sobre todos los rangos de claves de fila para las esperas de bloqueo durante el intervalo, el sistema prioriza el rango de claves de fila con el tiempo de espera de bloqueo más alto durante el intervalo especificado.
Todas las columnas de las tablas admiten valores nulos.
Esquema de la tabla
Nombre de la columna | Tipo | Descripción |
---|---|---|
INTERVAL_END |
TIMESTAMP |
Fin del intervalo en el que se produjeron los conflictos de bloqueo incluidos. |
ROW_RANGE_START_KEY |
BYTES(MAX) |
La clave de fila en la que ocurrió el conflicto de bloqueo. Cuando el conflicto
incluye un rango de filas, este valor representa el
clave de ese rango. Un signo más, + , indica un rango.
Para obtener más información,
Consulta ¿Qué es una clave de inicio de rango de filas?
|
LOCK_WAIT_SECONDS |
FLOAT64 |
El tiempo de espera de bloqueo acumulado de los conflictos de bloqueo registrados para todos las columnas del rango de clave de fila, en segundos. |
SAMPLE_LOCK_REQUESTS |
ARRAY<STRUCT<
|
Cada entrada del array corresponde a un ejemplo de solicitud de bloqueo.
contribuyó al conflicto de bloqueo al esperar un bloqueo o
Impedir que otras transacciones efectúen el bloqueo en la fila dada
tecla (rango). La cantidad máxima de muestras en este array es 20.
Cada muestra contiene los siguientes tres campos:
|
Modos de bloqueo
Las operaciones de Spanner adquieren bloqueos cuando son parte de un read-write. Las transacciones de solo lectura no adquirir bloqueos. Spanner usa distintos modos de bloqueo para maximizar la la cantidad de transacciones que tienen acceso a una celda de datos específica en un determinado tiempo. Las diferentes cerraduras tienen características diferentes. Por ejemplo, algunos bloqueos se puede compartir entre varias transacciones, mientras que otras no.
Se puede producir un conflicto de bloqueo cuando se intenta adquirir uno de los siguientes bloqueos modos en una transacción.
Candado
ReaderShared
: Un bloqueo que permite que otras lecturas accedan al hasta que la transacción esté lista para confirmarse. Se adquirió este bloqueo compartido cuando una transacción de lectura y escritura lee datos.Bloqueo de
WriterShared
: Este bloqueo se adquiere cuando se realiza una transacción de lectura y escritura. para confirmar una operación de escritura.Bloqueo de
Exclusive
: Se adquiere un bloqueo exclusivo cuando una operación de lectura y escritura. transacción, que ya adquirió un bloqueo ReaderShared, intenta escribir los datos después de la finalización de la lectura. Un bloqueo exclusivo es una actualización de un bloqueoReaderShared
. Un bloqueo exclusivo es un caso especial de una transacción manteniendo las cerradurasReaderShared
yWriterShared
al mismo tiempo. Ninguna otra transacción puede adquirir ningún bloqueo en la misma celda.Candado
WriterSharedTimestamp
: Es un tipo especial de bloqueoWriterShared
que se adquiere cuando se insertan filas nuevas en una tabla que tiene una confirmación marca de tiempo como parte de la clave primaria. Este tipo de bloqueo impide que los participantes de la transacción creen exactamente la misma fila y, por lo tanto, entran en conflicto entre sí. Spanner actualiza la clave de la fila insertada para que coincida con la marca de tiempo de confirmación de la transacción a la que realizó la inserción.
Para obtener más información sobre los tipos de transacciones y los tipos de bloqueos que se disponibles, consulta Transacciones.
Conflictos del modo bloqueado
En la siguiente tabla, se muestran los posibles conflictos entre los diferentes modos bloqueados.
Modos de bloqueo | ReaderShared |
WriterShared |
Exclusive |
WriterSharedTimestamp |
---|---|---|---|---|
ReaderShared |
No | Sí | Sí | Sí |
WriterShared |
Sí | No | Sí | No aplicable |
Exclusive |
Sí | Sí | Sí | No aplicable |
WriterSharedTimestamp |
Sí | No aplicable | No aplicable | Sí |
Los bloqueos WriterSharedTimestamp
solo se usan cuando se insertan filas nuevas con un
y marca de tiempo
como parte de su clave primaria. Las cerraduras WriterShared
y Exclusive
tienen las siguientes características:
Se usa cuando se escribe en celdas existentes o se insertan filas nuevas sin marcas de tiempo. Como
como resultado, WriterSharedTimestamp
no puede entrar en conflicto con otros tipos de bloqueos.
estas situaciones se muestran como No aplicable en la tabla anterior.
La única excepción es ReaderShared
, que se puede aplicar a filas que no existen y, por lo tanto, podría entrar en conflicto con WriterSharedTimestamp
. Para
ejemplo, un análisis completo de la tabla bloquea toda la tabla, incluso las filas que aún no se hayan
por lo que es posible que ReaderShared
entre en conflicto con
WriterSharedTimestamp
¿Qué es una clave de inicio del rango de filas?
La columna ROW_RANGE_START_KEY
identifica la clave primaria compuesta.
clave primaria inicial de un rango de filas, que tiene conflictos de bloqueo. Lo siguiente
se usa para ilustrar un ejemplo.
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);
Como se muestra en la siguiente tabla de clave de fila y rangos de clave de fila, un rango es se representa con un signo más (+) en la clave. La clave en esos casos representa la tecla de inicio de un rango de teclas en el que se produjo un conflicto de bloqueo.
ROW_RANGE_START_KEY | Explicación |
---|---|
cantantes(2) | Tabla Cantantes (Singers) en la clave SingerId=2 |
cantantes(2,1) | Tabla de álbumes en la clave SingerId=2,AlbumId=1 |
canciones(2,1,5) | Tabla de canciones en la clave SingerId=2,AlbumId=1,TrackId=5 |
canciones(2,1,5+) | Rango de claves de la tabla de canciones a partir de SingerId=2,AlbumId=1,TrackId=5 |
albums(2,1+) | Rango de claves de la tabla de álbumes a partir de SingerId=2,AlbumId=1 |
usuarios(3, 2020-11-01 12:34:56.426426+00:00) | Tabla de usuarios en la clave UserId=3, LastAccess=commit_timestamp |
Estadísticas agregadas
SPANNER_SYS
también contiene tablas para almacenar datos agregados de las estadísticas de bloqueo que capturó Spanner en un período específico:
SPANNER_SYS.LOCK_STATS_TOTAL_MINUTE
: Estadísticas agregadas de todos los bloqueos espera en intervalos de 1 minuto.SPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE
: Estadísticas agregadas de todos los bloqueos espera en intervalos de 10 minutos.SPANNER_SYS.LOCK_STATS_TOTAL_HOUR
: Estadísticas agregadas de todas las esperas de bloqueo en intervalos de 1 hora.
Las tablas conjuntas de estadísticas tienen las siguientes propiedades:
Cada tabla contiene datos de intervalos de tiempo no superpuestos de la duración que se especifica en el nombre de la tabla.
Los intervalos se basan en tiempos de reloj. Los intervalos de 1 minuto finalizan en el minuto, los intervalos de 10 minutos finalizan cada 10 minutos a partir de la hora y los intervalos de 1 hora finalizan en la hora.
Por ejemplo, a las 11:59:30 a.m., los intervalos más recientes disponibles para las consultas de SQL en las estadísticas de bloqueo agregadas son los siguientes:
- 1 minuto: de 11:58:00 a 11:58:59 a.m.
- 10 minutos: de 11:40:00 a 11:49:59 a.m.
- 1 hora: de 10:00:00 a 10:59:59 a.m.
Cada fila contiene estadísticas de todas las esperas de bloqueo en la base de datos durante el intervalo especificado, agregados. Solo hay una fila por vez durante un intervalo de tiempo determinado.
Las estadísticas capturadas en las tablas
SPANNER_SYS.LOCK_STATS_TOTAL_*
incluir las esperas de bloqueo que Spanner no capturó en elSPANNER_SYS.LOCK_STATS_TOP_*
tablas.Algunas columnas de estas tablas se exponen como métricas en Cloud Monitoring. Las métricas expuestas son las siguientes:
- Tiempo de espera de bloqueo
Para obtener más información, consulta Spanner métricas.
Esquema de la tabla
Nombre de la columna | Tipo | Descripción |
---|---|---|
INTERVAL_END |
TIMESTAMP |
Fin del intervalo en el que ocurrió el conflicto de bloqueo. |
TOTAL_LOCK_WAIT_SECONDS |
FLOAT64 |
Tiempo total de espera de bloqueo para los conflictos de bloqueo registrados en toda la base de datos, en segundos. |
Consultas de ejemplo
El siguiente es un ejemplo de una instrucción de SQL que puedes usar para recuperar bloqueos estadísticas. Puedes ejecutar estas instrucciones de SQL con el comando client bibliotecas, gcloud spanner o la Consola de Google Cloud.
Obtén una lista de las estadísticas de bloqueo del intervalo de 1 minuto anterior
La siguiente consulta muestra la información de espera de bloqueo para cada clave de fila con un conflicto de bloqueo, incluida la fracción de conflictos de bloqueo totales, durante intervalo de tiempo reciente de 1 minuto.
La función CAST()
convierte los BYTES de row_range_start_key
a una 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;
Resultado de la consulta
row_range_start_key | total_lock_wait_seconds | lock_wait_seconds | frac_of_total | sample_lock_requests |
---|---|---|---|---|
canciones(2,1,1) | 2.37 | 1.76 | 0.7426 | LOCK_MODE: ReaderShared COLUMNA: Singers.SingerInfo LOCK_MODE: WriterShared COLUMNA: Singers.SingerInfo |
Usuarios(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
es un campo interno que se utiliza para verificar si un
si cierta fila existe o no.
Retención de datos
Como mínimo, Spanner conserva los datos de cada tabla durante el siguiente tiempo períodos:
SPANNER_SYS.LOCK_STATS_TOP_MINUTE
ySPANNER_SYS.LOCK_STATS_TOTAL_MINUTE
: Intervalos que abarcan las 6 horas anteriores.SPANNER_SYS.LOCK_STATS_TOP_10MINUTE
ySPANNER_SYS.LOCK_STATS_TOTAL_10MINUTE
: Intervalos que abarcan los 4 días anteriores.SPANNER_SYS.LOCK_STATS_TOP_HOUR
ySPANNER_SYS.LOCK_STATS_TOTAL_HOUR
: Intervalos que abarcan los 30 días anteriores.
Soluciona problemas de conflictos de bloqueo en la base de datos con estadísticas de bloqueo
Puedes usar SQL o el botón de bloqueo estadísticas panel para ver los conflictos de bloqueo en tu base de datos.
En los siguientes temas, se muestra cómo puedes investigar estos conflictos de bloqueo mediante SQL código.
Selecciona un período para investigar
Examinas las métricas de latencia de tu base de datos de Spanner y descubres un período en el que tu app experimenta una latencia alta y un uso alto de la CPU. Por ejemplo, el problema comenzó alrededor de las 10:50 p.m. el 12 de noviembre de 2020.
Determina si la latencia de confirmación de la transacción aumentó junto con el tiempo de espera de bloqueo durante el período seleccionado
Las transacciones adquieren bloqueos, por lo que, si hay conflictos de bloqueo deberíamos poder ver el aumento en la latencia de confirmación de la transacción con el aumento en el tiempo de espera del bloqueo.
Habiendo seleccionado un período para comenzar nuestra investigación, uniremos la
estadísticas de transacciones TXN_STATS_TOTAL_10MINUTE
con estadísticas de bloqueo LOCK_STATS_TOTAL_10MINUTE
en esa época para ayudarnos
comprender si el aumento de la latencia de confirmación promedio se
el aumento del tiempo de espera de la cerradura.
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;
Toma los siguientes datos como ejemplo de los resultados que obtenemos de nuestra para cada búsqueda.
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 |
Estos resultados anteriores muestran un aumento significativo en avg_commit_latency_seconds
y total_lock_wait_seconds
durante el mismo período, de 2020-11-12 22:40:00 a 2020-11-12 22:50:00, y disminuyeron después de eso. Una cosa que debes tener en cuenta es que avg_commit_latency_seconds
es el tiempo promedio que se dedica solo al paso de confirmación. Por otro lado, total_lock_wait_seconds
es la
tiempo de bloqueo agregado del período, de modo que el tiempo parezca mucho más largo que el
tiempo de confirmación de la transacción.
Ahora que confirmamos que el tiempo de espera de bloqueo está estrechamente relacionado con el aumento de la latencia de escritura, en el siguiente paso investigaremos qué filas y columnas causan la espera prolongada.
Descubre qué claves de fila y columnas tuvieron tiempos de espera de bloqueo prolongados durante el período seleccionado
Para averiguar qué claves de fila y columnas experimentaron tiempos de espera de bloqueo elevados
durante el período que investigamos, consultamos el LOCK_STAT_TOP_10MINUTE
de la tabla, en la que se enumeran las claves de fila y las columnas que más contribuyen al bloqueo
y esperar.
La función CAST()
de la siguiente consulta convierte la
fila_rango_start_key de BYTES a una 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 |
---|---|---|---|---|
Cantantes(32) | 780.193 | 780.193 | 1 | LOCK_MODE: WriterShared COLUMNA: Singers.SingerInfo LOCK_MODE: ReaderShared COLUMNA: Singers.SingerInfo |
En esta tabla de resultados, podemos ver que el conflicto ocurrió en Singers
de clave SingerId=32. Singers.SingerInfo
es la columna en la que se produjo el conflicto de bloqueo entre ReaderShared
y WriterShared
.
Este es un tipo común de conflicto cuando hay una transacción que intenta lee una determinada celda y la otra transacción intenta escribir en la misma de la celda. Ahora sabemos cuál es la celda de datos exacta por la que compiten las transacciones por lo que, en el siguiente paso, identificaremos las transacciones que se para competir por los bloqueos.
Descubre qué transacciones acceden a las columnas involucradas en el conflicto de bloqueo
Identificar las transacciones que experimentan una latencia de confirmación significativa
dentro de un intervalo de tiempo específico debido a conflictos de bloqueo, debes consultar
las siguientes columnas del
Tabla SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
:
fprint
read_columns
write_constructive_columns
avg_commit_latency_seconds
Debes filtrar las columnas bloqueadas identificadas en el
Tabla SPANNER_SYS.LOCK_STATS_TOP_10MINUTE
:
Transacciones que leen cualquier columna que generó un conflicto de bloqueo cuando se intenta adquirir el bloqueo
ReaderShared
.Transacciones que escriben en cualquier columna que generó un conflicto de bloqueo cuando se intenta adquirir un bloqueo
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;
El resultado de la consulta está ordenado por la columna avg_commit_latency_seconds
de manera que puedas ver las
que experimenta la latencia de confirmación más alta primero.
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 |
Los resultados de la consulta muestran que dos transacciones intentaron acceder a la columna Singers.SingerInfo
, que es la columna que tuvo conflictos de bloqueo durante el período.
Una vez que identifiques las transacciones que causan los conflictos de bloqueo, puedes analizar
las transacciones con su huella digital, fprint
, para identificar posibles problemas
que contribuyeron al conflicto de bloqueo.
Después de revisar la transacción con fprint=1866043996151916800, puedes usar
Las columnas read_columns
y write_constructive_columns
para identificar qué parte
del código de la aplicación activó la transacción. A continuación, podrás ver
el DML subyacente que no filtra la clave primaria, SingerId
. Esto provocó un análisis completo de la tabla y bloqueó la tabla hasta que se confirmó la transacción.
Para resolver el conflicto de bloqueo, puedes hacer lo siguiente:
- Usa una transacción de solo lectura para identificar los valores
SingerId
obligatorios. - Usa una transacción de lectura y escritura separada para actualizar las filas de los valores
SingerId
obligatorios.
Aplica las prácticas recomendadas para reducir la contención de bloqueos
En nuestro ejemplo, pudimos usar las estadísticas de bloqueo y las estadísticas de transacciones para reducir nuestro problema a una transacción que no usaba la clave principal de nuestra tabla cuando se realizaban actualizaciones. Se nos ocurrieron ideas para mejorar la transacción según si conocíamos las claves de las filas que queríamos actualizar de antemano o no.
Cuando analices problemas potenciales en tu solución o, incluso, cuando diseñes considera estas prácticas recomendadas para reducir la cantidad de conflictos de bloqueo en tu base de datos.
Evita lecturas extensas en las transacciones de lectura y escritura
Use transacciones de solo lectura siempre que sea posible, ya que no adquieren ninguna cerraduras.
Evita los análisis completos de la tabla en una transacción de lectura y escritura. Esto incluye escribir un DML condicional en la clave primaria o asignación de un rango de claves específico cuando se usa la API de Read.
Mantén un período de bloqueo corto confirmando el cambio en cuanto leer los datos como sea posible en una transacción de lectura y escritura. A garantiza que los datos permanezcan inalterados después de que leas hasta que confirmes el cambio con éxito. Para lograrlo, el de datos requiere bloquear las celdas de datos durante la lectura confirmar. Por lo tanto, si puedes hacer que el período de bloqueo sea corto, tienen menos probabilidades de tener conflictos de bloqueo.
Prefiere las transacciones pequeñas antes que las grandes, o bien considera usar particionadas DML para transacciones de DML de larga duración. Un juego de larga duración cuando una transacción adquiere un bloqueo durante mucho tiempo, así que considera desglosarlo que abarca miles de filas en varias filas más pequeñas que actualizan cientos de filas siempre que sea posible.
Si no necesitas la garantía que proporciona una transacción de lectura y escritura, evita leer cualquier dato en la transacción de lectura y escritura antes de confirmar el cambio. Por ejemplo, puedes leer los datos en una transacción de solo lectura independiente. La mayoría de los conflictos de bloqueo se producen debido a la garantía sólida, que garantiza que los datos no cambien entre la operación de lectura y la confirmación. Si la transacción de lectura y escritura no lee ningún dato, no necesita bloquear las celdas por mucho tiempo.
Especifica solo el conjunto mínimo de columnas requerido en una operación de lectura y escritura transacción. Como los bloqueos de Spanner son por celda de datos, cuando La transacción de lectura y escritura lee una cantidad excesiva de columnas y adquiere un
ReaderShared
. bloquear estas celdas. Esto podría causar conflictos de bloqueo cuando otras transacciones adquirir un bloqueo deWriterShared
en las operaciones de escritura en las columnas excesivas. Para Por ejemplo, considera especificar un conjunto de columnas en lugar de*
en la lectura.Minimiza las llamadas a la API en una transacción de lectura y escritura. La latencia de las llamadas a la API podría generar contención de bloqueo en Spanner, ya que las llamadas a la API se y están sujetos a retrasos de red y del servicio. Recomendaciones y realiza llamadas a la API fuera de las transacciones de lectura y escritura siempre que sea posible. Si debes ejecutar llamadas a la API dentro de una transacción de lectura y escritura, asegúrate de supervisar la latencia de tus llamadas a la API para minimizar el impacto en el período de adquisición de bloqueo.
Sigue las prácticas recomendadas para el diseño de esquemas.
¿Qué sigue?
- Obtén más información sobre otras herramientas de introspección.
- Obtén más información sobre otros datos que Spanner almacena para cada base de datos en El esquema de información de las bases de datos desde una tabla de particiones.
- Obtén más información sobre las prácticas recomendadas de SQL para Spanner