Sincronizando dos bases de datos en SQL Server

16

Tengo dos bases de datos de SQL Server. Uno es el cliente (aplicación de Windows) y el segundo está en el servidor. Quiero sincronizar estas dos bases de datos de vez en cuando (por ejemplo, ¡cada 2 minutos!).

He leído acerca de las diferentes formas de sincronización, como la replicación, la marca de tiempo, las tablas de registro que utilizan desencadenantes, Microsoft Sync Framework, etc.

En realidad, no me gusta usar un método de sincronización que podría ser un cuadro negro (como la replicación) porque no quiero que se bloqueen las tablas específicas de SQL Server mientras las estoy actualizando y sincronizando con el servidor.

  1. ¿Qué método crees que debería usar en tales circunstancias? Recuerde que cada varios minutos debo enviar varios cambios de tabla del cliente al servidor y buscar también dos cambios de tabla del servidor.

  2. He encontrado un método extraño pero nuevo. ¿Es posible que registre todos los procedimientos almacenados ejecutados (para los preferidos específicos) en el cliente y los envíe con sus parámetros en un .sqlarchivo al servidor y los ejecute allí? Lo mismo sucederá en el servidor y se enviará al cliente. ¿Crees que este es un método simple pero útil o no?

  3. sugiérame algún enfoque útil si puede. Muchas gracias.

EDITAR: recuerde que esta es una sincronización en tiempo real y esto la hace especial. Significa que cuando el usuario del cliente está usando la tabla, el proceso de sincronización con el servidor debe ocurrir cada varios minutos, por lo que ninguna de las tablas debe estar bloqueada.

Emad Farrokhi
fuente
1
Recuerde que esas "cajas negras" están relativamente bien documentadas con respecto a cómo funcionan, cómo mantenerlas y monitorearlas, y qué puede hacer para solucionarlas en escenarios de falla comunes (y no tan comunes). Consideraría implementar mi propio método de sincronización y tener que buscar y corregir errores relacionados con casos extremos que las "cajas negras" abordaron hace mucho tiempo si y solo si tenía necesidades muy específicas de la aplicación (sincronización parcial o la necesidad de resolución interactiva de conflictos, etc.).
David Spillett
@DavidSpillett: ¿Usó la replicación en un proyecto de sincronización en tiempo real con éxito? Mi principal preocupación es la sincronización en tiempo real y el "bloqueo y bloqueo".
Emad Farrokhi

Respuestas:

14

Bueno, puede que no lo entienda, pero trato de responderlo.

Dijiste que necesitas una solución de alto rendimiento que se ejecute a menudo (mínimo los 2 minutos) y necesitas un buen enfoque que debería ser rápido sin bloqueo. Pero no quieres un sistema de caja negra.

En lugar de un sistema de caja negra, que se utiliza en millones de instalaciones con buenos resultados, ¿intenta inventar la rueda nuevamente y construir su propia solución? Hm, suena un poco raro.

De hecho, estas son mis sugerencias.

  1. Replicación incluso si dijiste que no la usarías. Es la solución más fácil y mejor que puede usar para esto. La replicación es fácil de configurar, se replica rápidamente y no tiene que inventar la rueda nuevamente. Si simplemente te gusta bloquear, puedes intentar configurarlo ISOLATION LEVELen READ_COMMITTED_SNAPSHOT. Puedes leer más sobre esto aquí . Esto usará una parte de su tempdb, pero su tabla siempre es de lectura y escritura y la replicación puede funcionar en segundo plano.

Vea el siguiente ejemplo:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture) también puede ser una solución. Pero de esta manera necesita construir casi todo por su cuenta. Y he hecho la experiencia que CDCpuede ser algo frágil en algunas circunstancias. CDCcapturará todos los datos en una tabla observada (debe especificar cada tabla observada manualmente). Después obtendrá el valor antes y el valor después de un INSERT, UPDATEo DELETE. CDCretendrá esa información por un período de tiempo (puede especificarla usted mismo). El enfoque podría ser usar CDCen ciertas tablas que necesita ver y replicar manualmente esos cambios en la otra base de datos. Por cierto, también CDCutiliza la replicación de SQL Server debajo del capó. ;-) Puedes leer más sobre esto aquí .

