Firebird 3: usando bases de datos anteriores

6 comentarios

Ok, ya hemos instalado a Firebird 3, ahora queremos empezar a utilizarlo. ¿Cómo lo hacemos?

Lo más probable es que tengamos bases de datos creadas con versiones anteriores de Firebird. Entonces hay que convertir esas bases de datos al formato que usa Firebird 3.

El Firebird utiliza un número interno llamado ODS (On Disk Structure) para saber con cual versión de Firebird fue creada una Base de Datos. Cada versión del Firebird tiene un número único de ODS. Esos números son:

FIREBIRD3_15

Captura 1. Si haces clic en la imagen la verás más grande

Si no coincide la ODS de una Base de Datos con la versión del Servidor del Firebird entonces no podremos conectarnos a esa Base de Datos.

¿Cómo cambiamos la ODS de una Base de Datos?

Mediante un ciclo backup/restore. Hacemos el backup con la versión actual y el restore con la nueva versión.

IMPORTANTE: Esto solamente funciona en una dirección: de una ODS menor a una ODS mayor.

Ejemplo: Usar una Base de Datos creada con Firebird 2.5 en Firebird 3

firebird3_16

Captura 2. Si haces clic en la imagen la verás más grande

Como podemos ver en la Captura 2. la conexión falló porque la ODS de la Base de Datos es 11.2 y la ODS que reconoce el Servidor del Firebird es 12.0

Entonces lo que debemos hacer es convertir la ODS de esa Base de Datos a 12.0, para que pueda ser reconocida. Para ello necesitaremos realizar un ciclo backup/restore.

FIREBIRD3_17

Captura 3. Si haces clic en la imagen la verás más grande

En la Captura 3. hicimos el backup con la versión 2.5 del Firebird ¿cómo sabemos eso? Por dos pistas: a) la carpeta donde se encuentra el programa GBAK.EXE y b) el puerto que usamos para conectarnos a la Base de Datos. En nuestros ejemplos usamos el puerto 3050 para Firebird 2.5 y el puerto 3053 para Firebird 3.

Ahora que ya tenemos el backup realizado el siguiente paso es restaurarlo. Para ello, nos ubicamos en la carpeta donde instalamos al Firebird 3 y escribimos:

FIREBIRD3_18

Captura 4. Si haces clic en la imagen la verás más grande

Cuando la restauración finalice tendremos una nueva Base de Datos, de nombre PRUEBA1-3.FDB y cuya ODS será 12.0 y por lo tanto nos podremos conectar a ella usando Firebird 3.

FIREBIRD3_19

Captura 5. Si haces clic en la imagen la verás más grande

Como podemos ver en la Captura 5. no fue necesario especificar el puerto 3053 ¿por qué no? porque para la conexión usamos el programa ISQL.EXE que se instala junto con el Firebird 3. Sin embargo, en otros casos sí necesitaremos especificar dicho puerto:

FIREBIRD3_20

Captura 6. Si haces clic en la imagen la verás más grande

En el string de conexión que vemos en la Captura 6. indicamos la dirección IP de la computadora donde se encuentra la Base de Datos y también el puerto de esa computadora que usa el Servidor del Firebird 3.

Como siempre, hay que indicar además el path completo a la Base de Datos (ese path es desde el punto de vista del Servidor), el nombre de un usuario, y la contraseña de ese usuario.

Conclusión:

Para que en Firebird 3 podamos usar una Base de Datos creada con una versión anterior del Firebird debemos hacer un ciclo backup/restore. El backup lo hacemos con la versión anterior del Firebird y el restore lo hacemos con Firebird 3.

Para conectarnos a la Base de Datos restaurada a veces será necesario especificar el puerto que utiliza el Firebird 3.

Artículos relacionados:

Instalando Firebird 3 (1)

Instalando Firebird 3 (2)

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios

Error 10060. No se puede conectar al Servidor

8 comentarios

Si en el archivo FIREBIRD.LOG, que se encuentra en la misma carpeta donde instalaste el Firebird, encuentras el error 10060 eso significa que no se pudo realizar la conexión con el Servidor porque ya transcurrió demasiado tiempo desde que se intentó la conexión y por eso fue rechazada.

