"भविष्य में" MySQL InnoDB लॉग से बेहतर कोई रास्ता नहीं है?


16

मुझे MySQL 5.0 में यह InnoDB त्रुटि मिली है। मैसकल्ड को सफाई से रोक दिया गया था, लेकिन मैं ib_logfile0 और ib_logfile1 को बाद में खोने में कामयाब रहा। अब एक साफ स्टार्टअप के बाद, InnoDB ने अपनी "क्रैश रिकवरी" की है। मैं innodb_force_recovery = 4 व्यवसाय के माध्यम से गया, एक त्रिशंकु MyISAM तालिका की मरम्मत की, और अब प्रतिकृति इसके अलावा जाने के लिए तैयार है। बड़ी संख्या में प्रशंसा:

111116 15:49:36  InnoDB: Error: page 393457 log sequence number 111 561,760,232
InnoDB: is in the future! Current system log sequence number 70 3,946,969,851.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html
InnoDB: for more information.

यह एक दास सर्वर पर है। उपरोक्त त्रुटि सैकड़ों लोगों द्वारा प्रायोजित है। मुझे यह उत्तर मिला: "64 GB डेटा डालें और हटाएं, ताकि लॉग अनुक्रम संख्या पर्याप्त रूप से बड़ी हो जाए"।

http://forums.mysql.com/read.php?22,50163,50163#msg-50163

64GB की वह जादुई संख्या 4GB * 16 से आती है, जहां उस आदमी की इनोडब लॉग "मेजर नंबर" 0 से बढ़कर 15. आवश्यकता है। मेरा 70 से 111 = 164 GB चल रहा है। इसमें 5 दिन लगेंगे। मैं अपनी स्क्रिप्ट को गति देने के लिए काम करता रहूंगा, और इसे गति देने के लिए इसे समानांतर में चलाऊंगा। इस बीच, मैं उम्मीद कर रहा हूं कि किसी और के पास बेहतर जवाब होगा। यह बेवक़ूफ़ी है।


एक आशाजनक उत्तर: "यदि यह एक दास सर्वर है, तो सबसे अच्छा समाधान वास्तव में डेटाबेस को एक तरफ ले जाना और मास्टर से एक नया स्नैपशॉट स्थापित करना होगा।" दुर्भाग्य से २५ डेटाबेस में २०,००० टेबल हैं, उत्पादन २४x tables में MyISAM और InnoDB का मिश्रण। फिर से शुरू करने से पहले उस सभी को बंद करने और नए सिरे से पूर्ण प्रतिकृति करने में बहुत लंबा समय लगेगा।
इकारसएनएम

4
अब मेरे पास यह 8-कोर मशीन है जो अपने घुटनों पर एक बेकार दौड़ में 164 गीगा डेटा बनाने और हटाने के लिए है। एकमात्र विकल्प जो मैं सुन रहा हूं, वह इस गुलाम पर सब कुछ करना और खरोंच से शुरू करना है। सभी को प्रभावी ढंग से दो फाइलों में एक नंबर को बदलना है। निश्चित रूप से वहाँ एक समर्थक टिप के साथ कुछ InnoDB इंजीनियर है। क्या किसी ने कभी Emacs में ib_logfile0 खोला है, हेक्स में जादू नंबर पाया है, और बस इसे बदल दिया है?
इकारसएनएम

इसे करने के कुछ तरीकों पर एक शानदार लेख यहां दिया गया है। Percona निश्चित रूप से MySQL पर प्राधिकरण है। percona.com/blog/2013/09/11/…
jbrahy

जवाबों:


10

यह एक बहुत ही दुर्लभ स्थिति थी। मुझे आशा है कि फिर से कभी खत्म नहीं होगी, एक InnoDB के साथ "लॉग अनुक्रम संख्या भविष्य में है!" त्रुटि। मेरे विशेष विवरण के कारण, मेरे सर्वर के डेटा का पुनर्निर्माण / पुनर्स्थापन एक अंतिम उपाय था। अच्छे विचारों की मदद करने में कुछ धोखा देती है, लेकिन अंत में, मैंने इस मूर्खतापूर्ण खेल को खेलने के लिए सिर्फ अपनी पर्ल स्क्रिप्ट में सुधार करने का निर्णय लिया और जितना हो सके उतने गिग्स / घंटे के माध्यम से मंथन करें। क्या बिल्ली, यह एक अच्छी प्रणाली तनाव परीक्षण है।

