Error en la operación "ALTERAR ÍNDICE TODO RECONSTRUCCIÓN" en SQL Server 2012 porque el registro de transacciones se quedó sin espacio. Los índices nunca se han reorganizado o reconstruido, por lo que la fragmentación supera el 80% en casi todos.
El DB utiliza un modelo de recuperación simple. Supuse que después de cada operación de índice realizada por la forma "TODO" del comando, los datos del registro de transacciones se eliminarían antes de la próxima reconstrucción del índice. ¿Es así como funciona realmente, o las reconstrucciones de índice se registran como si fueran parte de una sola transacción?
En otras palabras, ¿podría reducir el crecimiento del registro de transacciones escribiendo un script para realizar cada reconstrucción individualmente? ¿Hay otros factores a considerar?
fuente
Respuestas:
1) Descarga de registros: el modelo de recuperación SIMPLE no borra el registro después de cada transacción, sino en los puntos de control. ( enlace para más información)
2a) REBUILD ALL: sí, REBUILD ALL funciona como una sola transacción. Las reconstrucciones de índice dentro tienen sus propias transacciones, pero la operación general no se confirma por completo hasta el final. Entonces, sí, puede limitar el crecimiento del archivo de registro reconstruyendo índices individuales (y posiblemente emitiendo comandos CHECKPOINT).
2b) ¡Prueba! Aquí, tenga un script de demostración. (Construido en 2016 dev) Primero, configure una base de datos de prueba, con tabla e índices:
Ahora puede comparar la actividad de registro entre REBUILD ALL y reconstruir individualmente
Observe cómo la primera transacción abierta (ID de transacción 0000: 000002fa para mí) no se confirma hasta el final de REBUILD ALL, pero para las reconstrucciones de índice por índice, se confirman sucesivamente.
fuente
Tal como está, esta es una transacción única.
fuente
La pregunta es trivial para una reconstrucción sin conexión . Por supuesto es una sola transacción. Imagine el caos que se produciría si la operación dividiera cada índice en su propia transacción, ya que tendría que liberar los bloqueos al confirmar y luego volver a adquirirlos. Si bien se liberó el bloqueo de la tabla crítica SCH-M, se pueden descartar índices y se pueden crear nuevos índices, ¿cómo manejaría la declaración tales casos? ¡Sin mencionar que la tabla puede descartarse e incluso volver a crearse entre las dos transacciones! Incluyendo el caso cuando la tabla se cae y se crea una tabla diferente con la misma identificación de objeto (sí, puede suceder) ...
¿Qué sucede si aumenta la pregunta para decir qué sucede si la reconstrucción del índice es en línea? reconstrucción en ? ¿Es una sola transacción o muchas? La respuesta es compleja, ya que en realidad hay varias transacciones internas involucradas . Sin embargo, el punto clave es que hay una transacción de archivado general que abarca toda la operación (la declaración ALTER) y esto fija el registro en su lugar (no se puede truncar), por lo tanto, la operación debe planificarse en consecuencia para permitir ~ 1.6x datos tamaño para el modo de recuperación COMPLETA, o tamaño de datos 0.2x para el modo BULK_LOGGED / SIMPLE. Vea el documento vinculado para más detalles.
Puede argumentar que ¿por qué la compilación fuera de línea no emplea las mismas transacciones internas que el modo en línea y divide la operación? Los problemas que mencioné sobre la alteración / caída de la tabla entre las operaciones de índice individuales (es decir, la "estabilidad del esquema" de la tabla) aún requerirían que haya una transacción global que mantenga un SCH-S en la tabla durante toda la duración de la declaración. Dado que esta transacción también debe contener el SCH-S durante la recuperación, debe registrarse y, como tal, habrá un registro de registro BEGIN XACT que fijará el registro y evitará el truncamiento durante toda la declaración. Sé que este problema en particular se estaba abordando en el marco de tiempo SQL 2016-2017 (debido a problemas de tamaño de registro de SQL Azure),
pero no estoy seguro de qué progreso se hizo. Parece que ahora está en la vista previa:La reconstrucción de índice en línea reanudable está en una vista previa pública para SQL Server 2017 CTP 2.0 .fuente
Sí, tuve el mismo problema con una mesa muy grande. Cada vez que emitía ALTER INDEX ALL, el registro de transacciones crecería mucho, pero si se emitía ALTER INDEX individualmente, el uso del espacio de registro sería menor.
fuente
La respuesta anterior de Remus de que la indexación en línea requiere 1,6 veces el tamaño del índice en el modo de recuperación COMPLETA no es correcta. La proporción del espacio de registro de transacciones requerido para reconstruir un índice en línea bajo COMPLETO puede ser mucho mayor y hemos observado muchas veces el tamaño del índice, especialmente cuando el índice que se está reconstruyendo se comprime porque el registro de transacciones no se comprime. Esto solo debería dejar en claro que el registro de transacciones durante una reconstrucción en línea bajo COMPLETO puede ser al menos unas veces el tamaño del índice. Agregue una sobrecarga de registro de tlog que no está completamente documentada por Microsoft, pero a menudo se estima en 60 bytes por fila y el tamaño proporcional del registro durante una reconstrucción de índice en línea bajo recuperación completa puede ser muchas veces el tamaño del índice que se está reconstruyendo, especialmente si el índice está comprimido
fuente
Rdfozz es correcto, esa es la mejor manera de decidir si su índice más grande puede reconstruirse en función del almacenamiento actual. Simplemente ejecute
dm_exec_requests
mientras se realiza la operación (o SQL Profiler) para ver si se están reconstruyendo todos los índices. También consideraría cambiar el modelo de recuperación a registro masivo. Esto es lo que hago y todavía hay copias de seguridad del registro de transacciones durante la ventana. Vea a continuación el artículo https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxfuente