Informazioni su FederatedX

Lo Storage Engine FederatedX è un fork dello Storage Engine Federated, che non è più mantenuto da Oracle. Lo scopo di FederatedX è mantenere attivo lo sviluppo del programma-- aggiungendo nuove funzionalità e correggendo i vecchi bug.

Cos'è lo Storage Engine FederatedX?

Lo Storage Engine FederatedX funziona sia con MariaDB sia con MySQL. Mentre gli altri SE sono creati come interfacce verso dati di livello più basso registrati sui file, FederatedX utilizza libmysql per dialogare con le fonti dei dati, cioè RDBMS remoti. Attualmente, siccome FederatedX può utilizzare solo libmysql, riesce a parlare soltanto con MySQL. Il progetto naturalmente è di permettergli di interfacciarsi con altri RDBMS usandoli come fonti di dati. Esisteva un progetto chiamato Federated ODBC che era in grado di dialogare con PostgreSQL, e questo tipo di funzionalità verranno portate in FederatedX nelle prossime versioni.

Storia

La storia di FederatedX deriva da quella di Federated. Cisco aveva bisogno di uno Storage Engine per MySQL che permettesse a un qualche tipo di dispositivo di routing di consolidare alcune tabelle remote, mettendolo in grado di interagire con esse come se si trovassero sul dispositivo stesso, anche se il realtà erano altrove; questo perché il dispositivo non aveva spazio a sufficienza per contenerle. Il primo prototipo di Federated è stato sviluppato da JD (bisognerebbe verificarlo- Brian Aker può controllare) utilizzando l'interfaccia HANDLER. Brian ha passato il codice a Patrick Galbraith e ha spiegato come doveva funzionare, e lui con l'aiuto di Brian e Monty ha realizzato uno Storage Engine che funzionava su MySQL 5.0.Infine, Federated è stato rilasciato al pubblico in una sottoversione di MySQL 5.0.

Quando MySQL 5.1 è stato pronto per gli ambienti di produzione, Federated aveva già molti miglioramenti, ad esempio:

  • I comandi SERVER sono stati aggiunti al parser. Questa funzionalità era stata richiesta da Cisco, che voleva poter modificare i parametri della connessione di numerose tabelle allo stesso tempo, senza doverne modificare la struttura o ricrearle.
  • Supporto di base alle transazioni-- per supportare le tabelle remote transazionali
  • Vari bug che dovevano essere corretti in MySQL 5.0
  • Capacità di Plugin

Come funziona FederatedX

Tutti gli Storage Engine devono implementare i metodi della API di una classe standard. FederatedX non è diverso dagli altri, in questo senso. La grande differenza è che FederatedX deve implementare questi metodi in modo da comporre istruzioni SQL che vengano eseguite su un server remoto e, se c'è un set di risultati, elaborarlo nel formato interno per poi restituirli all'utente.

Funzionamento interno di FederatedX

I normali file di database sono locali e pertanto: se si crea una tabella chiamata 'users', verrà creato un file chiamato 'users.MYD'. Un handler legge, inserisce, elimina e modifica i dati di questo file. Essi sono registrati in un formato particolare, perciò in lettura devono essere sottoposti a parsing, per identificare i campi, mentre in scrittura i campi devono essere registrati in questo formato.

Con lo Storage Engine FederatedX non vi sono file locali che contengono i dati di ogni tabella (come i .MYD). Un database esterno mantiene i dati che gli altri Storage Engine registrerebbero in un file. Questa operazione rende necessario l'uso dell'API client di MySQL per poter leggere, eliminare, modificare e inserire i record. I dati dovranno essere estratti attraverso una query SQL "SELECT * FROM users ". Dopodiché, per poterli leggere, si dovrà eseguire la funzione mysql_fetch_row una riga alla volta, poi dovranno essere convertiti dalla colonna a questa select nel formato che l'handler si aspetta.

