Spostare un database è un dump e un'importazione. A mandare tutto storto è ciò che un dump non contiene, e scoprirlo quando il sito punta già al server nuovo.

Il dump

mysqldump --single-transaction --quick --routines --triggers --events \
          --default-character-set=utf8mb4 shop | gzip > shop.sql.gz

Il trasferimento

scp shop.sql.gz newserver:/tmp/
# or stream it directly, with no file in between
mysqldump --single-transaction shop | gzip | ssh newserver 'gunzip | mysql shop'

Crei la destinazione come si deve, prima di importare

mysql -e "CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
zcat /tmp/shop.sql.gz | mysql shop
Crei prima il database con il set di caratteri giusto. Importare in un database latin1 le dà uno schema che sembra corretto e rovina in silenzio l'arabo e le emoji: veda set di caratteri e collazione.

Le tre cose che il dump non porta

  • Utenti e permessi. Abitano nello schema mysql. Li ricrei: veda utenti e permessi.
  • La configurazione del server. Buffer pool, max_connections, timeout. Riporti le righe che la riguardano.
  • Gli eventi pianificati, a meno che non abbia passato --events, e lo scheduler degli eventi dev'essere attivo anche sul server nuovo.
CREATE USER 'shop'@'localhost' IDENTIFIED BY '...';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'shop'@'localhost';
SET GLOBAL event_scheduler = ON;

Verifichi prima di passare

# same table count, same row counts on the tables that matter
mysql -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='shop'"
mysql shop -e "SELECT COUNT(*) FROM orders; SELECT COUNT(*) FROM customers"
Confronti il numero di righe con il vecchio server prima di puntare l'applicazione sul nuovo. Un'importazione che fallisce a metà su certe strade finisce lo stesso senza lamentarsi, e mezzo database sembra identico a uno che funziona finché qualcuno non cerca il mese scorso.