Advertencia: CDCno se dará cuenta de los DDLcambios. Esto significa que si cambia una tabla y agrega una nueva columna, CDCobservará la tabla pero ignorará todos los cambios en la nueva columna. De hecho, solo registra NULLcomo valor antes y valor después. DDLDebe reiniciarlo después de -Cambios a una tabla observada.

  1. La forma en que describió anteriormente es algo así como capturar una carga de trabajo utilizando SQL Server Profiler y ejecutarla nuevamente en otra base de datos para algunos puntos de referencia. Bueno, podría funcionar. Pero el hecho de que haya demasiados efectos secundarios es demasiado pesado para mí. ¿Qué hacer si captura una llamada de procedimiento en su cliente? ¿Luego ejecuta el mismo comando en su base de datos principal ya que no está sincronizado? El procedimiento puede ejecutarse, pero puede eliminar / actualizar / insertar filas que no estaban presentes en su cliente. ¿O cómo manejas múltiples clientes con un principio? Creo que esto es demasiado complicado. En el peor de los casos, probablemente destruyas tu integridad.
  2. Otra idea podría ser la aplicación o el uso de un disparador. Dependiendo de cuántas tablas desea sincronizar. Puede escribir todos los cambios en una tabla de etapas separada y ejecutar un trabajo del Agente SQL Server todo x Minutos para sincronizar esas filas en la tabla de etapas con su maestro. Pero esto puede ser un poco pesado si intenta sincronizar (por ejemplo) 150 tablas. Tendrías una gran sobrecarga.

Bueno, estos son mis 2 centavos. Espero que tenga una buena visión general y tal vez haya encontrado una solución que funcione para usted.

Iónico
fuente
9

Intentaré enumerar algunas opciones aquí con ventajas y desventajas a medida que las percibo:

  1. Replicación de SQL Server : esta es la mejor y más optimizada herramienta nativa de SQL Server para esta tarea. Pero hay varios problemas: a. para todos sus clientes, independientemente de si son bases de datos SQL Express o no, necesitará una licencia CAL de SQL Server. Esto se puede evitar utilizando licencias por procesador. si. No puede sincronizar el cliente SQL CE según aquí . C. SQL Express o LocalDB no pueden actuar como editor o distribuidor , por lo que tiene menos control sobre el proceso de replicación del cliente.
  2. Microsoft Sync Framework : me parece más adecuado para bases de datos más pequeñas de aplicaciones móviles. Agrega muchas tablas a su base de datos y no es tan eficiente como la replicación. Como se implementa fuera de SQL Server como componente, será más difícil de configurar. No tengo experiencia con él, solo lo probé y decidí no usarlo.

  3. Seguimiento de cambios en la base de datos . Es una función incorporada de SQL Server que cambia el seguimiento, incluidas las inserciones, actualizaciones y eliminaciones. Todo lo demás, como enviar y aplicar cambios, resolver conflictos, etc., tendrá que codificarse.

  4. Columnas de conversión de fila (marca de tiempo) Si no permite todas las eliminaciones (sin sincronización de registros eliminados), puede implementar su propia solución basada solo en la información de conversión de fila. SQL Server Replication también utiliza columnas de versión de fila, por lo que deberá agregarlas de todos modos.
  5. CDC como se menciona en la respuesta de Ionic : no tengo experiencia con él, ya que está disponible solo en las ediciones Enterprise o Developer.

  6. El uso de su propio truco con el registro de los procedimientos almacenados ejecutados depende mucho de la naturaleza de su aplicación de base de datos. Pero cuando los procedimientos son un poco diferentes, allí puede obtener un gran lío en los datos. ¿Y cómo lidiarías con los conflictos?

