2008-10-21 13 views
6

मैं mysql (5.0.32-Debian_7etch6-लॉग) उपयोग कर रहा हूँ और मैं एक रात चल रहा है थोक लोड php मिल गया है है जब वहाँ (5.2.6) स्क्रिप्ट पीडीओ के माध्यम से (Zend_DB (1.5.1 का प्रयोग करके)) जो निम्नलिखित है:mysql डुप्लिकेट प्रविष्टि त्रुटि कोई डुप्लिकेट प्रविष्टि (php के माध्यम से बल्क लोड)

  1. 4 'आयात' टेबल
  2. का एक सेट छोटा
  3. थोक इन 4 'आयात' तालिकाओं में डेटा डालने (पहले से ही टेबल में भी आईड्स का पुन: उपयोग कर रहा है, लेकिन मैंने पूरी तालिका को छोटा कर दिया है, इसलिए यह कोई मुद्दा नहीं होना चाहिए, दाएं ?)
  4. यदि सब कुछ ठीक हो जाता है, तो 'लाइव' टेबल 'temp', 'आयात' टेबल 'लाइव' और फिर 'temp' (पुरानी 'लाइव') टेबल 'आयात'
पर 'लाइव' टेबल का नाम बदलें

यह सप्ताहों के लिए बहुत अच्छा काम करता है। अब मैं कभी कभी यह हो रही है, पूरे थोक लोड हो रहा है की प्रक्रिया के बीच में कहीं: आपको लगता है कि

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '911' for key 1

मन, यह पहली आईडी कि पहले से ही काट-छांट से पहले तालिका में दिया गया है नहीं है। जब मैं स्क्रिप्ट मैन्युअल रूप से फिर से शुरू करता हूं, यह एक आकर्षण की तरह काम करता है।

कोई विचार? बचे हुए इंडेक्स, शायद नामकरण के साथ कुछ करने के लिए?

इसके अतिरिक्त, जब मैं आईडी 911 के साथ किसी प्रविष्टि के लिए तालिका की जांच करता हूं, तो यह वहां भी नहीं होता है।

उत्तर

0

आपकी आयात स्क्रिप्ट चल रही है, जबकि कुछ अन्य स्क्रिप्ट डेटाबेस में डालने जा सकती है?

0

क्या आपने क्वेरी लॉग को सक्षम करने की कोशिश की है कि आप वास्तव में डुप्लिकेट डालने वाले हैं या नहीं?

क्या आप इसे अपने परीक्षण वातावरण में पुन: उत्पन्न कर सकते हैं? उत्पादन में क्वेरी लॉग सक्षम न करें।

यह संभव है कि यदि समस्या वास्तविक है तो तालिका दूषित हो गई है; यह कई चीजों के कारण हो सकता है, लेकिन डोडी हार्डवेयर या पावर विफलता संभावनाएं हैं।

यह देखने के लिए mysql लॉग जांचें कि क्या हाल ही में या अवधि के दौरान इसमें कोई समस्या है (या दुर्घटनाग्रस्त)।

फिर, मैं सुझाव दे सकता हूं कि इसे अपने परीक्षण वातावरण में पुन: उत्पन्न करने का प्रयास करें। परीक्षण डेटा के बहुत बड़े लोड बनाएं और बार-बार उन्हें लोड करें।

1

स्पष्ट रूप से कुछ लॉक मुद्दे या कुछ थे, मैं समानांतर कनेक्शन में प्रभावित और संबंधित तालिकाओं को 'चयन' कथन शूटिंग करके व्यवहार को पुन: उत्पन्न करने में सक्षम था।

अब मैं TRUNCATE के बजाय DELETE FROM का इस्तेमाल किया और RENAME TABLE बयान बदल एकल ALTER TABLE xxx RENAME TO zzz बयान के एक समूह के लिए और त्रुटि किसी भी अधिक पुन: पेश नहीं कर सकते हैं (जहां मैं 3 बार प्रत्येक में नाम बदलता किया)।

इसलिए इसे हल किया जा सकता है। हो सकता है कि कोई और मेरे शोध से खर्च किए गए दिन और कई कोशिश-और-त्रुटि से लाभ उठा सके।

0

क्या आप लेनदेन का उपयोग कर रहे हैं?आप लेन-देन के साथ कई तरह की समस्याओं को खत्म कर सकते हैं, खासकर यदि टेबल को लॉक करना या लेन-देन अलगाव मोड को क्रमबद्ध करने के लिए सेट करना संभव है। मैं MySQL पर उन लोगों से वास्तव में परिचित नहीं हूं, लेकिन मेरा मानना ​​है कि लेनदेन केवल इनो डीबी टेबल पर काम करते हैं (या यह अप्रचलित ज्ञान हो सकता है)।

2

इस तरह की त्रुटियां तब हो सकती हैं जब एक MyISAM तालिका भ्रष्ट हो जाती है। सवाल में मेज पर मरम्मत आदेश चलाकर आम तौर पर सभी है कि यह तय करने के लिए आवश्यक है:

> repair table mytablename; 

एक बेहतर समाधान टेबल जहां डाटा निरंतर बदल रहा है के लिए MyISAM उपयोग करने के लिए नहीं है - InnoDB और अधिक बुलेटप्रूफ है, और के रूप में पॉल सही ढंग से बताता है, आप इनओडीबी टेबल पर लेनदेन का उपयोग कर सकते हैं, लेकिन माईसैम पर नहीं।

वैसे, मैं फ्लाई पर टेबल का नाम बदलने से बचूंगा - यह नियमित रूप से करने के लिए काफी कठोर चीज है, और अगर आपके पास कभी भी सिस्टम पर अन्य उपयोगकर्ता हैं तो नामांकन के दौरान कुछ अनपेक्षित परिणाम हो सकते हैं चल रहा। क्यों सिर्फ कुछ इस तरह नहीं है:

> truncate table temptable; 
> truncate table importtable; 

> #bulk insert new data 
> insert into importtable(col1,col2,col3) 
> values(1,2,3),(4,5,6),(7,8,9); 

> #now archive the live data 
> insert into temptable(col1,col2,col3) 
> select col1,col2,col3 from livetable; 

> #finally copy the new data to live 
> truncate table livetable; 
> insert into livetable(col1,col2,col3) 
> select col1,col2,col3 from importtable; 
बेशक

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

0

आप 'आईडी' फ़ील्ड छोड़े गए (या न्यूल), के साथ एक नया रिकॉर्ड बना रहे हैं लेकिन पहले आपने एक और रिकॉर्ड अपडेट किया है और इसे 'id' से '911' में बदल दिया है। दूसरे शब्दों में, यदि आप अपनी तालिका के AUTO_INCREMENT मान लेते हैं तो आप एक और रिकॉर्ड नहीं बना सकते हैं।

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

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