2011-09-08 25 views
20

Esto no es una consulta. Es un resumen de nuestra solución para evitar el problema de la corrupción en los archivos de bases de datos SQL Compact con éxito (casi) definitivo. SQLCE La corrupción es un problema muy común. Hemos recibido una gran ayuda de publicaciones anteriores en StackOverflow, y de ahí esta publicación.Resolver daños en archivos de base de datos de SQL Server Compact Edition

Nuestro producto es una arquitectura de 3 capas con el servidor ejecutándose como un Servicio de Windows conectado a Clientes Ricos mediante .Net Remoting. Nuestro producto usa SQLCE desde 2006. Hemos pasado de v3.1 a v3.5 y ahora v4.0. Tenemos una herramienta personalizada de OR-Mapping para algunos requisitos muy específicos. Nos enfrentamos a problemas limitados con v3.1, nos hemos enfrentado más con v3.5 y v4.0.

Inicialmente con v3.5, implementamos SqlCeEngine.Repair. Pero solo elimina los datos dañados e intenta recrear una base de datos estable. Descubrimos que las claves externas de las tablas afectadas desaparecieron. Tuvimos que acabar con esto de inmediato. Comenzamos a notificar a los usuarios acerca de la corrupción de db y restaurar la última copia de seguridad. Esto solo proporcionó un alivio temporal; el problema de la corrupción aún estaba en pie.

Este año, adoptamos v4.0. Sin embargo, nuestra aplicación también introdujo varias características nuevas que aumentaron tremendamente la cantidad de llamadas a la base de datos. v4.0 comenzó bien, pero comenzó a dar problemas cuando aumentó el uso del software. Las corrupciones que ocurrieron mientras se ejecutaba la aplicación no se debieron a fallas de Windows, interrupciones anormales o problemas de disco. La base de datos acaba de corromper.

El siguiente post cubre la solución que hemos ideado para este problema:

+0

¿Puede describir el problema con más detalle, luego, mueva la solución a una respuesta? Gracias. –

Respuesta

17

[La separación de la consulta y la solución]

Aquí va cómo hemos resuelto el problema:

A) Cierre/Eliminación Objetos de conexión/comando/transacción: Nos aseguramos de que no haya objetos no conectados de conexión, transacción u orden. Nuestra herramienta ORM se usó para crear nuevos objetos después de realizar la confirmación de la transacción, que en algunos casos estaban inactivos. Esto prácticamente redujo el número de corrupciones en un 50%.

B) Deshabilitar el encogimiento automático: El único procedimiento que se produjo en el medio de una aplicación ejecutada, sobre la que no teníamos control fue Auto-Shrink. Estábamos llamando a SqlCeEngine.Compact cuando se inicia la aplicación. Decidimos eliminar tanto la compactación como la contracción automática. Y para nuestra sorpresa, redujimos la corrupción en otro 48%. Fue un tiro en la oscuridad, y no podíamos creer que Auto-Shrinking podría haber causado tales problemas. Prácticamente resolvimos el problema con esa actualización.

C) Transacciones de base de datos sincronizadas: Algunas corrupciones de bases de datos todavía están sucediendo. Sin razones claras detectadas, decidimos sincronizar las transacciones de la base de datos. Sé que a muchas personas de bases de datos no les va a gustar esto. No me gusta tampoco. Introdujimos bloqueos en nuestro nivel medio para garantizar que solo una llamada modifique la base de datos a la vez. Nuestra implementación más grande es de 55 clientes que utilizan simultáneamente nuestro sistema. La sincronización de las llamadas a la base de datos casi no dio lugar a ningún retraso en el rendimiento visible. Más bien, la sincronización nos permitió implementar una llamada controlada por temporizador a SqlCeEngine.Compact a intervalos regulares. Sabíamos que Compact no era el culpable, y sentimos que Compaction es una llamada necesaria ya que reindexa la base de datos (nuestra solución realiza muchas inserciones y eliminaciones). Sin embargo, necesita funcionar exclusivamente; no hay llamadas a la base de datos cuando llamas a Compact. La sincronización nos permitió controlar eso durante una ejecución de la aplicación. Desde que lo hicimos, no hemos recibido un solo problema de corrupción de la base de datos. Ha pasado más de un mes ahora. De casi 5 clientes en una semana, a cero en un mes.

El razonamiento básico que nos llevó a las ideas B y C es que SQLCE es una base de datos integrada. Las corrupciones son comunes a todas las soluciones de bases de datos integradas. Una base de datos de soluciones a gran escala funciona de manera independiente con un servidor db 24x7 que gestiona conexiones y otras tareas. Un sistema de base de datos incrustado no tiene dicho sistema de soporte. La única etapa en que está vivo es cuando se abre una conexión.

Algunos indicadores más: 1) Implementamos la confirmación con CommitMode.Immediate, lo que hace que la propiedad Flush-Interval sea redundante. 2) AutoShrink está configurado en 100, lo que desactiva completamente el procedimiento 3) Aumenté el tiempo de espera de la conexión para permitir que las llamadas a la base de datos sincronizadas funcionen sin problemas. 4) Se llama Compact cuando comienza la aplicación. En los casos en que los clientes no apagan su máquina, implementamos el temporizador para llamar a Compact cada 24 horas.

Espero que esta publicación ayude a resolver problemas.

+0

Gracias por esta publicación detallada. Estoy en una situación similar. Mi primera implementación de SQL CE estuvo funcionando bien en el desarrollo, pero se estrelló esta mañana en producción. Probando tus recomendaciones –

+0

@desaiw: JFYI, todas las corrupciones que recibimos a nuestro conocimiento después de esto fueron causadas por fallas del servidor, cuelgues del servidor, etc., pero no fueron tratadas o desconocidas. –

+0

Después de seguir su publicación, puedo decir con seguridad que estoy de acuerdo. Nuestras bases de datos ahora funcionan bien. Gracias otra vez. –

5

Si se usa SQL Server CE 4.0, existe un problema conocido que puede impedir que los datos se descarguen en el disco (AT ALL). https://support.microsoft.com/en-us/kb/2979868 y revisión https://support.microsoft.com/en-us/kb/2960153

En sus propias palabras:

supone que ha especificado el intervalo de vaciado en el máximo número de segundos en la cadena de conexión antes de las transacciones confirmadas se vacían en el disco en Microsoft SQL Server Compact 4.0 . En esta situación, las transacciones comprometidas pueden llevar mucho más tiempo que el intervalo de enjuague que se vaciará en el disco o incluso puede que no se vacíen al disco. Además, la pérdida de datos ocurre si hay una terminación anormal del programa.

La revisión que resuelve este problema se incluye en un paquete de actualización de revisión bajo demanda para SQL Server Compact 4.0 Service Pack 1.

La solución proporcionada es utilizar transaction.Commit(CommitMode.Immediate) alrededor del bloque que desea asegurarse se enjuaga

+0

¿Podría describir la solución desde el enlace en la respuesta? Este es un seguro contra link rot. –

+0

gracias @JamesJones Lo he actualizado. – hsorbo

Cuestiones relacionadas