it-swarm.asia

Bagaimana saya bisa mengoptimalkan mysqldump dari database besar?

Saya memiliki aplikasi symfony dengan database InnoDB yang ~ 2GB dengan 57 tabel. Mayoritas ukuran basis data berada dalam satu tabel (~ 1.2GB). Saat ini saya menggunakan mysqldump untuk membuat cadangan database setiap malam.

Karena koneksi comcast saya, seringkali jika saya menjalankan dump secara manual koneksi saya ke server akan habis sebelum dump selesai menyebabkan saya harus menjalankan kembali dump. [Saat ini saya menjalankan cron yang melakukan dump setiap malam, ini hanya untuk dump yang saya jalankan secara manual.]

Apakah ada cara untuk mempercepat kesedihan untuk masalah waktu tunggu koneksi, tetapi juga untuk membatasi waktu server sibuk dengan proses ini?

BTW, saya saat ini sedang bekerja untuk mengurangi ukuran keseluruhan database untuk menyelesaikan masalah ini.

179
Patrick

Hambatan utama dalam dump seperti ini adalah drive I/O. Anda membaca banyak data dan menulisnya lagi. Anda dapat mempercepat ini dalam beberapa cara:

  • Pastikan output Anda pergi ke drive yang berbeda dari yang disimpan oleh file database - ini akan membuat perbedaan besar dengan disk berputar karena kepala drive tidak akan selalu menjentikkan antara lokasi yang sedang dibaca dari dan lokasi yang sedang ditulis.
  • Output dari mysqldump akan sangat kompresibel, jadi jika Anda tidak dapat memisahkan output dari input seperti yang disebutkan di atas, pipa output melalui gzip atau serupa. Ini akan mengurangi jumlah penulisan yang dilakukan (jadi kurangi keseluruhan muatan IO, dan jumlah pergerakan head) dengan mengorbankan waktu CPU (yang mungkin Anda punya banyak waktu luang di bagaimanapun juga kali ini).
  • Juga, (juga atau bukan kompresi) melewatkan output melalui utilitas pipa (seperti pv ) yang mendukung buffer tulis besar ke blok grup yang ditulis ke drive bersama-sama lebih banyak, lagi untuk mengurangi efek head -movement latency - ini akan membuat perbedaan jika menggunakan --quick pilihan untuk mengurangi dampak RAM untuk membuat cadangan tabel besar).
  • Jalankan proses pencadangan Anda hanya ketika IO memuat rendah.

Namun, Anda mungkin memperbaiki masalah yang salah: mungkin lebih mudah untuk mengatasi penurunan koneksi (meskipun mengurangi beban I/O yang dikenakan oleh cadangan Anda akan membantu mengurangi efek yang Anda miliki pada pengguna lain sehingga tetap layak untuk dicoba). Bisakah Anda menjalankan pencadangan manual melalui layar (atau alat serupa seperti tmux )? Dengan begitu, jika koneksi Anda ke server terputus, Anda dapat menyambung kembali dan menyambung kembali ke sesi screen tanpa ada proses yang terganggu.

Jika Anda mengirim data secara langsung melalui koneksi (mis. Anda menjalankan mysqldump pada mesin lokal Anda terhadap database jauh, sehingga dump muncul secara lokal), Anda mungkin lebih baik menjalankan dump pada server terlebih dahulu, mengompresi sesuai kebutuhan, kemudian mentransfer data melalui jaringan menggunakan alat (seperti rsync) yang mendukung transfer parsial sehingga Anda dapat melanjutkan transfer (alih-alih memulai ulang) jika koneksi terputus.

Sebagai bagian dari "mengurangi ukuran keseluruhan basis data untuk menyelesaikan masalah ini", saya kira sebagian besar data Anda tidak berubah. Anda mungkin dapat memindahkan potongan besar 1.2Gb dari tabel utama ke yang lain dan menghapusnya dari yang disalin oleh panggilan mysqldump. Anda tidak perlu membuat cadangan data ini setiap kali jika tidak pernah berubah. Membagi data antara tabel dan basis data dengan cara ini biasanya disebut sebagai partisi data dan juga dapat memungkinkan Anda untuk menyebarkan data dan I/O memuat lebih dari beberapa drive. Basis data kelas atas telah mendukung pemartisian otomatis, meskipun dalam mysql Anda mungkin harus melakukannya secara manual dan mengubah lapisan akses data Anda untuk memperhitungkannya.

Menyimpang dari topik untuk situs ini (jadi Anda mungkin harus beralih ke ServerFault atau SuperUser untuk menanyakan apakah Anda perlu lebih detail): Jika Anda tampaknya kehilangan koneksi karena tidak aktif, periksa opsi di server SSH Anda dan klien SSH untuk membuat Pastikan paket keep-live diaktifkan dan dikirim cukup sering. Jika melihat penurunan bahkan jika koneksi aktif, Anda juga dapat mencoba menggunakan OpenVPN atau serupa untuk membungkus koneksi - itu harus menangani setetes, bahkan setetes jika seluruh koneksi Anda turun selama beberapa detik, sehingga klien SSH dan server tidak memperhatikan.

