it-swarm-eu.dev

Jak mohu optimalizovat mysqldump velké databáze?

Mám aplikaci symfony s databází InnoDB, která má ~ 2 GB s 57 tabulkami. Většina velikosti databáze je umístěna v jedné tabulce (~ 1,2 GB). Momentálně používám mysqldump k zálohování databáze každou noc.

Vzhledem k mému připojení k vysílání je často, když spustím výpis ručně, moje připojení k serveru vyprší časový limit, než je výpis dokončen, což mě nutí znovu spustit výpis. [V současné době provozuji cron, který provádí výpis za noc, je to jen pro výpisy, které spustím ručně.]

Existuje způsob, jak urychlit výpisy pro problém s vypršením časového limitu připojení, ale také omezit dobu, po kterou je server tímto procesem obsazen?

BTW, v současné době pracuji na zmenšení velikosti celkové databáze, abychom tento problém vyřešili.

179
Patrick

Hlavní překážkou na skládce, jako je tato, je jednotka I/O. Čtete načtení dat a zapíšete je znovu. Můžete to urychlit několika způsoby:

  • Ujistěte se, že váš výstup směřuje na jinou jednotku (jednotky), než na které jsou uloženy soubory databáze - to bude mít velký dopad na rotující disky, protože hlavy jednotek nebudou neustále blikat mezi místem, ze kterého se načítají a místo, na které se zapisuje.
  • Výstup mysqldumpu bude velmi stlačitelný, takže pokud nemůžete oddělit výstup od vstupu, jak je uvedeno výše, posuňte výstup přes gzip nebo podobně. Tím se sníží množství prováděného zápisu (takže snížíte celkové IO zatížení a množství pohybu hlavy) na úkor nějakého času CPU (který můžete mít spoustu volného času na tyto časy stejně).
  • Rovněž (také nebo namísto komprese) projde výstup pomocí obslužného programu pipe (jako pv ), který podporuje velké vyrovnávací paměti pro zápis do skupinových bloků zapisovaných do jednotek více společně, což opět snižuje účinek hlavy -latence zpoždění - to bude mít značný rozdíl, pokud použijete --quick možnost snížit dopad RAM zálohování velkých tabulek).
  • Spusťte proces zálohování pouze v případě, že IO načtení je jinak nízké).

Možná však opravujete nesprávný problém: namísto toho může být snazší řešit poklesy připojení (i když snížení zatížení I/O způsobeného vašimi zálohami pomůže snížit účinek, který máte na ostatní uživatele, takže stojí za to vyzkoušet). Mohli byste spustit manuální zálohování pomocí obrazovka (nebo podobných nástrojů jako tmux )? Tímto způsobem, pokud vaše připojení k serveru klesne, stačí se znovu připojit a znovu připojit k relaci screen, aniž by došlo k přerušení procesů.

Pokud odesíláte data přímo přes připojení (tj. Provozujete mysqldump na vašem lokálním počítači proti vzdálené databázi, takže se výpis objeví lokálně), možná bude lepší nejprve spustit výpis na serveru, komprimovat podle potřeby a poté přenést data v síti pomocí nástroje (například rsync), který podporuje částečné přenosy, takže můžete pokračovat v přenosu (namísto restartování), pokud to přeruší připojení.

V rámci vašeho „zmenšení velikosti celkové databáze k vyřešení tohoto problému“ bych hádal, že se velká část vašich dat nezmění. Možná budete moci přesunout velký kus 1,2 GB z této hlavní tabulky do jiného a odstranit jej z těch, které jsou zkopírovány voláním mysqldump. Pokud se to nikdy nezmění, není třeba tato data zálohovat pokaždé. Rozdělení dat mezi tabulkami a databázemi tímto způsobem je obvykle označováno jako dělení dat a může vám také umožnit rozložení dat a zatížení I/O na více jednotek. High-end databáze má vestavěnou podporu pro automatické dělení do oddílů, i když v mysql to budete pravděpodobně muset udělat ručně a změnit svou vrstvu přístupu k datům.

Straying off-topic pro tento web (takže byste se pravděpodobně měli přiblížit k ServerFault nebo SuperUser a zeptat se, jestli potřebujete více informací): Pokud se zdá, že ztratíte spojení kvůli nečinnosti, zkontrolujte možnosti na vašem SSH serveru a SSH klientovi Ujistěte se, že pakety typu keep-live jsou povoleny a zasílány dostatečně často. Pokud vidíte pokles, i když je připojení aktivní, můžete také zkusit zabalit připojení pomocí OpenVPN nebo podobného - mělo by to zvládnout krátkou kapku, dokonce i úplnou kapku, pokud je celé připojení na několik sekund přerušeno, takže klient SSH a server si toho nevšiml.

