2010-07-27 13 views
7

मैं अपने सर्वर के लिए एक sql फ़ाइल के रूप में अपने MySQL डाटाबेस बैकअप के लिए दाऊद वॉल्श (http://davidwalsh.name/backup-mysql-database-php) द्वारा डाटाबेस बैकअप स्क्रिप्ट का उपयोग कर रहा हूँ।क्यों मेरी डेटाबेस बैकअप स्क्रिप्ट php में काम नहीं कर रहा?

मैंने बैकअप नामक उपयोगकर्ता बनाया और इसे सभी विशेषाधिकार दिए (बस सुनिश्चित करने के लिए)। फिर मैंने कोड को एक php फ़ाइल में डाल दिया और php फ़ाइल चलाने के लिए क्रॉन जॉब सेट किया।

इस कोड है:

/* backup the db OR just a table */ 
function backup_tables($host,$user,$pass,$name,$tables = '*') 
{ 

    $link = mysql_connect($host,$user,$pass); 
    mysql_select_db($name,$link); 

    //get all of the tables 
    if($tables == '*') 
    { 
     $tables = array(); 
     $result = mysql_query('SHOW TABLES'); 
     while($row = mysql_fetch_row($result)) 
     { 
      $tables[] = $row[0]; 
     } 
    } 
    else 
    { 
     $tables = is_array($tables) ? $tables : explode(',',$tables); 
    } 

    //cycle through 
    foreach($tables as $table) 
    { 
     $result = mysql_query('SELECT * FROM '.$table); 
     $num_fields = mysql_num_fields($result); 

     $return.= 'DROP TABLE '.$table.';'; 
     $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table)); 
     $return.= "\n\n".$row2[1].";\n\n"; 

     for ($i = 0; $i < $num_fields; $i++) 
     { 
      while($row = mysql_fetch_row($result)) 
      { 
       $return.= 'INSERT INTO '.$table.' VALUES('; 
       for($j=0; $j<$num_fields; $j++) 
       { 
        $row[$j] = addslashes($row[$j]); 
        $row[$j] = ereg_replace("\n","\\n",$row[$j]); 
        if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; } 
        if ($j<($num_fields-1)) { $return.= ','; } 
       } 
       $return.= ");\n"; 
      } 
     } 
     $return.="\n\n\n"; 
    } 

    //save file 
    $handle = fopen('../backup/db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+'); 
    fwrite($handle,$return); 
    fclose($handle); 
} 

backup_tables('localhost','alupto_backup','pass','*'); 

जब क्रॉन जॉब चलाता है, बैकअप से काम नहीं करता और मैं त्रुटि प्रतीत होता है कि साथ एक ईमेल प्राप्त:


चेतावनी: mysql_fetch_row(): प्रदत्त तर्क मान्य MySQL परिणाम संसाधन /home5/ideapale/public_html/amator में नहीं है ders_basic/व्यवस्थापक/backup.php लाइन पर

लाइन 18 पर इस कोड है:

while($row = mysql_fetch_row($result))

जब मैं एसक्यूएल (शो टेबल्स) चलाने phpMyAdmin में, यह ठीक काम करता है और मुझे सभी तालिकाओं की एक सूची दिखाता है। लेकिन किसी कारण से, मुझे त्रुटि मिल रही है जब php फ़ाइल SQL को चलाने का प्रयास करती है।

क्यों मेरी डेटाबेस बैकअप स्क्रिप्ट काम नहीं कर रहा?

उत्तर

14

यह आपके डेटाबेस को SQL स्क्रिप्ट के रूप में बैक अप लेने के लिए काम नहीं करेगा, जब तक कि आपका डेटाबेस केवल एक खिलौना डेटाबेस नहीं है, जो "हैलो वर्ल्ड" स्क्रिप्ट के बराबर है।

