MySQL veritabanını ZFS anlık görüntüleri ile yedekleme


13

Tam olarak bunu yapmaktan bahseden birkaç site buldum, ancak birkaç önemli ayrıntıyı kaçırıyorum. Genel adımlar

  • Çalıştırmak FLUSH TABLES WITH READ LOCK
  • ZFS anlık görüntüsünü alın
  • Çalıştırmak UNLOCK TABLES

Çeşitli kaynaklar kullandığım InnoDB'nin aslında a FLUSH. MySQL kullanıcı kılavuzu FLUSH TABLES...FOR EXPORT, InnoDB ile kullanım için bir değişken olduğunu, ancak tüm veritabanını yedeklemek yerine her bir tabloyu ayrı ayrı belirtmeyi gerektirdiğini not eder. Her bir tabloyu ayrı ayrı belirtmekten kaçınmayı tercih ederim çünkü tabloların listesi gerçekte var olan tablolarla senkronize olmayacaktır.

Diğer sorunum da böyle bir şey yapmayı planlıyorum mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK". Ancak, oturumdan çıktıktan hemen sonra kilidi bırakır. Bu mantıklı, ama aynı zamanda oldukça can sıkıcı çünkü anlık görüntümü alırken okuma kilidini tutmam gerekiyor.

Benim diğer fikrim, Percona XtraBackup gibi bir araç kullanarak sıcak bir yedek almak ve yedeklemenin anlık görüntülerini almak, ancak tüm verileri ikinci bir konuma yazmak için maliyeti ödememeyi tercih ediyorum.


Neden statik bir tablo listesi var? Çalışma zamanında dinamik olarak bir liste oluşturabilirsiniz.
EEAA

1
Veritabanı bir VM'de mi yoksa çıplak metalde mi? Depolama aynı makinede mi?
Michael Hampton

EEAA, yeterince adil.
Andy Shulman

Michael, veritabanı ve ZFS kutusu farklı makinelerdir, ancak ikisi de sanallaştırılmamıştır.
Andy Shulman

@AndyShulman Bence düzeni biraz daha iyi açıklamalısınız. Bu mantıklı değil.
ewwhite

Yanıtlar:


4

Tüm tablolar için yalnızca InnoDB kullanıyorsanız ve şu şekilde ayarladıysanız innodb_flush_log_at_trx_commit:

  • 1 (InnoDB günlük arabelleğinin içeriği her işlem taahhüdünde günlük dosyasına yazılır ve günlük dosyası diske temizlenir) veya,
  • 2 (InnoDB günlük arabelleğinin içeriği, her işlem tamamlandıktan sonra günlük dosyasına yazılır ve günlük dosyası yaklaşık saniyede bir kez diske temizlenir),

anlık görüntü yapmadan önce FLUSH TABLES'e ihtiyacınız yoktur, sadece ZFS anlık görüntüsünü doğrudan çalıştırın. InnoDB, veri kaybı olmadan işlem taahhüt günlüklerindeki verileri kurtarabilir.

Ref: https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit


MySQL 8'de sunulan veri sözlüğü ile DDL (şema değişikliği) işlemleri artık atomiktir. Bundan önce, bir dosya sistemi anlık görüntüsü sırasında DDL işlemleri kısmen işlenmiş (yani bozuk) sonuçlar verebilir.
bernie

13

Bir (en) veritabanını sürekli olarak yedeklemek için tam bir veritabanı kilidine ihtiyacınız vardır.

El kitabı https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html , READ LOCK İLE FLUSH TABLES'in özellikle ZFS anlık görüntüleri için doğru olduğunu söylüyor .

Bir Dosya Sistemi Anlık Görüntüsü Kullanarak Yedekleme Yapma

Veritas dosya sistemi kullanıyorsanız, bunun gibi bir yedekleme yapabilirsiniz:

  1. Bir istemci programından çalıştırın FLUSH TABLES WITH READ LOCK.
  2. Başka bir kabuktan, montaj vxfsanlık görüntüsünü çalıştırın .
  3. İlk istemciden çalıştırın UNLOCK TABLES.
  4. Dosyaları anlık görüntüden kopyalayın.
  5. Anlık görüntüyü çıkarın.

Benzer anlık görüntü özellikleri, LVM veya ZFS gibi diğer dosya sistemlerinde kullanılabilir.

Saçma türüdür onlar gerektiği gerçeğini göz bıraktı FLUSH TABLES table_a, table_b, table_c FOR EXPORTiçin InnoDb bu talimatlardan. Her tabloyu böyle belirtmek de aptalca. Ancak EEAA'nın dediği gibi, yedeklemeye oldukça kolay başlarken bir tablo listesi oluşturabilirsiniz.

Kilidi tutmaya gelince, anlık görüntüyü gerçekleştirirken db bağlantısını aktif tutmalısınız

Genellikle Perl veya db'yi bağlayabilen, db'yi kilitleyebilen ve db bağlantısını korurken anlık görüntüyü alıp kilidini açıp bağlantıyı kesebilen başka bir programlama dili kullanırdım. Karmaşık değil. Bahse girerim zaten bunu yapan araçlar var ama bir tane yazmak kolay.

