Uno de los inconvenientes cuando añadimos replicación a nuestro entorno es que añade labores extras de monitorización y además los errores en el proceso de réplica pueden llegar a ser complejos de diagnosticar. En el anterior post vimos cómo podemos utilizar el monitor de replicación para monitorizar el estado de nuestra réplica. Si sospechamos que tenemos algún tipo de problema en nuestra replicación, éste debería ser el primer sitio donde deberíamos acudir para verificar el estado actual de nuestra réplica.Cada réplica requiere un proceso de verificación ligeramente distinto y que deberemos adaptar a nuestras necesidades concretas. Si seguimos con el ejemplo del post anterior tenemos una replicación transaccional unidireccional en marcha. El proceso de verificación a seguir podría ser el siguiente:1. Abrir el monitor de replicación y comprobar que el agente del log de transacciones está en marcha y no muestra ningún error

2. Comprobar desde el monitor de replicación que todos nuestros agentes de distribución asociados a los subscriptores están funcionando y no muestran ningún error:

3. Introducir un Token de traza desde el monitor de replicación y comprobar que la latencia es coherente con lo esperado. Si hemos configurado la réplica transaccional con los valores por defecto la latencia total debería estar por debajo de 10 segundos:

Si al analizar las latencias vemos que por ejemplo del publicador al distribuidor tardamos 3 segundos y del distribuidor al subscriptor tardamos 60 segundos ya tenemos una pista de por donde tenemos que orientar la resolución de nuestro problema.

En general en una replicación transaccional unidireccional se presupone que los datos en destino serán de solo lectura o, si hay escrituras, éstas no producirán colisiones con los datos replicados. Por ejemplo si recordamos el anterior post sobre replicación transaccional, una de las opciones que se ofrece durante la configuración de la publicación era la configuración de filtros. Con un filtro activo sería viable mantener inserciones de datos en la misma tabla que la réplica está funcionando siempre que no colisionemos con el filtro. A continuación vamos a simular una situación que causaría un error en la réplica y veremos de que forma podemos diagnosticar la causa exacta y resolver el problema.

Para ello comprobaremos que tenemos los agentes en marcha correctamente antes de comenzar mediante el monitor de réplica y además lanzaremos una consulta que nos devuelva el último contacto insertado en el publicador:

Haremos lo mismo en el subscriptor:

A continuación procederemos a realizar una inserción “no adecuada” en el subscriptor, utilizando para ello un ContactID que colisionará al irse incrementando el contador. Por ejemplo el ContactID 19981 acabará colisionando tras realizar unas pocas inserciones. Tras realizar esta inserción en el subscriptor procederemos a realizar varias inserciones en el publicador hasta alcanzar el 19981 al menos:

Si una vez estamos en este estado realizamos una inserción de un nuevo registro en el publicador, la inserción se realizará con éxito, independientemente de los problemas que ello pueda causar al subscriptor posteriormente. Si accedemos al monitor de replicación veremos como el subscriptor está teniendo algunos problemas aplicando comandos y estamos teniendo errores:

 

Pasados unos segundos los reintentos se convertirán en un error más concreto:

Como vemos, no se nos indica cual es el registro afectado concretamente únicamente la restricción problemática (la clave primaria) y la tabla afectada. En estas situaciones lo que recomendamos es detener el agente afectado, lanzar una traza de SQL Server Profiler y obtener más datos directamente de la actividad en la base de datos del subscriptor. Lanzaremos una traza filtrando únicamente aquella actividad proveniente del agente de réplica lo cual en nuestro caso podemos conseguirlo filtrando por like ‘%_publi’:

Una vez tenemos la traza en marcha los propios reintentos del agente nos mostrarán aquella fila que está dándole problemas con la inserción por colisión de clave primaria:

En el texto del comando que está fallando podemos deducir que el fallo se produce en una inserción (procedimiento almacenado con prefijo sp_MSins), que corresponde a la tabla Person.Contact (sufijo PersonContact en el procedimiento):

exec [dbo].[sp_MSins_PersonContact] 19981,0,NULL,N’Crystal’,NULL,N’Hu’,NULL,N’crystal21@adventure-works.com’,0,N’1 (11) 500 555-0126′,N’ZEgQH9qZIPiLgyBHYw/dD1FJQNpdQyIAa+BFfKX5/jg=’,N’7iy/umc=’,NULL,N'{2495BFFD-2041-4C4F-9238-8BC1E204C400}’,’2003-11-17 00:00:00′

Si examinamos el cuerpo del procedimiento veremos que el primer parámetro corresponde efectivamente con el ContactID por lo que ya sabemos que la solución para poder reanudar la réplica pasa por eliminar dicho registro del subscriptor. Una vez eliminado del subscriptor veremos que la réplica es capaz de recuperarse sin problemas:

Como conclusión debemos tener en cuenta que cuanto tengamos un problema con nuestra replicación el primer paso es acudir al monitor de replicación para intentar obtener pistas de dónde puede estar el problema. Es posible que un agente se encuentre simplemente detenido por un error de un operador que lo deshabilitó por error. Es posible también que problemas de red impidan al agente de distribución conectar con el subscriptor o que el subscriptor esté saturado de forma que las latencias sean mucho mayores de las habituales. Afortunadamente la mayoría de errores son diagnosticables mediante los errores que aparecen en el monitor y cuando no siempre tendremos nuestro fiel SQL Profiler listo para poder ayudarnos.

 

Rubén Garrigós