कि स्क्रिप्ट भयावह है। डेटाबेस का बैक अप लेने के लिए आपको इसका इस्तेमाल नहीं करना चाहिए। यही कारण है कि स्क्रिप्ट से पहले नियुक्त किया गया है: PHP Database Dump Script - are there any issues?

  • कोई त्रुटि mysql_connect() या mysql_queries के बाद जाँच()। आपने शायद गलत पासवर्ड या कुछ दिया है, लेकिन आप कभी नहीं जानते क्योंकि स्क्रिप्ट यह सत्यापित नहीं करती है कि कनेक्ट सफल था।

  • यदि आपके डेटाबेस में कोई एनयूएलएल है तो यह सही INSERT कथन का उत्पादन नहीं करेगा।

  • कैरेक्टर सेटों को नियंत्रित नहीं किया जाता है।

  • जोड़ों() not suitable डेटा से बचने के लिए है।

  • तालिका के नाम सीमित नहीं हैं।

  • विचार, प्रक्रियाओं, कार्यों या ट्रिगर्स का बैक अप नहीं लेता है।

  • mysql_query() बफ़र्स परिणाम, इसलिए यदि आप पंक्तियों या उससे अधिक के हजारों के साथ एक मेज है, तो आप अपने PHP स्मृति सीमा को पार कर जाएगा। वास्तव में, स्क्रिप्ट एक एकल PHP चर में INSERT कथन की श्रृंखला को जोड़ती है। तो इसे खत्म होने से पहले, आपके पास संपूर्ण डेटाबेस मेमोरी में प्रदर्शित होगा।

किसी को भी उस स्क्रिप्ट का उपयोग नहीं करना चाहिए। यह कचरा है, और मैं हल्के से यह नहीं कहता।

बस mysqldump चलाने के लिए shellexec() का उपयोग करें।

@ अलवारो जी। विकारियो का एक अच्छा बिंदु है, इस कार्य के लिए PHP का उपयोग करने की आवश्यकता नहीं है। मुझे लगता है कि आपको एक PHP स्क्रिप्ट से बैकअप बनाने की आवश्यकता है। यहां बताया गया है कि मैं क्रॉन स्क्रिप्ट से बैकअप कैसे बनाऊंगा:

एक शैल स्क्रिप्ट बनाएं, इसे आप जो चाहें उसे बुलाया जा सकता है, उदा। mymysqldump.sh। यहाँ कैसे मैं इसे लिखते थे बताया गया है:

: 
: ${BACKUP_HOST:="localhost"} 
: ${BACKUP_DATABASE:="mydatabase"} 
: ${BACKUP_DIR:="/opt/local/var/db/mysql5/backups"} 
: ${BACKUP_FILE:="${DATABASE}-`date +%Y%m%d%H%M%S`"} 

mysqldump -h ${BACKUP_HOST} ${BACKUP_DATABASE} > ${BACKUP_DIR}/${BACKUP_FILE} 

बेशक के रूप में अपने पर्यावरण के लिए आवश्यक चरों के मान को अनुकूलित।

आप देख सकते हैं कि उपयोगकर्ता नाम और पासवर्ड इस फ़ाइल में नहीं है। कृपया पासवर्ड को सादा पाठ में स्क्रिप्ट में न रखें ताकि हर कोई उन्हें पढ़ सके। इसके बजाए, हम इसे अधिक सुरक्षित बनाने के लिए उन्हें एक विकल्प फ़ाइल में डाल देंगे।

एक विशेष ऑपरेटिंग सिस्टम उपयोगकर्ता बनाएं जो क्रॉन से बैकअप चलाने जा रहा है। MySQL सर्वर को चलाने के लिए आपके सिस्टम में एक विशेष उपयोगकर्ता "mysql" या "_mysql" हो सकता है, लेकिन इस उपयोगकर्ता को वैध होम निर्देशिका रखने के लिए कॉन्फ़िगर किया जा सकता है। आपको ऐसे उपयोगकर्ता की आवश्यकता है जिसमें घर निर्देशिका हो। आइए इसे "mybackup" कहते हैं।

