Etkin okuma ve yazma özellikli canlı bir sistemde mysqldump gerçekleştirmenin en güvenli yolu?


78

Bunun doğru olup olmadığından emin değilim ama linux'da aşağıdaki komutu uygularsanız okumayı hatırlıyorum

mysqldump -u username -p database_name > backup_db.sql

Bir veritabanına okumalar ve yazılar yazılırken, döküm hataları içerebilir.

Bunun mysqldumpcanlı bir sistemde güvenli bir şekilde yapıldığından emin olmak için komutta belirli seçenekler var mı? Birkaç saniye boyunca kullanıcılarımız için okuma / yazma işlemlerinin devre dışı bırakılmasından memnunum (Veri tabanı <50MB)

Yanıtlar:


82

Tüm Veriler InnoDB

Bu size verinin tam olarak anlık bir görüntüsünü verecektir:

mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql

--single-transactionGelen değişiklikleri alırken dökümün kontrol noktasından önce tüm verileri yakalamasını sağlayan bir kontrol noktası üretir. Gelen değişiklikler, çöplüğün bir parçası değil. Bu, tüm tablolar için aynı zaman noktasını garanti eder.

--routines Tüm saklı yordamları ve saklanmış işlevleri döküyor

--triggers Onlara sahip olan her tablo için tüm tetikleyicileri atar

Tüm Veriler MyISAM veya InnoDB / MyISAM karışımıdır.

Genel bir okuma kilidi uygulamak, mysqldump gerçekleştirmek ve genel kilidi açmak zorunda kalacaksınız

mysql -uuser -ppass -Ae"FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)" &
sleep 5
mysql -uuser -ppass -ANe"SHOW PROCESSLIST" | grep "SELECT SLEEP(86400)" > /tmp/proclist.txt
SLEEP_ID=`cat /tmp/proclist.txt | awk '{print $1}'`
echo "KILL ${SLEEP_ID};" > /tmp/kill_sleep.sql
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
mysql -uuser -ppass -A < /tmp/kill_sleep.sql

Bir şans ver !!!

GÜNCELLEME 2012-06-22 08:12 EDT

Toplam <50 MB veri bulunduğundan, başka bir seçeneğim var. Sadece işlem kimliğini almak ve dışarıda öldürmek için 86400 sn (bu 24 saat) genel okuma kilidini tutmak için arka plana bir SLEEP komutu başlatmak yerine, işletim sistemi yerine mysql'de 5 saniye zaman aşımı ayarlamayı deneyelim:

SLEEP_TIMEOUT=5
SQLSTMT="FLUSH TABLES WITH READ LOCK; SELECT SLEEP(${SLEEP_TIMEOUT})"
mysql -uuser -ppass -Ae"${SQLSTMT}" &
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql

Bu, çok küçük veritabanları için daha temiz ve daha basit bir yaklaşımdır.


1
5 sn sadece ihtiyati tedbirdir. Daha düşük değerleri deneyebilirsiniz.
RolandoMySQLDBA

1
Rolando - ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during querybeklenen bir hata mesajı mı?
user784637

1
Tüm MySQL verileri mysqldump'ta mı çıktı?
RolandoMySQLDBA

1
Hata mesajından emin değilim. Bu yalnızca bir tahmindir, ancak ikinci komutta bahsettiğim kullanıcı tanımlı SLEEP işlev çağrısını öldüren tek satırlı komut dosyasından gelmiş olabilir.
RolandoMySQLDBA

1
Yeni önerimi dene ve iyi olup olmadığına bak. Umarım, hiçbir hata mesajı olmaz.
RolandoMySQLDBA

2
  • InnoDB tabloları için, --single-transactionbaşka bir cevapta belirtildiği gibi seçeneği kullanmalısınız .
  • MyISAM için var --lock-tables.

Resmi belgelere buradan bakın


1

