Mitos y verdades de la reducción de archivos en SQL (“shrink files/database”)

Últimamente he tenido varias cuestiones relacionas con la reducción de archivos, por lo que escribo este post para arrojar algo de luz en este aspecto.

Los archivos de SQL (tanto el de datos como el log de transacciones) tienen espacio marcado como “libre”, es decir, espacio asignado al archivo, pero que en este momento no contiene información, bien porque aún no se ha escrito, bien porque los datos que contenía se han borrado. SQL, por sí mismo, no libera este espacio, sino que lo mantiene en el archivo, marcándolo como libre, para ser utilizado cuando se necesite.

La primera pregunta que debemos hacernos antes de realizar una reducción (shrink) es: ¿realmente quiero hacerlo? Hay una razón por la que SQL no libera ese espacio: normalmente es espacio que se va a necesitar durante las operaciones diarias. Tener espacio libre en los archivos es una buena práctica, porque así evitamos operaciones de crecimiento (muy pesadas).

Mi recomendación personal es que nunca se hagan “shrinks” como parte de la tarea de mantenimiento, y que tampoco se configure de forma automática (autoshrink). Cualquiera de estas opciones probablemente desemboque en el siguiente escenario: Durante la tarea de mantenimiento, se libera espacio. Al empezar las operaciones diarias, se necesita espacio, por lo que hay una acción de autocrecimiento. Las consecuencias: Operaciones pesadas y fragmentación de los datos, ambas penalizan gravemente el rendimiento.

Mi recomendación, por lo tanto, es realizar shrinks sólo cuando haya habido un borrado masivo de datos o cuando haya graves problemas de espacio en disco.

Una vez que hemos decidido que queremos reducir el espacio, una situación muy frecuente es, utilizando la consola gráfica, elegir tareas en la base de datos, elegir reducir archivos, y utilizar la opción “Liberar espacio no utilizado” (release unused space). La tarea termina muy rápidamente, y en contra de lo esperado, no se libera espacio, o mucho menos del esperado.

Cuando se especifica esta opción, se libera el espacio no utilizado que se encuentra “al final” del archivo: sólo se libera espacio si el último “extent” (conjunto de 8 páginas) se encuentra completamente libre, en cuyo caso se libera, y se comprueba el anterior, deteniéndose cuando uno de los extents no está completamente libre. Por eso, si el espacio marcado como libre se encuentra repartido entre diferentes extents que no son el último asignado a la base de datos, no se liberará el espacio que se había estimado.

Si este es el caso, podemos liberar espacio eligiendo la opción: Reorganizar archivos antes de liberar espacio no utilizado (Reorganize files before releasing unused space). De esta manera, se “mueve” el espacio marcado como libre al final del archivo, y por lo tanto se puede liberar, reduciéndose el espacio ocupado en disco.

Espero que sea de utilidad.

Un saludo.  

 

Raquel Vicente

Ingeniero de Soporte de SQL Server