In MariaDB non è sempre necessario eseguire esplicitamente una CREATE TABLE perché una tabella compaia. A volte la tabella può già esistere nello Storage Engine, senza che il server lo sappia, perché non c'è un file .frm associato ad essa. Può accadere per diversi motivi, per esempio perché un motore di cluster ha creato la tabella in un altro server MariaDB. Ma qualunque sia la ragione, vi è un meccanismo con il quale lo Storage Engine può comunicare al server che quella tabella esiste. Il meccanismo si chiama table discovery e gli Storage Engine che vogliono servirsene devono utilizzare la discovery API.

Questa pagina descrive la vecchia discovery API, implementata in MySQL per NDB Cluster. Una nuova API più generica è attualmente in lavorazione.

Si compone di tre parti.

Primo, capisce che una tabella (magari menzionata in una query SELECT) non esiste, chiede a tutti gli Storage Engine se la conoscono. Per farlo chiama il metodo discover() di handlerton. Il metodo ha la seguente definizione:

int discover(handlerton *hton, THD* thd, const char *db, const char *name,
             unsigned char **frmblob, size_t *frmlen);

Prende come argomenti il nome del database e della tabella; restituisce 0 se questa esiste, altrimenti 1. Se restituisce 0, ci si aspetta che allochi (con my_malloc()) un buffer e vi copi l'immagine binaria completa del file .frm della tabella. Il server lo scrive poi su disco, creando il file .frm. I parametri di output frmblob e frmlen servono a restituire informazioni sul buffer. Spetta al chiamante la responsabilità di deallocare il buffer con my_free().

Secondo, in certi casi il server vuole solo sapere se la tabella esiste, ma non ha realmente bisogno di aprirla e non ha bisogno dell'immagine del file .frm. In questi casi usare il metodo discover() sarebbe uno spreco di risorse, perciò si usa il più leggero table_exists_in_engine(). Questo metodo ha la seguente definizione:

int table_exists_in_engine(handlerton *hton, THD* thd,
                           const char *db, const char *name);

e restituisce uno dei codici HA_ERR_, solitamente HA_ERR_NO_SUCH_TABLE o HA_ERR_TABLE_EXIST.

Terzo, ci sono situazioni in cui il server pensa che la tabella esista (ha trovato il file .frm ed è riuscito a leggerlo), ma dal punto di vista dello Storage Engine il file non è corretto. Per esempio la tabella è già stata cancellata dallo SE, o la sua definizione è stata modificata (di nuovo, modificata solo dallo SE). In tal caso il file .frm è obsoleto e il server dovrà rilevare di nuovo la tabella. Lo Storage Engine lo comunica al server restituendo il codice di errore HA_ERR_TABLE_DEF_CHANGED dal metodo open() dell'handler. Quando lo riceve, il server chiama il metodo discover() per ottenere la nuova immagine .frm. Ciò significa che dopo che la tabella è stata aperta, il server non si aspetti che i metadati cambino. Lo Storage Engine dovrebbe quindi accertarsi (magari con un qualche tipo di lock) che la definizione della tabella non possa essere modificata, finché questa rimane aperta.

E quarto, un utente potrebbe chiedere un elenco delle tabelle presenti in un certo database. Con SHOW TABLES o interrogando le tabelle di INFORMATION_SCHEMA. L'utente si aspetta di vedere tutte le tabelle, ma il server non è in grado di rilevarle una ad una, perché non conosce i loro nomi. In questo caso utilizza allora una tecnica particolare. E' il metodo find_files() nell'handlerton, che ha la seguente definizione:

int find_files(handlerton *hton, THD *thd,
               const char *db, const char *path,
               const char *wild, bool dir, List<LEX_STRING> *files);

e di solito restituisce 0 in caso di successo e 1 in caso di fallimento. Gli argomenti sono: db - il nome del database, path - il suo percorso, wild un pattern SQL con caratteri jolly (per esempio presente nell'istruzione SHOW TABLES LIKE '...'), e dir, se impostato, dice di rilevare i database anziché le tabelle.

Commenti

Sto caricando i commenti......