Ocurre generalmente cuando el firewall (cortafuegos) bloquea la conexión al puerto 3050 (o al puerto que estés utilizando para conectarte con el Servidor).

Posibles soluciones:

  1. Configurar al firewall (cortafuegos) para que permita la conexión al puerto 3050 (o al que sea que esté usando el Servidor)
  2. Si en el string de conexión se estaba usando el nombre de la computadora donde se encuentra el Servidor, cambiarlo por el IP de la computadora donde se encuentra el Servidor. En muchos casos así se soluciona.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Usando Servidor y embedded en la misma aplicación (2)

Deja un comentario

En un artículo anterior ya habíamos visto las ventajas de usar Servidor y embedded en la misma aplicación. Ahora veremos otro caso donde tal aprovechamiento puede resultar muy útil.

Escenario:

En un supermercado grande hay 40 cajas, de las cuales por lo menos 15 están constantemente trabajando. Normalmente esas cajas están conectadas a una Base de Datos mediante Cliente/Servidor y si todo funciona bien entonces es lo correcto porque todas las operaciones se realizan con rapidez.

Cada vez que se realiza una venta, se registran los datos de esa venta en una de las cajas y se insertan filas a las tablas respectivas de la Base de Datos. Todo bien hasta allí.

Sin embargo, ¿qué sucedería si por alguna razón se interrumpe la conexión de una (o varias, o todas) caja/s con el Servidor?

Escribir con papel y lápiz los datos de las ventas porque la conexión con el Servidor se cortó no es una opción en un supermercado que tiene mucha clientela.

¿Y entonces, qué hacemos?

Solución:

La solución es que si la aplicación detecta que se ha interrumpido la conexión con el Servidor entonces guarde los datos de las siguientes ventas en una Base de Datos local a la cual se conectará mediante embedded.

Así, ninguna venta se perderá, las cajas seguirán trabajando normalmente, y al final del turno, al final del día, o cuando se restablezca la conexión, los datos de las ventas que se habían insertado en la Base de Datos local serán transferidos a la Base de Datos remota.

Conclusión:

Que se corte la conexión entre una computadora y la Base de Datos que se encuentra en el Servidor no es frecuente pero puede ocurrir. Nuestra aplicación debe ser lo suficientemente inteligente como para prever esa posibilidad y actuar en consecuencia, de tal manera que esa interrupción de la conexión no cause trastornos a los usuarios.

La gran mayoría de los usuarios quizás ni se entere de que en cierto momento se interrumpió la conexión de su computadora con el Servidor porque siguieron trabajando normalmente, como si tal interrupción nunca hubiera ocurrido. Para ellos, todo fue normal.

Sin embargo, nuestra aplicación sí detectó que se interrumpió la conexión y entonces en la computadora de ese usuario automáticamente empezó a utilizar una Base de Datos alternativa, o auxiliar.

Cuando la conexión se restableció, o al final del turno del cajero, o al final del día, o cuando se decidió, todo lo que estaba en la Base de Datos alternativa se copió a la Base de Datos normal, la que se encuentra en el Servidor.

De esta manera, ninguna venta se perdió, y tampoco ningún dato se perdió.

Artículos relacionados:

Usando Servidor y embedded en la misma aplicación

El índice del blog Firebird21

El foro del blog Firebird21

¿Es seguro usar Servidor y embedded al mismo tiempo?

Deja un comentario

Sí, … pero con algunas condiciones.

En ocasiones podrías querer conectarte usando Servidor (es decir: Classic, SuperClassic, o SuperServer) a una Base de Datos y en ocasiones podrías querer conectarte usando embedded. Entonces … ¿puedes hacer algo así?

Sí, pero no puedes realizar la conexión al mismo tiempo.

Veamos:

  1. Conectarse a la Base de Datos A con Servidor y a la Base de Datos A con embedded. NO PERMITIDO
  2. Conectarse a la Base de Datos A con embedded y a la Base de Datos A con Servidor. NO PERMITIDO
  3. Conectarse a la Base de Datos A con Servidor y a la Base de Datos B con embedded. PERMITIDO
  4. Conectarse a la Base de Datos A con embedded y a la Base de Datos A con embedded. NO PERMITIDO

