Concentración de bloqueos (motor de base de datos)

La concentración de bloqueos es el proceso de convertir muchos bloqueos concretos en menos bloqueos más generales, lo que reduce la sobrecarga del sistema al tiempo que aumenta la probabilidad de contención de simultaneidad.

Cuando Microsoft SQL Server Database Engine (Motor de base de datos de SQL Server) adquiere bloqueos de bajo nivel, también coloca bloqueos con intención en los objetos que contienen los objetos de nivel más bajo:

  • Al bloquear filas o intervalos de claves de índice, Database Engine (Motor de base de datos) coloca un bloqueo con intención en las páginas que contienen las filas o claves.
  • Al bloquear páginas, Database Engine (Motor de base de datos) coloca un bloqueo con intención en los objetos de nivel más alto que contienen las páginas. Además de colocar un bloqueo de objeto (OBJECT) con intención en la tabla, se solicitan bloqueos de montón o árbol b (HOBT) con intención en:
    • El índice no agrupado si se trata de páginas con índice no agrupado.
    • El índice agrupado si se trata de páginas con índice agrupado. Esto incluye páginas de datos en tablas con índice agrupado.
    • El montón de páginas de datos si se trata de páginas de datos de una tabla sin índice agrupado.

Puede que Database Engine (Motor de base de datos) realice bloqueos de fila y página para una misma instrucción a fin de minimizar el número de bloqueos y reducir la probabilidad de que sea necesario realizar la concentración de bloqueos. Por ejemplo, Database Engine (Motor de base de datos) podría colocar bloqueos de página en un índice no agrupado (si se seleccionan suficientes claves contiguas del nodo del índice como para satisfacer la consulta) y bloqueos de fila en los datos.

Para concentrar bloqueos, Database Engine (Motor de base de datos) intenta cambiar el bloqueo de la tabla al correspondiente bloqueo completo; cambiar, por ejemplo, un bloqueo con intención exclusivo (IX) a un bloqueo exclusivo (X) o un bloqueo con intención compartido (IS) a un bloqueo compartido (S). Si el intento de concentración de bloqueos se realiza correctamente y se adquiere el bloqueo de tabla completo, se liberan todos los bloqueos de montón o árbol b, página (PAGE), intervalo de claves (KEY) o filas (RID) retenidos por la transacción de montón o índice. Si no se puede adquirir el bloqueo completo, no se produce ninguna concentración de bloqueos en el momento y Database Engine (Motor de base de datos) continúa para adquirir bloqueos de fila, clave o página.

Database Engine (Motor de base de datos) no concentra bloqueos de filas o intervalos de claves en bloqueos de páginas, sino que los concentra directamente en bloqueos de tablas. De manera similar, los bloqueos de páginas se concentran siempre en bloqueos de tablas.

Si un intento de concentración de bloqueos no se produce debido a conflictos de bloqueo retenidos por transacciones simultáneas, Database Engine (Motor de base de datos) intentará realizar de nuevo la concentración de bloqueos por cada 1.250 bloqueos adicionales adquiridos por la transacción.

Cada evento de concentración funciona principalmente en una sola instrucción de Transact-SQL. Cuando el evento se inicia, Database Engine (Motor de base de datos) intenta concentrar los bloqueos pertenecientes a la transacción actual que se encuentren en alguna de las tablas a las que se hace referencia en la instrucción activa, siempre que cumpla los requisitos de umbral de concentración. Si el evento de concentración se inicia antes de que la instrucción tenga acceso a la tabla, no se hace ningún intento de concentrar los bloqueos de la tabla. Si la concentración de bloqueos se realiza correctamente, los bloqueos adquiridos por la transacción en una instrucción anterior que sigan retenidos en el momento en que se inicia el evento se concentrarán, si se hace referencia a la tabla en la instrucción actual y se incluye la tabla en el evento de concentración.

Por ejemplo, suponga que la sesión realiza estas operaciones:

  • Inicia una transacción.
  • Actualiza TableA. Esto genera bloqueos exclusivos de fila en TableA que se retienen hasta que se completa la transacción.
  • Actualiza TableB. Esto genera bloqueos exclusivos de fila en TableB que se retienen hasta que se completa la transacción.
  • Ejecuta una instrucción SELECT que combina TableA con TableC. El plan de ejecución de la consulta llama a las filas que se van a recuperar de TableA antes de que se recuperen las filas de TableC.
  • La instrucción SELECT desencadena la concentración de bloqueos mientras recupera filas de TableA y antes de tener acceso a TableC.