Ecco le basi del funzionamento di FederatedX:

  • L'utente lancia un'istruzione SQL sulla tabella FederatedX locale. Questa istruzione viene tradotta in un albero di elementi
  • FederatedX usa l'API dell'handler mysql per implementare i vari metodi richiesti per uno Storage Engine. Ha accesso all'albero degli elementi ricavato dall'istruzione che è stata lanciata e all'oggetto Table con tutti i suoi membri Field.
  • Con queste informazioni, FederatedX costruisce un'istruzione SQL
  • L'istruzione SQL così creata viene inviata alla fonte dei dati remota attraverso libmysql, utilizzando l'API client mysql
  • Il database esterno legge il comando SQL e risponde inviando il risultato tramite l'API client mysql
  • Se l'istruzione SQL originale richiede un set di risultati dalla fonte dati esterna, lo SE FederatedX scorre i risultati e converte ogni riga e colonna nel formato interno dell'handler
  • Se l'istruzione SQL originale restituisce solo il numero di righe coinvolte dall'operazione (affected_rows), tale dato viene aggiunto alle statistiche della tabella in modo che l'utente possa vederlo.
Creare tabelle FederatedX

L'istruzione CREATE TABLE crea semplicemente un file .frm, e DEVE contenere informazioni in uno dei modi che seguono:

connection=scheme://nome_utente:password@nome_host:porta/database/nome_tabella
connection=scheme://nome_utente@nome_host/database/nome_tabella
connection=scheme://nome_utente:password@nome_host/database/nome_tabella
connection=scheme://nome_utente:password@nome_host/database/nome_tabella

Oppure si può usare la tabella introdotta in MySQL 5.1 per definire un server Federated (SQL/MED Spec xxxx)

connection="connessione_uno"
connection="connessione_uno/tabella_uno"

Ecco un esempio di stringa di connessione che specifica tutti i parametri possibili:

connection=mysql://nome_utente:password@nome_host/database/nome_tabella

Oppure, se si desidera usare un server Federated, prima lo si crea in questo modo:

create server 'server_uno' foreign data wrapper 'mysql' options
  (HOST '127.0.0.1',
  DATABASE 'db1',
  USER 'root',
  PASSWORD '',
  PORT 3306,
  SOCKET '',
  OWNER 'root');

E successivamente si crea la tabella FederatedX associandole il server Federated appena creato:

CREATE TABLE federatedx.t1 (
  `id` int(20) NOT NULL,
  `name` varchar(64) NOT NULL default ''
  )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='server_one';