La diferencia entre el caso 1. y el caso 2. está en quien se conectó primero a la Base de Datos A, pero sin importar quien lo haya hecho, la segunda conexión no es permitida.

Como habrás notado al mirar los casos anteriores, si te conectas por embedded, lo haces de forma exclusiva. Ninguna otra conexión a esa misma Base de Datos es permitida.

Resumiendo:

Se puede conectar usando Servidor y usando embedded en la misma computadora, pero la condición es que se haga a bases de datos distintas.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Conexión a través de Internet

22 comentarios

En esta época es cada vez más frecuente que debamos conectarnos remotamente a las bases de datos. Y aunque hay varias formas de hacer eso, lo normal es que lo hagamos a través de Internet.

Entonces, ¿qué necesitamos para poder establecer una conexión exitosa?

ROUTER

Gráfico 1. Si haces clic en la imagen la verás más grande

En el Gráfico 1 podemos ver un caso típico: una computadora remota se conecta a Internet a través de un router, y nuestro Servidor se conecta a Internet a través de otro router. La computadora remota solamente conoce la IP pública o IP estática, pero no conoce (ni debería conocer jamás) la IP que nuestro Servidor tiene en la red local.

Como podemos ver en el Gráfico 1, nuestro router tiene dos IP, una pública, conocida por todo el mundo (que en este ejemplo es 120.130.140.150) y una privada, conocida solamente dentro de la red local (que en este ejemplo es 192.168.1.1)

La computadora donde tenemos instalado el Servidor del Firebird también tiene una IP privada (que en este ejemplo es 192.168.1.31).

¿Qué debemos hacer para que la conexión pueda ser establecida?

Decirle al router que toda la comunicación que se realice a través de Internet mediante un determinado puerto (para el caso de Firebird, generalmente es el 3050) se redirija a la computadora donde tenemos nuestro Servidor de Firebird.

O sea, si alguien envía datos a nuestro router usando la IP estática y el puerto que establecimos, el router enviará esos datos a la computadora donde tenemos el Servidor del Firebird.

Ejemplo de conexión:

A través de las siguientes capturas de pantalla veremos como debemos configurar nuestro router para que podamos conectarnos remotamente a una Base de Datos. Aquí, se usó un router de la marca Motorola, y por supuesto que si el router es de otra marca las capturas serán diferentes, pero en esencia es la misma cosa.

Router2

Captura 1. Si haces clic en la imagen la verás más grande

Router3

Captura 2. Si haces clic en la imagen la verás más grande

Router4

Captura 3. Si haces clic en la imagen la verás más grande

Router5

Captura 4. Si haces clic en la imagen la verás más grande

Resumen:

  1. Abrir el navegador (Internet Explorer, Firefox, Google Chrome, etc.)
  2. En la barra de direcciones escribir: 192.168.1.1 (esta es la IP privada del router)
  3. En Username escribir: AdminTHW (todo junto, sin espacios en blanco)
  4. En Password escribir: motorola
  5. Hacer clic sobre el botón Advanced
  6. Hacer clic sobre el botón Forwarding
  7. Escribir el IP de la computadora donde se encuentra el Servidor del Firebird. En este ejemplo es 192.168.1.31
  8. En Start Port y en End Port escribir 3050
  9. Hacer clic sobre el botón Apply

Conexión:

A partir de este momento ya podremos conectarnos a la Base de Datos remota con un comando como el siguiente:


CONNECT 120.130.140.150:D:\BASESDATOS\CONTA.FDB USER SYSDBA PASSWORD masterkey;

Problemas:

Si no puedes conectarte a la Base de Datos, verifica lo siguiente:

  • Que la IP pública pueda ser accedida. Eso lo harías con el comando PING. Abre una ventanita “Símbolo del sistema” y escribe: PING 120.130.140.150 (desde luego que aquí escribirías el PING que le corresponde a tu IP pública o estática, 120.130.140.150 es solamente un ejemplo)

Router6

Captura 5. Si haces clic en la imagen la verás más grande

Como puedes ver en la Captura 5, el IP 120.130.140.150 no puede ser accedido. Cuando la conexión puede realizarse sin problema todos los paquetes enviados deben ser recibidos y el porcentaje de perdidos debe ser 0%

