Base de Datos corrupta debido a un corte de luz

12 comentarios

En general el Firebird es muy bueno en este aspecto, es casi imposible que una Base de Datos se corrompa por culpa de un corte de la energía eléctrica, sin embargo podría ocurrir si el corte se produjo justo en el momento en que se estaban insertando datos. Para solucionarlo:

  1. Verificar las tablas MON$ATTACHMENTS y MON$STATEMENTS
  2. Detener el servicio del Firebird
  3. Forzar un ROLLBACK con el programa GFIX.EXE
  4. Reiniciar el servicio del Firebird
  5. Verificar nuevamente las tablas MON$ATTACHMENTS y MON$STATEMENTS

Si tu Base de Datos está muy corrupta, no podrás ejecutar el paso 1. y deberás empezar con el paso 2.

1. Para verificar las tablas MON$ATTACHMENTS y MON$STATEMENTS

SELECT
   *
FROM
   MON$ATTACHMENTS
WHERE
   MON$STATE = 1

En la tabla MON$ATTACHMENTS se guardan los datos de las conexiones. La columna MON$STATE te dirá si la conexión está libre (cuando su valor es 0) o si la conexión está activa (cuando su valor es 1). Solamente deberías fijarte en las conexiones activas, o sea las que tienen un valor de 1 en la columna MON$STATE

SELECT
   *
FROM
   MON$STATEMENTS
WHERE
   MON$STATE = 1

La columna MON$TRANSACTION_ID muestra los números de todas las transacciones activas. Anota en un papel los números de las transacciones que deseas deshacer con el programa GFIX pues podrías necesitarlos cuando uses ese programa.

2. Para detener el servicio del Firebird

Inicio | Panel de Control | Firebird Server Manager | Stop

3. Para forzar un ROLLBACK con el programa GFIX.EXE

Inicio | Todos los programas | Accesorios | Símbolo del sistema

CD “C:\Archivos de Programa\Firebird\Firebird_2_5\bin”

Alternativa 1:

GFIX -user SYSDBA -password masterkey -rollback MiNúmeroTransacción MiBaseDatos.fdb

Alternativa 2:

GFIX -user SYSDBA -password masterkey -rollback all MiBaseDatos.fdb

 Como ves, aquí tienes dos alternativas posibles. Utilizarías la alternativa 1. cuando quieres especificar cual transacción se deshacerá, deberás reemplazar MiNúmeroTransacción por un número de transacción que obtuviste en el paso 1. y que anotaste en un papel. Y utilizarías la alternativa 2. para deshacer todas las transacciones, sin excepción. Lo normal es que utilices la alternativa 2. pero habrá casos en que prefieras la alternativa 1.

4. Para reiniciar el servicio del Firebird

Inicio | Panel de Control | Firebird Server Manager | Start

Conclusión

Aunque es muy raro que ocurra corrupción en una Base de Datos Firebird no es imposible (¿conoces la Ley de Murphy?) y los pasos de arriba te ayudarán a solucionarla. No siempre podrás conectarte a una Base de Datos corrupta y por lo tanto es posible que necesites empezar desde el paso 2. en cuyo caso deberás deshacer a todas las transacciones (la alternativa 2. de más arriba). Cuando una transacción se deshace (ROLLBACK) todo lo que se había hecho dentro de esa transacción se pierde o sea que cualquier INSERT/DELETE/UPDATE realizado dentro de esa transacción desaparecerá como si nunca se lo hubiera realizado.

Como una Base de Datos corrupta solamente causa trastornos lo conveniente es evitar que tal cosa ocurra. Una medida elemental de precaución es tener una buena UPS (unidad de energía ininterrumpida) conectada a la computadora donde se encuentra la Base de Datos. Otra medida elemental es jamás compartir la carpeta donde se encuentra la Base de Datos.

 

.

COMMIT y ROLLBACK en stored procedures y triggers

5 comentarios

Todas las transacciones del Firebird pueden terminar solamente con un COMMIT o con un ROLLBACK. Es un error muy frecuente en los principiantes escribirlos dentro de un stored procedure o de un trigger pero ese es un error grave y por lo tanto el Firebird lo rechazará.

Al ejecutar un stored procedure o un trigger esto siempre ocurre dentro de una transacción y los comandos COMMIT y ROLLBACK están afuera, se usan para terminarla, por eso no puede aceptarse que se escriban dentro de un stored procedure o un trigger.

 

 

 