Birkaç kez kolay, karmaşık değil vb. Diyorum. Bazı temel programlama veya iyi komut dosyası yazma becerileriniz olduğunu varsayıyorum.


Bash'te böylesine kavramsal olarak basit bir senaryo tutmayı umuyordum, ancak doğru dilleri değiştirmek bunu çok daha kolay hale getiriyor. Ben cevap yanlış okuma olabilir, ancak ben her iki yürütmek için ihtiyaç söylüyorsun görünüyor FLUSH TABLES WITH READ LOCKsonra ve FLUSH TABLES...FOR EXPORTMySQL kılavuzun benim okuma tek gerekli olması gerektiğini söylüyor, oysa.
Andy Shulman

Üzgünüm net değildim. Sadece el kitabından geçiyorum ve iki farklı şey söylüyor. Doğru olduğunu tahmin ediyorum ve sadece daha sonra ihtiyacım var. Ancak tüm tablolar tek bir komutta kilitlenmelidir.
Ryan Babchishin

1
Belgelerin çok net olmadığı, tüm veritabanının kilitlenmesi gerektiği ve anlık görüntü alınırken bir DB bağlantısının sürdürülmesi gerektiği göz önüne alındığında, DB'nin kapatılması, yedeklenmesi ve yeniden başlatılması daha kolay görünüyor o.
Andrew Henle

2
@andrew iç çekti ... anladım. Ama bu yavaş olacak, bağlantıların düşmesine / bozulmasına neden olacak ve veritabanlarının düzgün bir şekilde geri gelmemesine neden olduğunu gördüm (otomasyon için kötü). MySQL / Oracle'dan kesin bir cevap almak iyi olurdu. Bir posta listesi olmalı.
Ryan Babchishin

7

Kapalı kopyalanan ve ben başka Sunucu Hatası bulunan Bash sade ve anlamlı bir senaryoyu adapte ettik mesaja göre Tobia . Sizi o yolun yaklaşık% 90'ına götürmelidir.

mysql_locked=/var/run/mysql_locked

# flush & lock MySQL, touch mysql_locked, and wait until it is removed
mysql -hhost -uuser -ppassword -NB <<-EOF &
    flush tables with read lock;
    delimiter ;;
    system touch $mysql_locked
    system while test -e $mysql_locked; do sleep 1; done
    exit
EOF

# wait for the preceding command to touch mysql_locked
while ! test -e $mysql_locked; do sleep 1; done

# take a snapshot of the filesystem, while MySQL is being held locked
zfs snapshot zpool/$dataset@$(date +"%Y-%m-%d_%H:%M")

# unlock MySQL
rm -f $mysql_locked

Burada, kullandığınız mysqlkomut arka planda çalıştırılır ve bir dosyaya dokunur. Tablodan çıkmadan ve böylece tabloların kilidini açmadan önce dosyanın kaybolmasını bekler. Bu arada ana komut dosyası dosya bulunana kadar bekler, ardından anlık görüntüyü oluşturur ve dosyayı siler.

Tarafından işaret edilen dosyanın $mysql_lockedher iki makine tarafından erişilebilir olması gerekir; bu dosyalar, her ikisi de ortak bir veri kümesine erişebildikleri için (kolayca farklı yollar kullanabilirler ve bunu hesaba katmanız gerekir) yeterince kolay bir şekilde yapabilmeniz gerekir.


MySQL komut dosyası bilmiyorum, bu yüzden bu aptalca bir fikir olabilir, ama sadece system zfs snapshot...ana komut dosyası içinde yapamadı ? Veya geçmeli shotting yok olması ayrı bir işlemde çalıştırmak için?
TripeHound

@Tripehound Her iki şeyin de bir şekilde paralel olması gerekiyor
Ryan Babchishin

@RyanBabchishin Aslında haklı olduğunu düşünüyorum. SYSTEMKomut yerel şeyleri çalışır. FreeBSD kutusunda mysql istemcisini çalıştırıp çalıştırırsam LOCK; SYSTEM zfs snapshot; UNLOCK, bu işe yarayacak gibi görünüyor.
Andy Shulman

@Andy sadece paralel olmaları gerektiğini söyledim. Nasıl devam edeceğiniz önemli değil.
Ryan Babchishin

2

Günlük tutmadığı için myisam için OKU KİLİTLİ YIKAMA TABLOLARI'na ihtiyacınız var.

Innodb için hiçbir şeye ihtiyacınız yok, IMO, çünkü günlüğe kaydediliyor. Yine de tutarlı olacak, sadece çektiğiniz atom anında anında bir şey oluyorsa günlüğü otomatik olarak geri alır.

Uygulama düzeyinde tutarlılık istiyorsanız, uygulamanız işlemleri kullanmalıdır. Uygulamanız işlem ve innodb kullanıyorsa, herhangi bir anlık görüntü tutarlı olacaktır ve uygulama düzeyine otomatik olarak nasıl gidileceğini sorun.


2

Bu benim kilit kilit tutarken nasıl ZFS anlık görüntü oluşturmak için:

mysql << EOF
    FLUSH TABLES WITH READ LOCK;
    system zfs snapshot data/db@snapname
    UNLOCK TABLES;
EOF
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.