139
David Spillett

PŘEHLED DO BACKUPSŮ S mysqldump

IMHO Provádění záloh se stalo více uměleckou formou, pokud víte, jak k ní přistupovat

Máte možnosti

Možnost 1: mysqldump celou instanci mysql

Tohle je nejjednodušší, bez přemýšlení !!!

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

Vše napsané v jednom souboru: struktury tabulek, indexy, triggery, uložené procedury, uživatelé, šifrovaná hesla. Jiné možnosti mysqldump mohou také exportovat různé styly příkazů INSERT, soubor protokolu a souřadnice polohy z binárních protokolů, možnosti vytváření databáze, částečná data (- kdekoli) atd.

Možnost 2: mysqldump oddělit databáze do samostatných datových souborů

Začněte vytvořením seznamu databází (2 techniky, jak toho dosáhnout)

Technika 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

Technika 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

Technika 1 je nejrychlejším způsobem. Technika 2 je nejbezpečnější a nejbezpečnější. Technika 2 je lepší, protože někdy uživatelé vytvářejí složky pro obecné účely v/var/lib/mysql (datadir), které se netýkají databáze. Information_schema by složku zaregistroval jako databázi v tabulce information_schema.schemata. Technika 2 by obcházela složky, které neobsahují data mysql.

Jakmile sestavíte seznam databází, můžete seznamem procházet a mysqldump je procházet, i když je to žádoucí, paralelně.

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

Pokud existuje příliš mnoho databází pro spuštění najednou, vypusťte je souběžně s výpisem 10 najednou:

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

Možnost 3: mysqldump oddělit tabulky do samostatných datových souborů

Začněte vytvořením seznamu tabulek

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

Poté vypíše všechny tabulky do skupin po 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

Možnost 4: POUŽÍVEJTE VÁŠ OBRAZ

Vyzkoušejte varianty výše uvedených možností a technik pro čisté snímky

Příklady

  1. Seřaďte seznam tabulek podle velikosti každé tabulky vzestupně nebo sestupně.
  2. Před spuštěním mysqldumps pomocí samostatného procesu spusťte „FLUSH TABLES WITH READ LOCK; SELECT SLEEP (86400)“. Po dokončení mysqldumps tento proces zabijte. To je užitečné, pokud databáze obsahuje InnoDB i MyISAM
  3. Uložte mysqldumps do datovaných složek a otočte staré záložní složky.
  4. Načíst celou instanci mysqldumps do samostatných serverů.