Importante: Tú no debes escribir 120.130.140.150 sino el IP público (o estático) que tiene tu router.

  • Que el firewall no esté bloqueando el puerto que usas para conectarte. En nuestro ejemplo usamos el puerto 3050, ese puerto debe estar abierto o nada podrá enviarse o recibirse a través de él.
  • Que la computadora donde se encuentra el Servidor del Firebird sea visible para las otras computadoras de la red local. Eso también puedes averiguarlo con el comando PING y luego poniendo la IP privada, en nuestro ejemplo sería: PING 192.168.1.31
  • Que te conectes a la Base de Datos usando el mismo puerto que le dijiste al router que redirigiera al Servidor del Firebird. Por defecto, con Firebird se usa el puerto 3050, si quieres usar otro puerto puedes hacerlo pero en tu string de conexión debes indicarlo, porque el Firebird no puede adivinar que estás usando otro puerto. Así que se lo debes indicar:
CONNECT 120.130.140.150/3152:D:\BASESDATOS\CONTA.FDB USER SYSDBA PASSWORD masterkey;

En este ejemplo usamos el puerto 3152 para la conexión, por lo tanto es ese puerto el que debes redirigir en el router (y para que el Firebird use el puerto 3152 debes indicárselo en el archivo FIREBIRD.CONF, en la entrada RemoteServicePort).

Seguridad:

Internet es una red pública y por lo tanto todo lo que se envíe a través de esa red es pasible de ser interceptado y leído por personas no autorizadas. Para disminuir el riesgo existen programas (como el Zebedee, por ejemplo) que comprimen y encriptan los datos, haciendo por lo tanto la tarea de los hackers mucho más dificultosa. Firebird envía los datos sin encriptarlos entonces si son interceptados podrán ser leídos bastante fácilmente. Al usar Zebedee conseguiremos dos cosas: 1) como los datos se comprimen entonces la velocidad de transmisión será más alta, 2) como los datos se encriptan entonces la posibilidad de ser leídos por personas no autorizadas es nula o casi nula.

Por lo tanto, es altamente recomendable usar Zebedee (o algún programa similar) si la Base de Datos podrá ser accedida a través de Internet.

Conclusión:

Para que podamos conectarnos remotamente a una Base de Datos, los datos enviados a nuestra IP pública usando el puerto 3050 (o el que especifiquemos) deben ser redirigidos a la computadora donde se encuentra el Servidor del Firebird.

Para ello, debemos configurar el router, porque de lo contrario jamás podremos realizar la conexión. Al router se le indica que todos los datos que lleguen a través del puerto 3050 (o el que deseemos) se envíen a la computadora cuya IP privada se especifique.

Como Internet es una red pública, es recomendable que se use algún programa (como el Zebedee) para encriptar los datos que se envían entre computadoras.

Artículos relacionados:

Proteger a las bases de datos visibles en Internet

Usando Zebedee con Firebird

Usando Zebedee con Firebird. Parte 2

Ejemplos del uso de Zebedee con Firebird

El índice del blog Firebird21

El foro del blog Firebird21

Evitando que un usuario se conecte más de una vez (método mejorado)

10 comentarios

En este artículo ya habíamos visto un método para evitar que los usuarios se conecten más de una vez a la Base de Datos:

Evitando que un usuario se conecte más de una vez a la Base de Datos

pero allí podríamos tener un pequeño problema si la computadora donde se encuentra el Servidor del Firebird se apaga incorrectamente, dejando por lo tanto nombres de usuarios en la tabla CONECTADOS. Esos usuarios evidentemente cuando se reinicia el Servidor no estarán conectados pero en la tabla CONECTADOS dirá que sí lo están. Una solución sería que un usuario quien no estaba conectado borre todas las filas de esos usuarios en la tabla CONECTADOS. Funcionará bien, pero, hmmmmmmm, no es profesional, ¿verdad?

Aquí hay otro método para borrar a esos usuarios “fantasmas”. Son “fantasmas” porque la tabla CONECTADOS nos indica que están conectados a la Base de Datos pero la realidad es que no lo están.

