it-swarm.it

Come posso ottimizzare un mysqldump di un database di grandi dimensioni?

Ho un'applicazione symfony con un database InnoDB che è ~ 2 GB con 57 tabelle. La maggior parte delle dimensioni del database risiede in una singola tabella (~ 1,2 GB). Attualmente sto usando mysqldump per eseguire il backup del database ogni notte.

A causa della mia connessione comcast, spesso se eseguo un dump manualmente la mia connessione al server si interromperà prima che il dump sia completo, causandomi di dover rieseguire il dump. [Attualmente eseguo un cron che esegue il dump ogni notte, questo è solo per i dump che eseguo manualmente.]

C'è un modo per accelerare i dump per il problema di timeout della connessione, ma anche per limitare il tempo in cui il server è occupato con questo processo?

A proposito, sto attualmente lavorando per ridurre le dimensioni del database generale per risolvere questo problema.

179
Patrick

Il principale collo di bottiglia nella discarica come questo è I/O dell'unità. Stai leggendo un sacco di dati e scrivendoli di nuovo. Puoi accelerarlo in diversi modi:

  • Assicurati che il tuo output stia andando su una o più unità diverse da quelle su cui sono archiviati i file di database - questo farà una differenza enorme con i dischi rotanti poiché le testine dell'unità non scorreranno costantemente tra la posizione da cui stai leggendo e la posizione in cui si sta scrivendo.
  • L'output di mysqldump sarà molto comprimibile, quindi se non è possibile separare l'output dall'input come menzionato sopra, reindirizzare l'output attraverso gzip o simili. Ciò ridurrà la quantità di scrittura eseguita (quindi riduci il totale IO e la quantità di movimento della testina) a scapito di un po 'di tempo della CPU (di cui potresti avere molto di riserva in queste volte comunque).
  • Inoltre, (come pure o invece della compressione), passa l'output attraverso un'utility pipe (come pv ) che supporta grandi buffer di scrittura per raggruppare più blocchi scritti sulle unità, ancora una volta per ridurre l'effetto della testa latenza del movimento: questo farà la differenza se si utilizza --quick opzione per ridurre il RAM del backup di tabelle di grandi dimensioni).
  • Esegui il processo di backup solo quando IO il carico è altrimenti basso.

È possibile che tu stia risolvendo il problema sbagliato: potrebbe invece essere più semplice affrontare le cadute di connessione (sebbene ridurre il carico di I/O imposto dai tuoi backup contribuirà a ridurre l'effetto che hai sugli altri utenti, quindi vale la pena provare comunque). Potresti eseguire i tuoi backup manuali attraverso schermo (o strumenti simili come tmux )? In questo modo se la tua connessione al server si interrompe, puoi semplicemente riconnetterti e ricollegarti alla sessione screen senza che i processi vengano interrotti.

Se stai inviando i dati direttamente tramite la connessione (ovvero stai eseguendo mysqldump sul tuo computer locale contro un database remoto, quindi il dump appare localmente) potresti essere meglio eseguendo prima il dump sul server, comprimendolo secondo necessità, quindi trasferendo i dati sulla rete utilizzando uno strumento (come rsync) che supporta i trasferimenti parziali in modo da poter riprendere il trasferimento (anziché riavviare) se una caduta di connessione lo interrompe.

Come parte del tuo "ridurre le dimensioni del database complessivo per risolvere questo problema", immagino che una grande porzione dei tuoi dati non cambi. Potresti essere in grado di spostare un grosso pezzo di 1.2Gb da quella tabella principale in un'altra e rimuoverlo da quelli che sono copiati dalla chiamata mysqldump. Non è necessario eseguire il backup di questi dati ogni volta che non cambiano mai. La suddivisione dei dati tra tabelle e database in questo modo viene generalmente definita partizionamento dei dati e può anche consentire di distribuire i dati e il carico di I/O su più unità. Il database di fascia alta ha integrato il supporto per il partizionamento automatico, sebbene in mysql probabilmente dovrai farlo manualmente e modificare il tuo livello di accesso ai dati per renderlo conto.

Distaccarsi dall'argomento per questo sito (quindi probabilmente dovresti passare a ServerFault o SuperUser per chiedere se hai bisogno di maggiori dettagli): Se sembra che tu stia perdendo connessioni a causa di inattività, controlla le opzioni nel tuo server SSH e nel client SSH per effettuare certo che i pacchetti keep-alive sono abilitati e inviati abbastanza spesso. Se vedi i drop anche se la connessione è attiva, puoi anche provare a usare OpenVPN o simile per concludere la connessione: dovrebbe gestire un drop breve, anche un drop completo se l'intera connessione è inattiva per alcuni secondi, in modo che il client SSH e il server non se ne accorge.

139
David Spillett

INSIGHT IN FARE BACKUP CON mysqldump

IMHO Fare backup è diventato più una forma d'arte se sai solo come affrontarlo

Hai delle opzioni

Opzione 1: mysqldump un'intera istanza mysql

Questo è il più semplice, il gioco da ragazzi !!!

mysqldump -h... -u... -p... --hex-blob --routines --triggers --all-databases | gzip > MySQLData.sql.gz

Tutto scritto in un unico file: strutture di tabelle, indici, trigger, procedure memorizzate, utenti, password crittografate. Altre opzioni di mysqldump possono anche esportare diversi stili di comandi INSERT, file di registro e coordinate di posizione da registri binari, opzioni di creazione del database, dati parziali (opzione --where) e così via.

Opzione 2: mysqldump database separati in file di dati separati

Inizia creando un elenco di database (2 tecniche per farlo)

Tecnica 1

mysql -h... -u... -p... -A --skip-column-names -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql')" > ListOfDatabases.txt

Tecnica 2

mysql -h... -u... -p... -A --skip-column-names -e"SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfDatabases.txt

La tecnica 1 è il modo più veloce. La tecnica 2 è la più sicura e sicura. La tecnica 2 è migliore perché, a volte, gli utenti creano cartelle per scopi generali in/var/lib/mysql (datadir) che non sono correlate al database. Information_schema registra la cartella come database nella tabella information_schema.schemata. La tecnica 2 ignorerebbe le cartelle che non contengono dati mysql.

Una volta compilato l'elenco dei database, è possibile procedere a scorrere l'elenco e mysqldump, anche in parallelo, se desiderato.

for DB in `cat ListOfDatabases.txt`
do
    mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
done
wait

Se ci sono troppi database da avviare contemporaneamente, esegui il dump parallelo di 10 alla volta:

COMMIT_COUNT=0
COMMIT_LIMIT=10
for DB in `cat ListOfDatabases.txt`
do
    mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

Opzione 3: mysqldump tabelle separate in file di dati separati

Inizia creando un elenco di tabelle

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfTables.txt

Quindi scaricare tutte le tabelle in gruppi di 10

COMMIT_COUNT=0
COMMIT_LIMIT=10
for DBTB in `cat ListOfTables.txt`
do
    DB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $1}'`
    TB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $2}'`
    mysqldump -h... -u... -p... --hex-blob --triggers ${DB} ${TB} | gzip > ${DB}_${TB}.sql.gz &
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