याद रखें: लक्ष्य एक एकल काउंटर ("लॉग अनुक्रम संख्या") को बढ़ाना है जो ib_logfile0 और ib_logfile1 के हेडर में कहीं संग्रहीत है । यह InnoDB बाहर नकली करने के लिए है इसलिए यह एक स्पष्ट समय ताना को अनदेखा करेगा और जीवन के साथ मिलेगा। लेकिन उस नंबर को एडिट करना कोई नहीं जानता। या अगर वे जानते हैं, तो किसी की बात नहीं।

यहाँ मेरा अंतिम उत्पाद है। YMMV, लेकिन आंतरिक रूप से डेटा उत्पन्न करने के लिए mysql के REPEAT फ़ंक्शन का उपयोग करना अत्यधिक कुशल है।

 #!/usr/bin/perl
 use DBI;
 $table = shift || die;
 $dbh = DBI->connect("DBI:mysql:junk:host=localhost", "user", "pass"); #Edit "junk" (DB name), user, and pass to suit.
 $dbh->do("DROP TABLE IF EXISTS $table");
 $dbh->do("CREATE TABLE $table (str TEXT) ENGINE=INNODB");
 $sth = $dbh->prepare("INSERT INTO $table (str) VALUES (REPEAT(?,1000000))");
 foreach (1..50) {
    $sth->execute('0123456789');   # 10 MB
 }
 $dbh->do("DELETE FROM $table");

मेरा सुझाव दिया नुस्खा:

  1. एक 'जंक' डेटाबेस बनाएँ
  2. उपरोक्त पर्ल स्क्रिप्ट को जंक.प्ल के रूप में सहेजें
  3. चलाने के लिए junk.pl data1 , और junk.pl data2 , और junk.pl data3 , आदि एक ही बार में कई सीपीयू कोर के रूप में आपके डेटाबेस सर्वर के रूप में शुरू करने के लिए है। कई गोले खोलें और प्रत्येक रन को बैश लूप में लपेटें while true; do date; junk.pl dataX; done:।

अपने LSN विकास को देखें, शायद दूसरे लूप में:

 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 3871092821
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 4209892586
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 125 85212387

बड़ी संख्या एक अहस्ताक्षरित 32-बिट INT है जो 4GB पर लिपटेगी, जो हर बार छोटी संख्या को बढ़ाती है। इस मामले में यह सिर्फ 124 से 125 तक लुढ़क गया। आपका लक्ष्य mysqld.log में छिपा हुआ है जिसने आपको पहली बार में इस हास्यास्पद समाधान के लिए Googling भेजा था। एक बार जब आप उस फिनिश लाइन को पार कर लेते हैं, तो बस! हॉर्न बजाओ! कंफ़ेद्दी जारी!

साइडबार: यह mysqld 5.0 w / REPEAT में एक दिलचस्प बग को उजागर करता है: यदि आप 20 एमबी पर जाते हैं, तो यह कुछ आंतरिक काउंटर और रोल को ~ 96 KB तक बढ़ा देता है। कहीं भी कोई चेतावनी या त्रुटि नहीं। मैं उस समय ट्रैकिंग को बर्बाद करने के बारे में नहीं था। 10 एमबी महान काम करता है। यदि आप कुछ अन्य सीमा से टकराते हैं, तो यह शिकायत कर सकता है। मेरे पास डिफ़ॉल्ट से बढ़े हुए कई निर्दोष बफ़र हैं। स्वाद के लिए मौसम। हमेशा की तरह, mysqld.log को एक विंडो में देखें।


इसे बाहर की जाँच करें percona.com/blog/2013/09/11/…
जोनास स्टेट्स

धन्यवाद जोनास; वह दिलचस्प है। मुझे लगता है कि मैं अपने तरीके से ऊपर रह सकता हूं। वह चल रहे mysqld के खिलाफ gdb का उपयोग करके दिखाता है जिसे मैं शायद कभी जोखिम में नहीं डालूंगा। लेकिन वहां भी अच्छी जानकारी।
इकारसएनएम

कुछ अजीब कारण के लिए, MariaDB का उपयोग करते हुए, मुझे 'छोटी संख्या [स्पेस] बड़ी संख्या' लॉग अनुक्रम संख्या नहीं मिलती है - लेकिन सिर्फ एक 'बड़ी संख्या' है, इसलिए दुख की बात है कि यह विधि मेरे लिए काम नहीं करती है। खैर, बेशक, लॉग अपडेट हो जाता है, मुझे नहीं पता कि कब रोकना है!
ग्वेनेथ लेलेवेन 10

5

आपके पास तीन (3) विकल्प हैं:

