Aprile 2018 non è solo una data per il mondo MySQL. MySQL 8.0 è stato rilasciato lì e, più di un anno dopo, è probabilmente giunto il momento di considerare la migrazione a questa nuova versione.
MySQL 8.0 presenta importanti miglioramenti delle prestazioni e della sicurezza e, come in tutte le migrazioni a una nuova versione del database, ci sono diverse cose da tenere in considerazione prima di entrare in produzione per evitare problemi gravi come la perdita di dati, eccessivi tempi di inattività o anche un rollback durante l'attività di migrazione.
In questo blog menzioneremo alcune delle nuove funzionalità di MySQL 8.0, alcune cose deprecate e cosa devi tenere a mente prima di migrare.
Cosa c'è di nuovo in MySQL 8.0?
Riassumiamo ora alcune delle caratteristiche più importanti menzionate nella documentazione ufficiale per questa nuova versione di MySQL.
- MySQL incorpora un dizionario di dati transazionali che memorizza informazioni sugli oggetti del database.
- Un'istruzione DDL atomica combina gli aggiornamenti del dizionario dati, le operazioni del motore di archiviazione e le scritture dei log binari associati a un'operazione DDL in un'unica transazione atomica.
- Il server MySQL esegue automaticamente tutte le attività di aggiornamento necessarie all'avvio successivo per aggiornare le tabelle di sistema nello schema mysql, nonché gli oggetti in altri schemi come lo schema sys e gli schemi utente. Non è necessario che il DBA invochi mysql_upgrade.
- Supporta la creazione e la gestione di gruppi di risorse e consente di assegnare thread in esecuzione all'interno del server a gruppi particolari in modo che i thread vengano eseguiti in base alle risorse disponibili per il gruppo.
- La crittografia delle tabelle ora può essere gestita a livello globale definendo e applicando le impostazioni predefinite di crittografia. La variabile default_table_encryption definisce un'impostazione predefinita di crittografia per gli schemi appena creati e il tablespace generale. Le impostazioni predefinite di crittografia vengono applicate abilitando la variabile table_encryption_privilege_check.
- Il set di caratteri predefinito è cambiato da latin1 a utf8mb4.
- Supporta l'uso di espressioni come valori predefiniti nelle specifiche del tipo di dati. Ciò include l'uso di espressioni come valori predefiniti per i tipi di dati BLOB, TEXT, GEOMETRY e JSON.
- La registrazione degli errori è stata riscritta per utilizzare l'architettura del componente MySQL. La registrazione degli errori tradizionale viene implementata utilizzando componenti integrati e la registrazione tramite il registro di sistema viene implementata come componente caricabile.
- Un nuovo tipo di blocco del backup consente il DML durante un backup online, prevenendo le operazioni che potrebbero causare uno snapshot incoerente. Il nuovo blocco di backup è supportato dalla sintassi LOCK INSTANCE FOR BACKUP e UNLOCK INSTANCE. Per utilizzare queste istruzioni è richiesto il privilegio BACKUP_ADMIN.
- MySQL Server ora consente la configurazione specifica di una porta TCP/IP per le connessioni amministrative. Ciò fornisce un'alternativa alla singola connessione amministrativa consentita sulle interfacce di rete utilizzate per le connessioni ordinarie anche quando le connessioni max_connections sono già stabilite.
- Supporta gli indici invisibili. Questo indice non viene utilizzato dall'ottimizzatore e consente di verificare l'effetto della rimozione di un indice sulle prestazioni della query, senza rimuoverlo.
- Archivio documenti per lo sviluppo di applicazioni di documenti SQL e NoSQL utilizzando un unico database.
- MySQL 8.0 rende possibile la persistenza di variabili globali e dinamiche del server utilizzando il comando SET PERSIST invece del solito SET GLOBAL.
Sicurezza MySQL e gestione dell'account
Dato che ci sono molti miglioramenti relativi alla sicurezza e alla gestione degli utenti, li elencheremo in una sezione separata.
- Le tabelle di concessione nel database di sistema mysql sono ora tabelle InnoDB.
- Il nuovo plug-in di autenticazione caching_sha2_password è ora il metodo di autenticazione predefinito in MySQL 8.0. Implementa l'hashing delle password SHA-256, ma utilizza la memorizzazione nella cache per risolvere i problemi di latenza al momento della connessione. Fornisce una crittografia della password più sicura rispetto al plug-in mysql_native_password e offre prestazioni migliori rispetto a sha256_password.
- MySQL ora supporta i ruoli, che sono denominate raccolte di privilegi. Ai ruoli possono essere concessi e revocati privilegi e possono essere concessi e revocati dagli account utente.
- MySQL ora conserva le informazioni sulla cronologia delle password, consentendo restrizioni sul riutilizzo delle password precedenti.
- Consente agli amministratori di configurare gli account utente in modo tale che troppi errori di accesso consecutivi dovuti a password errate causino il blocco temporaneo dell'account.
Miglioramenti InnoDB
Come punto precedente, ci sono anche molti miglioramenti relativi a questo argomento, quindi li elencheremo anche in una sezione separata.
- Il valore massimo corrente del contatore di incremento automatico viene scritto nel registro di ripristino ogni volta che il valore cambia e salvato in una tabella di sistema privata del motore su ciascun checkpoint. Queste modifiche rendono persistente il valore del contatore di incremento automatico massimo corrente durante i riavvii del server
- Quando si verifica un danneggiamento dell'albero degli indici, InnoDB scrive un flag di danneggiamento nel log di ripristino, il che rende il flag di danneggiamento sicuro. InnoDB scrive anche i dati del flag di danneggiamento in memoria in una tabella di sistema privata del motore su ciascun checkpoint. Durante il ripristino, InnoDB legge i flag di danneggiamento da entrambe le posizioni e unisce i risultati prima di contrassegnare la tabella in memoria e gli oggetti indice come danneggiati.
- Una nuova variabile dinamica, innodb_deadlock_detect, può essere utilizzata per disabilitare il rilevamento dei deadlock. Nei sistemi a concorrenza elevata, il rilevamento dei deadlock può causare un rallentamento quando numerosi thread attendono lo stesso blocco. A volte, può essere più efficiente disabilitare il rilevamento del deadlock e fare affidamento sull'impostazione innodb_lock_wait_timeout per il rollback della transazione quando si verifica un deadlock.
- Le tabelle temporanee InnoDB sono ora create nel tablespace temporaneo condiviso, ibtmp1.
- Le tabelle di sistema mysql e le tabelle del dizionario dei dati vengono ora create in un unico file tablespace InnoDB denominato mysql.ibd nella directory dei dati di MySQL. In precedenza, queste tabelle venivano create in singoli file tablespace InnoDB nella directory del database mysql.
- Per impostazione predefinita, i log di annullamento ora risiedono in due tablespace di annullamento creati quando l'istanza MySQL viene inizializzata. I registri di annullamento non vengono più creati nel tablespace di sistema.
- La nuova variabile innodb_dedicated_server, che è disabilitata per impostazione predefinita, può essere utilizzata per fare in modo che InnoDB configuri automaticamente le seguenti opzioni in base alla quantità di memoria rilevata sul server:innodb_buffer_pool_size, innodb_log_file_size e innodb_flush_method. Questa opzione è concepita per le istanze del server MySQL eseguite su un server dedicato.
- I file tablespace possono essere spostati o ripristinati in una nuova posizione mentre il server è offline utilizzando l'opzione innodb_directories.
Ora, diamo un'occhiata ad alcune delle funzionalità che non dovresti più utilizzare in questa nuova versione di MySQL.
Che cos'è deprecato in MySQL 8.0?
Le seguenti funzionalità sono obsolete e verranno rimosse in una versione futura.
- Il set di caratteri utf8mb3 è obsoleto. Utilizza invece utf8mb4.
- Poiché caching_sha2_password è il plug-in di autenticazione predefinito in MySQL 8.0 e fornisce un superset delle funzionalità del plug-in di autenticazione sha256_password, sha256_password è deprecato.
- Il plug-in validate_password è stato reimplementato per utilizzare l'infrastruttura del componente server. Il modulo plug-in di validate_password è ancora disponibile ma è deprecato.
- La clausola ENGINE per le istruzioni ALTER TABLESPACE e DROP TABLESPACE.
- La modalità SQL PAD_CHAR_TO_FULL_LENGTH.
- Il supporto AUTO_INCREMENT è deprecato per le colonne di tipo FLOAT e DOUBLE (ed eventuali sinonimi). Prendi in considerazione la rimozione dell'attributo AUTO_INCREMENT da tali colonne o convertile in un tipo intero.
- L'attributo UNSIGNED è deprecato per le colonne di tipo FLOAT, DOUBLE e DECIMAL (ed eventuali sinonimi). Prendi in considerazione l'utilizzo di un semplice vincolo CHECK invece per tali colonne.
- La sintassi FLOAT(M,D) e DOUBLE(M,D) per specificare il numero di cifre per le colonne di tipo FLOAT e DOUBLE (ed eventuali sinonimi) è un'estensione MySQL non standard. Questa sintassi è obsoleta.
- Lo stile C non standard &&, || e ! gli operatori che sono sinonimi rispettivamente degli operatori SQL AND, OR e NOT standard sono deprecati. Le applicazioni che utilizzano gli operatori non standard devono essere adattate per utilizzare gli operatori standard.
- Il client mysql_upgrade è deprecato perché le sue capacità di aggiornare le tabelle di sistema nello schema di sistema mysql e gli oggetti in altri schemi sono state spostate nel server MySQL.
- Il file mysql_upgrade_info, che viene creato nella directory dei dati e utilizzato per memorizzare il numero di versione di MySQL.
- La variabile di sistema relay_log_info_file e l'opzione --master-info-file sono obsolete. In precedenza, venivano utilizzati per specificare il nome del registro delle informazioni del registro di inoltro e del registro delle informazioni master quando erano impostati relay_log_info_repository=FILE e master_info_repository=FILE, ma tali impostazioni sono state deprecate. L'uso dei file per il registro delle informazioni del registro di inoltro e il registro delle informazioni master è stato sostituito dalle tabelle slave a prova di crash, che sono l'impostazione predefinita in MySQL 8.0.
- L'uso della variabile di ambiente MYSQL_PWD per specificare una password MySQL è deprecato.
E ora, diamo un'occhiata ad alcune delle funzionalità che devi smettere di usare in questa versione di MySQL.
Cosa è stato rimosso in MySQL 8.0?
Le seguenti funzionalità sono state rimosse in MySQL 8.0.
- La variabile di sistema innodb_locks_unsafe_for_binlog è stata rimossa. Il livello di isolamento READ COMMITTED fornisce funzionalità simili.
- Utilizzo di GRANT per creare utenti. Invece, usa CREATE USER. Seguendo questa pratica, la modalità SQL NO_AUTO_CREATE_USER non è rilevante per le istruzioni GRANT, quindi anch'essa viene rimossa e ora viene scritto un errore nel registro del server quando la presenza di questo valore per l'opzione sql_mode nel file delle opzioni impedisce l'avvio di mysqld.
- Utilizzo di GRANT per modificare le proprietà dell'account diverse dalle assegnazioni di privilegi. Ciò include proprietà di autenticazione, SSL e limite di risorse. Invece, stabilisci tali proprietà al momento della creazione dell'account con CREATE USER o modificale in seguito con ALTER USER.
- IDENTIFIED BY PASSWORD sintassi 'auth_string' per CREATE USER e GRANT. Utilizzare invece IDENTIFIED WITH auth_plugin AS 'auth_string' per CREATE USER e ALTER USER, dove il valore 'auth_string' è in un formato compatibile con il plugin denominato.
- La funzione PASSWORD(). Inoltre, la rimozione di PASSWORD() significa che la sintassi SET PASSWORD ... =PASSWORD('auth_string') non è più disponibile.
- La variabile di sistema old_passwords.
- Le istruzioni FLUSH QUERY CACHE e RESET QUERY CACHE.
- Queste variabili di sistema:query_cache_limit, query_cache_min_res_unit, query_cache_size, query_cache_type, query_cache_wlock_invalidate.
- Queste variabili di stato:Qcache_free_blocks, Qcache_free_memory, Qcache_hits, Qcache_inserts, Qcache_lowmem_prunes, Qcache_not_cached, Qcache_queries_in_cache, Qcache_total_blocks.
- Questi stati del thread:verifica dei privilegi sulla query memorizzata nella cache, verifica della cache delle query per una query, invalidamento delle voci della cache delle query, invio dei risultati memorizzati nella cache al client, memorizzazione dei risultati nella cache delle query, in attesa del blocco della cache delle query.
- Le variabili di sistema tx_isolation e tx_read_only sono state rimosse. Usa invece transaction_isolation e transaction_read_only.
- La variabile di sistema sync_frm è stata rimossa perché i file .frm sono diventati obsoleti.
- La variabile di sistema secure_auth e l'opzione client --secure-auth sono state rimosse. L'opzione MYSQL_SECURE_AUTH per la funzione API C mysql_options() è stata rimossa.
- La variabile di sistema log_warnings e l'opzione del server --log-warnings sono state rimosse. Usa invece la variabile di sistema log_error_verbosity.
- L'ambito globale per la variabile di sistema sql_log_bin è stato rimosso. sql_log_bin ha solo l'ambito della sessione e le applicazioni che si basano sull'accesso a @@GLOBAL.sql_log_bin devono essere modificate.
- Le variabili di sistema date_format, datetime_format, time_format e max_tmp_tables non utilizzate sono state rimosse.
- I qualificatori ASC o DESC deprecati per le clausole GROUP BY sono stati rimossi. Le query che in precedenza si basavano sull'ordinamento GROUP BY possono produrre risultati diversi dalle precedenti versioni di MySQL. Per produrre un determinato ordinamento, fornisci una clausola ORDER BY.
- Il parser non considera più \N come sinonimo di NULL nelle istruzioni SQL. Usa invece NULL. Questa modifica non influisce sulle operazioni di importazione o esportazione di file di testo eseguite con LOAD DATA o SELECT ... INTO OUTFILE, per le quali NULL continua a essere rappresentato da \N.
- Le opzioni lato client --ssl e --ssl-verify-server-cert sono state rimosse. Usa --ssl-mode=REQUIRED invece di --ssl=1 o --enable-ssl. Usa --ssl-mode=DISABLED invece di --ssl=0, --skip-ssl o --disable-ssl. Usa --ssl-mode=VERIFY_IDENTITY invece delle opzioni --ssl-verify-server-cert.
- Il programma mysql_install_db è stato rimosso dalle distribuzioni MySQL. L'inizializzazione della directory dei dati deve essere eseguita richiamando mysqld con l'opzione --initialize o --initialize-insecure. Inoltre, l'opzione --bootstrap per mysqld utilizzata da mysql_install_db è stata rimossa ed è stata rimossa l'opzione INSTALL_SCRIPTDIR CMake che controllava il percorso di installazione per mysql_install_db.
- L'utilità mysql_plugin è stata rimossa. Le alternative includono il caricamento dei plug-in all'avvio del server utilizzando l'opzione --plugin-load o --plugin-load-add o in fase di esecuzione utilizzando l'istruzione INSTALL PLUGIN.
- L'utilità resolveip è stata rimossa. È invece possibile utilizzare nslookup, host o dig.
Ci sono molte funzionalità nuove, deprecate e rimosse. Puoi controllare il sito ufficiale per informazioni più dettagliate.
Considerazioni prima della migrazione a MySQL 8.0
Citiamo ora alcune delle cose più importanti da considerare prima di migrare a questa versione di MySQL.
Metodo di autenticazione
Come accennato, caching_sha2_password non è il metodo di autenticazione predefinito, quindi dovresti verificare se la tua applicazione/connettore lo supporta. In caso contrario, vediamo come modificare nuovamente il metodo di autenticazione predefinito e il plug-in di autenticazione utente in "mysql_native_password".
Per modificare il metodo di autenticazione predefinito, modifica il file di configurazione my.cnf e aggiungi/modifica la seguente riga:
$ vi /etc/my.cnf
[mysqld]
default_authentication_plugin=mysql_native_password
Per modificare il plug-in di autenticazione utente, esegui il seguente comando con un utente privilegiato:
$ mysql -p
ALTER USER ‘username’@’hostname’ IDENTIFIED WITH ‘mysql_native_password’ BY ‘password’;
Comunque, queste modifiche non sono una soluzione permanente poiché la vecchia autenticazione potrebbe essere presto ritirata, quindi dovresti tenerne conto per un futuro aggiornamento del database.
Anche i ruoli sono una caratteristica importante qui. Puoi ridurre i privilegi individuali assegnandolo a un ruolo e aggiungendovi gli utenti corrispondenti.
Ad esempio, puoi creare un nuovo ruolo per i team di marketing e sviluppatori:
$ mysql -p
CREATE ROLE 'marketing', 'developers';
Assegna i privilegi a questi nuovi ruoli:
GRANT SELECT ON *.* TO 'marketing';
GRANT ALL PRIVILEGES ON *.* TO 'developers';
E poi, assegna il ruolo agli utenti:
GRANT 'marketing' TO 'marketing1'@'%';
GRANT 'marketing' TO 'marketing2'@'%';
GRANT 'developers' TO 'developer1'@'%';
E questo è tutto. Avrai i seguenti privilegi:
SHOW GRANTS FOR 'marketing1'@'%';
+-------------------------------------------+
| Grants for [email protected]% |
+-------------------------------------------+
| GRANT USAGE ON *.* TO `marketing1`@`%` |
| GRANT `marketing`@`%` TO `marketing1`@`%` |
+-------------------------------------------+
2 rows in set (0.00 sec)
SHOW GRANTS FOR 'marketing';
+----------------------------------------+
| Grants for [email protected]% |
+----------------------------------------+
| GRANT SELECT ON *.* TO `marketing`@`%` |
+----------------------------------------+
1 row in set (0.00 sec)
Set di personaggi
Dato che il nuovo set di caratteri predefinito è utf8mb4, dovresti assicurarti di non utilizzare quello predefinito poiché cambierà.
Per evitare alcuni problemi, dovresti specificare le variabili character_set_server e collation_server nel file di configurazione my.cnf.
$ vi /etc/my.cnf
[mysqld]
character_set_server=latin1
collation_server=latin1_swedish_ci
Motore MyISAM
Le tabelle dei privilegi MySQL nello schema MySQL vengono spostate in InnoDB. Puoi creare un motore di tabella =MyISAM e funzionerà come prima, ma copiare una tabella MyISAM in un server MySQL in esecuzione non funzionerà perché non verrà rilevato.
Partizionamento
Non devono esserci tabelle partizionate che utilizzano un motore di archiviazione che non dispone del supporto del partizionamento nativo. Puoi eseguire la query seguente per verificare questo punto.
$ mysql -p
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';
Se devi cambiare il motore di una tabella, puoi eseguire:
ALTER TABLE table_name ENGINE = INNODB;
Verifica aggiornamento
Come ultimo passaggio, puoi eseguire il comando mysqlcheck usando il flag check-upgrade per confermare se tutto sembra a posto.
$ mysqlcheck -uroot -p --all-databases --check-upgrade
Enter password:
mysql.columns_priv OK
mysql.component OK
mysql.db OK
mysql.default_roles OK
mysql.engine_cost OK
mysql.func OK
mysql.general_log OK
mysql.global_grants OK
mysql.gtid_executed OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.innodb_index_stats OK
mysql.innodb_table_stats OK
mysql.password_history OK
mysql.plugin OK
mysql.procs_priv OK
mysql.proxies_priv OK
mysql.role_edges OK
mysql.server_cost OK
mysql.servers OK
mysql.slave_master_info OK
mysql.slave_relay_log_info OK
mysql.slave_worker_info OK
mysql.slow_log OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
sys.sys_config OK
world_x.city OK
world_x.country OK
world_x.countryinfo OK
world_x.countrylanguage OK
Ci sono diverse cose da controllare prima di eseguire l'aggiornamento. Puoi controllare la documentazione ufficiale di MySQL per informazioni più dettagliate.
Metodi di aggiornamento
Ci sono diversi modi per aggiornare MySQL 5.7 a 8.0. Puoi utilizzare l'aggiornamento sul posto o persino creare uno slave di replica nella nuova versione, in modo da poterlo promuovere in un secondo momento.
Ma prima dell'aggiornamento, il passaggio 0 deve eseguire il backup dei dati. Il backup dovrebbe includere tutti i database inclusi i database di sistema. Quindi, in caso di problemi, puoi eseguire il rollback il prima possibile.
Un'altra opzione, a seconda delle risorse disponibili, può essere la creazione di una replica a cascata MySQL 5.7 -> MySQL 8.0 -> MySQL 5.7, quindi dopo aver promosso la nuova versione, se qualcosa è andato storto, puoi promuovere il nodo slave con la vecchia versione indietro. Ma potrebbe essere pericoloso se si verificasse qualche problema con i dati, quindi il backup è d'obbligo prima.
Per qualsiasi metodo da utilizzare, è necessario un ambiente di test per verificare che l'applicazione funzioni senza alcun problema utilizzando la nuova versione di MySQL 8.0.
Conclusione
Più di 1 anno dopo il rilascio di MySQL 8.0, è tempo di iniziare a pensare di migrare la tua vecchia versione di MySQL, ma fortunatamente, poiché la fine del supporto per MySQL 5.7 è il 2023, hai tempo per creare un piano di migrazione e testare il comportamento dell'applicazione senza fretta. Trascorrere del tempo in quella fase di test è necessario per evitare problemi dopo la migrazione.