Archive for the 'trucos de la abuela' Category

Exportando datos en vivo desde mySQL hasta postgreSQL usando mysqldump

Tuesday, June 17th, 2008

En muchos casos el proceso de migración de datos de una base de datos a otra se convierte en un tedioso proceso de convertir cosas de un punto a otro (ejemplo: crear archivos separados por coma o dumps SQL que debemos modificar) y muchas veces la gente no explota las capacidades de mySQL como “agente de migración” rápido y efectivo.

MySQL goza de una capacidad interesante para “emular” el comportamiento de otras bases de datos, esto se logra via la variable sql_mode; a nivel de la herramienta de migración mysqldump es a través del parámetro –compatible; con esta capacidad, podremos generar “volcados” (dumps) de tablas completas de una manera “compatible” con otras bases de datos, incluyendo postgreSQL.

La situación de ejemplo:

Tengo dos bases de datos, una en mysql llamada dpt_venezuela (División Político Territorial Venezolana), la obtuve a partir de interesantes transformaciones de la data que entrega el INE (Instituto Nacional de Estadística) que es una vulgar hoja de excel a la cual hay que hacerle muchas transformaciones en los datos (y que gracias a LOAD DATA INFILE en mySQL eso es un paseo); tengo las 4 tablas (entidades, municipios, parroquias y ciudades) en un schema “dpt” dentro de una DB en postgreSQL para un proyecto (iut); la idea ahora es llenar esas tablas sin tener que hacerlo a mano ni tener que generar un DUMP para trabajar con COPY, sino hacerlo directo y “en vivo”.

Describe de la tabla dpt_entidades (mySQL)