Uso de las vistas

3 comentarios

Una vista (VIEW) es una consulta predeterminada que se guarda dentro de la Base de Datos lo cual hace que su ejecución sea mucho más rápida que escribir el SELECT correspondiente.

En general se usa con una cláusula WHERE.

Solamente se pueden usar las columnas que están definidas dentro de la vista, no se pueden utilizar las otras columnas que tenga la tabla.

Mantenimiento de índices

5 comentarios

  1. Siempre hay que definir TODAS las restricciones de integridad que pueden aplicarse a una tabla (Primary Key, Foreign Key, Unique Key) porque de esta manera las optimizaciones JOIN serán automáticas.
  2. Hay que definir un índice para CADA COLUMNA que se usará en las consultas (cláusula WHERE) que no hayan sido definidos en el punto 1.
  3. Se deben actualizar los índices regularmente. Al hacer un backup éstos se actualizan automáticamente así que los backups frecuentes también tienen esa ventaja
  4. Se deben actualizar los índices de todas las tablas que tienen 10.000 filas o más cada vez que se insertan/borran/modifican el 25% de sus filas
  5. Una vez que se tienen muestras representativas de datos del mundo real en la Base de Datos se debe evaluar la usabilidad de los índices para eliminar aquellos que no ayudan en las consultas y para agregar nuevos índices que permitan aumentar la velocidad de las consultas
  6. Los índices que tienen poca selectividad (pocos valores distintos) son muy malos porque no ayudan en la velocidad de las consultas y en cambio hacen que las inserciones/borrados/modificaciones sean muy lentos
  7. Si un índice de poca selectividad se usa frecuentemente acompañado de otros índices entonces quizás sea preferible hacer un solo índice compuesto
  8. Si siempre/frecuentemente se usa un grupo de columnas para condiciones de filtro, un índice compuesto sobre esas columnas puede aumentar drásticamente la velocidad de las

    consultas. Pero esto se debe hacer solamente si uno no está satisfecho con la velocidad que proveen los índices sobre las columnas individuales.

 

Cantidad máxima de modificaciones que puede tener un stored procedure

1 comentario

El Firebird permite que un stored procedure sea modificado como máximo 255 veces, pero el contador de modificaciones vuelve a cero cada vez que se hace un backup. Por lo tanto, si alguna vez te encuentras con un mensaje diciéndote que el stored procedure no se puede modificar porque ya se llegó a las 255 modificaciones la solución es sencilla: le haces un backup a tu Base de Datos, restauras ese backup y ya está.

 

¿Cómo saber si el Servidor se está comunicando con el Cliente?

1 comentario

Antes de enviarle un comando al Servidor lo correcto es que verifiquemos que puede comunicarse con el Cliente. Esa comunicación pudo haberse interrumpido por varias razones, debidas tanto a fallas del hardware como del software. Entonces ¿el Cliente se está pudiendo comunicar con el Servidor? Podemos responder a esta pregunta a través de la siguiente consulta:

SELECT
    CURRENT_TIME
FROM
    RDB$DATABASE

Si recibimos respuesta (es decir, si obtenemos la hora que tiene el Servidor) entonces está todo ok y se están comunicando entre sí. Si no recibimos respuesta, hay algún problema.

Como saber si la Base de Datos está validada.

5 comentarios

Algo muy importante en Firebird y en cualquier otro motor SQL es asegurarse que la Base de Datos está toda ok, que no tiene problemas. Para verificarla sigue estos pasos:

  1. Hazle un backup con el programa GBAK
  2. Ejecuta el programa GFIX (que encontrarás en la carpeta \BIN del Firebird) así:
    • GFIX -user SYSDBA -password masterkey MiBaseDatos.FDB -v -full
  3. Si ningún mensaje aparece, está todo ok, felicitaciones. Si aparece algún mensaje, a corregir urgente el problema

 

Para saber cuales puertos está usando la computadora

1 comentario

Por defecto el Firebird utiliza el puerto 3050 para comunicar la computadora donde se encuentra el Servidor con las computadoras donde se encuentran los Clientes (si prefieres o necesitas utilizar otro puerto, cambia la entrada RemoteServicePort en el archivo FIREBIRD.CONF, reemplaza el número 3050 por otro número de puerto. El Windows tiene reservados para su propio uso los primeros 1024 puertos, así que los números de puerto que puedes utilizar van desde el 1025 al 65535 pero debes tener mucho cuidado porque si otro programa está usando el número que le asignaste al Servidor del Firebird tendrás muchos conflictos)