विकल्प 01: मास्टर से गुलाम (मास्टर पर डाउनटाइम) के rsync का प्रदर्शन करें

  • चरण 01: reset master;मास्टर पर चलाएं (Zaps बाइनरी लॉग्स)
  • चरण ०२: service mysql stopगुरु पर
  • चरण 03: service mysql stopदास पर
  • चरण 04: मास्टर से दास के लिए rsync / var / lib / mysql
  • चरण 05: service mysql startगुरु पर
  • चरण 06: मास्टर पर पहले बाइनरी लॉग का उपयोग करें, जिससे प्रतिकृति शुरू करने के लिए लॉग के रूप में। प्रतिकृति से प्रारंभ करने की स्थिति के रूप में उस लॉग की फ़ाइलों का उपयोग करें
  • चरण 07: service mysql stop --skip-slave-start दास पर
  • चरण 08: चरण 06 से ज्ञात लॉग और स्थिति से सेटअप प्रतिकृति के लिए कमांड चेंज मास्टर चलाने के लिए
  • चरण 09: start slave;दास पर चलें और प्रतिकृति को पकड़ने दें

विकल्प 02: मास्टर से गुलाम (मास्टर पर न्यूनतम डाउनटाइम) के rsync का प्रदर्शन करें

  • चरण 01: भागो reset master;मास्टर पर (Zaps बाइनरी लॉग्स)
  • चरण 02: service mysql stop दास पर
  • चरण 03: मास्टर से दास के लिए rsync / var / lib / mysql
  • चरण 04: चरण 03 को दोहराएं जब तक कि दो लगातार rsyncs समान समय न ले लें
  • चरण 05: service mysql stopगुरु पर
  • चरण 06: मास्टर से दास के लिए rsync / var / lib / mysql
  • चरण ०: service mysql startगुरु पर
  • चरण 08: मास्टर पर पहले बाइनरी लॉग का उपयोग करें जिससे प्रतिकृति शुरू करने के लिए लॉग के रूप में। प्रतिकृति से प्रारंभ करने की स्थिति के रूप में उस लॉग की फ़ाइलों का उपयोग करें
  • चरण 09: service mysql stop --skip-slave-startदास पर
  • चरण 10: चरण 08 से पता लगाया गया लॉग और स्थिति से प्रतिकृति प्रतिकृति करने के लिए कमांड चेंज मास्टर चलाएँ
  • चरण 11: start slave;दास पर चलें और प्रतिकृति को पकड़ने दें

विकल्प 03: XtraBackup का उपयोग करें

यह सॉफ़्टवेयर टूल न केवल एक रनिंग मास्टर की एक गैर-अप्रचलित प्रतिलिपि बना देगा, बल्कि आपके लिए संबंधित ib_logfiles भी बनाएगा। आपको प्रतिकृति बनाना होगा

मैंने इस विषय पर इससे पहले StackExchange पर पोस्ट किया है

मैंने अपने नियोक्ता की वेब होस्टिंग कंपनी के लिए कई बार ये काम किया है। एक ग्राहक को स्थानांतरित करने के लिए 3.7TB था और इसमें लगभग 16 घंटे लगे। तुलना में 64GB बहुत छोटा है।


विकल्प 02 चरण 05 में आप मास्टर शुरू करने के लिए कहते हैं। इसे कब रोका गया था? एक लाइव मास्टर पर रुपी जम्पी है। मैं प्रसन्न हूँ। और सौभाग्य से मैं innodb_file_per_table का उपयोग कर रहा हूं। लेकिन अंततः आपको बुलेट को काटने और एक अंतिम rsync के लिए लंबे समय तक मास्टर को रोकने के लिए प्रतिकृति शुरू करने से पहले चलना होगा। यह एक संभावना है जिसका मैं सहारा ले सकता हूं, लेकिन यह एक बहुत सक्रिय डीबीएमएस है। और मैं अपनी जानकारी के लिए XtraBackup देखूंगा।
इकारसएनएम

@IcarusNM: आह, टाइपो। मैंने इसे ठीक किया। धन्यवाद !!!
रोलैंडमाइसीडीडीबीए