CREATE TABLE `dpt_entidades` (
  `id_entidad` int(8) unsigned NOT NULL AUTO_INCREMENT,
  `entidad` varchar(50) DEFAULT NULL,
  `cod_entidad` char(3) DEFAULT NULL,
  `capital` varchar(128) DEFAULT NULL,
  `mostrar` tinyint(1) unsigned NOT NULL DEFAULT '1',
  PRIMARY KEY (`id_entidad`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8

Tabla dpt.entidades (postgreSQL):

CREATE TABLE dpt.entidades
(
  id_entidad int4 NOT NULL,
  entidad varchar(65) NOT NULL,
  cod_entidad char(3) NOT NULL,
  capital varchar(128),
  mostrar int2 NOT NULL DEFAULT 1,
  CONSTRAINT dpt_entidades_pk PRIMARY KEY (id_entidad)
)
WITHOUT OIDS;
ALTER TABLE dpt.entidades OWNER TO postgres;

Entendiendo a mysqldump:

mysqldump puede generar archivos separados por coma, xml o en su defecto (que usaremos) sentencias INSERT INTO; como hay diferencias sintácticas entre mySQL y postgreSQL usaremos un parámetro de mysqldump conocido como “–compatible” y que recibe como valor la palabra “postgresql”, el resto de parámetros son útilitarios de mysqldump (–skip-opt elimina comentarios y opciones “solo mysql” y -n me permite obviar las sentencias de CREATE TABLE de la tabla respectiva, –tables me permite generar una lista de tablas que serán exportadas).

Nota: debemos agregar –default-character-set=utf8 ya que por defecto, mysql hará el dump en latin1 y postgreSQL es por defecto utf8.

Inicialmente, la sentencia de mysqldump quedaría asi:

mysqldump -u root --password=paswd001! --database dpt_venezuela -t -n --compact --skip-opt --default-character-set=utf8 --compatible=postgresql --tables dpt_entidades

El único problema que tenemos ahora, es que la sentencia INSERT INTO generada:

INSERT INTO "dpt_entidades" VALUES (1,'Distrito Capital','DCA','Caracas',1);

No es aún compatible con postgresql, ya que como verán, la relación public.dpt_entidades no existe, sino que es dpt.entidades (schema: dpt, tabla: entidades); pero no hay nada que el comando linux sed no pueda arreglar.

Arreglando la salida con sed:

sed es en resumidas cuentas un comando editor; nos permite hacer sustituciones y reemplazos sobre archivos o sobre la salida std de nuestra consola; por ende, podemos pasar toda la salida del comando mysqldump a través de sed y modificar lo que queramos, en nuestro caso, un reemplazo de “dpt_entidades” > dpt.entidades.

Para ello, adicionalmente usamos pipe ( | ) un “concatenador” de la consola Unix, que nos permite indicar que la salida de un comando irá integramente hacia la entrada del comando siguiente; de esta manera, nuestra sentencia mysqldump ahora dice:

mysqldump -u root --password=paswd001! --database dpt_venezuela -t -n --compact --skip-opt --default-character-set=utf8 --compatible=postgresql --tables dpt_entidades | sed -e "s|\"dpt_entidades\"|dpt.entidades|"

Ahora si vemos, nuestras sentencias INSERT tienen la forma que postgreSQL necesita:

INSERT INTO dpt.entidades VALUES (1,'Distrito Capital','DCA','Caracas',1);

Ahora solo falta entregarle estas sentencias a psql (el comando de entrada de postgreSQL).

psql y entrando datos a postgreSQL:

Usar psql es bastante simple, solamente convocamos la DB (iut) usando el usuario owner de la misma (jesuslara) y pidiendo password (-W), en nuestro caso, recibirá datos de entrada usando PIPE ( | ) que viene desde el comando mysqldump+sed anteriormente ejecutado:

psql -U jesuslara -W -h localhost -d iut

y la cosa al final queda:

mysqldump -u root --password=paswd001! --database dpt_venezuela -t -n --compact --skip-opt --default-character-set=utf8 --compatible=postgresql --tables dpt_entidades | sed -e "s|\"dpt_entidades\"|dpt.entidades|" | psql -U jesuslara -W -h localhost -d iut

Entrando los datos correctamente hasta la tabla dpt.entidades de la base de datos iut.

Repetimos esto para municipios, parroquias o ciudades (o de plano, hacemos un dump de todas las tablas, agrandando acorde el sed para transformar todas las salidas a la vez) y tendremos migrados nuestras tablas desde mysql a postgresql sin necesidad de archivos intermedios.

Usando mySQL como gestor de migraciones:

sql_mode y –compatible son grandes aliados a la hora de migrar datos; LOAD DATA INFILE es mucho más poderoso que COPY y por ejemplo, hay muchas cosas allá afuera en MS Access o MS Fox Pro que ameritan ser migradas y mySQL ayuda muchisimo para cargar (además de normalizar y transformar) la data que venga de orígenes heterogéneos y llevarla limpia y sin problemas a postgreSQL.

Que disfruten este truco de la abuela!.

Nota: recuerden que sed es un comando muy poderoso y pueden por ejemplo, aplicar expresiones regulares de reemplazo para la transformación de los datos y los metadatos.

[Ponencia] Linux Tweak & Tunning

Saturday, June 14th, 2008

Durante algún tiempo he agrupado una colección de trucos y detalles sobre los sistemas Linux y fue hace poco que decidí agruparlos en una presentación que he llamado “Linux Tweak & Tunning”; espero ir agrandándola a medida que vaya coleccionando trucos y nuevas cosas.

Agrego adicionalmente unas modificaciones a la charla de “integración de Servicios de infraestructura con openLDAP” con la integración hacia freeRadius y autenticación.

Charla: Linux Tweak & Tunning

Charla: Integración de servicios de infraestructura sobre openLDAP

Un ppp/options y un peers para Movilnet

Monday, April 28th, 2008

Tuve que reinstalar mi equipo (tenia mucho tiempo sin hacerlo, ya era hora) y olvidé respaldar el archivo ppp/options; necesario para configurar las conexiones PPP a través de la red EvDO de Movilnet (me imagino que debe funcionar para Movistar/Digitel).

Inicialmente estaba recibiendo muchos errores del tipo:

PAP Authentication Failed

Si embargo, no era problema del login y password; sino de la forma como se gestionaba la conexión (LCP) y la autenticación PAP; como evidentemente pasé (otra vez) varios días probando opciones hasta que por fín logré una configuración que conecta a la primera (a lo sumo, segundo intento); entonces decidí hacer un artículo posteando ambos archivos para quien tenga problemas para conectarse a la red EvDO de movilnet via linux.

El archivo options

el archivo options va en /etc/ppp/options y es este.

Una de las cosas que caracteriza al archivo options es evitar usar CHAP como medio de autenticación:

-chap

Y forzar siempre PAP

+pap

Además de activar el control por hardware:

crtscts

Y evitar que la conexión se caiga y mantener un enlace persistente:

persist

Hay otras opciones adicionales agregadas; espero que les sean útiles.

El archivo peers

Luego que usas pppconfig para crear una conexión; esta agrega un archivo en /etc/ppp/peers/movilnet

Voy a explicar alguna de las opciones más importantes del archivo.

hide-password
noauth

#Opción donde se guarda los parámetros de conexión del modem EvDO:
connect “/usr/sbin/chat -v -f /etc/chatscripts/movilnet”

debug

#El modem EvDO PCMCIA de Movilnet es una tarjeta EvDO módulo airprime y se monta como este dispositivo:
/dev/ttyUSB0

#Baudrate de la conexión:
115200

#Convertir a esta conexión como la ruta por defecto (ejecuta un route add default gw al gateway de movilnet):
defaultroute

#El IP lo obtengo de la red de movilnet/cantv:
noipdefault

#El username de la conexión:
user “TU TELEFONO@cantv.net”

#Importante: persist mantiene y re-intenta la conexión si no cae la llamada, en vez de salirse:
persist
usepeerdns

#Movilnet no usa compresión de la conexión; por ende, para evitar fallos, agregar esto:
nodeflate

remotename movilnet

Con estas opciones; solo basta ejecutar:

pon movilnet

Y nos conectaremos a la red movilnet, usando el password asignado y como username, nuestro número telefónico (sin el 0416) seguido del dominio (@cantv.net).

Evaluando el proceso de conexión:

Apr 28 14:09:46 lexotanil pppd[4386]: rcvd [IPCP ConfNak id=0x1 <addr 10.17.202.19> <ms-dns1 200.44.32.12> <ms-dns3 192.168.11.35>]
Apr 28 14:09:46 lexotanil pppd[4386]: sent [IPCP ConfReq id=0x2 <compress VJ 0f 01> <addr 10.17.202.19> <ms-dns1 200.44.32.12> <ms-dns3 192.168.11.35>]
Apr 28 14:09:46 lexotanil pppd[4386]: rcvd [CCP ConfReq id=0x2]
Apr 28 14:09:46 lexotanil pppd[4386]: sent [CCP ConfAck id=0x2]
Apr 28 14:09:46 lexotanil pppd[4386]: rcvd [CCP ConfAck id=0x2]
Apr 28 14:09:46 lexotanil pppd[4386]: rcvd [IPCP ConfAck id=0x2 <compress VJ 0f 01> <addr 10.17.202.19> <ms-dns1 200.44.32.12> <ms-dns3 192.168.11.35>]
Apr 28 14:09:46 lexotanil pppd[4386]: local  IP address 10.17.202.19
Apr 28 14:09:46 lexotanil pppd[4386]: remote IP address 192.168.74.97
Apr 28 14:09:46 lexotanil pppd[4386]: primary   DNS address 200.44.32.12
Apr 28 14:09:46 lexotanil pppd[4386]: secondary DNS address 192.168.11.35
Apr 28 14:09:46 lexotanil pppd[4386]: Script /etc/ppp/ip-up started (pid 4405)
Apr 28 14:09:46 lexotanil pppd[4386]: rcvd [CCP TermReq id=0x3]
Apr 28 14:09:46 lexotanil pppd[4386]: CCP terminated by peer
Apr 28 14:09:46 lexotanil pppd[4386]: sent [CCP TermAck id=0x3]
Apr 28 14:09:46 lexotanil pppd[4386]: Compression disabled by peer.

Al recibir “Compression Disabled by peer” y obtenido IP y DNS; la conexión está lista; veremos:

>route -n

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.74.97   0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
0.0.0.0         0.0.0.0         0.0.0.0         U     0      0        0 ppp0

Que tenemos a ppp0 como routa por defecto a Internet.

Notas adicionales

Tomen en cuenta que el hardware (su modem evdo) NO se autentica; por ende, cualquier tarjeta EvDO sirve para conectar con cualquier equipo; así no sea el número de teléfono asociado a ella.

Nota adicional: Traten en lo posible de si usan PPP como gestor de conexión; de desactivar network-manager; este “tumbará” su puerta de enlace por defecto (la de la conexión EvDO) para colocar la puerta de enlace de la red wifi que detecte; además, network-manager cada 10 minutos (al menos he visto ese comportamiento en Debian, Ubuntu y Fedora) intentará ejecutar un dhclient (obtener una IP de un servidor DHCP) para obtener una IP para las interfaces monitorizadas.