MySQL 5.6 - Nuove funzionalita'

La versione MySQL 5.6 introduce nuove funzionalita' nell'RDBMS Free piu' diffuso al mondo.
L'uscita in produzione della nuova versione si e' fatta attendere parecchio... finalmente oggi [NdE 5 febbraio 2013] e' stata rilasciata la versione GA: ecco quindi pubblicato anche questo documento!

In questo documento sono riportati i principali nuovi elementi introdotti dalla versione 5.6 riportando esempi pratici di utilizzo. Ecco l'elenco degli esempi:

Ma le novita' non sono solo queste... continuate a leggere!

Host cache

MySQL utilizza da sempre una cache contenente i dati degli host da cui provengono le connessioni. Tale tabella interna al server MySQL e' utilizzata per ragioni prestazionali (evita continui lookup sul DNS) e, in qualche caso, diventa importante conoscerne il contenuto. Per evitare attacchi brute force al database MySQL disabilita l'accesso agli host che hanno superato un certo numero di tentativi falliti consecutivi (variabile max_connect_errors). E' possibile sboccare la situazione con il comando di FLUSH HOST ma, nelle versioni precedenti alla 5.6 di MySQL, non era in nessun modo possibile monitorare il numero di accessi e gli errori.
Dalla versione 5.6.5 di MySQL la host cache e' visibile come tabella:

select IP, HOST, SUM_CONNECT_ERRORS ERR, FIRST_ERROR_SEEN, LAST_ERROR_SEEN from performance_schema.host_cache; +---------------+-----------------+-----+---------------------+---------------------+ | IP | HOST | ERR | FIRST_ERROR_SEEN | LAST_ERROR_SEEN | +---------------+-----------------+-----+---------------------+---------------------+ | 10.101.102.69 | shadow02.xxx.it | 2 | 2013-02-05 11:12:13 | 2013-02-05 17:17:17 | +---------------+-----------------+-----+---------------------+---------------------+

Le informazioni disponibili sono raccolte su una ventina di colonne molto esplicative (eg. IP, HOST, HOST_VALIDATED, SUM_CONNECT_ERRORS, COUNT_HOST_BLOCKED_ERRORS, LAST_SEEN, ...) e consentono un rapido controllo degli accessi direttamente con l'SQL.

Millisecondi