[~ # ~] upozornění [~ # ~]

Pouze možnost 1 přináší vše. Nevýhodou je, že mysqldumps vytvořené tímto způsobem lze znovu načíst do stejné hlavní verze verze mysql, která byla vygenerována. Jinými slovy, mysqldump z databáze MySQL 5.0 nelze načíst v 5.1 nebo 5.5. Důvod ? Schéma mysql se u hlavních vydání celkem liší.

Možnosti 2 a 3 nezahrnují ukládání uživatelských jmen a hesel.

Zde je obecný způsob, jak vypsat SQL Granty pro uživatele, které jsou čitelné a přenosnější

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

Možnost 3 neuloží uložené procedury, takže můžete provést následující

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

Další bod, který je třeba poznamenat, se týká InnoDB. Pokud máte velký fond vyrovnávacích pamětí InnoDB, je rozumné jej před provedením jakýchkoli záloh vyprázdnit co nejlépe. V opačném případě MySQL tráví tabulky propláchnutí času zbývající špinavou stránkou z fondu vyrovnávacích pamětí. Zde je to, co navrhuji:

Asi 1 hodinu před provedením zálohy spusťte tento příkaz SQL

SET GLOBAL innodb_max_dirty_pages_pct = 0;

V MySQL 5.5 je výchozí hodnota innodb_max_dirty_pages_pct 75. V MySQL 5.1 a zpět je výchozí hodnota innodb_max_dirty_pages_pct 90. Nastavením innodb_max_dirty_pages_pct na 0 to urychlí propláchnutí špinavých stránek na disk. Tím se zabrání nebo alespoň sníží dopad vyčištění veškerých neúplných dvoufázových odevzdání dat InnoDB před provedením jakéhokoli mysqldump proti jakýmkoli tabulkám InnoDB.

ZÁVĚREČNÉ slovo ON mysqldump

Většina lidí se vyhýbá mysqldumpu ve prospěch jiných nástrojů a tyto nástroje jsou opravdu dobré.

Mezi takové nástroje patří

  1. MAATKIT (paralelní výpis / obnovit skripty, od Percona [Zastaralé, ale skvělé])
  2. XtraBackup (TopNotch Snapshot Backup from Percona)
  3. CDP R1Soft ( MySQL Module Option , který pořizuje momentky)
  4. MySQL Enterprise Backup (dříve InnoDB Hot Backups [komerční])

Pokud máte ducha opravdové MySQL DBA, můžete přijmout mysqldump a získat nad ním úplné mistrovství, kterého lze dosáhnout. Všechny vaše zálohy mohou být odrazem vašich schopností MySQL DBA .

122
RolandoMySQLDBA

Podívejte se na replikační master MySQL na slave. Umožňuje klonovat databázi masteru na jiný databázový server se stejnou databází. To zahrnuje totožnost pána a otroka. Slave si vytvoří přesnou kopii hlavního databázového serveru nebo jeho databází. Může existovat vztah jeden-jeden, jeden-mnoho, mnoho-jeden mezi pánem a otroky.

Slave nepřetržitě čte binární log na master (bin bin ukládá dotazy zapsané na master databázovém serveru) a získává vstup na jeho slave databázový server. (to znamená, že vaše hlavní databáze nebude nijak ovlivněna)

Dobrou zprávou je, že to nebude mít vliv na váš server MySQL tak moc, jako byste si nevšimli žádných prostojů nebo pomalých odpovědí na dotazy. Používáme jej pro 10Gb databáze a funguje to jako kouzlo bez jakýchkoli prostojů.

MySQL replikace ve stejném počítači

20
poelinca

Plán A: Viz také Xtrabackup z Percony. To umožňuje online zálohu InnoDB, aniž by došlo k významnému uzamčení.

Plán B: Otrok lze zastavit a můžete provést konzistentní zálohu několika způsoby (kopírování souborů, mysqldump, xtrabackup atd.)

Plán C: Snímek LVM. Po nějakém kryptickém nastavení je prostoje zálohy kratší než minuta, bez ohledu na velikost databáze. Zastavíte mysqld, uděláte snímek, restartujete mysqld a potom zkopírujete snímek. Poslední krok může trvat dlouho, ale MySQL není dole.

Plán D: Snímek slave - nulové prostoje.

19
Rick James

Nejdříve několik admin bodů: Připojujete se, abyste udělali ftp, nebo jste zasaženi a umírá? Pokud ssh, pak použijte screen, abyste mohli pokračovat po pádu comcastu. Pokud ftp, pak se ujistěte, že jste kompresi/dehtu před odesláním.

Vyzkoušejte také parametr --opt nebo - quick

--opt Tato volba zapne řadu dalších možností, aby byly operace výpisu a načtení efektivnější. Konkrétně je to ekvivalentní společné použití možností --add-drop-table, --add-locks, --all, --quick, --extended-insert, --lock-tables a --disable-keys. Všimněte si, že tato možnost způsobí, že výstup bude méně přenosný a bude méně pravděpodobné, že jej pochopí jiné databázové systémy.

--quick Tato volba říká mysqldump, aby zapisoval výstup výpisu, když načítá každý řádek ze serveru, což může být užitečné pro velké tabulky. Ve výchozím nastavení mysqldump před zápisem výstupu přečte všechny řádky z tabulky do paměti; u velkých tabulek to vyžaduje velké množství paměti, což pravděpodobně způsobí selhání výpisu.

15
David Hall

Také jsem měl problémy s timeouty během výpisů velkých databází. Nakonec jsem vyřešil, zda posíláním jednotlivých příkazů pro každou tabulku v db a připojením všeho k jednomu souboru, jako je tento:

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

Myslím, že jde o to, jak rychleji obnovit z vytvořených souborů výpisu z mysqldumpu, nikoli o jiné řešení zálohy.

Jedním ze způsobů, jak toho dosáhnout, je vytvoření skupin tabulek ve vašem schématu a vytvoření samostatného uživatele DB pro každou skupinu, pak nakonec použít oprávnění MySQL, která neumožní vkládání tabulek do všech uživatelů kromě jednoho uživatele DB.

Toto je osvědčená, rychlá, téměř paralelní technika, ale není si stoprocentně jistá, jak dlouho bude trvat, než se obnoví z velkých skládek, jako je 500G nebo tak. Ale podle mého skromného názoru potřebujete něco paralelního. Podívejte se na níže uvedený odkaz jako příklad.

[Rychlé a paralelní obnovení z výpisů SQL (mysqldump) pro MySQL] [1]

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

"Rychlé a paralelní obnovení z výpisů SQL (mysqldump) pro MySQL"

3
syed