Come posso spostare un database da un server a un altro?


136

Come posso spostare le tabelle MySQL da un server fisico a un altro?

Come questo scenario esatto: ho un server MySQL che utilizza una tabella innodb e ha una dimensione di circa 20 GB.

Voglio spostarlo su un nuovo server, qual è il modo più efficiente per farlo?


4
Vorrei usare xtrabackup percona.com/docs/wiki/… È molto simile a copiarlo ma puoi mantenere il server in esecuzione e supponendo che tu usi principalmente tabelle innodb (che hai detto di avere), puoi considerarlo un "caldo" anche il backup.
Jonathan,

Non traggo beneficio da altre persone che usano questo strumento. È gratuito / open-source e anche se è stato realizzato da un'azienda, è abbastanza facile da usare che non è necessario prendere in considerazione l'acquisto di supporto da quella società.
Jonathan,

Risposte:


80

Il mio modo preferito è reindirizzare un comando sqldump a un comando sql. È possibile eseguire tutti i database o uno specifico. Quindi, per esempio,

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

Puoi fare tutti i database con

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

L'unico problema è quando il database è troppo grande e il tubo collassa. In tal caso, è possibile eseguire una tabella per tabella o uno qualsiasi degli altri metodi indicati di seguito.


4
Suggerimento: se nessuno dei database consente connessioni remote, passare attraverso netcat.
Bart van Heukelom,

1
Perché questo funzioni per me, ho dovuto creare un database vuoto con lo stesso nome sul server remoto e quindi aggiungere il nome di quel database alla fine del comando.
Zugwalt,

1
Questo è elegante, ma senza compressione non è abbastanza veloce per un database da 20 GB.
Daddy32,

Questa soluzione è valida solo per una rete completamente controllata (se e solo se su una rete privata sicura, leggi: non Internet)! Ma soluzione semplice e veloce!
martedì

Questo è velocissimo! Ma quello che ha detto @Zugwalt era vero anche per me. Il comando non ha funzionato fino a quando non ho creato il database (vuoto) e aggiunto il nome del database alla fine del comando.
Skeets,

65

Di recente ho spostato un database da 30 GB con la seguente stragegy:

Vecchio server

  • Arresta il server mysql
  • Copia il contenuto di Datadir in un'altra posizione sul disco ( ~/mysqldata/*)
  • Avvia nuovamente il server mysql (il tempo di inattività è stato di 10-15 minuti)
  • comprimere i dati ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • copia il file compresso sul nuovo server

Nuovo server

  • installa mysql (non avviare)
  • decomprimere file compresso ( tar -xzvf mysqldata.tar.gz)
  • sposta i contenuti di mysqldata nel datadir
  • Assicurati che il tuo innodb_log_file_size sia lo stesso sul nuovo server o, in caso contrario, non copiare i vecchi file di registro ( mysql li genererà )
  • Inizia mysql

1
Salta la copia dopo comprimere / decomprimere. Trasmetti il ​​tar sulla rete usando ssh, oppure (se e solo se su una rete privata sicura leggi: non Internet) usa netcat per evitare il sovraccarico di crittografia. Inoltre, se su una rete locale salta il gzipping, se hai una pipe di rete veloce troverai il trasferimento colli di bottiglia su un core ancorato che esegue la compressione
atxdba

Questo funziona sia per innodb che per myisam? Inoltre, anche gli utenti mysql sono nel datadir?
giorgio79,

2
@ giorgio79 sicuro purché si spostino anche i file ibdata. Per impostazione predefinita, questi sono nel datadir. Gli utenti MySQL sono archiviati nella cartella mysql in un tablespace utente.
Derek Downey,

2
Questa procedura funzionerà per passare da Windows a Linux?
ypercubeᵀᴹ

2
@ TypoCubeᵀᴹ mi dispiace impiegare più di due anni per rispondere, ma mi avrebbe aiutato se qualcuno avesse detto definitivamente: "Sì, funziona da Windows a Linux". Nel mio caso, sono passato da Windows Server 2012 R2 al sistema operativo Cent (Red Hat 4.8.5-11) . La versione specifica di mysql era Maria DB 10.1 . Come prescritto, ho interrotto entrambi i servizi mysql, risincronizzato la directory dei dati e all'avvio del servizio mysql sul nuovo server, tutti i database, le tabelle del database e gli utenti del database erano completamente intatti.
WEBjuju

30

Secondo la Guida allo studio sulla certificazione MySQL 5.0 , capitolo 32, sezione 32.3.4, pagine 456.457 descrivono le condizioni per la portabilità binaria che mettono in evidenza quanto segue:

La portabilità binaria è importante se si desidera eseguire un backup binario creato su un computer e utilizzarlo su un altro computer con un'architettura diversa. Ad esempio, l'utilizzo di un backup binario è un modo per copiare database da un server MySQL a un altro.

Per MyISAM, la portabilità binaria significa che è possibile copiare direttamente i file per una tabella MyISAM da un server MySQL a un altro su un altro computer e il secondo server sarà in grado di accedere alla tabella.

Per InnoDB, la portabilità binaria significa che è possibile copiare direttamente i file del tablespace da un server MySQL su un computer su un altro server su un altro computer e il secondo server sarà in grado di accedere al tablespace. Per impostazione predefinita, tutte le tabelle InnoDB gestite da un server sono memorizzate insieme nel tablespace, pertanto la portabilità del tablespace dipende dal fatto che tutte le singole tabelle InnoDB siano portatili. Se anche una tabella non è portatile, non lo è nemmeno il tablespace.

Le tabelle MyISAM e i tablespace InnoDB sono portatili binari da un host all'altro se sono soddisfatte due condizioni:

  • Entrambe le macchine devono usare l'aritmetica di interi a complemento a due
  • Entrambe le macchine devono utilizzare il formato IEEE in virgola mobile, altrimenti le tabelle non devono contenere colonne in virgola mobile (FLOAT o DOUBLE)

In pratica, queste due condizioni pongono poche restrizioni. L'aritmetica dei numeri interi a due complementi e il formato a virgola mobile IEEE sono la norma sull'hardware moderno. Una terza condizione per la portabilità binaria di InnoDB è che è necessario utilizzare nomi minuscoli per tabelle e database. Questo perché InnoDB memorizza questi nomi internamente (nel suo dizionario dei dati) in minuscolo su Windows. L'uso di nomi in minuscolo consente la portabilità binaria tra Windows e Unix, per forzare l'uso di nomi in minuscolo, è possibile inserire le seguenti righe in un file di opzioni:

[mysqld]
lower_case_table_names=1

Se si configura InnoDB per l'utilizzo di tablespace per tabella, le condizioni per la portabilità binaria vengono estese per includere anche i file .ibd per le tabelle InnoDB. (Le condizioni per i tablespace condivisi sono ancora applicabili perché contiene il dizionario dei dati che memorizza le informazioni su tutte le tabelle InnoDB.)

Se le condizioni per la portabilità binaria non sono soddisfatte, è possibile copiare le tabelle MyISAM o InnoDB da un server a un altro scaricandole utilizzando un formato di testo (ad esempio, con mysqldump) e ricaricandole nel server di destinazione.

Esistono due modi principali basati sul motore di archiviazione per spostare singole tabelle.

Per l'esempio dato supponiamo che:

  1. il datadir è / var / lib / mysql
  2. database chiamato mydb
  3. tabella nel database mydb denominata mytable .

Tabelle MyISAM

Se mydb.mytable utilizza il motore di archiviazione MyISAM, la tabella verrà fisicamente manifestata come tre file separati

  1. /var/lib/mysql/mydb/mytable.frm (file .frm)
  2. /var/lib/mysql/mydb/mytable.MYD (file .MYD)
  3. /var/lib/mysql/mydb/mytable.MYI (file .MYI)

.Frm contiene la struttura della tabella
.MYD contiene i dati della tabella
.MYI contiene la pagina dell'indice della tabella

Questi file vengono utilizzati in modo interdipendente per rappresentare la tabella da un punto di vista logico in mysql. Poiché a questi file non è associata alcuna ulteriore associazione logica, la migrazione di una tabella da un server DB a un altro. Puoi persino farlo da un server Windows a un server Linux o MacOS. Ovviamente, potresti spegnere mysql e copiare i 3 file della tabella. È possibile eseguire quanto segue:

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

in una sessione ssh per tenere la tabella in sola lettura e tenere il blocco per 24 ore. Un secondo dopo, esegui la copia in un'altra sessione ssh. Quindi uccidi la sessione mysql con il blocco di 24 ore. Non è necessario attendere 24 ore.

Tabelle InnoDB

Sulla base della citazione di cui sopra dal libro di certificazione, ci sono molti fattori che regolano il backup di una tabella InnoDB specifica. Per semplicità, chiarezza e brevità, è sufficiente eseguire un mysqldump della tabella desiderata utilizzando i parametri --single-transazione per ottenere un perfetto dump temporaneo della tabella. Non c'è bisogno di cncernarsi con la semantica InnoDB se si desidera solo una tabella. Puoi ricaricare quel file di dump su qualsiasi server MySQL di tua scelta.