Si la concentración de bloqueos se realiza correctamente, sólo se concentran los bloqueos retenido por la sesión de TableA. Esto incluye los bloqueos compartidos de la instrucción SELECT y los bloqueos exclusivos de la instrucción UPDATE anterior. Aunque para determinar si se debe realizar la concentración de bloqueos sólo se cuentan los bloqueos que la sesión adquirió en TableA para la instrucción SELECT, cuando se lleva a cabo la concentración, todos los bloqueos retenidos por la sesión en TableA se concentran en un bloqueo exclusivo en la tabla y se liberan los demás bloqueos de granularidad inferior, incluidos los bloqueos con intención, de TableA.

No se intentan concentrar bloqueos en TableB porque no había una referencia activa a TableB en la instrucción SELECT. De manera similar, no se intenta concentrar los bloqueos de TableC porque aún no se había tenido acceso a esta tabla cuando se produjo la concentración.

Umbrales de concentración de bloqueos

La concentración de bloqueos se desencadena en cualquiera de los momentos siguientes:

  • Cuando una sola instrucción Transact-SQL adquiere, al menos, 5.000 bloqueos en un solo índice o tabla.
  • Cuando el número de bloqueos de una instancia de Database Engine (Motor de base de datos) supera los umbrales de memoria o configuración.

Si los bloqueos no se pueden concentrar debido a conflictos de bloqueo, Database Engine (Motor de base de datos) desencadena periódicamente la concentración de bloqueos cada 1.250 nuevos bloqueos adquiridos.

Umbral de concentración para una instrucción de Transact-SQL

La concentración de bloqueos se desencadena cuando una instrucción Transact-SQL adquiere, al menos, 5.000 bloqueos en una única referencia de una tabla o índice; o si la tabla tiene particiones, en una única referencia de una partición de tabla o partición de índice. Por ejemplo, la concentración de bloqueos no se desencadena si una instrucción adquiere 3.000 bloqueos en un índice y 3.000 bloqueos en otro índice de la misma tabla. De forma similar, la concentración de bloqueos no se desencadena si una instrucción tiene una autocombinación en una tabla y cada referencia a la tabla sólo adquiere 3.000 bloqueos de la tabla.

La concentración de bloqueos sólo se produce para tablas a las que se ha obtenido acceso en el momento en que se desencadena la concentración. Suponga que una instrucción SELECT única es una combinación que tiene acceso a tres tablas por este orden: TableA, TableB y TableC. La instrucción adquiere 3.000 bloqueos de fila del índice agrupado de TableA y, al menos, 5.000 bloqueos de fila del índice agrupado de TableB, pero todavía no ha tenido acceso a TableC. Cuando Database Engine (Motor de base de datos) detecta que la instrucción ha adquirido, al menos, 5.000 bloqueos de fila de TableB, intenta concentrar todos los bloqueos retenidos por la transacción actual de TableB. También intenta concentrar todos los bloqueos retenidos por la transacción actual de TableA, pero como el número de bloqueos de TableA es < 5.000, no se realiza la concentración. No se intenta ninguna concentración de bloqueos en TableC porque aún no se había tenido acceso a ella cuando se produjo la concentración.

Umbral de concentración para una instancia del motor de base de datos

Siempre que el número de bloqueos sea mayor que el umbral de memoria para la concentración de bloqueos, Database Engine (Motor de base de datos) desencadena la concentración de bloqueos. El umbral de memoria depende del valor de la opción de configuración locks:

  • Si la opción locks se establece en el valor predeterminado de 0, el umbral de concentración de bloqueos se alcanza cuando la memoria que utilizan los objetos de bloqueo es el 24 por ciento de la memoria que utiliza Database Engine (Motor de base de datos), excluida la memoria AWE. La estructura de datos que se utiliza para representar un bloqueo tiene aproximadamente una longitud de 100 bytes. Este umbral es dinámico debido a que Database Engine (Motor de base de datos) adquiere y libera memoria dinámicamente para ajustarse a las variaciones de las cargas de trabajo.
  • Si la opción locks es un valor distinto de 0, el umbral de concentración de bloqueos es 40 por ciento (o menos si existe alguna presión en la memoria) del valor de la opción.