Bunu MyISAM veya karma tablolar için, masaları kilitlemenin aksamasına gerek kalmadan yapmak istiyorsanız, bağımlı veri tabanı kurabilir ve anlık görüntülerinizi oradan alabilirsiniz. Köle veritabanını ayarlamak ne yazık ki, canlı veritabanının dışa aktarılmasına bazı kesinti sürelerine neden olur, ancak bir kez çalışıyorsa, tablolarını kilitleyebilmeli ve başkalarının tarif ettiği yöntemleri kullanarak dışa aktarabilmelisiniz. Bu gerçekleştiğinde, yöneticinin gerisinde kalacak, ancak yöneticinin tablolarını güncellemesini durduramayacak ve yedekleme tamamlanır tamamlanmaz yakalayacaktır.


1

İşte böyle yaptım. Kullandığından beri her durumda çalışması gerekir FLUSH TABLES WITH READ LOCK.

#!/bin/bash

DB=example
DUMP_FILE=export.sql

# Lock the database and sleep in background task
mysql -uroot -proot $DB -e "FLUSH TABLES WITH READ LOCK; DO SLEEP(3600);" &
sleep 3

# Export the database while it is locked
mysqldump -uroot -proot --opt $DB > $DUMP_FILE

# When finished, kill the previous background task to unlock
kill $! 2>/dev/null
wait $! 2>/dev/null

echo "Finished export, and unlocked !"

Shell sleepkomutu yalnızca mysql kilitleme komutunu çalıştıran arka plan görevinin mysqldump başlamadan önce yürütülmesini sağlamak içindir. 1 saniyeye kadar düşürebilirsiniz ve hala iyi olmalı. 30 saniyeye yükseltin ve kilitli olduğunu göreceğiniz 30 saniye boyunca başka bir müşteriden herhangi bir tabloya bir değer eklemeyi deneyin.

Bu manuel arka plan kilitleme kullanarak, kullanmak yerine 2 avantajı vardır mysqldumpseçenekleri --single-transactionve --lock-tables:

  1. MyISAM / InnoDB masalarını karıştırdıysanız, bu her şeyi kilitler.
  2. mysqldumpAynı kilitleme süresine ek olarak diğer komutları da çalıştırabilirsiniz . Örneğin, bir ana düğümde çoğaltma kurarken kullanışlıdır, çünkü SHOW MASTER STATUS;çoğaltma kölesi oluşturmak için (günlük açmadan önce) oluşturduğunuz dökümü tam olarak ikili günlük konumu ile almanız gerekir .


0

çok büyük bir MYISAM tablonuz varsa ve masayı kilitlemeden boşaltmanız ve yüksek sunucu yükünden kaçınmanız gerekiyorsa, aşağıdaki betiği kullanabilirsiniz.

#!/bin/sh

my_user="user"
my_password="password"
my_db="vpn"
my_table="traffic"
my_step=100000

read -p "Dumping table ${my_db}.${my_table} to ${my_table}.sql?" yn
case $yn in
    [Yy]* ) break;;
    * ) echo "User cancel."; exit;;
esac

my_count=$(mysql $my_db -u $my_user -p$my_password -se "SELECT count(*) FROM $my_table")
my_count=$(($my_count + 0))

if [ ! $my_count ]
then
    echo "No records found"
    exit
fi

echo "Records in table ${my_db}.${my_table}: ${my_count}"

echo "" > $my_table.sql

max_progress=60

for (( limit=0; limit<=$my_count; limit+=$my_step )); do
    progress=$((max_progress * ( limit + my_step) / my_count))

    echo -ne "Dumping ["
    for ((i=0; i<$progress; i ++)); do
        echo -ne "#"
    done
    for ((; i<$max_progress; i ++)); do
        echo -ne "."
    done

    mysqldump -u $my_user -p$my_password --complete-insert --no-create-info --opt --where="1 limit $limit , $my_step" $my_db $my_table >> $my_table.sql
    echo "" >> $my_table.sql

    echo -ne "] $((100 * ( limit + my_step ) / my_count)) %"
    echo -ne "\r"

    sleep 1

done

echo -ne "\n"
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.