Poiché qui sono state unite due domande (jcolebrand): EDIT

Se sei più che disposto a vivere con alcune prestazioni DB lente, puoi eseguire una serie di rsync dal vecchio server (ServerA) al nuovo server (ServerB) anche mentre mysql è ancora in esecuzione su ServerA.

Step 01) installa la stessa versione di mysql su ServerB di ServerA

Passaggio 02) Su ServerA, eseguire SET GLOBAL innodb_max_dirty_pages_pct = 0;da mysql e circa 10 minuti (Questo elimina le pagine sporche dal pool di buffer InnoDB. Inoltre, consente di eseguire più rapidamente l'arresto di mysql) Se il database è tutto MyISAM, è possibile saltare questo passaggio.

Step 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

Passaggio 04) Ripetere il passaggio 03 fino a quando un rsync impiega meno di 1 minuto

Passaggio 05) service mysql stopsu ServerA

Passaggio 06) Eseguire un altro rsync

Step 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Passaggio 08) service mysql startsu ServerB

Passaggio 08) service mysql startsu ServerA (opzionale)

Provaci !!!

AVVERTIMENTO

È possibile creare uno slave di replica come questo. Ricorda solo di avere ID server esplicitamente impostato nel master /etc/my.cnf e un numero diverso per id server nello slave /etc/my.cnf


29

Non hai nemmeno bisogno di mysqldump se stai spostando un intero schema di database e sei disposto a fermare il primo database (quindi è coerente quando viene trasferito)

  1. Arresta il database (o bloccalo)
  2. Vai alla directory in cui si trovano i file di dati mysql.
  3. Trasferisci sulla cartella (e sui suoi contenuti) nella directory dei dati mysql del nuovo server
  4. Avvia il backup del database
  5. Sul nuovo server, emettere un comando 'crea database'. '
  6. Ricreare gli utenti e concedere le autorizzazioni.

Non riesco a ricordare se mysqldump gestisce utenti e autorizzazioni, o solo i dati ... ma anche se lo fa, questo è molto più veloce rispetto a fare un dump ed eseguirlo. Lo userei solo se avessi bisogno di scaricare un database mysql per poi reinserirlo in qualche altro RDBMS, se avessi bisogno di cambiare le opzioni di archiviazione (innodb vs. myisam), o forse se stessi cambiando i versi principali di mysql (ma Penso di averlo fatto tra 4 e 5, però)


Questo è più efficiente, specialmente se si è un amministratore di sistema / DBA. BTW mysqldump utilizza --all-databasesdump dello schema mysql. L'avvio di mysql sulla macchina successiva porta le autorizzazioni a condizione che tu abbia trasferito la cartella dei dati sull'altra macchina con la stessa versione principale di MySQL. (MySQL 5.5.xa MySQL 5.5.x, MySQL 5.1.xa MySQL 5.1.x, MySQL 5.0.xa MySQL 5.0.x)
RolandoMySQLDBA

4
@Joe, yes, mysqldumpgestisce utenti e permessi, poiché questi sono memorizzati nello mysqlschema.
Shlomi Noach il

Questo approccio è particolarmente utile con l'hosting cloud, come AWS. Puoi interrompere mysql, smontare e staccare dal server corrente; collegare e montare su un nuovo server e avviare mysql. Nessun overhead di copia se il volume è rimasto nella stessa server farm.
Frattale laterale

12

Se vuoi solo spostare una tabella specifica prova:

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

È possibile specificare più nomi di tabella sopra, nello stesso comando. Una volta completato il comando, spostare il file databasename.tablename.sql sull'altro server e quindi ripristinare utilizzando:

mysql -u username -ppassword databasename < databasename.tablename.sql

Si noti che il file .sql posteriore viene creato utilizzando il programma mysqldump e il ripristino viene eseguito direttamente in mysql .


7
  1. Se si dispone dell'accesso ssh, è possibile utilizzare mysqldump dalla riga di comando
  2. Se non hai accesso ssh ma hai accesso phpMyAdmin puoi usarlo per esportare / importare
  3. Se non si dispone dell'accesso a phpMyAdmin, ci sono alcuni utili script php che verranno scaricati e importati (tuttavia, per esperienza personale, non ne ho mai trovato uno affidabile come phpMyAdmin).

Potrebbe esserci questa possibilità in cui si spostano i file di database effettivi (per la mia installazione si trovano in / var / lib / mysql), ma non sono proprio sicuro di come funzionerà / funzionerà.


5

