La pasada semana estuve trabajando en un caso con una base de datos de Microsoft Dynamics AX en la que no era posible reducir el tamaño (en Inglés, “shrink”) del log de transacciones. En el pasado encontré problemas similares con bases de datos de SQL Server 2005 que eran debidos a los llamados “ghost records” (en Castellano, “registros fantasma”); este hecho se encuentra discutido en el artículo Microsoft KB953991, pero en nuestro caso la base de datos era de SQL Server 2008.

Hay varias razones por las que un log de transacciones puede no reducir su tamaño cuando se ejecuta una tarea de shrink, un listado de estas puede encontrase en este artículo de MSDN. Para encontrar la razón por la que el log de transacciones no puede ser truncado utilizamos la Vista Dinámica o DMV (del Inglés “Dynamic Management View”) sys.databases y buscando la información bajo la columna log_reuse_wait_desc. En la mayoría de las ocasones la descripción en esta columna será LOG_BACKUP, indicando que es necesario un backup del log de transacciones para poder relizar un truncado del mismo (y una posterior reducción del tamaño mediante SHRINK). En nuestro caso el resultado de esta consulta era REPLICATION, como se puede ver a continuación (en el ejemplo estoy utilizando la base de datos AdventureWorks):

USE master;
GO
SELECT name, log_reuse_wait_desc, * FROM sys.databases
WHERE name = 'AdventureWorks';

untitled

Tras discutir los detalles del caso con el cliente, encontramos que un proceso DBCC CHECKDB fue ejecutado en la base de datos varios días atrás utilizando la opción de recuperación ALLOW_REPAIR_DATA_LOSS. No estoy completamente seguro de que ambas acciones estén relacionadas pero en su momento me encontré con una situación similar en SQL Server 2005 en la que un log de transacciones de una base de datos aparecía marcaddo como REPLICTOIN después de ejecutar el comando DBCC CHECKDB con la misma opción de recupearción.

En nuestro caso intentamos resestear el estado del log de transacciones utilizando el procedimiento almacenado de replicación sp_repldone, pero el procedimiento almancenado falló indicando que la base de datos no estaba configurada para replicación. Encontramos que la forma más rápida y sencilla de eliminar la marca “REPLICATION” del fichero de log de transacciones era configurar una replicación de tipo Snapshot (“Instantánea”) en la base de datos y, justo después, elminiar esta configuración del servidor.

Para configurar una replicación de tipo Snapshot (“Instantánea”) utilizando SQL Server Management Studio puedes seguir los pasos descritos en este vídeo Tehcnet de 10 minutos de Ty Anderson (sólo en Inglés). La primera parte del vídeo muestra cómo configurar la instancia de SQL Server como su propio Publicador y Distribuidor mientras que la segunda parte mustra cómo configurar los Suscriptores. En nuestro caso no es necesario configurar ningún suscriptor cuando ejecutemos el Asistente de Configuración para la replicación Snaphsot, tan solo tenemos que tener en cuenta la siguiente información:

  • Seleccionamos la base de datos afectada como la base de datos para Replicación
  • No necesitmoa seleccionar todos los objetos para el proceso de Replicacion, podemos seleccionar una tabla cualquiera
  • Recordamos crear un Snapshot o Instantánea inicial cuando seamos preguntados por el Asistente
  • Podemos configurar la cuenta de servicio del Agent de SQL Server en las opcioens de seguridad ya que esta configuraión será sólo temporal

Una vez el Asistente para la Replicación tipo Snaphot configure el entorno de replilcación correctamente, ejecutaremos la instrucción SELECT anterior; en este punto la descripción de la columna log_reuse_wait_desc nos deberá mostrar la etiqueta NOTHING o la etiqueta LOG_BACKUP:

untitled2

Si el estado de esta columna para el fichero de log de transacciones muestra todavía REPLICATION, ejecutaremos la siguiente instrucción:

EXEC sp_repldone @xactid = NULL, @xact_sgno = NULL, @numtrans = 0, @time = 0, @reset = 1;

A continuación necesitamos eliminar todos los objetos de replicación de la base de datos ya que no necesitamos mantenerlos. Inicialmente eliminamos la publicación (no necesitamos eliminar los suscriptores antes ya que no hemos configurado ninguno):

USE AdventureWorks;
GO
EXEC sp_droppublication @publication = N'AW_Test_Publication'USE master
GO
EXEC sp_replicationdboption @dbname = N'AdventureWorks', @optname = N'publish', @value = N'false';

En este ejemplo se puede ver que el nombre de nuestra Publicación es “AE_Test_Publication”. Este nombre será diferente en función de lo que hayamos escrito durante el asistente para configurar la Replicación. A continuación eliminamos el Distribuidor:

USE master;
GO
exec sp_dropdistributor @no_checks = 1;

Y finalmento nos aseguramos de que no queda ningún objeto de replicación en la bae de datos ejecutando el siguiente procedimiento almacenado:

USE master;
GO
sp_removedbreplication 'AdventureWorks';

Jorge Pérez Campo – Microsoft Customer Support Services