sql >> Base de Datos >  >> RDS >> Sqlserver

Escalamiento de bloqueo de SQL Server

Introducción

Las bases de datos relacionales siguen las propiedades ACID en la forma en que implementan transacciones:atomicidad, consistencia, aislamiento y durabilidad. El aislamiento es necesario para garantizar que múltiples transacciones no puedan causar cambios en los datos y dejar los resultados eventuales inconsistentes. Para garantizar que las operaciones permanezcan aisladas, SQL Server aplica mecanismos de bloqueo.

Modos de bloqueo y jerarquía

El mecanismo de SQL Server para el control de concurrencia está involucrado. Para optimizar el rendimiento en términos de esperas de bloqueo, interbloqueos y similares, debe tomar una decisión basada en el escenario específico.

En SQL Server, los bloqueos se pueden mantener de varias formas y en varios niveles de granularidad. Los Modos de Bloqueo son las formas específicas de hacerlo, y sus niveles son Jerarquía de Bloqueo.

La figura 1 muestra los modos de bloqueo disponibles en SQL Server para el nivel de aislamiento de transacciones predeterminado (LECTURA COMPROMETIDA):

Descripción general de la escalada de bloqueo

SQL Server puede bloquear recursos en varios niveles. Depende de los actos más eficientes según la naturaleza de la carga de trabajo. La tabla 1 muestra los recursos que se pueden bloquear.

  • Los bloqueos a un nivel más granular (por ejemplo, bloqueos de nivel de fila) permiten una mayor simultaneidad y menos bloqueos.
  • Los bloqueos en un nivel superior (p. ej., Bloqueo de nivel de tabla) reducen la simultaneidad. Pueden causar más bloqueos, dependiendo de cuánto dure la declaración real.

SQL Server elige el nivel de bloqueo necesario según las métricas internas.

Una escalada de bloqueo ocurre cuando un bloqueo se convierte de un nivel más fino de granularidad a un nivel más grueso.

Por ejemplo, convertir un bloqueo de fila en un bloqueo de tabla (Consulte la Tabla 1).

Recurso Descripción
RID El identificador de fila utilizado para bloquear una sola fila dentro de un montón.
CLAVE El bloqueo de fila dentro de un índice utilizado para proteger rangos de claves en transacciones serializables.
PÁGINA La página de 8 kilobytes (KB) en una base de datos, como páginas de datos o de índice.
EXTENSIÓN El grupo contiguo de ocho páginas, como páginas de datos o de índice.
HoBT El montón o árbol B. El bloqueo protege un árbol B (índice) o las páginas de datos del montón en una tabla que no tiene un índice agrupado.
TABLA La tabla completa, incluidos todos los datos e índices.
ARCHIVO El archivo de la base de datos.
APLICACIÓN El recurso especificado por la aplicación.
METADATOS Bloqueos de metadatos.
ASIGNACIÓN_UNIDAD La unidad de asignación.
BASE DE DATOS Toda la base de datos.

La justificación para escalar bloqueos

Los bloqueos en SQL Server pueden ser bastante costosos. Para cada bloqueo que adquiere el administrador de bloqueos, SQL Server debe reservar memoria:64 bytes o 128 bytes. La cantidad depende de si estamos ante un sistema de 32 bits o de 64 bits, respectivamente.

A medida que aumenta el número de bloqueos de fila en una tabla, SQL Server debe adquirir más y más memoria. Por lo tanto, otros procesos se están muriendo de hambre, sin memoria.

Tiene sentido convertir bloqueos de fila y bloqueos de página en un solo bloqueo de nivel de tabla (objeto). Ocurre cuando el número de bloqueos para esa tabla supera los 5000.

El compromiso ocurre cuando la tabla completa ya no está disponible para otras sesiones en el proceso de transacción.

Demostración de escalada de bloqueo

Podemos hacer una demostración de Escalamiento de bloqueo usando el código del Listado 1.

Primero describamos un poco la tabla. Producción.ProductosI es una tabla relativamente pequeña que lleva alrededor de 7777 filas. Los elementos de construcción son el mismo conjunto de 77 filas duplicadas 101 veces. El Código del Listado 1 consta de tres versiones de la misma declaración de actualización, cada una encerrada en una transacción.

-- Listing 1: Demonstrating Lock Escalation