Lo que haremos será agregarle una columna a la tabla CONECTADOS y en esa columna guardaremos el identificador de la conexión. Luego, en nuestro trigger antes de intentar la inserción borraremos a todos los usuarios cuyos identificadores de conexión no se encuentren en la tabla CONECTADOS y también en la tabla MON$ATTACHMENTS.

En la tabla del sistema MON$ATTACHMENTS se guardan los datos de todas y cada una de las conexiones actuales. Uno de esos datos es el identificador de la conexión.

Entonces, la estructura de nuestra tabla CONECTADOS ahora sería la siguiente:

CONECTADOS1

Captura 1. Si haces clic en la imagen la verás más grande

Como puedes ver en la Captura 1. a la tabla CONECTADOS se le agregó la columna CON_IDECON, para guardar en esa columna el identificador de la conexión (ese identificador lo encontraremos en la tabla MON$ATTACHMENTS y para la conexión actual siempre será igual a CURRENT_CONNECTION).

El trigger para insertar un usuario a la tabla CONECTADOS

Nuestro trigger ahora cambiará un poco, quedará así:

Listado 1.

CREATE TRIGGER INSERTAR_CONECTADO
   ACTIVE ON CONNECT
   POSITION 2
AS
BEGIN

   -- Primero, se borran las filas de los usuarios que no están conectados
   -- pero aparecen como conectados

   DELETE FROM
      CONECTADOS
   WHERE
      CON_IDECON NOT IN (SELECT MON$ATTACHMENT_ID FROM MON$ATTACHMENTS);

   -- Segundo, se trata de insertar una fila a la tabla CONECTADOS.
   -- Como la tabla CONECTADOS tiene una restricción UNIQUE KEY, un usuario
   -- no se podrá conectar más de una vez al mismo tiempo

   INSERT INTO CONECTADOS
              (CON_IDENTI, CON_IDECON , CON_NOMBRE , CON_TIMEST)
       VALUES (0 , CURRENT_CONNECTION, CURRENT_USER, CURRENT_TIMESTAMP);

END;

¿Qué hace este trigger?

Primero, borrará todas las filas de la tabla CONECTADOS cuyo valor de CON_IDECON no coincida con algún valor de ATTACHMENT_ID de la tabla ATTACHMENTS. En otras palabras, en la tabla CONECTADOS quedarán solamente los nombres de los usuarios que efectivamente están conectados a la Base de Datos, no tendrá filas “fantasmas”.

Segundo, intentará insertar una fila a la tabla CONECTADOS. Si el nombre del usuario que intenta la conexión no existe en esa tabla entonces podrá continuar pero si existe entonces ocurrirá una excepción y se evitará la conexión.

El trigger para borrar un usuario de la tabla CONECTADOS

Este trigger quedará exactamente igual al que habíamos visto en el artículo anterior, no tiene por qué cambiar.

Listado 2.

CREATE TRIGGER BORRAR_CONECTADO
   ACTIVE ON DISCONNECT
   POSITION 3
AS
BEGIN

   DELETE FROM
      CONECTADOS
   WHERE
      CON_NOMBRE = CURRENT_USER;

END;

Conclusión:

Para evitar que un apagado anormal del Servidor del Firebird deje usuarios “fantasmas” en la tabla CONECTADOS podemos tener en esa tabla una columna que nos indique cual es el identificador de cada conexión. Así, antes de intentar insertar los datos de un usuario en la tabla CONECTADOS borramos las filas de esa tabla que no tengan una conexión activa. Lo que conseguiremos será que la tabla CONECTADOS siempre nos muestre los nombres de los usuarios que efectivamente se encuentran conectados.

Artículos relacionados:

Limitando la cantidad de usuarios conectados

Evitando que un usuario se conecte más de una vez a la Base de Datos

El índice del blog Firebird21

El foro del blog Firebird21

Evitando que un usuario se conecte más de una vez a la Base de Datos

14 comentarios

A veces quieres que un usuario no pueda conectarse desde más de una computadora al mismo tiempo, o desde la misma computadora más de una vez. Eso es especialmente importante en las aplicaciones de seguridad o donde se maneja dinero. Entonces, ¿cómo evitamos que lo haga?