Avrai bisogno di fermarti. Ci vorrà del tempo a seconda della velocità della rete. Presumo che tu stia eseguendo MySQL su Linux / Unix. Ecco il processo che utilizzo:

  1. Arresta il demone mysql sull'host di origine.
  2. Crea una cartella tmp sul tuo host di destinazione per ricevere i file.
  3. Usa lo schermo per creare una sessione di shell che sopravviverà se il tuo ssh viene disconnesso.
  4. Utilizzare rsync per trasferire i file tra host. Qualcosa del tipo: rsync -avhP source user @ targethost: / path / to / folder /
  5. Esegui i tuoi casi di test per assicurarti di non aver perso nulla nel trasferimento.

Quindi procedere come al solito ottenendo la configurazione locale di MySQL.

* Nota: è anche possibile utilizzare il parametro -c con rsync per aggiungere un checksum al trasferimento, tuttavia questo sarà sloowow a seconda della velocità della CPU.


4

Posso confermare che il metodo DTest funziona anche per la copia tra ubuntu e osx.

Per copiare tutti i database senza dover eseguire alcun dumping o simili:

Assicurati di avere un mysql pulito di mysql (installato il dmg scaricato da mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), quello (MOLTO IMPORTANTE) non è mai stato eseguito.

Copia il contenuto della cartella / var / lib / mysql / dalla macchina ubuntu sopra / usr / local / mysql / data / contents sul mac. Per ottenere l'accesso per ottenere la cartella sulla macchina Ubuntu ho dovuto usare sudo cioè:

sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder

Ho copiato la cartella usando scp.

Prima di iniziare, prendi una copia della cartella mysql sul Mac per assicurarti di non rovinare nulla.

Dopo aver copiato la cartella, eseguire le seguenti operazioni sul computer Mac:

sudo chown -R _mysql /usr/local/mysql/data/
sudo chgrp -R wheel /usr/local/mysql/data/
sudo chmod -R g+rx /usr/local/mysql/data/

Avviare il server mysql per la prima volta (dal riquadro delle preferenze in Preferenze di Sistema-> mysql). Tutti gli utenti e i database ora dovrebbero essere impostati correttamente.

Funzionava con mysql 5.1.61 su Ubuntu 64 bit 11.10 e mysql 5.1.63 su osx lion (macbook pro).


4

Penso che tutte le risposte precedenti probabilmente funzionino bene, ma in realtà non risolvono il problema dell'impostazione di un nome di database durante il trasferimento.

Ecco come l'ho appena fatto con bash:

Potrebbe essere meglio usare rsyncdi scpe non comprimere il file se lo si fa spesso.

Sul mio server di origine:

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

Sul mio server di destinazione:

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

Su entrambe le macchine per vedere i progressi:

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

Tutto questo presuppone che tu abbia il file di configurazione di MySQL nella tua home directory su entrambe le macchine e imposta le autorizzazioni:

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf

3

lo stai spostando su un altro server mysql db? in tal caso, esegui un'esportazione

# mysqldump -u username -ppassword database_name > FILE.sql

Mysqldump? Questo è quando hai a che fare con una piccola quantità di dati?
Oh Chin Boon,

2
Penso che piccolo / grande sia abbastanza soggettivo in questi giorni. Quando ho visto il titolo della domanda mi aspettavo che il database fosse molto più grande di 20 GB per essere considerato "grande" ...
Aaron Bertrand

3

Metodo linux generico:

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

modificare il datadir (e il socket) sia per mysqld che mysqld_safe (se applicabile) per puntare alla nuova posizione, quindi

/etc/init.d/mysql start

Ho pubblicato questo perché nessuno sembrava semplicemente elencare il minor numero di passaggi per farlo e penso che sia il modo più semplice personalmente.


2

Forse questo è un modo migliore per farlo:

Versione 1 : copia dei file di dati (solo MYISAM)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

servizio ssh server2 riavvia mysql

  • Se i tuoi file di database vengono letti solo puoi saltare l'arresto del server.

Versione 2 : mysqldump

Installa pigz: sui moderni processori Xeon o Opteron, specialmente quando hai 2 o più CPU, è MOLTO più veloce di gzip.

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

Versione 3 : master / slave + mysqldump / file-copy

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

script:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

PS:

per copiare piccoli tavoli usare:

ssh server1 tabella schema mysqldump | schema ssh server2 mysql


2

Suggerirei due semplici passaggi per trasferire l'intero database da un server a un altro.

Passaggio 1 : eseguire un backup completo dei database nel server di origine utilizzando mysqldump .

Passaggio 2 : è possibile utilizzare il comando rsync per trasferire l'intero database al server di destinazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.