(Si noti che in MariaDB, lo Storage Engine originale Federated è stato sostituito con il nuovo FederatedX. Per garantire la compatibilità all'indietro è stato mantenuto il vecchio nome "FEDERATED", che quindi va usato nella create table. Perciò in MariaDB, il nome dello SE dovrebbe essere specificato come "FEDERATED" senza la "X" finale).

Ecco l'equivalente di quanto è stato fatto sopra, utilizzando i parametri di connessione:

CONNECTION="mysql://root@127.0.0.1:3306/db1/t1"

E' anche possibile far sì che un server già definito punti a un nuovo schema:

ALTER SERVER 'server_uno' options(DATABASE 'db2');

Tutte le chiamate seguenti a una qualsiasi tabella FederatedX che utilizza 'server_uno' ora utilizzeranno db2.t1!E indovina? Non occorre eseguire un alter table per aggiornare le tabelle FederatedX al nuovo server!

Questa stringa di connessione, o connecton="connection string", è necessaria perché l'handler possa connettersi al server remoto (utilizzando un URL oppure il nome del server).

Chiamate ai metodi

Un modo per capire come funziona lo Storage Engine FederatedX è compilare una build di debug debug di MariaDB e abilitare il logging del trace. Usando una tabella di due colonne, con un record, insieme alle istruzioni SQL mostrate sotto, è possibile sapere quali metodi interni vengono chiamati e cosa fanno.

SELECT

Se ad esempio la query è "SELECT * FROM foo ", allora i primi metodi principali che si vedranno son il debug abilitato saranno:

ha_federatedx::info
ha_federatedx::scan_time:
ha_federatedx::rnd_init: share->select_query SELECT * FROM foo
ha_federatedx::extra

Poi per ogni riga estratta dal database esterno:

ha_federatedx::rnd_next
ha_federatedx::convert_row_to_internal_format
ha_federatedx::rnd_next

Dopo che tutte le righe dei dati sono state lette, si vede:

ha_federatedx::rnd_end
ha_federatedx::extra
ha_federatedx::reset
INSERT

Se la query è "INSERT INTO foo (id, ts) VALUES (2, now()); ", il trace è:

ha_federatedx::write_row
ha_federatedx::reset
UPDATE

Se la query è "UPDATE foo SET ts = now() WHERE id = 1; ", il trace risultante è il seguente:

ha_federatedx::index_init
ha_federatedx::index_read
ha_federatedx::index_read_idx
ha_federatedx::rnd_next
ha_federatedx::convert_row_to_internal_format
ha_federatedx::update_row

ha_federatedx::extra
ha_federatedx::extra
ha_federatedx::extra
ha_federatedx::external_lock
ha_federatedx::reset

Possibilità e limitazioni di FederatedX

  • Le tabelle DEVONO essere state create sul server esterno prima che l'handler possa svolgere qualsiasi operazione su di esse, prima versione. IMPORTANTE: se si deve utilizzare FederatedX sul server remoto, bisogna assicurarsi che la tabella alla quale ci si connette non punti alla tabella originale! E' come mettere due specchi uno di fronte all'altro, con il rifletto che continua all'infinito.
  • Non c'è modo, per l'handler, di sapere se il database esterno o la tabella remota sono stati modificati. Il motivo è che tale database funziona come un file dei dati, il quale si spera non venga mai modificato da nient'altro all'infuori del database. L'integrità dei dati della tabella locale potrebbe guastarsi, nel caso in cui il database esterno venga modificato.
  • Supporta SELECT, INSERT, UPDATE , DELETE e gli indici.
  • Non ci sono chiamate ad ALTER TABLE, DROP TABLE o altri comandi del Data Definition Language.
  • I prepared statement non vengono utilizzati nella prima implementazione, resta da capire se il limitato sottoinsieme dell'API client li supporta.
  • Questa implementazione utilizza SELECT, INSERT, UPDATE, DELETE, ma non HANDLER.
  • Non funziona con la cache delle query.

Come si usa FederatedX?

Utilizzare questo handler è molto semplice. Occorre avere due database funzionanti che possono trovarsi sullo stesso host o su macchine differenti.

Dopo che un server si è collegato all'host esterno (client), si crea una tabella in questo modo:

CREATE TABLE test_table (
  id     int(20) NOT NULL auto_increment,
  name   varchar(32) NOT NULL default '',
  other  int(20) NOT NULL default '0',
  PRIMARY KEY  (id),
  KEY name (name),
  KEY other_key (other))
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:9306/federatedx/test_federatedx';

Si notino i campi "ENGINE" e "CONNECTION": qui si impostano rispettivamente lo Storage Engine, "FEDERATED" appunto, e i dati relativi all'host esterno, cioè il database al quale il client si connette e che viene usato come file dei dati. Ovviamente, il database esterno gira sulla porta 9306, e anche l'altro è impostato per collegarsi alla stessa porta, mentre il database FederatedX su una porta differente. In questo ambiente, si utilizza la porta 5554 per FederatedX e la porta 5555 per il database esterno.

Poi, sul database esterno:

CREATE TABLE test_table (
  id     int(20) NOT NULL auto_increment,
  name   varchar(32) NOT NULL default '',
  other  int(20) NOT NULL default '0',
  PRIMARY KEY  (id),
  KEY name (name),
  KEY other_key (other))
ENGINE="<NAME>" <-- whatever you want, or not specify
DEFAULT CHARSET=latin1 ;

Questa tabella è identica (e deve esserlo necessariamente), eccetto per il fatto che non utilizza l'handler FederatedX e non ha bisogno di un URL.

Come vedere lo Storage Engine in azione

Sviluppando questo handler, ho compilato il database con FederatedX per il debug:

./configure --with-federatedx-storage-engine \
  --prefix=/home/mysql/mysql-build/federatedx/ --with-debug

Una volta compilato, ho lanciato un 'make install' (non allo scopo di installare i binari, ma per installare tutti i file che l'eseguibile si aspetta di trovare nella diretory che ho specificato nella build con:

--prefix=/home/code-dev/maria

Poi ho riavviato il server esterno:

/usr/local/mysql/bin/mysqld_safe \
  --user=mysql --log=/tmp/mysqld.5555.log -P 5555

Dopodiché sono tornato alla directory contenente il mysqld appena compilato<builddir>/sql/, e ho avviato gdb:

gdb ./mysqld

E nel prompt di gdb:

(gdb) run --gdb --port=5554 --socket=/tmp/mysqld.5554 --skip-innodb --debug

Successivamente ho aperto diverse finestre e per ognuna:

  1. Un tail sul trace: tail -f /tmp/mysqld.trace|grep ha_fed
  2. Un tail sulle chiamate SQL al database esterno: tail -f /tmp/mysqld.5555.log
  3. Una finestra con un client aperto sul server FederatedX alla porta 5554
  4. Una finestra con un client aperto sul server federatedx alla porta 5555

Ho creato una tabella sul server esterno sulla porta 5555, e poi sul server FederatedX 5554. A questo punto posso eseguire tutte le query che voglio sul server FederatedX ricordando sempre che qualsiasi cambiamento io faccia sulla tabelle, o se creo nuove tabelle, dovrò poi ripeterlo sul server esterno.

Un comando da controllare è 'show variables', che dice che FederatedX è supportato:

show variables like '%federat%'

e poi:

show storage engines;

Entrambi mostra l'handler FederatedX.

Come si crea un server Federated?

Un server Federated è un modo per definire una fonte di dati, con tutti i parametri della connessione, per non doverli specificare esplicitamente in una stringa.

Per esempio, supponiamo di avere una tabella t1 che si specifica in questo modo:

connection="mysql://patg@192.168.1.123/first_db/t1"

E' possibile definire un server:

create server 'server_one' foreign data wrapper 'mysql' options
  (HOST '192.168.1.123',		
  DATABASE 'first_db',		
  USER 'patg',
  PASSWORD '',
  PORT 3306,
  SOCKET '',		
  OWNER 'root');

Ora si può specificare il server invece della stringa di connessione completa:

connect="server_one"

In che modo FederatedX differisce dal vecchio Federated?

FederatedX, dal punto di vista dell'utente, rimane invariato in quasi tutte le sue parti. Le differenze tra FederatedX e Federated sono le seguenti:

  • Riscritto il codice sorgente principale di Federated da un singolo file ha_federated.cc in tre componenti astratti principali:
    • ha_federatedx.cc - Il cuore dell'implementazione di FederatedX
    • federated_io.cc - Classe connection padre che viene sovrascritta da ogni libreria client per i vari RDBMS
    • federatated_io_<driver>.cc - Classe derivata federated_io per un dato RDBMS
    • federated_txn.cc - Nuovo supporto per gli engine transazionali sul server remoto che utilizzano un poll di connessioni
  • Vari bug corretti (bisogna guardare i bug aperti di Federated)

Dove posso ottenere FederatedX?

FederatedX è parte di MariaDB 5.1 e successivo. MariaDB importa il FederatedX più recente quando c'è bisogno di correggere un bug. Si può ottenere il codice dalla home page di FederatedX.

Quali sono i piani futuri per FederatedX?

  • Supporto per altri RDBMS attraverso ODBC
  • Supporto per il pushdown delle condizioni
  • Possibilità di limitare le dimensioni dei set di risultati

Commenti

Sto caricando i commenti......
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.