En nuestra ayuda vienen los triggers de las bases de datos. Estos se disparan cuando alguien se conecta o se desconecta de la Base de Datos. Lo que podemos hacer es crear una tabla, la llamamos por ejemplo CONECTADOS y cada vez que alguien se conecta insertamos una fila a esta tabla, y cada vez que se desconecta borramos la fila que le corresponde.

CONECTADOS1

Captura 1. Si haces clic en la imagen la verás más grande

La columna CON_NOMBRE se encuentra en una restricción Unique Key, como podemos ver en su DDL:

ALTER TABLE CONECTADOS ADD CONSTRAINT UQ_CONECTADOS UNIQUE (CON_NOMBRE);

¿Por qué?

Porque de esa manera no tendremos que verificar nosotros que un usuario no se conecte más de una vez, el Firebird hará esa tarea por nosotros.

Si no tuviéramos esa restricción Unique Key entonces tendríamos que buscar el nombre del usuario en la tabla CONECTADOS y si existe allí entonces lanzar una excepción para evitar que se conecte. Pero al tener la restricción no es necesario que hagamos eso, ya que el mismo Firebird lanzará automáticamente la excepción. O sea, nos ahorramos trabajo.

En un trigger de la Base de Datos que se dispara cuando alguien se conecta haríamos el intento de insertar una fila en la tabla CONECTADOS, algo como:

CREATE TRIGGER INSERTAR_CONECTADO
   ACTIVE ON CONNECT
   POSITION 2
AS
BEGIN

   INSERT INTO CONECTADOS
              (CON_IDENTI, CON_NOMBRE , CON_TIMEST)
       VALUES (0 , CURRENT_USER, CURRENT_TIMESTAMP);

END;

Si el nombre del usuario no existe en la tabla CONECTADOS entonces se conectará sin problemas, pero si existe entonces el Firebird lanzará una excepción “violation of PRIMAY or UNIQUE KEY constraint …”

Y como lanzó una excepción el usuario no podrá conectarse.

No debemos olvidarnos de crear otro trigger de la Base de Datos, el que se encargará de borrar la fila que le corresponde al usuario de la tabla CONECTADOS, sería algo como:

CREATE TRIGGER BORRAR_CONECTADO
   ACTIVE ON DISCONNECT
   POSITION 3
AS
BEGIN

   DELETE FROM
      CONECTADOS
   WHERE
      CON_NOMBRE = CURRENT_USER;

END;

Entonces, cuando el usuario se desconecta la fila con su nombre será borrada de la tabla CONECTADOS.

¿Y qué ocurre si se apagó anormalmente la computadora donde se encuentra el Servidor del Firebird?

Si las cosas se hacen bien y como corresponde entonces la computadora donde se encuentra el Servidor del Firebird jamás debería apagarse intempestivamente, debería tener sí o sí una UPS en buen estado y nunca se apagaría esa computadora si hay alguien conectado a la Base de Datos.

Pero sabemos que no siempre las cosas se hacen correctamente. En ese caso los usuarios que hubieran estado conectados a la Base de Datos no podrán volver a conectarse y se requerirá que otro usuario, alguien que no estaba conectado, borre los nombres de dichos usuarios de la tabla CONECTADOS.

Luego de eso ya podrán conectarse nuevamente.

Ventaja adicional:

Este método además de evitar que un usuario se conecte más de una vez también tiene la ventaja de que siempre podremos saber quienes son TODOS los usuarios conectados.

CONECTADOS2

Captura 2. Si haces clic en la imagen la verás más grande

Como podemos ver en la Captura 2. un simple SELECT nos dirá los nombres de cada usuario conectado y también la fecha y hora de su conexión.

Conclusión:

Si queremos evitar que un usuario se conecte más de una vez a la Base de Datos y al mismo tiempo entonces podemos crear una tabla y dos triggers: uno que se disparará cuando intenta conectarse y el otro que se disparará cuando se desconecta.

De esta manera solamente podrá conectarse una vez. Tendrá que desconectarse para luego volver a conectarse.

Adicionalmente este método tiene la ventaja de que en cualquier momento podremos saber quienes son los usuarios conectados y cuando se conectaron.

Artículos relacionados:

Como evitar que se conecten a una Base de Datos

Impidiendo la conexión a una Base de Datos

El índice del blog Firebird21

El foro del blog Firebird21

Older Entries