Anuncios

Bienvenidos sean a este post, en el post anterior creamos las tablas pero hoy veremos como enviar instrucciones al servidor remoto.

Anuncios

El motor CONNECT nos permite enviar instrucciones SQL de forma arbitraria a un servidor remoto, su utilidad principal es la posibilidad de enviar instrucciones administrativas o la creacion de tablas remotamente sin la necesidad de tener que conectarnos directamente al servidor remoto, pero para esto necesitamos una tabla CONNECT especial, veamos un ejemplo:

CREATE TABLE srv1_sql (
  statement VARCHAR(128) NOT NULL FLAG = 0,
  number INTEGER NOT NULL FLAG = 1,
  message VARCHAR(255) FLAG = 2,
  warnings INTEGER NOT NULL FLAG = 3
)
  ENGINE = CONNECT,
  TABLE_TYPE = MYSQL,
  CONNECTION 'srv1',
  OPTION_LIST = 'Execsrc=1,Maxerr=10';
Anuncios
Anuncios

Para este caso los nombres de las columnas no son relevantes y se pueden definir de forma arbitraria, aqui usamos el nombre de un servidor seguido del sufijo _sql, esto puede ser lo mas logico si estamos definiendo una tabla especial para enviar las instrucciones a equipos remotos, inclusive puede ser mas util si decidimos usar a FEDERATEDX o SPIDER para acceder a los equipos remotos, sin embargo debemos ser cuidadosos a la hora de establecer los permisos para estas tablas especiales, estos deberian ser accedidas solo por root o usuarios con privilegios de SUPER.

Anuncios
Anuncios

La opcion OPTION_LIST es la encargada de darle el proposito de tabla especial, pero la verdadera opcion clave es Execsrs, la segunda opcion Maxerr nos sirve para establecer el numero maximo de errores y avisos que pueden ser recibidos desde el servidor por cada instruccion enviada, cada columna en la tabla tiene su significado, los cuales deberian ser claros si usamos nombres descriptivos, el proposito de estas es definido con FLAG que es una opcion de columna para CONNECT, si vemos el ejemplo y renombramos a message esto no afectara a la columna en si, mientras FLAG no sea modificado, veamos algunos de los valores que podemos usar en FLAG:

Valor de FLAGSignificado
0Instruccion para ejecutarse
1Numero de filas afectadas por una instruccion de escritura o devueltas por query
2Un mensaje informativo
3Numero de errores y avisos
Anuncios

El valor predeterminado para FLAG es 0 y habitualmente es omitido al momento de ejecutar CREATE TABLE, veamos el siguiente ejemplo donde podemos ejecutar una instruccion mediante la tabla anterior:

MariaDB [test]> SELECT * FROM srv1_sql WHERE statement = '
    '> CREATE OR REPLACE TABLE db1.new_table (id INT) ENGINE = InnoDB
    '> ';
Anuncios

En este caso enviamos la instruccion mediante la opcion WHERE, si todo sale bien deberia salir esta instruccion en nuestra columna statement, para saber si fue exitosa en warning debemos tener el valor de 0 y por ultimo para este en number deberia figurar como 0 porque es el valor que devuelve la instruccion CREATE TABLE cuando se ejecuta asi de simple, para verificarlo simplemente debemos crear una nueva tabla de la siguiente manera:

MariaDB [test]> CREATE TABLE new_table (
    -> id INT
    -> )
    -> ENGINE = CONNECT,
    -> TABLE_TYPE = MYSQL,
    -> CONNECTION 'srv1/new_table';
Anuncios

Una vez creado simplemente haciendo un query en esta nueva tabla, por ejemplo vamos a ejecutar un count sobre esta:

MariaDB [test]> SELECT COUNT(*) FROM new_table;
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
Anuncios

Pero tambien podemos enviar mas de una instruccion a un equipo remoto con un simple SELECT en una tabla CONNECT, esto puede ser usando un operador IN, veamos un ejemplo:

MariaDB [test]> SELECT * FROM srv1_sql WHERE statement IN (
    -> 'SET @@global.innodb_file_per_table = 1',
    -> 'SET @@global.innodb_strict_mode = 1'
    -> );
+--------------------------------------+--------+---------------+----------+
|statement                             | number | message       | warnings |
+--------------------------------------+--------+---------------+----------+
|SET @@global.innodb_file_per_table = 1|      0 | Affected rows |        0 |
|SET @@global.innodb_strict_mode = 1   |      0 | Affected rows |        0 |
+--------------------------------------+--------+---------------+----------+
2 rows in set (0.00 sec)
Anuncios