139
David Spillett

WAWASAN KE DALAM MELAKUKAN BACKUPS DENGAN mysqldump

IMHO Melakukan pencadangan menjadi lebih dari sekadar bentuk seni jika Anda tahu cara mendekatinya

Anda punya opsi

Opsi 1: mysqldump seluruh contoh mysql

Ini adalah yang termudah, no-brainer !!!

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

Semuanya ditulis dalam satu file: struktur tabel, indeks, pemicu, prosedur tersimpan, pengguna, kata sandi terenkripsi. Opsi mysqldump lainnya juga dapat mengekspor berbagai gaya perintah INSERT, file log, dan koordinat posisi dari log biner, opsi pembuatan basis data, data sebagian (opsi di mana), dan sebagainya.

Opsi 2: mysqldump memisahkan database menjadi file data terpisah

Mulailah dengan membuat daftar database (2 teknik untuk melakukan ini)

Teknik 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

Teknik 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

Teknik 1 adalah cara tercepat. Teknik 2 adalah yang paling pasti dan paling aman. Teknik 2 lebih baik karena, kadang-kadang, pengguna membuat folder untuk keperluan umum di/var/lib/mysql (datadir) yang tidak terkait database. Information_schema akan mendaftarkan folder sebagai database di tabel information_schema.schemata. Teknik 2 akan memotong folder yang tidak berisi data mysql.

Setelah Anda mengompilasi daftar database, Anda dapat melanjutkan untuk mengulang daftar dan mysqldump mereka, bahkan secara paralel jika diinginkan.

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

Jika ada terlalu banyak basis data untuk diluncurkan pada satu waktu, paralel membuangnya 10 sekaligus:

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

Opsi 3: mysqldump tabel terpisah menjadi file data terpisah

Mulailah dengan membuat daftar tabel

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

Kemudian buang semua tabel dalam kelompok 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

Opsi 4: GUNAKAN IMAGINASI ANDA

Coba variasi Pilihan yang disebutkan di atas ditambah teknik untuk snapshot bersih

Contohnya

  1. Pesanlah daftar tabel dengan ukuran masing-masing tabel naik atau turun.
  2. Menggunakan proses terpisah, jalankan "FLUSH TABLES WITH READ LOCK; SELECT SLEEP (86400)" sebelum meluncurkan mysqldumps. Matikan proses ini setelah mysqldumps selesai. Ini bermanfaat jika database berisi InnoDB dan MyISAM
  3. Simpan mysqldumps di folder bertanggal dan putar keluar folder cadangan yang lama.
  4. Muat seluruh contoh mysqldumps ke server mandiri.