-- Update very few rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK 

Para mayor claridad, desglosaremos el contenido del Listado 1.

Antes de eso, observemos el Listado 2:una consulta para mostrar los bloqueos retenidos en la base de datos TSQLV4.

Nuestra primera acción es ejecutar el Listado 1a. Luego, usamos el Listado 2 para examinar cómo Lock Manager realiza el bloqueo en el escenario. Ejecutamos el Listado 1a sin emitir la declaración de reversión. De esta forma, conservamos los bloqueos el tiempo suficiente para que la consulta del Listado 2 pueda capturarlos.

-- Listing 1a: Demonstrating Lock Escalation
-- Update very few rows

BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Listing 2: Displaying Locks Held in Database TSQLV4

USE TSQLV4
GO
SELECT 
resource_type
, DB_NAME (resource_database_id) database_name
--, OBJECT_NAME(resource_associated_entity_id) resource_name
, request_mode
, request_type
, request_status
, request_reference_count
, request_session_id
, resource_associated_entity_id
, OBJECT_NAME(resource_associated_entity_id) [object_name] --small obj ids
, getuser.login_name
FROM sys.dm_tran_locks
CROSS APPLY dmv.dbo.getuser(request_session_id) as getuser
WHERE DB_NAME (resource_database_id)='TSQLV4';

Cuando ejecutamos la consulta en el Listado 1a y luego verificamos los bloqueos usando la consulta en el Listado 2, SQL Server devuelve el resultado que se muestra en la Figura 2.

404 filas en la tabla tienen unitprice=’18.00’ . El administrador de bloqueos bloquea estas filas junto con los demás bloqueos de cualquier nivel necesario. Lleva el recuento de filas de la Figura 2 a 467.

-- Listing 1b: Demonstrating Lock Escalation
-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

Observamos un comportamiento similar cuando ejecutamos la consulta en el Listado 1b. Esta vez, estamos tratando con 4406 filas. Refleja el número de filas en la tabla Production.ProductI con precio unitario>18.00.

-- Listing 1c: Demonstrating Lock Escalation
-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK

Cuando vamos más allá y ejecutamos el código en el Listado 1c, vemos un comportamiento diferente (vea la Figura 4).

El Listado 1c intenta actualizar las 7777 filas en la tabla Production.ProductI. SQL Server determina que bloquear tantas filas ya no es eficaz para garantizar el aislamiento. En cambio, toda la tabla está bloqueada.

Más información sobre la escalada de bloqueos

El bloqueo de la tabla implica que ninguna otra sesión puede modificar sus filas durante la duración de la transacción, lo que puede ocurrir incluso cuando una sesión de bloqueo no manipula todas las filas de la tabla.

También vale la pena mencionar que otros factores pueden afectar la forma en que se adquieren y escalan los bloqueos en SQL Server. Esos son el nivel de aislamiento configurado, la indexación y las marcas de rastreo.

Los indicadores de seguimiento T1211 y T1224 se pueden aplicar para deshabilitar por completo la escalada de bloqueo. Lock Escalation también se puede deshabilitar y habilitar para una tabla específica con el siguiente código:

-- Listing 5: Disable and Enable Lock Escalation

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=DISABLE);

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=TABLE);

Es posible que desee hacerlo para reducir el bloqueo asociado al bloqueo de toda la tabla. Debido al impacto en la memoria, debe considerarse como una medida temporal.

Conclusión

SQL Server usa Lock Escalation para controlar el impacto de un bloqueo más granular en los recursos del servidor. Para mostrar la forma en que ocurren estos bloqueos (bloqueos de fila, bloqueos de página, bloqueos de objetos, etc.), consulte la vista de administración dinámica sys.dm_tran_locks. Proporciona mucha información sobre el bloqueo, además de Escalamiento de bloqueo.

Si bien es posible manipular el comportamiento del administrador de bloqueos, es esencial hacerlo con mucho cuidado. También es fundamental conocer el impacto preciso en el rendimiento de cualquier esfuerzo dirigido a realizar tales modificaciones.

Referencias

  1. Korotkevitch, D., 2016. Pro SQL Server Internals. Florida:Dmitri Korotkevitch
  2. Escenarios de bloqueo mediante Sys.dm_tran_locks
  3. Guía de control de versiones de filas y bloqueo de transacciones