[BabelfishPG] Usando tds_fdw para acceder a BabelfishPG
Consultando BabelfishPG/MSSQL Server desde Postgres
Series: BabelfishPG
¿Soporta TDS, verdad?
Algunas cosas pasan una vez en la vida, y la historia alrededor de esto es bastante particular. Un cliente requirió algo que al principio sonaba contraintuitivo: migrar una base de datos Postgres existente a BabelfishPG.
La cosa era que la aplicación era un núcleo crítico del negocio, con una gran cantidad de código que requeriría años para migrar completamente para soportar otra estrategia de almacenamiento. Pero la razón real era que su cliente no quería apegarse a ningún modelo de licenciamiento privado, y requería usar soluciones Open Source.
Babelfish era su primera opción, WiltonDB también fue considerado. Pero, considerando Babelfish una variante de Postgres – ya que implementa protocol hooks a nivel de motor –, sería imprudente apegarse a un fork de variante considerando que las releases son más frecuentes que el upstream de Postgres.
Entonces, como profesional, pregunté continuamente las preguntas correspondientes:

Todo el concepto de Babelfish es permitir que una gran porción de las aplicaciones MSSQL se ejecuten bajo una licencia Open Source. Puedes estar preguntándote sobre el impacto en el rendimiento de hacer doble-parsing, pero si esto es un asunto para ti, podrías reconsiderar mantener la compatibilidad TSQL.
Pero si no tienes demasiadas opciones y decides usar BabelfishPG, aquí hay algunas consideraciones además del mantenimiento estándar de Postgres:
- Las actualizaciones requieren algunos pasos adicionales, siempre que se actualice la versión del motor y la extensión.
- Las soluciones de pool son bastante limitadas en el campo Open Source, para aprovechar conexiones a través del backend TDS. Cubrí esto en TDSPool con BabelfishPG.
- Se espera alguna degradación de rendimiento ya que aplica un doble-parsing de los statements.
- El volcado de datos tiene algunas adiciones además del vanilla Postgres. No está muy bien documentado, pero parece estar relacionado con una reescritura pesada de la utilidad pg_dump en el núcleo.
- El soporte TSQL es limitado, y necesitas evaluar tu migración a través de la herramienta Babelfish Compass, para adaptar las piezas necesarias.
Aparte de eso, BabelfishPG es un Postgres. Entonces, almacenamiento, replicación y configuración permanecen iguales.
Migración de Postgres a BabelfishPG (o MSSQL Server a Postgres)
Como dijimos, Babelfish almacena datos en tipos de datos de Postgres. Cómo Babelfish mapea esos tipos de datos es un tema por sí mismo.
El caso más común sería insertar los datos directamente en las tablas de Postgres:
- Un FDW desde un Postgres remoto a la base de datos Postgres que tiene la base de datos Babelfish inicializada.
- Transformar los datos vía consultas en el remoto, e insertar en tablas Postgres que fueron definidas previamente en Babelfish.
Como dije, este caso es atípico, ya que estamos moviendo Postgres a MSSQL Server. Aunque, podría ser posible que tengas las mismas razones sobre licenciamiento y quieras migrar MSSQL Server a Babelfish.
Afortunadamente, hay una extensión que proporciona un Foreign Data Wrapper que soporta TDS: tds_fdw.
Si el caso es que quieres migrar desde un MSSQL Server a BabelfishPG, el proceso sería;
- Una vez que inicializaste Babelfish con la estructura, crea la extensión
tdf_fdw, define las tablas foráneas. - A través de consultas, extrae datos del remoto e inserta en las tablas Postgres.
Usando tds_fdw contra BabelfishPG
Los siguientes pasos funcionan en bases de datos no inicializadas, es decir, fuera de la base de datos BabelfishPG. Para soportar tds_fdw en Babelfish +4, necesitas compilar la extensión babelfishpg_tsql como se establece en las instrucciones de instalación del paquete:
PG_CPPFLAGS='-I/usr/include -DENABLE_TDS_LIB' SHLIB_LINK='-lsybdb -L/usr/lib64' make
PG_CPPFLAGS='-I/usr/include -DENABLE_TDS_LIB' SHLIB_LINK='-lsybdb -L/usr/lib64' make install
Aunque sería más rápido insertar datos directamente en Postgres, también es posible hacerlo a través del protocolo TDS.
Puedes usar este FDW bidireccionalmente (como la mayoría de los FDW que hay):
- Traer datos de TDS a Postgres.
- Enviar datos de Postgres a TDS.
- Implementar vistas Postgres usando
queryen el FDW contra un MSSQL Server o BabelfishPG.
En este caso, me apegaré al escenario de mover datos de Postgres a BabelfishPG, aunque migramos datos usando FDW vanilla.
Afortunadamente, tds_fdw depende mucho de FreeTDS, así que necesitarás instalar las dependencias apropiadas:
sudo apt install freetds-common freetds-dev freetds-bin
La configuración de conexión para tds_fdw reside en el freetds.conf:
[global]
tds version = 7.4
dump file = /var/log/tdspool.log
[babelfish]
host = localhost
port = 1433
database = master ; puedes apegarse a una sola base de datos si no cambias entre esquemas
tds version = auto. 7.4 es la versión predeterminada. Ver cómo controlar la versión del protocolo TDS a través de babelfishpg_tds.tds_default_protocol_version.Instalar la extensión está adecuadamente documentado en Instalación en Ubuntu.
export TDS_FDW_VERSION="2.0.3"
wget https://github.com/tds-fdw/tds_fdw/archive/v${TDS_FDW_VERSION}.tar.gz
tar -xvzf v${TDS_FDW_VERSION}.tar.gz
cd tds_fdw-${TDS_FDW_VERSION}/
make PG_CONFIG=/opt/babelfish/4.1.0/bin/pg_config USE_PGXS=1
sudo make PG_CONFIG=/opt/babelfish/4.1.0/bin/pg_config USE_PGXS=1 install
Una vez que te conectas a la base de datos:
CREATE EXTENSION tds_fdw;
Ahora, el siguiente paso requerirá crear el SERVIDOR. Usaremos la etiqueta babelfish en el nombre del servidor, como se establece en el freetds.conf arriba. Más documentación en Foreign Server.
DROP SERVER babelfish CASCADE;
CREATE SERVER babelfish
FOREIGN DATA WRAPPER tds_fdw
OPTIONS (servername 'babelfish', port '1433',
database 'externalTDS', tds_version '7.4');
CREATE USER MAPPING FOR postgres
SERVER babelfish
OPTIONS (username 'babelfish_admin', password 'xxx');
Ahora, creamos la Foreign Table en la base de datos Postgres para apuntar al Servidor correspondiente:
CREATE FOREIGN TABLE tbl_employee_remote (
EMPLOYEE_ID uuid,
TYP_EMPLOYEE_ID uuid,
EMPLOYEE_NUMBER varchar(60),
EMPLOYEE_DOCUMENT varchar(40),
DEP_ID uuid,
EMPLOYEE_STATUS boolean,
BAN_ACC_NUMBER varchar(250),
EMPLOYEE_CREATEDATE timestamp,
EMPLOYEE_START_DATE timestamp,
EMPLOYEE_FINAL_DATE timestamp,
EMPLOYEE_ADDRESS varchar(400),
)
SERVER babelfish
OPTIONS ( table_name 'tbl_employee' );
Documentación en Foreign Tables. Cubriremos conversiones de tipos de datos en otro post.
Ahora, los datos pueden transformarse e insertarse con solo una consulta estándar:
INSERT INTO tbl_employee_remote
SELECT ... FROM tbl_employee ...
Incompatibilidades
IMPORT FOREIGN SCHEMA externalTDS
FROM SERVER babelfish
INTO extenalTDSSchema
OPTIONS (import_default 'true');
¡Gracias por leer!