Como podemos ver en la salida gracias a IN nos devolvera una linea por cada instruccion que fue enviada en la opcion WHERE, ahora pasemos al tema de errores donde de manera predeterminada solo los fatales son enviados y contenidos en nuestra columna de FLAG tipo 2:

MariaDB [test]> SELECT * FROM srv1_sql WHERE statement = 'SET @@global.performance_schema = 1' \G
*************************** 1. row ***************************
statement:
SET @@global.performance_schema = 1

   number: 1238
  message: Remote: Variable 'performance_schema' is a read only variable
 warnings: 0
1 row in set (0.23 sec)
Anuncios

Si bien en la mayoria de las situaciones nos sera mas que suficiente pero en algunas circunstancias preferimos evaluar cada aviso para hacer una mejor depuracion de los errores, para esto existen tres comandos especiales que podemos enviar a una tabla especial como si fueran instrucciones SQL, el motor los analizara pero no los enviara al equipo remoto, veamos algunos ejemplos:

  • Note
  • Warning
  • Error
Anuncios

Estos le diran que muestre no solamente los errores sino tambien las notas y avisos en el resultado del SELECT, veamos un ejemplo:

MariaDB [test]> SELECT * FROM srv1_sql WHERE statement IN (
    -> 'Note','Warning', 'Error',
    -> 'DROP TABLE IF EXISTS t1',
    -> 'Note','Warning', 'Error',
    -> 'CREATE TABLE t1 (c INT) ENGINE = MySAM'
    -> );
+----------------------------------------+--------+--------------------------------------------+----------+
| statement                              | number | message                                    | warnings |
+----------------------------------------+--------+--------------------------------------------+----------+
| DROP TABLE IF EXISTS t1                |      0 | Affected rows                              |        1 |
| Note                                   |   1051 | Unknown table 'db1.t1'                     |        0 |
| CREATE TABLE t1 (c INT) ENGINE = MySAM |      0 | Affected rows                              |        2 |
| Warning                                |   1286 | Unknown storage engine 'MySAM'             |        0 |
| Warning                                |   1266 | Using storage engine InnoDB for table 't1' |        0 |
+----------------------------------------+--------+--------------------------------------------+----------+
5 rows in set (0.42 sec)
Anuncios

Del ejemplo anterior podemos desprender que la primera nota nos informa que intentamos eliminar una tabla que no existe, pero mas importante son las ultimas dos lineas que nos muestran un aviso de que no existe el moto MySam y por lo tanto se uso a InnoDB para crear la tabla, si bien esta tecnica no nos provee una forma directa para recuperar una serie de resultados de un equipo remoto si ttenemos una posibilidad de poder hacerlo con un procedimiento facil:

  • Enviar una instruccion CREATE TABLE … SELECT al equipo remoto
  • Crear una tabla CONNECT que apunta a una nueva tabla remota
  • Query a una tabla local
Anuncios

Tengan en cuenta que deben recrear la tabla local cada vez que la tabla remota cambie al menos que sus columnas sigan siendo las mismas, veamos el siguiente ejemplo para obtener la version del equipo remoto:

MariaDB [test]> SELECT * FROM srv1_sql WHERE statement = '
    '> CREATE OR REPLACE TABLE a.output AS SELECT version(), @@global.version_comment
    '> ';
+----------------------------------------------------------------------------------+--------+---------------+----------+
| statement                                                                        | number | message       | warnings |
+----------------------------------------------------------------------------------+--------+---------------+----------+
| CREATE OR REPLACE TABLE a.output AS SELECT version(), @@global.version_comment   |      1 | Affected rows |        0 |
+----------------------------------------------------------------------------------+--------+---------------+----------+
1 row in set (0.75 sec)

MariaDB [test]> CREATE OR REPLACE TABLE output
    ->      ENGINE = CONNECT,
    ->      TABLE_TYPE = MYSQL,
    ->      CONNECTION 'srv1/output';
Query OK, 0 rows affected (0.09 sec)

MariaDB [test]> SELECT * FROM output;
+---------------------+--------------------------+
| version()           | @@global.version_comment |
+---------------------+--------------------------+
| 10.0.11-MariaDB-log | MariaDB Server           |
+---------------------+--------------------------+
1 row in set (0.25 sec)
Anuncios

Para este caso primero crearemos una tabla en el equipo remoto, luego crearemos la tabla local para poder acceder a ella y por ultimo podemos ver el dato solicitado al equipo remoto.

Anuncios

En resumen, hoy hemos visto como enviar instrucciones a equipos remotos, desde la forma mas basica hasta algunas mas complejas, sus distintas opciones y particularidades, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50

Anuncio publicitario