विकल्प 02 शायद अभी भी कुछ काम का उपयोग कर सकता है। उदाहरण के लिए, आपको चरण 1 से पहले चरण 2 करना चाहिए। आप शायद चाहते हैं कि कहीं पर एक परिणाम प्राप्त हो। चरण 4 में टाइपो। और आप चरण 5 में "पहले बाइनरी लॉग" कहते हैं, लेकिन आप वास्तव में "केवल" या "अंतिम" बाइनरी लॉग का मतलब है। और आपको लॉग पोज़िशन का पता लगाने के लिए mysqlbinlog का उपयोग करना चाहिए, न कि फ़ाइल आकार का। और यह सब तब भी काम नहीं करेगा जब तक आप किसी बिंदु पर मास्टर को रोकते नहीं हैं। एक rsync समाप्त होने पर लॉग स्थिति / समय को आधार पर रखना जोखिम भरा होता है।
इकारसएनएम

मैं DB होस्टिंग ग्राहकों के साथ पिछले 4 वर्षों से OPTION 2 कर रहा हूं जिनके पास TeraByte Range में डेटा है। यह एक चल रहे सर्वर के खिलाफ हर बार काम करता है। केवल वास्तविक गलती आप गुलाम पर कर सकते हैं। वह गलती यह होगी कि प्रतिकृति ठीक से सेटअप की गई थी या नहीं। इसके अतिरिक्त, RESET SLAVEउपयोगी है, खासकर यदि आपने कई जीबी रिले लॉग्स को ढेर कर दिया है। Rsync प्रक्रिया और प्रतिकृति के पुन: स्थापन के बाद, कृपया CHASS MASTER TO कमांड को याद रखें, साथ ही आपके लिए रिले लॉग भी मिटा देंगे।
रोलैंडमाइसीडीडीबीए

मिमी ... अजीब। मैंने xtrabackup (हमेशा की तरह) का उपयोग करके अपने दास को स्थापित किया और अभी भी इन लॉग त्रुटियों (percona mysql 5.5.x) को मिला ... लगता है कि इस दास पर कुछ गलत हुआ है और मुझे इसे फिर से करना होगा।
हराल्ड

2

मुझे पता चला कि विभाजन की मेज पर काम करने वाली इस समस्या को हल करने के लिए शायद एक अच्छा तरीका है। मुझे कुछ साल पहले से विभाजन को छोड़ने की आवश्यकता थी, और 2014 के लिए कुछ जोड़ना था। लगभग सभी विभाजन इस त्रुटि की रिपोर्ट करते हैं, इसलिए पुराने भी। बहुत बुरा दुर्घटना।

इसलिए जब पुराना पुराना हो रहा है और MAXVALUE विभाजन (पिछले एक) के REORGANIZE का उपयोग करते हुए, यह नई फाइलें बनाएगा जो ठीक हैं, इसलिए मुझे कम और कम चेतावनी मिलती है। इस बीच, यह लॉग अनुक्रम काउंटर को बढ़ाने में मदद करता है, इसलिए मुझे फर्जी डेटा डालने की आवश्यकता नहीं है। मैं यह एक मास्टर सर्वर btw पर हो रहा है ...

तो यह:

ALTER TABLE Events DROP PARTITION p1530 , p1535 , p1540 , p1545 , 
p1550, p1555 , p1560 , p1565 , p1570 , p1575 , p1580 , p1585 , p1590 , 
p1595 , p1600 , p1605 , p1610 , p1615 , p1620 , p1625 , p1630 , p1635 , 
p1640 , p1645 , p1650 , p1655 , p1660 , p1665 , p1670 , p1675 , p1680 , 
p1685 , p1690 , p1695 , p1700 , p1705 , p1710 , p1715 , p1720 , p1725 , 
p1730 , p1735 , p1740 , p1745 , p1750 , p1755 , p1760 , p1765 , p1770 , 
p1775 , p1780 , p1785 , p1790 , p1795 , p1800 , p1805 , p1810 , p1815 , 
p1820 , p1825 , p1830 , p1835 , p1840;

और इस:

ALTER table Events REORGANIZE PARTITION p3000 INTO (
PARTITION p3500 VALUES LESS THAN (TO_DAYS('2013-01-01')),
PARTITION p3510 VALUES LESS THAN (TO_DAYS('2013-01-04')),
PARTITION p3520 VALUES LESS THAN (TO_DAYS('2013-01-07')),
PARTITION p3530 VALUES LESS THAN (TO_DAYS('2013-01-10'))
...
PARTITION p4740 VALUES LESS THAN (TO_DAYS('2014-01-08')),
PARTITION p9000 VALUES LESS THAN MAXVALUE)

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

अब तालिका के बाकी हिस्सों के लिए, क्योंकि मैंने इस प्रक्रिया में सभी विभाजनों को नहीं छुआ है, कुछ लॉग अनुक्रम चेतावनी के साथ छोड़ दिए जाएंगे, उन लोगों के लिए जो टूट गए हैं और इस पुनर्गठित कार्रवाई द्वारा कवर किए गए हैं जो मैं संभवतः इसे चलाऊंगा:

ALTER TABLE Events REBUILD PARTITION p0, p1;

या वो

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

इसलिए, मुझे यह सोचकर मिला, आप इसे सादे वेनिला तालिकाओं के साथ कर सकते हैं, हैश द्वारा अस्थायी जोड़ विभाजन और बाद में इसे हटा दें (या उन्हें रखें, मैं विभाजन की जोरदार सिफारिश कर सकता हूं)।

मैं mariadb का उपयोग कर रहा हूँ, फिर भी mysql नहीं (तो XtraDB)

शायद इससे किसी को मदद मिले। मैं अभी भी इसे चला रहा हूं, अब तक बहुत अच्छा है। बदलते हुए इंजन का काम भी ऐसा लगता है, इसलिए मैं इसे MyIsam और उन्हें वापस InnoDB के बीच लाता हूं।

यह काफी तार्किक है, यदि आप इंजन बदलते हैं, तो तालिका निर्दोष से गायब हो जाती है, इसलिए यह अब समस्या नहीं होगी।

ALTER TABLE Events ENGINE=MyISAM;
ALTER TABLE Events ENGINE=InnoDB;

यहाँ काम करने लगता है। मैं विभाजित तालिकाओं पर कुछ बातों की पुष्टि कर सकता हूं:

  • ALTER TABLE xyz Engine = InnoDB बहुत धीमा है, Aria (mariadb) से दो बार तेज है, लेकिन सामान्य रूप से लॉग अनुक्रम काउंटर को बढ़ाने का एक धीमा तरीका है
  • सारणी सारणी REBUILD विभाजन सभी तालिकाओं को 'ठीक' करने और काउंटर को बढ़ाने में मदद करने का सबसे तेज़ तरीका है
  • अन्य सारणी विश्लेषण के भाग के लिए सभी पूर्व की तुलना में धीमी है और विभाजन को फिर से लिखने के लिए ठीक नहीं है। REBUILD एक अस्थायी तालिका स्कीमा को फिर से लिखने का आश्वासन देता है।

मैंने पिछले वाले को कई तालिकाओं पर इस्तेमाल किया। चेतावनी तब होती है जब वह फ़ाइलों को खोलने की कोशिश कर रहा होता है और हर विभाजन परिभाषा के लिए एक होता है जो काउंटर मुद्दों के साथ खुलता है। लगभग आखिरी टेबल के लिए आज काउंटर पर लुढ़का। मुझे लगता है कि एक बार यह सब संसाधित हो जाने के बाद बाइनरी लॉग को फ्लश करने की आवश्यकता होती है।

अद्यतन : मैं कुछ चीजों को समाप्त कर सकता हूं अब मैं इस समस्या को हल करने में कामयाब रहा।

  • मेरी दुर्घटना आरिया प्रारूप (मारियाबीडी) में एक टेबल पर विभाजन को पुनर्गठित करने के कारण हुई थी।
  • (मेरे लिए) विभाजन का पुनर्निर्माण करते हुए सबसे अच्छा और सबसे तेजी से काम किया ताकि अनुक्रम का मुकाबला किया जा सके। इंजन को बदलना धीमा है और आपको इसे प्रभावित करने के लिए दो बार करने की आवश्यकता है। innoDB में परिवर्तन करना काफी धीमा है MyIsam या Aria के लिए।
  • मैंने मारबाडी 5.3 को अपग्रेड किया और 5.5 को नहीं (:: 5.2) किया और यह ठीक काम करता है। मुझे लगता है कि इस संयोजन का उपयोग करने के लिए 5.5, (और पुष्ट बग) में विभाजन के साथ बहुत अधिक समस्याएं हैं।
  • लॉग अनुक्रम काउंटर को रीसेट करने के लिए वास्तव में एक बेहतर तरीका होना चाहिए।

मारियाबीडी के तहत, आप USE INFORMATION_SCHEMA; SELECT CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` REBUILD PARTITION ALL;") AS MySQLCMD AS MySQLCMD FROM TABLES;(स्रोत: dba.stackexchange.com/questions/35073/… ) का उपयोग करके सभी तालिकाओं को जल्दी से बदल सकते हैं और इसे कमांड की एक श्रृंखला के रूप में निष्पादित करने के लिए एक फ़ाइल के लिए टी कर सकते हैं।
ग्वेनेथ लेलेवेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.