Para saber cuales son los puertos que está “escuchando” la computadora, en la ventanita de símbolo del sistema (la ventanita negra del DOS) escribe:

NETSTAT

Nunca le asignes al Firebird un puerto que otro programa está usando, eso solamente puede ocasionarte muchos problemas.

Gracias al comando NETSTAT podrás saber si el número de puerto que le quieres asignar al Servidor del Firebird está siendo usado o está libre. Asegúrate de asignarle un número que esté libre.

Salvo que tengas una razón de mucho peso para hacerlo NO CAMBIES EL PUERTO DEL FIREBIRD, déjalo que siga escuchando al puerto 3050.

Conectar el Cliente al Servidor

15 comentarios

1. La versión del Firebird a instalar (tanto en el Servidor como en el Cliente) corresponde a los CPU de la computadora. En una computadora de 32 bits, Firebird de 32 bits; en una computadora de 64 bits, Firebird de 64 bits. En el caso del Cliente lo que importa son los bits de su computadora, no los bits del Servidor (o sea que si la computadora Cliente es de 32 bits se le debe instalar el Firebird de 32 bits)

2. El Servidor debe tener liberado el puerto que utiliza el Firebird para las conexiones TCP/IP (normalmente es el puerto 3050, salvo que lo hayas cambiado)

3. En la computadora Cliente debe instalarse el driver ODBC del Firebird

4. Para asegurarse que el Cliente pueda “ver” al Servidor se puede escribir el comando PING en la ventanita “símbolo del sistema”, por ejemplo:

PING 192.168.0.101

5. Después de verificar que el Cliente puede ver al Servidor, en el string de conexión se puede escribir:

  • \\PC_SERVIDOR\C:\DATOS\MiBaseDatos.FDB       — Puede usarse esta forma dentro de una red local
  • 192.168.0.101:C:\DATOS\MiBaseDatos.FDB             — También puede usarse de esta forma en una red local
  • 7.82.252.110:C:\DATOS\MiBaseDatos.FDB               — Así se conecta a una computadora remota
  • 7.82.252.110/3051:C:\DATOS\MiBaseDatos.FDB  — Cuando se usa un puerto distinto al 3050 (que es el puerto por defecto)
  • MiServidor:C:\DATOS\MiBaseDatos.FDB                    — Esta forma es muy buena porque oculta la IP de MiServidor
  • 7.82.252.110:MiBaseDatos                                                — En este caso MiBaseDatos es un alias, no es un archivo con extensión .FDB
  • MiServidor:MiBaseDatos                                                     — Esta es la forma recomendable por ser la más segura de todas
  • MiServidor/3051:MiBaseDatos                                        — Cuando no se usa el puerto 3050 sino otro puerto

6. Si hay espacios en blanco deben usarse comillas o apóstrofos para delimitar el nombre de la Base de Datos, por ejemplo:

  • 7.82.252.110:C:\MIS DATOS\MiBaseDatos.FDB           no funcionará porque hay un espacio en blanco entre MIS y DATOS
  • ‘7.82.252.110:C:\MIS DATOS\MiBaseDatos.FDB’         sí funcionará porque está delimitado con apóstrofos

Como evitar que una tabla tenga más de una fila

1 comentario

A veces necesitamos que una tabla tenga una fila, solamente una fila, y nada más que una fila. Por ejemplo si en esa tabla guardamos parámetros para la configuración de nuestra aplicación. Entonces, debemos evitar que por descuido o mala intención alguien le inserte más filas. Podemos conseguir eso de varias maneras:

1. Agregándole una Primary Key o una Unique Key y luego escribir un trigger como este:

CREATE TRIGGER MiTrigger FOR MiTabla ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
BEGIN
    NEW.EMP_IDENTI = 1;
END

Así, la primera fila tendrá 1 en la columna EMP_IDENTI y los siguientes intentos de inserción serán rechazados (por supuesto que la columna EMP_IDENTI no debe ser actualizada por otro trigger)

2. Otra forma, que puede utilizarse cuando la tabla ya tiene una fila

IF (INSERTING) THEN
    EXCEPTION MiExcepcion 'No se pueden insertar nuevas filas' ;

Older Entries