"Cannot commit index" o cómo extraer datos de una base de datos parcialmente restaurada (inconsistente)
Alexey Kovyazin, última actualización 30-marzo-2014
Después de corregir corrupciones, es frecuente ver el error “Cannot commit index” en el paso de restauración. En Firebird 2.0 y posteriores esto aparece como una advertencia y la base de datos no se pondrá en línea; en Firebird 1.0-1.5 e InterBase esto ocurre como un error muy desagradable que detiene el proceso de restauración (es impresionante ver este error al final de la restauración de una base de datos de 200Gb).
La razón del error “Cannot commit index..” es obvia: la corrupción afecta la integridad referencial de la base de datos, y los registros desaparecen de manera mágica (desde el punto de vista del servidor).
Por ejemplo, tienes una tabla “Customers” y una tabla asociada “Orders” referenciada por una clave foránea. Sin corrupción, no es posible violar la clave foránea y eliminar un registro de Customers sin antes eliminar todas las órdenes que se refieren a ese cliente en particular. La corrupción afecta el archivo de la base de datos a bajo nivel y elimina registros directamente. Qué sorpresa tan agradable para el servidor ver enlaces no resueltos a registros maestros desde registros de claves foráneas.
Aquí necesito agregar un consejo sobre el proceso de restauración: el motor restaura todas las tablas con índices no activados (esto hace que el llenado de tablas con registros sea mucho más rápido), y después comienza a activar (es decir, construir) los índices uno por uno. Esto significa que todos los datos ya están en la base de datos cuando el proceso de restauración comienza el paso de creación de índices y ves el error “Cannot commit index..”.
Bueno, el primer deseo cuando ves el error “Cannot commit index” es eliminar la restricción de clave foránea correspondiente para permitir que la restauración termine. La pregunta es qué vamos a hacer con la base de datos inconsistente pero restaurada con éxito: la clave foránea eliminada puede ser una parte importante de la lógica de negocio.
Hay 2 enfoques aquí: recrear los datos faltantes o eliminar los datos inconsistentes. Veamos qué significa esto en el ejemplo de Customers-Orders anterior.
Recreación de datos faltantes
Entonces, has decidido que necesitas recrear los Customers faltantes para las Orders inconsistentes. De esta manera, necesitas determinar los IDs perdidos. Usualmente uso una consulta SQL como esta (creo que será fácil adaptarla a la situación apropiada):
SELECT O.Customer_ID FROM ORDERS O WHERE NOT EXISTS ( SELECT C.Customer_ID FROM CUSTOMERS C WHERE O.Customer_ID=C.Customer_ID)
Después de eso, puedes insertar manualmente registros con la lista de claves primarias faltantes y ejecutar backup/restore nuevamente.
Bombeo de datos consistentes
Si crees que es aceptable perder registros inconsistentes, puedes bombear todos los datos de la base de datos parcialmente restaurada a una base de datos vacía y simplemente omitir los registros inconsistentes, usando el siguiente enfoque:
-
Descarga la herramienta gratuita IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip
-
Crea solo la base de datos de metadatos a partir del backup de la base de datos reparada (después de IBFirstAID) usando el comando
gbak -c -m -user SYSDBA -pass masterkey Disk:\Path\backup.fbk Disk:\Path\fresh.fdb
-
Ejecuta IBDataPump y configura la base de datos parcialmente reparada como Origen, y la base de datos vacía nueva como Destino
-
Haz clic en las siguientes pestañas, haz clic en los botones apropiados y en la 3ª pestaña haz clic en “Pump”. Espera a que se complete (puede ser un proceso largo; para tener una idea, puedes verificar la dinámica de crecimiento del tamaño de la base de datos de destino).
-
Como resultado, tendrás una base de datos fresh.fdb con relaciones de claves foráneas consistentes: está completamente bien.
Si la base de datos tiene un bucle con claves foráneas, IBDataPump te advertirá y te dará una lista de tales restricciones: una o más de ellas deben eliminarse antes de que el bombeo esté disponible.
Por supuesto, ha habido casos en los que el bombeo requiere un enfoque especial, y si te enfrentas a tal situación, por favor contacta a nuestro soporte.