Según su pregunta, parece que necesita sincronizar solo algunas tablas y no todas las grandes bases de datos. Para este propósito, debe analizar sus necesidades con más detalle de lo que ha especificado en la pregunta, como:

  • ¿Pueden suceder eliminaciones y qué sucede entonces?
  • ¿Pueden suceder conflictos, cómo prevenirlos y cómo resolverlos?
  • ¿Cómo lidiaré con los cambios en la estructura de la tabla?
  • ...

Si finalmente descubre que las eliminaciones y los conflictos no son su problema y que su estructura no cambiará mucho, puede considerar escribir su propia lógica, pero puede crecer fácilmente a 1000 filas de código.

Vojtěch Dohnal
fuente
2

Gracias a todos por sus comentarios.

Resolví con éxito el proceso de sincronización capturando los procedimientos almacenados ejecutados no como un grupo sino uno por uno, lo que funcionó muy bien en mi caso. Dado que la integridad y todo se consideran cuidadosamente, el sistema ha estado funcionando en tiempo real hasta ahora.

Emad Farrokhi
fuente
Genial, sin embargo, ¿puede explicar con más detalle lo que hizo? ¿Simplemente registra las llamadas de los procedimientos almacenados que se ejecutaron y las almacena en alguna tabla temporal / secuencia de comandos y hace que un trabajo ejecute esta secuencia de comandos y que establezca un campo (como un campo de bits o un campo de fecha y hora donde diga para TODOS estos registros que no se han procesado, ¿los procesan y actualizan el campo de bits?
JonH
0

Respuesta tardía, pero podría ser útil enganchar a los visitantes

Tuve un desafío similar al tratar de distribuir datos entre diferentes servidores y lo resolví utilizando herramientas de terceros ( Diff para cambios de esquema y DataDiff para sincronización de cambios de datos) y siguiendo el script de PowerShell requerido para automatizar el proceso:

#check for the existence of the Outputs folder
function CheckAndCreateFolder($rootFolder, [switch]$Outputs)
{
$location = $rootFolder

#setting up location 
if($Outputs -eq $true)
{
    $location += "\Outputs"
}

#if the folder doesn't exist it will be created
if(-not (Test-Path $location))
{ mkdir $location -Force:$true -Confirm:$false | Out-Null }

return $location
}

#root folder for the schema sync process
$rootFolder = "SchemaSync"

#schema output summaries location 
$outsLoc = CheckAndCreateFolder $rootFolder -Outputs

#ApexSQL Diff location, date stamp variable is defined, along with tools parameters 
$diffLoc   = "ApexSQLDiff"
$stamp = (Get-Date -Format "MMddyyyy_HHMMss") 
$Params = "/pr:""MyProject.axds""    /out:""$outsLoc\SchemaOutput_$stamp.txt"" /sync /v /f" 
$returnCode = $LASTEXITCODE

#initiate the schema comparison and synchronization process
(Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params))

#write output to file
"$outsLoc\SchemaOutput_$dateStamp.txt"

#schema changes are detected
if($returnCode -eq 0)
{
"`r`n $returnCode - Schema changes were successfully synchronized" >> 

}
else
{
#there are no schema changes
if($returnCode -eq 102)
{
"`r`n $returnCode - There are no schema changes. Job aborted" >> 
}
#an error is encountered
else
{
"`r`n $returnCode - An error is encountered" >> 

#output file is opened when an error is encountered
Invoke-Item "$outsLoc\SchemaOutput_$stamp.txt"
}

}

Este método programa la comparación entre dos bases de datos y sincroniza los cambios encontrados en tiempo real. Aquí hay algunos artículos que ofrecen instrucciones paso a paso:

https://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/ https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- esquemas sincronizados /

Monte Chavis
fuente