Opzione 4: USA LA TUA IMMAGINAZIONE

Prova le varianti delle opzioni sopra menzionate e le tecniche per istantanee pulite

Esempi

  1. Ordinare l'elenco delle tabelle in base alla dimensione di ciascuna tabella crescente o decrescente.
  2. Utilizzando un processo separato, eseguire "FLUSH TABLES WITH READ LOCK; SELECT SLEEP (86400)" prima di avviare mysqldumps. Uccidi questo processo dopo che mysqldumps è completo. Ciò è utile se un database contiene sia InnoDB che MyISAM
  3. Salvare i mysqldumps in cartelle datate e ruotare le vecchie cartelle di backup.
  4. Carica l'intera istanza mysqldumps in server autonomi.

[~ ~ #] avvertimento [~ ~ #]

Solo l'opzione 1 porta tutto. Lo svantaggio è che mysqldumps creato in questo modo può essere ricaricato solo nella stessa versione di mysql di rilascio majot che mysqldump è stata generata. In altre parole, un mysqldump da un database MySQL 5.0 non può essere caricato in 5.1 o 5.5. La ragione ? Lo schema mysql è totalmente diverso tra le versioni principali.

Le opzioni 2 e 3 non includono il salvataggio di nomi utente e password.

Ecco il modo generico per scaricare le sovvenzioni SQL per gli utenti che è leggibile e più portatile

mysql -h... -u... -p... --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql -h... -u... -p... --skip-column-names -A | sed 's/$/;/g' > MySQLGrants.sql

L'opzione 3 non salva le procedure memorizzate, quindi è possibile effettuare le seguenti operazioni

mysqldump -h... -u... -p... --no-data --no-create-info --routines > MySQLStoredProcedures.sql &

Un altro punto che dovrebbe essere notato riguarda InnoDB. Se si dispone di un pool di buffer InnoDB di grandi dimensioni, è consigliabile scaricarlo nel modo migliore prima di eseguire qualsiasi backup. Altrimenti, MySQL passa il tempo a svuotare le tabelle con le pagine sporche rimanenti dal pool di buffer. Ecco cosa suggerisco:

Circa 1 ora prima di eseguire il backup eseguire questo comando SQL

SET GLOBAL innodb_max_dirty_pages_pct = 0;

In MySQL 5.5 il valore predefinito innodb_max_dirty_pages_pct è 75. In MySQL 5.1 e versioni successive, il valore predefinito innodb_max_dirty_pages_pct è 90. Impostando innodb_max_dirty_pages_pct su 0, questo accelererà il flusso di pagine sporche su disco. Ciò impedirà o almeno ridurrà l'impatto della ripulitura di eventuali commit incompleti a due fasi dei dati InnoDB prima di eseguire qualsiasi mysqldump contro qualsiasi tabella InnoDB.

Word FINALE SU mysqldump

Molte persone evitano mysqldump a favore di altri strumenti e questi strumenti sono davvero buoni.

Tali strumenti includono

  1. MAATKIT (parallelo dump / ripristino script, da Percona [obsoleto ma eccezionale])
  2. XtraBackup (TopNotch Snapshot Backup da Percona)
  3. CDP R1Soft ( Opzione modulo MySQL che scatta istantanee temporizzate)
  4. MySQL Enterprise Backup (precedentemente InnoDB Hot Backups [commerciale])

Se hai lo spirito di un vero DBA MySQL, puoi abbracciare mysqldump e avere la padronanza completa su di essa che può essere raggiunta. Possano tutti i tuoi backup riflettere le tue capacità di DBA MySQL .

122
RolandoMySQLDBA

Dai un'occhiata al master di replica MySQL su slave. Consente di clonare il database del master su un altro server di database con lo stesso database. Ciò include le identità master e slave. Slave si rende la copia esatta del server di database principale e/o dei suoi database. Può esserci una relazione uno-uno-molti-molti-uno tra il/i maestro/i e il/i schiavo/i.

Lo slave legge continuamente il registro binario sul master (il registro bin memorizza le query scritte sul server del database master) e ottiene l'input sul suo server del database slave. (questo significa che il tuo database principale non sarà affatto interessato)

La buona notizia è che non influenzerà troppo il tuo server MySQL poiché non noterai tempi di inattività o risposte lente alle query. Lo usiamo per database da 10 Gb e funziona come un incantesimo senza tempi di inattività.

Replica MySQL sulla stessa macchina

20
poelinca

Piano A: vedi anche Xtrabackup da Percona. Ciò consente il backup online di InnoDB, senza alcun blocco significativo.

Piano B: uno slave può essere arrestato e è possibile eseguire un backup coerente in uno dei diversi modi (copia file, mysqldump, xtrabackup, ecc.)

Piano C: Istantanea LVM. Dopo alcune impostazioni criptiche, i tempi di inattività di un backup sono inferiori a un minuto, indipendentemente dalle dimensioni del database. Interrompi mysqld, esegui l'istantanea, riavvia mysqld, quindi copia l'istantanea. L'ultimo passaggio può richiedere molto tempo, ma MySQL non è inattivo.

Piano D: Istantanea di uno Slave - zero tempi di inattività.

19
Rick James

Prima alcuni punti di amministrazione: ti stai connettendo per fare un ftp o sei entrato e sta morendo? Se ssh, assicurati di usare schermo in modo da poter riprendere dopo l'arresto anomalo del comcast. Se ftp, assicurati di comprimerlo/tar prima dell'invio.

Prova anche il parametro --opt o --quick

--opt Questa opzione attiva una serie di opzioni aggiuntive per rendere più efficienti le operazioni di dump e ricarica. In particolare, equivale a usare insieme le opzioni --add-drop-table, --add-locks, --all, --quick, --extended-insert, --lock-tables e --disable-keys. Si noti che questa opzione rende l'output meno portatile e meno comprensibile per altri sistemi di database.

--quick Questa opzione dice a mysqldump di scrivere l'output di dump mentre legge ogni riga dal server, il che potrebbe essere utile per le tabelle di grandi dimensioni. Per impostazione predefinita, mysqldump legge tutte le righe da una tabella in memoria prima di scrivere l'output; per tabelle di grandi dimensioni, ciò richiede grandi quantità di memoria, che potrebbe causare il fallimento del dump.

15
David Hall

Avevo problemi con i timeout anche durante il dump di grandi database. Ho finalmente risolto se inviando singoli comandi per ogni tabella nel db e aggiungendo tutto a un file come questo:

TABLES=`mysql -u $USER -p$PWD -Bse 'show tables' $DB`
for TABLE in $TABLES
do
    mysqldump -u $USER -p$PWD $DB $TABLE >> dump.sql
done
5
Patrick Heck

Penso che la domanda sia su come ripristinare più velocemente dai file di dump creati da mysqldump, non una diversa soluzione di backup.

Uno dei modi, è possibile farlo, creando gruppi di tabelle nel proprio schema e creando un utente DB separato per ciascun gruppo, quindi infine utilizzare le autorizzazioni MySQL per non consentire l'inserimento di tabelle nell'uso di tutti gli utenti DB tranne uno.

Questa è una tecnica collaudata, veloce, quasi parallela ma non sicura al 100%, quanto tempo ci vorrà per ripristinare da grandi discariche come 500 G o giù di lì. Ma a mio modesto parere, hai bisogno di qualcosa di parallelo. Controlla il link qui sotto per un esempio.

[Ripristino rapido e parallelo dai dump SQL (mysqldump) per MySQL] [1]

http://geeksww.com/tutorials/database_management_systems/mysql/tips_and_tricks/fast_parallel_restore_from_sql_dumps_mysqldump_for_mysql.php

"Ripristino rapido e parallelo dai dump SQL (mysqldump) per MySQL"

3
syed