सक्रिय पढ़ने और लिखने के साथ लाइव सिस्टम पर mysqldump प्रदर्शन करने का सबसे सुरक्षित तरीका?


78

मुझे यकीन नहीं है कि यह सच है, लेकिन मुझे याद है कि अगर आप लिनक्स में निम्नलिखित कमांड चलाते हैं

mysqldump -u username -p database_name > backup_db.sql

जबकि पढ़ता है और लिखता है एक डेटाबेस के लिए किया जा रहा है तो डंप त्रुटियों हो सकता है।

क्या mysqldumpयह सुनिश्चित करने के लिए कमांड में कोई विशेष विकल्प हैं कि यह लाइव सिस्टम पर सुरक्षित रूप से किया गया है? मैं अपने उपयोगकर्ताओं के लिए कुछ सेकंड्स के लिए पढ़े / लिखे जाने के साथ ठीक हूं (डेटाबेस <50MB)

जवाबों:


82

सभी डेटा InnoDB है

यह वह है जो आपको डेटा का सटीक पॉइंट-इन-टाइम स्नैपशॉट देगा:

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

--single-transactionएक चेकपॉइंट का उत्पादन करता है जो डंप आने वाले परिवर्तनों को प्राप्त करते समय चेकपॉइंट से पहले सभी डेटा को कैप्चर करने की अनुमति देता है। आने वाले बदलाव डंप का हिस्सा नहीं बनते। यह सभी तालिकाओं के लिए समान बिंदु-समय सुनिश्चित करता है।

--routines सभी संग्रहीत प्रक्रियाओं और संग्रहीत कार्यों को डंप करता है

--triggers प्रत्येक तालिका के लिए सभी ट्रिगर डंप करता है जो उनके पास है

सभी डेटा MyISAM है या InnoDB / MyISAM का मिश्रण है

आपको एक वैश्विक रीड लॉक लगाना होगा, mysqldump का प्रदर्शन करना होगा, और वैश्विक लॉक को रिलीज़ करना होगा

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

कोशिश करो !!!

UPDATE 2012-06-22 08:12 EDT

चूंकि आपके पास कुल डेटा का <50MB है, मेरे पास एक और विकल्प है। 86400 सेकंड (कि 24 घंटा) के लिए वैश्विक रीड लॉक को धारण करने के लिए पृष्ठभूमि में एक SLEEP कमांड लॉन्च करने के बजाय, केवल प्रक्रिया आईडी प्राप्त करने और बाहर मारने के लिए, आइए OS में के बजाय mysql में 5 सेकंड का समय निर्धारित करने का प्रयास करें:

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

यह बहुत छोटे डेटाबेस के लिए एक क्लीनर और सरल दृष्टिकोण है।


1
5 सेकंड सिर्फ एहतियाती है। आप कम मूल्यों की कोशिश कर सकते हैं।
रोलैंडमाइसीडीडीबीए

1
रोलैंडो - ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during queryएक त्रुटि संदेश है?
user784637

1
क्या mysqldump में सभी MySQL डेटा बाहर आए थे?
रोलैंडम्यूसीडीडीबीए

1
मुझे त्रुटि संदेश के बारे में निश्चित नहीं है। यह केवल एक अनुमान है, लेकिन यह एक-लाइन स्क्रिप्ट से आया है जो उपयोगकर्ता द्वारा परिभाषित SLEEP फ़ंक्शन कॉल मैं दूसरी स्क्रिप्ट में उल्लिखित करता है।
रोलैंडम्यूसीडीडीबीए

1
मेरा नया सुझाव आज़माएं और देखें कि क्या यह ठीक है। उम्मीद है, कोई त्रुटि संदेश नहीं होगा।
रोलैंडम्यूसीडीडीबीए


1

यदि आप बिना किसी डाउनटाइम के MyISAM या मिश्रित टेबल के लिए ऐसा करना चाहते हैं, तो आप एक दास डेटाबेस सेट कर सकते हैं, और अपने स्नैपशॉट को वहां से ले जा सकते हैं। गुलाम डेटाबेस की स्थापना, दुर्भाग्य से, लाइव डेटाबेस को निर्यात करने के लिए कुछ डाउनटाइम का कारण बनता है, लेकिन एक बार जब यह चल रहा होता है, तो आपको इसे तालिकाओं को लॉक करने में सक्षम होना चाहिए, और दूसरों द्वारा वर्णित विधियों का उपयोग करके निर्यात करना चाहिए। जब ऐसा हो रहा होता है, तो यह मास्टर से पीछे हो जाएगा, लेकिन मास्टर को इसे टेबल पर अपडेट करने से नहीं रोकेगा, और बैकअप पूरा होते ही पकड़ लेगा।


1

यहाँ है कि मैं यह कैसे किया। इसका उपयोग करने के बाद से इसे सभी मामलों में काम करना चाहिए 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 !"

शेल sleepकमांड सिर्फ यह सुनिश्चित करने के लिए है कि mysql लॉकिंग कमांड चलाने वाले बैकग्राउंड टास्क को mysqldump शुरू होने से पहले निष्पादित किया जाए। आप इसे 1 सेकंड तक कम कर सकते हैं और यह अभी भी ठीक होना चाहिए। इसे 30 सेकंड तक बढ़ाएं और उन 30 सेकंड के दौरान किसी अन्य तालिका से किसी भी तालिका में मान सम्मिलित करने का प्रयास करें।

इस मैनुअल बैकग्राउंड लॉकिंग का उपयोग करने के बजाय mysqldumpविकल्प --single-transactionऔर उपयोग करने के 2 फायदे हैं --lock-tables:

  1. यह सब कुछ लॉक कर देता है, यदि आपने MyISAM / InnoDB टेबल को मिलाया है।
  2. आप mysqldumpएक ही लॉकिंग अवधि के दौरान अन्य कमांड चला सकते हैं । उदाहरण के लिए, मास्टर नोड पर प्रतिकृति स्थापित करते समय यह उपयोगी है, क्योंकि SHOW MASTER STATUS;आपके द्वारा बनाए गए डंप की सटीक स्थिति पर बाइनरी लॉग पोजीशन प्राप्त करने की आवश्यकता है (डेटाबेस को अनलॉक करने से पहले), एक प्रतिकृति दास बनाने में सक्षम होने के लिए।

1

Mysql आधिकारिक दस्तावेज का सुझाव यह है कि आपके पास एक मास्टर "M1" डेटाबेस और एक दास "S1" डेटाबेस होना चाहिए, जिसे "परिदृश्य 2" में वर्णित किया गया है: केवल पढ़ने के लिए एक बैकअप के साथ बैकअप " एक मास्टर या गुलाम बनाने के लिए बैकअप " सिफ़ पढ़िये

आपको केवल पढ़ने के लिए दास डेटाबेस सेट करना चाहिए और वें प्रदर्शन करना चाहिए


0

यदि आपके पास एक बहुत बड़ी MYISAM टेबल है और आपको बिना लॉक के टेबल को डंप करने और उच्च सर्वर लोड से बचने की आवश्यकता है, तो आप निम्न स्क्रिप्ट का उपयोग कर सकते हैं।

#!/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"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.