कि उपयोगकर्ता की होम निर्देशिका के अंतर्गत, निम्न सामग्री के साथ एक फ़ाइल .my.cnf बनाएँ:

[mysqldump] 
user = alupto_backup 
password = xyzzy 

कहाँ "alupto_backup" और "xyzzy" MySQL उपयोगकर्ता नाम और उसका पासवर्ड (अपने परिवेश के लिए इन बदल) कर रहे हैं। स्वामित्व और इस फाइल के मोड सेट करें कि केवल उसके मालिक यह पढ़ सकते हैं:

chown mybackup .my.cnf 
chmod 600 .my.cnf 

इस प्रयोक्ता के घर के नीचे एक बिन निर्देशिका बनाएँ और इसे में हमारे खोल स्क्रिप्ट डाल दिया।

mkdir ~mybackup/bin 
mv mymysqldump ~mybackup/bin 

अब आप यह परीक्षण करने के लिए खोल स्क्रिप्ट चला सकते हैं:

sh ~mybackup/bin/mymysqldump 

अब इस उपयोगकर्ता के लिए एक क्रॉन फ़ाइल बनाने:

crontab -u mybackup 

@daily ~mybackup/bin/mymysqldump 

कि यह होना चाहिए।

+0

देखें और यह सूची में जोड़ने के लिए बहिष्कृत 'ereg_replace()' का उपयोग करता है। –

+1

शेलेक्सैक? क्रॉन के माध्यम से प्रोग्राम चलाने के लिए PHP का उपयोग क्यों करें? –

+0

ठीक है, मैंने कभी यह महसूस नहीं किया। क्या आप एक अच्छे ट्यूटोरियल के बारे में जानते हैं जो दिखाता है कि mysqldump चलाने के लिए shellexec() का उपयोग कैसे करें? – zeckdude

0

MySQL_error() फ़ंक्शन का उपयोग यह देखने के लिए करें कि MySQL क्या शिकायत करता है।

+0

मैं इसे कहां जोड़ूं? – zeckdude

0

आपको यह सुनिश्चित करना होगा कि mysql_query पहले गैर-स्ट्रीम वापस नहीं करेगा। इसे आज़माएं:

.... 

if (false !== ($result = mysql_query('SHOW TALBES')) { 
    while($row = mysql_fetch_row($result)) 
    { 
     $tables[] = $row[0]; 
    } 
} else { 
    // see Mchl's point about mysql_error 
} 
+0

मैं अन्य खंड में क्या लिखूंगा? – zeckdude

+0

एक सरल 'echo mysql_error()' एक अच्छी शुरुआत होगी। यह बताने के लिए है कि क्वेरी में क्या गलत है। हालांकि, कोई भी डिबगिंग कथन पर्याप्त होगा। – efritz

3

स्क्रिप्ट बहुत कमजोर IMHO दिखती है। आप mysqldump का उपयोग कर इसे यह आपके सिस्टम में उपलब्ध है पर विचार करना चाहिए।

अद्यतन

बुनियादी कमांड लाइन होगा:

mysqldump -hYOURHOSTNAME -uYOURUSER -pYOURPASSWORD infocap > dump.sql 

आप अपने स्थानीय कंप्यूटर में mysqldump परीक्षण कर सकते हैं और, एक बार आप परिणाम से खुश हैं, या तो एक खोल स्क्रिप्ट बना सकते हैं या इसे जोड़ने सीधे एक क्रॉन कार्य के रूप में।

+0

यह एक अच्छा विकल्प की तरह दिखता है। क्या आप एक अच्छे ट्यूटोरियल के बारे में जानते हैं जो दिखाता है कि यह कैसे करें? MYSQL दस्तावेज़ को समझना इतना आसान नहीं है। – zeckdude

+0

@zeckdude: अद्यतन –

संबंधित मुद्दे