[~ # ~] peringatan [~ # ~]

Hanya Opsi 1 yang membawa semuanya. Kekurangannya adalah mysqldumps yang dibuat dengan cara ini hanya dapat dimuat ulang ke versi rilis mysql majot yang sama dengan mysqldump yang dihasilkan. Dengan kata lain, mysqldump dari database MySQL 5.0 tidak dapat dimuat dalam 5.1 atau 5.5. Alasannya ? Skema mysql sangat berbeda di antara rilis utama.

Opsi 2 dan 3 tidak termasuk menyimpan nama pengguna dan kata sandi.

Berikut adalah cara umum untuk membuang SQL Grants untuk pengguna yang mudah dibaca dan lebih portabel

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

Opsi 3 tidak menyimpan prosedur tersimpan, sehingga Anda dapat melakukan hal berikut

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

Poin lain yang harus diperhatikan adalah tentang InnoDB. Jika Anda memiliki kumpulan buffer InnoDB besar, masuk akal untuk menyiramnya sebaik mungkin sebelum melakukan backup apa pun. Jika tidak, MySQL menghabiskan waktu membersihkan tabel dengan halaman kotor yang tersisa dari buffer pool. Inilah yang saya sarankan:

Sekitar 1 jam sebelum melakukan pencadangan, jalankan perintah SQL ini

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Di MySQL 5.5 default innodb_max_dirty_pages_pct adalah 75. Di MySQL 5.1 dan kembali, innodb_max_dirty_pages_pct default adalah 90. Dengan menetapkan innodb_max_dirty_pages_pct ke 0, ini akan mempercepat pembilasan halaman kotor ke disk. Ini akan mencegah atau setidaknya mengurangi dampak pembersihan setiap komitmen dua fase data InnoDB sebelum melakukan mysqldump terhadap tabel InnoDB.

FINAL Word ON mysqldump

Kebanyakan orang menghindar dari mysqldump demi alat-alat lain dan alat-alat itu memang bagus.

Alat-alat tersebut termasuk

  1. MAATKIT (paralel dump / restore skrip, dari Percona [Sudah usang tapi bagus])
  2. XtraBackup (Cadangan Snapshot TopNotch dari Percona)
  3. CDP R1Soft ( Opsi Modul MySQL yang mengambil snapshot point-in-time)
  4. MySQL Enterprise Backup (sebelumnya InnoDB Hot Backups [komersial])

Jika Anda memiliki semangat DBA MySQL yang benar, Anda dapat merangkul mysqldump dan memiliki penguasaan penuh atas hal itu yang dapat dicapai. Semoga semua cadangan Anda mencerminkan keterampilan Anda sebagai DBA MySQL .

122
RolandoMySQLDBA

Lihat master replikasi MySQL menjadi slave. Ini memungkinkan Anda untuk mengkloning database master ke server database lain dengan database yang sama. Itu termasuk identitas master dan slave. Slave menjadikan dirinya sendiri salinan tepat dari server database master dan atau databasenya. Mungkin ada satu-satu, satu-banyak, banyak-satu hubungan antara master dan budak.

Budak terus membaca log biner di master (log bin menyimpan pertanyaan yang ditulis di server database master) dan mendapatkan input ke server database budaknya. (Ini berarti database master Anda tidak akan terpengaruh sama sekali)

Kabar baiknya adalah bahwa itu tidak akan mempengaruhi server MySQL Anda terlalu banyak karena Anda tidak akan melihat downtime atau memperlambat respons permintaan. Kami menggunakannya untuk basis data 10Gb dan berfungsi seperti jimat tanpa downtime.

Replikasi MySQL Pada Mesin Yang Sama

20
poelinca

Paket A: Lihat juga Xtrabackup dari Percona. Ini memungkinkan pencadangan online InnoDB, tanpa penguncian signifikan.

Paket B: Seorang Budak dapat dihentikan, dan Anda dapat mengambil cadangan yang konsisten dengan beberapa cara (menyalin file, mysqldump, xtrabackup, dll)

Paket C: Cuplikan LVM. Setelah beberapa pengaturan samar, downtime untuk cadangan kurang dari satu menit, terlepas dari ukuran database. Anda berhenti mysqld, lakukan snapshot, restart mysqld, lalu salin snapshot. Langkah terakhir bisa memakan waktu lama, tetapi MySQL tidak down.

Plan D: Snapshot of a Slave - nol downtime.

19
Rick James

Beberapa poin admin pertama: Apakah Anda terhubung untuk melakukan ftp atau Anda ssh'ed dan sedang sekarat? Jika ssh, maka pastikan untuk menggunakan layar sehingga Anda dapat melanjutkan setelah crash comcast. Jika ftp, maka pastikan Anda mengompres/tar sebelum pengiriman.

Coba juga parameter --opt atau --quick

--opt Opsi ini mengaktifkan seperangkat opsi tambahan untuk membuat operasi dump dan memuat ulang lebih efisien. Secara khusus, ini setara dengan menggunakan opsi --add-drop-table, --add-locks, --all, --quick, --extended-insert, --lock-tables, dan --disable-keys bersamaan. Perhatikan bahwa opsi ini membuat output lebih mudah dibawa-bawa dan kecil kemungkinannya untuk dipahami oleh sistem basis data lainnya.

--quick Opsi ini memberitahu mysqldump untuk menulis keluaran dump saat membaca setiap baris dari server, yang mungkin berguna untuk tabel besar. Secara default, mysqldump membaca semua baris dari tabel ke dalam memori sebelum menulis output; untuk tabel besar, ini membutuhkan sejumlah besar memori, mungkin menyebabkan dump gagal.

15
David Hall

Saya dulu punya masalah dengan timeout selama kesedihan database besar juga. Saya akhirnya dipecahkan jika dengan mengirim perintah individual untuk setiap tabel di db dan menambahkan everthing ke satu file seperti ini:

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

Saya pikir pertanyaannya adalah tentang bagaimana memulihkan lebih cepat dari file dump yang dibuat mysqldump, bukan solusi cadangan yang berbeda.

Salah satu cara, Anda dapat melakukan ini adalah dengan membuat grup tabel dalam skema Anda, dan membuat pengguna DB yang terpisah untuk setiap grup kemudian akhirnya menggunakan izin MySQL untuk tidak membiarkan tabel dimasukkan dengan menggunakan semua kecuali satu pengguna DB.

Ini adalah teknik yang terbukti, cepat, hampir paralel, tetapi tidak 100% yakin, berapa lama untuk memulihkan dari dump besar seperti 500G atau lebih. Tapi menurut saya, Anda perlu sesuatu yang paralel. Lihat tautan di bawah untuk contoh.

[Cepat, pengembalian paralel dari SQL dumps (mysqldump) untuk MySQL] [1]

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

"Cepat, pemulihan paralel dari SQL dumps (mysqldump) untuk MySQL"

3
syed