Qualcosa in piu' su MySQL

Avete gia' letto il documento su MySQL e quindi pensate di sapere gia' tutto. In realta' c'e' molto di piu' da imparare... continuate a leggere e scoprirete cosa! Per esempio su Installazione, Upgrade, Utilizzo, Utenti ed abilitazioni, Locking e transazioni, Storage Engine, Configurazione e tuning, Amministrazione, Architettura, MySQL Cluster, Programmazione, Fork, ...
Naturalmente la migliore e piu' completa sorgente di informazioni e' il sito ufficiale MySQL ed in particolare il manuale on-line, ma forse troverete qualcosa di utile anche qui. Questo documento e' stato preparato utilizzando la versione 4.1 di MySQL su un Linux Red Hat 3 ma e', mutatis mutandis, valido anche per le altre versioni (verificato fino alla versione MySQL 5.1 su Linux Red Hat 5.4).

Installazione

Spesso su Linux MySQL e' gia' installato: basta usarlo!

Se non e' cosi' e' possibile il reperimento del software e l'installazione con un solo comando: apt-get install mysql-server (Debian, Ubuntu, ...) yum install mysql-server (Red Hat, CentOS, ...), o yast -i mysql-server (Suse).
E' molto semplice anche l'installazione con gli RPM, spesso utilizzati per disporre dell'ultima versione di MySQL. E' sufficiente scaricare gli RPM corretti dal sito MySQL (pacchetti e versioni possono cambiare, dalla versione 5.0 e' stata utilizzata una suddivisione differente):
RPMDescrizione
MySQL-server-version.rpmIl motore della base dati: mysqld
MySQL-client-version.rpmLa parte client: mysql
MySQL-devel-version.rpmAmbiente di sviluppo
MySQL-embedded-version.rpmEmbedded MySQL (single-task)
MySQL-bench-version.rpmBenchmark suite
MySQL-Max-version.rpmLibrerie per l'utilizzo di Storage Engine aggiuntivi
MySQL-ndb-storage-version.rpmMySQL cluster: NDB Storage Engine
MySQL-ndb-management-version.rpmMySQL cluster: NDB Manager
MySQL-ndb-extra-version.rpmNDB extra
MySQL-ndb-tools-version.rpmNDB Tools

In una configurazione tipica sono necessari solo gli RPM MySQL-server e MySQL-client. Per effettuare l'installazione dare i comandi:

# rpm -ila MySQL-server-version.rpm
# rpm -ila MySQL-client-version.rpm

In meno di 5 minuti l'installazione e' conclusa, i servizi attivi, i DB mysql e test creati (dalla 5.0 viene creato anche il database information_schema che contiene il data dictionary).

Per controllare i pacchetti installati: rpm -qa | grep -i mysql Infine, per rimuove i pacchetti il comando e' rpm -e [PKG_NAME].

Installazione binaria

Un'altra possibilita' e' quella di utilizzare un tarball. Effettuato il download dell'ultima versione (dal sito http://www.mysql.com), decompresso e scaricato il tar, i passi da seguire sono i seguenti:
# groupadd mysql
# useradd -g mysql mysql
# cd /usr/local
# gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
# ln -s full-path-to-mysql-VERSION-OS mysql
# cd mysql
# scripts/mysql_install_db --user=mysql
# chown -R root  .
# chown -R mysql data
# chgrp -R mysql .
# bin/mysqld_safe --user=mysql &

Terminata l'installazione e' opportuno creare una base dati con lo script mysql_install_db, inserire le password per gli utenti con il comando SET PASSWORD, abilitare eventuali accessi dalla rete agendo sulle tabelle user, db e host (senza dimenticare il comando FLUSH PRIVILEGES;)...

Per maggiori dettagli consultate il documento Installazione di MySQL su Unix.

Upgrade

L'upgrade di MySQL e' spesso banale: basta installare i nuovi RPM ed in pochi minuti le basi dati ed il software vengono automaticamente aggiornate alla nuova release. L'unico requisito e' quello di effettuare l'upgrade di una sola versione alla volta. Per esempio per passare dalla 4.0 alla 5.1 i passi sono: 4.0 -> 4.1, 4.1 -> 5.0, 5.0 -> 5.1.

In qualche caso l'aggiornamento non avviene automaticamente: ad esempio in caso di installazione binaria o di migrazione con un dump ad una versione successiva. In questo caso e' possibile caricare tutti i dati salvati con mysql_dump, quindi lanciare il comando mysql_upgrade ed infine riavviare la base dati. Lo script mysql_upgrade si occupa di aggiornare tutte le tabelle la cui struttura e' cambiata (eg. i grant tra la versione 5.0 e la 5.1). Per caricare invece i contenuti aggiornati dell'help va lanciato lo script SQL fill_help_tables.sql.

E' ovvio, ma e' meglio ricordarlo: prima di ogni upgrade, cosi' come prima di ogni attivita' di amministrazione significativa, e' necessario effettuare un backup completo delle basi dati!

Utilizzo

L'utilizzo di una base dati MySQL con il client mysql e' semplice e potente.

$ mysql -u root -p'password'
mysql> use test
mysql> show tables
mysql> create table emp (ename char(20));
mysql> show create table emp
mysql> select * from emp;
MySQL puo' anche essere utilizzato con script:
mysql <<EOF
use test
select * from emp;
EOF
Un file di comandi SQL puo' essere lanciato dall'interprete utilizzando il comando SOURCE. In effetti i comandi riconosciuti dal client mysql sono parecchi:
List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear command.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute a SQL script file. Takes a file name as an argument.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.

Rispetto ad altri RDBMS MySQL concede molti errori agli utenti e cerca comunque di eseguire lo statement digitato. In caso di qualche problema viene generato un warning ma lo statement viene comunque eseguito. Quindi il casting delle variabili, l'assegnazione di valori di default, gli arrotondamenti, ... sono normali in MySQL e perdonano, corregendoli, molti errori degli utenti. Un'eccezione e' forse nella gestione del maiuscolo/minuscolo che, a volte, presenta qualche difficolta'.

L'accesso da remoto e' ugualmente semplice. MySQL opera su una porta socket (3306). L'unica avvertenza e' quella di abilitare host ed utenti nel modo corretto. Quale elemento in piu' e' nel prossimo capitolo.

La creazione delle tabelle utilizza una sintassi SQL Standard. I datatype supportati da MySQL sono tanti!

Un campo puo' essere definito di tipo SERIAL che e' un sinonimo di BIGINT UNSIGNED NOT NULL AUTO_INCREMENT. In ogni caso fa quello che ci si aspetta: definisce un valore progressivo!

Oltre ai normali comandi SQL sono disponibili diversi comandi come:

SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern']
SHOW CREATE DATABASE db_name
SHOW CREATE TABLE tbl_name
SHOW DATABASES [LIKE 'pattern']
SHOW ENGINE engine_name {LOGS | STATUS }
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW GRANTS FOR user
SHOW INDEX FROM tbl_name [FROM db_name]
SHOW INNODB STATUS
SHOW [BDB] LOGS
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern']
SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']
SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern']
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern']
SHOW WARNINGS [LIMIT [offset,] row_count]
...
Da ultimo l'help in linea, richiamato con il comando HELP e' semplice e completo.

Oltre che da linea comando e' possibile utilizzare ambienti grafici Client/Server come MySQL Browser, SQuirreL, Toad, ...:

Abilitazioni ed utenti

MySQL permette una gestione completa e sofisticata delle abilitazioni e degli utenti.

Le abilitazioni vengono registrate sulle tabelle: mysql.user, mysql.db, mysql.host, mysql.tables_priv, mysql.columns_prov, mysql.procs_priv e vengono generalmente gestite con i comandi di GRANT e REVOKE o con comandi DML direttamente sulle tabelle. Il comando FLUSH PRIVILEGES; attiva le abilitazioni effettuate con il DML (oppure si puo' riattivare mysqld...).

La tipologia di privilegi e' possibile gestire e' molto ampia: ALL, ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE USER, CREATE VIEW, DELETE, DROP, EXECUTE, FILE, INDEX, INSERT, LOCK TABLES, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SELECT, SHOW DATABASES, SHOW VIEW, SHUTDOWN, SUPER, UPDATE, USAGE, GRANT OPTION.
Commentarli tutti sarebbe inutilmente pesante: molti sono ovvi! ALL assegna tutti i privilegi tranne GRANT OPTION. USAGE in pratica non definisce alcun privilegio: serve solo a poter definire un utente.

I privilegi vengono gestiti a piu' livelli:

Gli utenti oggetto delle abilitazioni sono definiti come coppia username@hostname. Lo username puo' essere anonimo, in questo caso viene indicato con la stringa vuota ''. L'hostname puo' essere definito come IP address, come nome semplice o come nome completo con dominio. L'hostname accetta l'utilizzo delle wildcard _ e %. Insomma dovrebbe essere chiaro cosa significa: GRANT ALL ON *.* TO ''@'%';
Anche il nome del database permette wildcard. In questo caso pero' deve essere utilizzato l'apice reverso: GRANT ALL ON `test%`.* TO 'test'@'%';

L'installazione di MySQL crea un utente anonymous per tutti gli accessi locali (da localhost). Naturalmente puo' essere disabilitato con una opportuna REVOKE o con una DELETE dalla tabella mysql.user.
Utili anche i comandi da Unix per impostare le password all'utente root (per default senza password da localhost):

/usr/bin/mysqladmin -u root password newPassword
/usr/bin/mysqladmin -u root -h hostname password newPassword

Per modificare la password di un utente il comando e': SET PASSWORD FOR user = PASSWORD('some password')
Come visto i comandi sono quelli di GRANT, ma funziona anche... mysql> INSERT INTO mysql.user VALUES ('10.0.0.84','root','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
La valutazione dei privilegi segue un ordine preciso: global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
Attenzione va posta quando sono presenti tabelle con nomi in maiuscolo/minuscolo e la variabile lower_case_table_names e' settata. Il GRANT funziona ma... la REVOKE no!
Hai modificato manualmente le tabelle degli utenti/grant e embra non funzionare quanto hai modificato? Esegui FLUSH PRIVILEGES!

Riassumendo le possibilita' sono parecchie... ma tipicamente si decide il livello su cui abilitare gli utenti e si lavora con quello semplificando tutto! La scelta naturalmente dipende dall'utilizzo del DB e dal livello di sicurezza necessario.

Transazioni e Lock

MySQL consente una gestione completa delle transazioni e dei lock con le proprieta' ACID.

La gestione delle transazioni implementata da MySQL e' standard e completa. Consente quindi di gestire la concorrenza in modifica dei dati ed il rollback delle transazioni in caso d'errore.
Di default MySQL e' impostato in AUTOCOMMIT (ogni statement SQL e' una transazione) e con ISOLATION LEVEL impostato su REPEATABLE READ (una select restituisce sempre gli stessi dati all'interno di una transazione anche se questi sono stati modificati da transazioni committate). I valori di default possono essere cambiati con:

mysql> set AUTOCOMMIT=0
mysql> set TRANSACTION ISOLATION LEVEL READ COMMITTED
Il comando di SET permette di indicare la clausola [GLOBAL | SESSION].

Se piu' utenti accedono in modifica agli stessi dati il primo aquisisce il lock e gli altri attendono. In caso di deadlock o comunque di lock mantenuti per un tempo troppo ampio, MySQL manda in timeout le transazioni pendenti:

mysql> update emp set ename='SCOTT';

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

Affinche' tali funzionalita' siano presenti e' necessario che le tabelle oggetto delle modifiche siano state create con Storage Engine che supportano le transazioni (eg. InnoDB, NDB). Una transazione puo' riguardare tabelle definite su Engine differenti. Naturalmente solo per quelle definite su Engine transazionali varranno le proprieta' ACID ed i lock...

Storage Engine

MySQL permette di utilizzare modalita' di memorizzazione diversa per ogni singola tabella: gli Storage Engine. Gli Storage Engine sono molto diversi tra loro e forniscono funzionalita' specifiche.
Si tratta di una possibilita' molto importante offerta da MySQL. Le differenze tra i diversi Engine non sono soltanto prestazionali ma anche funzionali. Se si vuole un motore leggero, veloce, efficiente, con ottime prestazioni nelle ricerche e nella gestione dei testi la scelta sara' MyISAM; se e' importante la gestione completa delle transazioni la scelta migliore e' InnoDB; per un sistema che debba fornire servizi 7x24 e garantire la continuita' del servizio anche in caso di un fault HW verra' utilizzato un Engine NDB Cluster...

Per controllare gli Storage Engine disponibili nella propria installazione:

mysql> SHOW ENGINES;
+------------+---------+------------------------------------------------------------+
| Engine     | Support | Comment                                                    |
+------------+---------+------------------------------------------------------------+
| MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance     |
| MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables  |
| MERGE      | YES     | Collection of identical MyISAM tables                      |
| ISAM       | NO      | Obsolete storage engine, now replaced by MyISAM            |
| MRG_ISAM   | NO      | Obsolete storage engine, now replaced by MERGE             |
| InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys |
| BDB        | YES     | Supports transactions and page-level locking               |
| NDBCLUSTER | NO      | Clustered, fault-tolerant, memory-based tables             |
| EXAMPLE    | NO      | Example storage engine                                     |
| ARCHIVE    | NO      | Archive storage engine                                     |
| CSV        | NO      | CSV storage engine                                         |
...
+------------+---------+------------------------------------------------------------+

MySQL e' molto flessibile e consente la scelta dello storage engine adatto per ogni singola tabella. Le differenti caratteristiche degli Engine possono cosi' essere sfruttati al meglio:

L'indicazione dell'Engine e' una clausola SQL dello statement di CREATE TABLE e puo' essere modificato con lo statement ALTER TABLE table_name ENGINE=engine_type.

In una normale installazione sono presenti solo gli Engine piu' comuni (eg. MyISAM, InnoDB, ...). Installando l'RPM MySQL-Max vengono aggiunti gli altri Engine (eg. NDB, CSV, ...) (dalla versione 5.0 sono inclusi di default Ndr). Per quanto riguarda l'NDBCLUSTER e' necessario un'ulteriore passo. MySQL-Max infatti non contiene l'intero software ma solo il richiamo dinamico a questo, l'Engine risulta cosi configurato ma disabilitato. E' necessario installare l'RMP MySQL-ndb-storage e configurare il file /etc/my.cfg. Nel seguito sono riportati maggiori elementi relativamente alla configurazione in cluster.

Poiche' l'Engine su cui le versioni piu' recenti stanno convergendo e' l'InnoDB e' opportuno descriverlo maggiormente. InnoDB e' l'Engine di default dalla versione 5.5. Il parametro innodb_file_per_table e' attivo per default dalla versione 5.6.6. In versioni precedenti di MySQL alcune operazioni amministrative (eg. drop di una tabella con file dedicato) utilizzavano lock potenzialmente di lunga durata (eg. un'intero buffer pool scan), ma nelle versioni piu' recenti InnoDB e' molto piu' efficiente e scalabile.
InnoDB utilizza un file ibdata1 per i dati/tabelle InnoDB sia interni (InnoDB ha un suo data dictionary) che degli utenti. E' possibile allocare staticamente piu' file ibdataX (elencandoli nel my.cnf) ed indicare se autoincrementali o di dimensione fissa. Se si imposta il parametro dinamico innodb_file_per_table la creazione di ogni nuova tabella utilizza un suo file .ibd. innodb_file_per_table ha effetto solo le "nuove" tabelle: il data dictionary e le tabelle gia' create continuano ad utilizzare l'ibdata comune. Uno o molti, a dimensione fissa o in autoextent i file InnoDB ibdataX non possono essere eliminarti o ridotti di dimensione.
InnoDB utilizza il paradigma MVCC per mantenere letture consistenti alle transazioni committate. In pratica di ogni tabella esistono contemporaneamente piu' versioni all'interno dei file ibdataX. InnoDB utilizza due file di logging, ib_logfile0 e ib_logfile1, per la gestione delle transazioni. La dimensione dei file di log, fissata nel my.cnf, e' molto importante per le performances.
Tutto cio' premesso quando si cancellano dati da una tabella in realta', grazie all'MVCC, lo spazio richiesto da una tabella aumenta! Per tenere la copia dei dati prima e dopo ogni istruzione di DML. Terminate le transazioni lo spazio resta allocato alla tabella in oggetto. In qualche caso lo spazio non viene rilasciato oppure risulta frammentato, quindi successive modifiche continuano a richiedere nuovo spazio ed a far aumentare la dimensione dei file ibdataX. In questo caso un'OPTIMIZE risolve il problema.
Anche effettuando una DROP di una tabella lo spazio non viene liberato al file system. Lo spazio della tabella cancellata resta a disposizione di tutte le tabelle InnoDB. Naturalmente se la DROP e' relativa ad una tabella creata con innodb_file_per_table lo spazio viene realmente liberato.

Configurazione e tuning

Una volta installato MySQL puo' essere utilizzato immediatamente. Pero' le possibilita' di configurazione e tuning sono molteplici.
MySQL utilizza algoritmi che, rispetto ad altri RDBMS, utilizzano poca memoria; e' tuttavia possibile migliorare le performance concedendo a MySQL piu' spazio in memoria effettuando un tuning specifico.

Ci sono alcuni elementi importanti da conoscere. Innanzi tutto va inquadrato il comportamento di MySQL sul sistema: sta effettuando troppo I/O oppure il bottleneck e' la CPU? L'architettura di MySQL e' semplice ed e' cosi' facile, per un buon sistemista Linux, identificarne il corretto funzionamento e gli eventuali colli di bottiglia.
Prima di effettuare un tuning sulla base dati e' molto importante aver controllato che la base dati sia utilizzata correttamente. Ci sono tutti gli indici che servono? Gli statement SQL sono corretti? I risultati di questa analisi possono portare a miglioramenti molto significativi (l'aggiunta di un indice puo' migliorare una query di due ordini di grandezza).
Infine il tuning di MySQL dipende molto dal tipo di applicazioni (eg. centinaia di utenti interattivi in Client/Server, applicazioni PHP, attivita' batch, attivita' DWH, ...) e soprattutto dal tipo di Engine utilizzato (eg. MyISAM, InnoDB).

I parametri con maggior effetto sull'Engine MyISAM sono key_buffer_size e table_cache, conviene effettuare un tuning di queste due variabili prima di modificarne altre. Con il comando seguente si esegue mysqld con un'allocazione maggiore di memoria: $ mysqld_safe --key_buffer_size=64M --table_cache=256 --sort_buffer_size=4M --read_buffer_size=1M &
Se si utilizzano applicazioni che effettuano ripetutamente gli stessi statement SQL (situazione comune con molti CMS), impostare la Query Cache da' vantaggi prestazionali elevatissimi: query_cache_size=16M.

Per l'Engine InnoDB il tuning dei parametri ha molta importanza. In particolare, con transazioni di breve durata, l'impostazione del flush dei log file con innodb_flush_log_at_trx_commit puo' cambiare le prestazioni di un ordine di grandezza. Quando le basi dati hanno dimensioni significative il tuning dei parametri delle cache e' fondamentale (eg. innodb_buffer_pool_size innodb_additional_mem_pool_size innodb_log_buffer_size). Su basi dati con elevati volumi transazionali anche il sizing dei log ha un'importanza notevole. Per evitare rallentamenti in fase di allocazione e' possibile preallocare con innodb_data_file_path=ibdata1:2G;ibdata2...
Il comando di OPTIMIZE TABLE e' disponibile su tutti gli engine, ma e' particolarmente efficace su tabelle InnoDB di grandi dimensioni con colonne BLOB ed attivita' di INSERT/DELETE.

Esaminare in dettaglio tutti i parametri di configurazione sarebbe troppo lungo, quelli indicati fino ad ora sono i piu' significativi per le prestazioni (eg. my.cnf (BASE)).
Un elenco piu' completo di parametri si trova in my.cnf (Sample), my.cnf (MyISAM) riporta una configurazione aggressiva per MyISAM e my.cnf (InnoDB) una contiene una configurazione con le ottimizzazioni per InnoDB. Sono esempi da cui trarre spunto per le proprie configurazioni. Ricordate comunque di lasciare sufficiente memoria libera per il sistema operativo e per gli altri processi per non mandare il sistema in paginazione.

E' importante ricordare che le opzioni riconosciute come ottimali vanno inserite nel file /etc/my.cnf per essere attive ad ogni avvio del server. my.cnf e' un file di testo diviso in sezioni. L'installazione di MySQL contiene alcuni file di esempio (eg. /usr/share/mysql/*.cnf) da cui partire.

Su un sistema dedicato come DB Server puo' essere utile qualche ulteriore indicazione sul tuning dello storage e del sistema operativo.
Come sosteneva Lapalisse i dischi piu' veloci hanno prestazioni migliori dei dischi piu' lenti; su un DB Server e' importante: utilizzate dischi veloci [NdA ovviamente, se potete permetterveli, usate dischi SSD]! Utilizzate RAID 10 su RAID HW o su una SAN con write cache e BBU per le migliori prestazioni.
Come file system ext3 su Linux va benissimo: e' robusto e veloce. Ho provato ZFS: e' ottimo ma non posso dire quale sia il migliore: erano macchine troppo diverse per fare un paragone... Il disk scheduler (elevator) noop e' quello che ho trovato piu' veloce per MySQL (la letteratura riporta anche il deadline).
E' necessario evitare che il sistema vada in paginazione: con MySQL l'uso della buffer cache di sistema e' significativo ed ogni tanto il sistema operativo prende un abbaglio... Meglio evitare con vm.swappiness=0 nel file sysctl.conf [NdA meglio =1 sui kernel piu' recenti]. L'impostazione noatime al mount riduce gli accessi al disco, ovviamente da impostare solo sul FS dedicato ai dati del database. Con MyISAM ogni tabella utilizza 3 file: su basi dati con molti utenti e schemi complessi puo' essere superato il numero di file aperti. Se succede MySQL e' costretto a chiudere e riaprire continuamente i file: meglio aumentare il limite del parametro nofile a mysql su /etc/security/limits.conf
Agite sul Sistema Operativo solo se sapete quello che state facendo... altrimenti meglio utilizzare i default.

Amministrazione

L'installazione dell'RPM inserisce direttamente gli script di partenza del servizio al boot: per attivare/disattivare MySQL dare il comando: service mysql start o stop. Il controllo dello stato e delle attivita' presenti si effettua con mysqladmin version status proc.
Dal punto di vista Unix non sono necessarie particolari attivita' se non il normale controllo degli spazi, l'effettuazione dei backup, ...
L'amministrazione di MySQL richiede generalmente poche altre attivita' e l'ambiente grafico Client/Server MySQL Administrator la rende molto semplice:

Tra tutti i tool di amministrazione sicuramente il piu' utilizzato e' il phpMyAdmin che offre un interfaccia web per la gestione:

Sono disponibili molteplici altri tool Open Source, Freeware o a pagamento per l'amministrazione di MySQL. Tra questi TOAD ed SQLyog che sono completi e semplici strumenti in Client/Server. Definito il server cui accedere e la porta da utilizzare la connessione e' immediata.

Come tutti i tool grafici sono piu' semplici da utilizzare che da spiegare quindi... provate!

Architettura

Dal punto di vista dell'architettura di MySQL l'elemento di maggior interesse sono la struttura dei processi e l'organizzazione dei dati.

La struttura dei processi si analizza semplicemente con il comando ps -efa:

/bin/sh /usr/local/mysql/bin/mysqld_safe --user=mysql
/usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --pid-file=/usr/local/mysql/...

L'architettura e' semplicissima: il processo mysqld gestisce un thread per ogni connessione! Per completezza nel riquadro sopra e' stato riportato anche il processo dello shell di lancio che resta attivo e che riavvia la base dati in caso di caduta del processo. Come gia' riportato, il controllo dello stato e delle attivita' presenti avviene con mysqladmin version status proc.
Gli utenti si collegano a MySQL utilizzando una connessione TCP-IP su una porta socket. Di default la porta utilizzata da MySQL e' la 3306. Il processo mysqld e' in LISTEN su tale porta e quando arriva una nuova richiesta di connessione effettua l'attivazione del thread corrispondente.

MySQL Architecture

I dati vengono mantenuti su file organizzati come previsto dallo Storage Engine. Ogni database corrisponde ad una directory posta sotto /var/lib/mysql (o nella directory indicata dal parametro datadir). All'interno della directory si trovano i file relativi ad ogni tabella. E' sempre presente un file tabella.frm che contiene la struttura della tabella, eventuali altri file dipendono dall'Engine di memorizzazione (eg. .frm, .MYD e .MYI per MyISAM, solo .frm per InnoDB).

MySQL Cluster (NDB)

MySQL puo' essere utilizzato in configurazione di cluster con cui i dati vengono partizionati e distribuiti su piu' sistemi permettendo di disporre continuamente delle informazione anche in caso di caduta di un server.

Il cluster e' costituito da nodi che svolgono tra differenti funzioni:

Il Management Node non deve necessariamente essere sempre attivo, e' necessario solo durante le attivita' di configurazione o di rejoin. Ma, anche se e' spento, la continuita' di servizio e' garantita.

Gli Storage Node mantengono i dati allineati tra loro utilizzando un'ampia cache in memoria e dialogando sulla porta 1186 con il nodo di Management. Il cluster mantiene in memoria l'intero DB. L'occupazione per ogni singolo nodo e' pari alla dimensione del DB per il numero di repliche (due di default) diviso il numero di storage node. Agli Storage Node si connettono i processi mysqld. Si tratta di processi distinti che possono essere eseguiti su server differenti: un insieme di processi realizza lo Storage NDB, i server mysqld sono invece i gestori delle richieste SQL.
I dati vengono mantenuti sul file system. Ogni database corrisponde ad una directory posta sotto /var/lib/mysql-cluster. All'interno della directory si trovano i file per ogni tabella.

Una configurazione senza single point of failure prevede l'utilizzo di almeno 3 sistemi. Per disporre di una configurazione fault tolerant sono necessari due server che ospitano MySQL e lo Storage Node, un terzo server e' utilizzato come stazione di management per l'NDB. Gli accessi ai server SQL possono essere bilanciati con un load balancer HW o SW, con un DNS in round robin o applicativamente.

Nella figura e' presentata una configurazione di esempio con due nodi che ospitano i server MySQL e gli storage node, un terzo nodo con il solo server MySQL ed una stazione di gestione. I client possono accedere ad uno qualsiasi dei tre MySQL server lavorando sullo stesso storage e vedendo gli stessi dati.

Configurazione ed amministrazione Cluster

Nel seguito e' riportato un esempio di una configurazione minimale che utilizza un server di gestione e due server che ospitano sia i dati i server MySQL (i riferimenti riportati sono relativi alla versione MySQL 4.1 ma la stessa configurazione e' stata utilizzata con successo con le versioni 5.0 e 5.1).
Sul sistema di gestione debbono essere installati gli RPM:
RPMDescrizione
MySQL-ndb-storage-version.rpmMySQL cluster: NDB Storage Engine
MySQL-ndb-management-version.rpmMySQL cluster: NDB Manager

Sul sistema di gestione deve essere configurato il file /var/lib/mysql-cluster/config.ini:

[NDBD DEFAULT]
NoOfReplicas=2
[MYSQLD DEFAULT]
[NDB_MGMD DEFAULT]
[TCP DEFAULT]
# Managment Server
[NDB_MGMD]
HostName=10.0.0.81          # IP del nodo di management
# Storage Engines
[NDBD]
HostName=10.0.0.82          # IP del primo server
DataDir= /var/lib/mysql-cluster
[NDBD]
HostName=10.0.0.83          # IP del secondo server
DataDir=/var/lib/mysql-cluster
# 2 MySQL Clients "liberi"
[MYSQLD]
[MYSQLD]

Sui sistemi che ospitano i dati ed i demoni mysqld debbono essere installati gli RPM:
RPMDescrizione
MySQL-server-version.rpmIl motore della base dati: mysqld
MySQL-Max-version.rpmLibrerie per l'utilizzo di Storage Engine aggiuntivi
MySQL-ndb-storage-version.rpmMySQL cluster: NDB Storage Engine
MySQL-ndb-management-version.rpmMySQL cluster: NDB Manager

Sui sistemi che ospitano i dati deve essere configurato il file /etc/my.cnf:

[mysqld]
ndbcluster
ndb-connectstring=10.0.0.81
[mysql_cluster]
ndb-connectstring=10.0.0.81

La configurazione e' terminata, va inizializzato l'NDB ed attivati i servizi. Va attivata il nodo di management lanciando ndb_mgmd, quindi vanno attivati gli Engine sui tre server con il comando /usr/sbin/ndbd --initial. Ora l'NDB e' attivo ed e' possibile attivare i demoni MySQL con service mysql start. Il comando ndb_mgm sul server di gestione consente il controllo dello stato del cluster. Attenzione il parametro --initial va solo utilizzato quando si costruisce il cluster. Le attivazioni successive non debbono utilizzarla.
La situazione deve essere:

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=2    @10.0.0.82  (Version: 4.1.13, Nodegroup: 0, Master)
id=3    @10.0.0.83  (Version: 4.1.13, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @10.0.0.81  (Version: 4.1.13)

[mysqld(API)]   2 node(s)
id=4    @10.0.0.82  (Version: 4.1.13)
id=5    @10.0.0.83  (Version: 4.1.13)

La stazione di Management utilizza poca memoria e non richiede un grande traffico su rete. Conviene tenerla sempre attiva. Sull'interfaccia di gestione comandi piu' utilizzati sono: SHOW, SHUTDOWN, HELP e PURGE STALE SESSIONS.

Dal punto di vista di utilizzo il cluster e' molto semplice. Basta utilizzare l'Engine NDB, tutto il resto e' trasparente!
Semplice e funziona.

Non bisogna dimenticare i limiti di NDB. E' piu' lento rispetto ad altri Storage; non supporta tutti gli stessi datatype, indici, ...; ha un uso molto elevato di memoria (anche considerando la possibilita' di mappare alcune tabelle su disco).
Oltre ad NDB esistono altre soluzioni per garantire l'HA con mysql. Innanzitutto la Replication che effettua un'aggiornamento asincrono con una configurazione master/slave su due o piu' nodi. La replication di MySQL e' molto efficiente e leggera (e' statement based anche se nelle versioni piu' recenti e' stata inserita anche la modalita' row based) e trova ampie possibilita' di utilizzo anche per gestire DB in sola lettura.
Altra possibilita' e' utilizzare il sistema operativo di base con una soluzione cluster Active/Passive. Su Linux la soluzione piu' comune, efficiente ed economica e' HA+DRBD ma in genere su Unix sono disponibili molteplici soluzioni cluster (eg. RHCS, VCS).

Programmazione

Naturalmente una base dati viene utilizzata anche da applicazioni. MySQL offre diverse interfacce di programmazione:

E' possibile compilare applicazioni in modalita' Embedded. In questo caso le librerie di gestione della base dati sono linkate con l'applicazione e non e' necessaria una base dati esterna.

E' possibile utilizzare una base dati MySQL utilizzando un connettore. MySQL fornisce i seguenti connettori:

Insomma le possibilita' di utilizzo e di programmazione su MySQL sono molteplici: buon divertimento!

Fork

MySQL e' un progetto Open Source e come in tutti i software aperti sono possibili nuovi sviluppi indipendenti (fork) per esplorare nuove funzionalita' o per qualsiasi altro motivo (come l'acquisizione di MySQL da parte di Oracle). Tra i fork piu' interessanti:


Testo: Qualcosa in piu' su MySQL
Data: 15 Luglio 2005
Versione: 1.0.15 - 15 Agosto 2012
Autore: mail@meo.bogliolo.name