Database Engine (Motor de base de datos) puede elegir una instrucción activa de cualquier sesión de concentración; además, por cada 1.250 nuevos bloqueos, elegirá instrucciones de concentración siempre que la memoria utilizada en la instancia se mantenga por encima del umbral.

Concentrar tipos de bloqueo mixtos

Cuando se produce una concentración de bloqueos, el bloqueo seleccionado para el montón o índice es lo suficientemente fuerte como para cumplir con los requisitos del bloqueo de bajo nivel más restrictivo.

Por ejemplo, suponga que una sesión:

  • Inicia una transacción.
  • Actualiza una tabla que contiene un índice agrupado.
  • Emite una instrucción SELECT que hace referencia a la misma tabla.

La instrucción UPDATE adquiere estos bloqueos:

  • Bloqueos exclusivos (X) en las filas de datos actualizadas.
  • Bloqueos con intención exclusivos (IX) en las páginas del índice agrupado que contienen estas filas.
  • Un bloqueo IX en el índice agrupado y otro en la tabla.

La instrucción SELECT adquiere estos bloqueos:

  • Bloqueos compartidos (S) en todas las filas de datos que lee, a no ser que la fila esté ya protegida por un bloqueo X de la instrucción UPDATE.
  • Bloqueos con intención compartidos en todas las páginas de índice agrupado que contienen dichas filas, a no ser que la página esté ya protegida por un bloqueo IX.
  • Ningún bloqueo en el índice agrupado o la tabla porque ya están protegidos por bloqueos IX.

Si la instrucción SELECT adquiere suficientes bloqueos como para desencadenar la concentración de bloqueos y ésta se realiza correctamente, el bloqueo IX de la tabla se convierte en un bloqueo X y se liberan todos los bloqueos de fila, página e índice. Las actualizaciones y las lecturas están protegidas por el bloqueo X de la tabla.

Reducir bloqueos y extensiones

En la mayoría de los casos, Database Engine (Motor de base de datos) presta el mejor rendimiento cuando funciona con la configuración predeterminada para bloqueo y concentración de bloqueos. Si una instancia de Database Engine (Motor de base de datos) genera gran cantidad de bloqueos y se producen extensiones de bloqueo frecuentes, considere la posibilidad de reducir la cantidad de bloqueos mediante:

  • El uso de un nivel de aislamiento que no genere bloqueos compartidos para operaciones de lectura.
    • Un nivel de aislamiento READ COMMITTED si la opción de base de datos READ_COMMITTED_SNAPSHOT está en ON.
    • Un nivel de aislamiento SNAPSHOT.
    • Un nivel de aislamiento READ UNCOMMITTED. Este nivel sólo se puede utilizar en sistemas que puedan funcionar con lecturas no actualizadas.
  • El uso de las sugerencias de tabla PAGLOCK o TABLOCK para que Database Engine (Motor de base de datos) utilice bloqueos de página, montón o índice en lugar de bloqueos de filas. Esta opción, sin embargo, aumenta los problemas derivados de usuarios que bloquean a otros usuarios al intentar obtener acceso a los mismos datos y sólo se debe utilizar en sistemas con pocos usuarios simultáneos.

También se pueden utilizar las marcas de traza 1211 y 1224 para deshabilitar todas las extensiones de bloqueo o sólo algunas. Para obtener más información, vea Marcas de traza (Transact-SQL). Además, supervise la concentración de bloqueos mediante el uso del evento Lock:Escalation de Analizador de SQL Server; vea Usar el Analizador de SQL Server.

Vea también

Conceptos

Niveles de aislamiento del motor de base de datos
Granularidad y jerarquías de bloqueo
Modos de bloqueo
Compatibilidad de bloqueos (motor de base de datos)
locks (opción)

Otros recursos

SET TRANSACTION ISOLATION LEVEL (Transact-SQL)
Sugerencias de tabla (Transact-SQL)
Arquitectura de tablas e índices

Ayuda e información

Obtener ayuda sobre SQL Server 2005