Questa e' una funzionalita' richiesta da moltissimo tempo: dalla versione 5.6 i datatype TIME, DATETIME e TIMESTAMP gestiscono i microsecondi. L'utilizzo e' molto semplice basta indicare tra parentesi il numero di cifre frazionarie (fino a sei). Se non si indica nessuna parte frazionaria vengono considerati arrotondati al secondo (e' una differenza rispetto allo standard SQL ma cosi' si mantiene la compatibilita' con le precedenti versioni).

E' inoltre possibile avere sulla stessa tabella piu' colonne TIMESTAMP o con valori impostati per default alla data attuale.

mysql> create table evento(codice serial, chi varchar(64), cosa varchar(64), quando timestamp(4), dove varchar(64), perche varchar(64)); Query OK, 0 rows affected (0.10 sec) mysql> insert into evento(chi, cosa, perche) values ('meo', 'INSERT','Esempio uso timestamp con millisecondi'); Query OK, 1 row affected (0.07 sec) mysql> select * from evento; +--------+------+--------+--------------------------+------+--------------------------------+ | codice | chi | cosa | quando | dove | perche | +--------+------+--------+--------------------------+------+--------------------------------+ | 1 | meo | INSERT | 2013-02-05 08:44:55.7357 | NULL | Esempio uso timestamp con msec | +--------+------+--------+--------------------------+------+--------------------------------+ 1 row in set (0.01 sec)

Analisi prestazioni

Il data dictionary di MySQL e' sempre stato piuttosto limitato soprattutto nella parte di monitoraggio e strumentazione delle attivita'. La versione 5.6 consente invece un'analisi molto completa delle prestazioni di tutta la base dati e, in particolare, sull'Engine InnoDB.

Il Performance schema era gia' stato introdotto nella versione 5.5 ma ora e' abilitato per default ed e' molto piu' completo. Nella versione 5.6 sono disponibili oltre cinquanta viste rispetto alla ventina della versione precedente. Oltre alla Host cache, che abbiamo gia' visto in dettaglio, sono sicuramente utili le viste: events_statements_* table_io_waits_summary_* table_lock_waits_summary_by_table
Una nota curiosa... attivare il performance schema impatta significavamente riducendo le prestazioni! Sui blog specializzati sono moltissimi i commenti a questa feature. Per confrontare le prestazioni tra una versione 5.5 ed una versione 5.6, con un elevato traffico transazionale in concorrenza, e' infatti consigliabile disattivare il performance schema. Su altri tipi di carico invece la presenza del Performance schema non presenta controindicazioni.

Anche il database INFORMATION_SCHEMA e' stato arricchito con nuove utili viste: INNODB_METRICS, INNODB_SYS_TABLES, ...

Infine l'EXPLAIN PLAN ora puo' analizzare tutti gli statement DML e non solo le SELECT.

EXPLAIN update evento set dove='Torino' where chi='meo'; +----+-------------+--------+-------+---------------+--------+------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | klen | ref | rows | Extra | +----+-------------+--------+-------+---------------+--------+------+------+------+-------------+ | 1 | SIMPLE | evento | index | codice | codice | 8 | NULL | 1 | Using where | +----+-------------+--------+-------+---------------+--------+------+------+------+-------------+

lost+found

Quante volte vi e' capitato di configurare la directory dei dati di MySQL su un file system e ritrovarvi come nome di database Lost+Found?
Finalmente e' possibile escludere una serie di directory dalla ricerca di MySQL impostando il parametro ignore-db-dir o la variabile ignore_db_dirs !

[mysqld] max_allowed_packet=128M log_error log_warnings=2 slow_query_log=1 long_query_time=5 log_bin_trust_function_creators=1 max_connections=1000 datadir=/mydata tmpdir=/mydata/tmpdir ignore-db-dir=tmpdir ignore-db-dir=lost+found innodb_buffer_pool_size=256M innodb_flush_log_at_trx_commit=1 innodb_log_buffer_size=8M key_buffer = 64M query_cache_type=1 query_cache_size=16M # NB table_cache has been renamed to table_open_cache table_open_cache=512 tmp_table_size=32M max_heap_table_size=32M event_scheduler=1

Fulltext search

La funzionalita' di fulltext search e' presente da sempre sull'Engine MyISAM ma solo dalla release 5.6 e' disponibile anche con InnoDB.
Come usarla? Vediamo un esempio!

CREATE TABLE articoli (id SERIAL, occhiello VARCHAR(128), titolo VARCHAR(64), sommario VARCHAR(256), catenaccio VARCHAR(64), corpo TEXT) ENGINE=InnoDB; INSERT INTO articoli(titolo, corpo) VALUES ('MySQL 5.6', 'L''uscita della nuova versione di database...'); CREATE FULLTEXT INDEX idx_ft on articoli (titolo, corpo); SELECT occhiello, titolo, corpo FROM articoli WHERE MATCH (titolo, corpo) AGAINST ('database');

Con la query si cerca la parola "database" nel titolo e nel corpo di tutti gli articoli: semplice!

La documentazione ufficiale spiega tutto con dovizia di particolari.
Un poco piu' complessi sono gli internal e non e' il caso di entrare nei particolari... un unico consiglio: su tabelle di grandi dimensioni prima caricate i dati e poi create l'indice FULLTEXT.

memcache

memcache e' una cache distribuita per l'accesso a chiave-valore molto diffusa perche' semplice e, sopratutto, perche' terribilmente veloce. MySQL 5.6 introduce un'interfaccia memcache a tabelle InnoDB veloce (non utilizza sessioni, autenticazione, parsing SQL, ottimizzatore, ...) e perfettamente compatibile.

Configurare MySQL 5.6 per l'uso con memcache non e' difficile:

mysql < share/innodb_memcached_config.sql

install plugin daemon_memcached soname 'libmemcached.so'

Il primo comando crea un database (innodb_memcache) ed una configurazione di esempio (descritta nella tabella containers) con una tabella InnoDB accessibile come key-value. Il secondo comando attiva il plugin e... magia: il processo mysqld ascolta anche sulla porta 11211 [NdE la porta di default del demone memcache]. Gia fatto?! Basta provare, il modo piu' veloce e' da terminale:

telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set meo 0 0 8 bogliolo STORED get meo VALUE meo 0 8 bogliolo END quit

Funziona! Ho inserito una riga con chiave "meo" ed un valore lungo 8: "bogliolo" (gli altri valori sono flags ed expire). Cosi' mi ricordo chi sono...
Naturalmente l'uso piu' comune di memcache e' mediante un API di un linguaggio di programmazione come riportato in questo esempio in PHP. In pratica si tratta di sostituire le query SQL piu' frequenti con le semplici chiamate a memcache; basta cambiare poche righe di codice per migliorare le prestazioni di siti molto acceduti [NdA stiamo parlando di tempi di lantenza sul milliseconto con centinaia di accessi al secondo: sono queste le condizioni tipiche di utilizzo di memcache].

Due note tecniche: memcache opera sia su porte TCP che UDP; per disattivare l'accesso a memcache basta disinstallare il plugin.

InnoDB

L'engine InnoDB e' presente da sempre in MySQL (dalla versione 3.23.34) ed e' diventato l'engine di default nella versione 5.5 sostituendo MyISAM. Alcune delle novita' su InnoDB sono gia' state riportate (eg. fulltext, performance views, ...), altre verranno accennate nel seguito (eg. parametri di default piu' elevati), molte innovazioni non vengono descritte affatto in questa pagina perche' troppo complesse (eg. riduzione delle regioni critiche per il locking, algoritmo adattivo di padding dei dati per migliorare la compressione, ...).
Ma l'Engine InnoDB merita comunque un capitolo a se anche in questa pagina relativa alla versione 5.6: semplicemente e' stato notevolmente migliorato.

In generale e' piu' veloce (in particolare nell'uso concorrente), resta piu' veloce nel tempo (grazie al nuovo formato dei dati ed alla persistenza delle statistiche), le prestazioni sono piu' facilmente controllabili (con le nuove performance views) ed e' piu' facilmente gestibile (con il parametro INNODB_FILE_PER_TABLE impostato per default).

Sicurezza

Last but not least: security!
Per la prima volta MySQL dimostra attenzione verso agli aspetti di sicurezza. Sono molti e "piccoli" gli interventi ma tutti utili.

L'installazione puo' generare password casuali [NdE /root/.mysql_secret]. Uno script disabilita l'accesso anonimo. E' gestito un flag per la scadenza delle password (colonna password_expired in mysql.user). E' disponibile un plugin (opzionale) per la verifica della qualita' delle password quando inserite; se il plugin e' installato e' possibile verificare attuali da SQL con VALIDATE_PASSWORD_STRENGTH(). E' possibile crittografare le password con il potente algoritmo SHA-256. ...

ALTER USER 'meo'@'mypc.xenialab.it' PASSWORD EXPIRE;

Varie ed eventuali

Altre novita' interessanti sono:

Molte altre funzionalita' erano state introdotte nelle versioni precedenti: MySQL 5.5, MySQL 5.1, MySQL 5.0. Un breve riassunto delle funzionalita' introdotte nel tempo si trova su Introduzione a MySQL. Un documento completo con tutte le versioni dei prodotti che ritengo piu' significativi e' il tuo server puzza!


Titolo: MySQL 5.6 - Nuove funzionalita'
Livello: Avanzato (3/5)
Data: 10 Luglio 2012
Versione: 1.2.4 - 14 Febbraio 2013
Autore: mail [AT] meo.bogliolo.name