it-swarm.asia

هل هناك طريقة أفضل للخروج من سجل MySQL InnoDB "في المستقبل"؟

لقد تلقيت خطأ InnoDB في MySQL 5.0. تم إيقاف Mysqld بشكل نظيف ، لكنني تمكنت من فقدان 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 غيغابايت ، بحيث يصبح رقم تسلسل السجل مبالغًا فيه بما يكفي".

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

يأتي هذا الرقم السحري من 64 غيغابايت من 4 غيغابايت * 16 حيث يحتاج سجل ذلك الرجل "الرقم الرئيسي" المطلوب لزيادة من 0 إلى 15. المنجم من 70 إلى 111 = 164 غيغابايت. سيستغرق ذلك 5 أيام. سأستمر في العمل على تسريع النص الخاص بي ، وتشغيله بالتوازي لتسريع هذا. في غضون ذلك ، آمل أن يكون لدى شخص آخر إجابة أفضل. هذا سخيف.

16
IcarusNM

كان هذا وضعًا نادرًا جدًا. آمل ألا ينتهي بي الأمر إلى هناك مرة أخرى ، مع رقم تسلسل سجل InnoDB في المستقبل! " خطأ. نظرًا لتفاصيلي الخاصة ، كانت إعادة بناء/استعادة بيانات الخادم الخاص بي هي الملاذ الأخير. بعض الغش في المساعدة التي كانت أفكارًا جيدة ، لكن في النهاية ، قررت فقط مواصلة تحسين نص Perl النصي الخاص بي للعب هذه اللعبة السخيفة وأضغط على أكبر عدد ممكن من العربات/الساعة. ما هذا ، إنه اختبار ضغط نظام جيد.

تذكر: الهدف هو زيادة عداد واحد ("رقم تسلسل السجل") يتم تخزينه في مكان ما في رؤوس ib_logfile و ib_logfile1. هذا هو لتزييف InnoDB حتى يتجاهل انفتال الوقت الواضح والمضي قدما في الحياة. لكن لا أحد يعرف كيف يعدّل هذا الرقم. أو إذا كانوا يعرفون ، لا أحد يتحدث.

ها هو منتجي النهائي. YMMV ، ولكن استخدام وظيفة REPEAT mysql لتوليد البيانات داخليًا فعال للغاية.

 #!/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. احفظ نص Perl النصي أعلاه junk.pl.
  3. قم بتشغيل junk.pl data1 و junk.pl data2 و junk.pl data ، وما إلى ذلك ، في نفس الوقت ، لعدد من مراكز وحدة المعالجة المركزية كما فعل خادم قاعدة البيانات ، للبدء. افتح العديد من الأصداف ولف كل دورة في حلقة باش: 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

الرقم الكبير عبارة عن INT 32 بت غير موقعة والذي سيتم التفافه عند 4 غيغابايت ، مما يؤدي إلى زيادة العدد الأصغر في كل مرة. في هذه الحالة أعلاه ، تدحرجت للتو من 124 إلى 125. هدفك مخفي في mysqld.log الذي أرسل لك Google لهذا الحل السخيف في المقام الأول. بمجرد عبور خط النهاية ، هذا كل شيء! تفجير الأبواق! أطلق النثار!

الشريط الجانبي: كشف هذا عن خطأ مثير للاهتمام في mysqld 5.0 w/REPEAT: إذا ذهبت إلى 20 ميغابايت ، فإنه يقلب بعض العدادات الداخلية ويتحول إلى ~ 96 كيلوبايت. لا تحذير أو خطأ في أي مكان. لم أكن على وشك إضاعة الوقت في تتبع ذلك. 10 ميجا بايت تعمل بشكل رائع. إذا وصلت إلى حد آخر ، فقد يشكو. لدي العديد من innodb زيادة المخازن المؤقتة من الافتراضي. الموسم حسب الذوق. كما هو الحال دائمًا ، شاهد mysqld.log في نافذة واحدة.

10
IcarusNM

لديك ثلاثة خيارات:

الخيار 01: قم بإجراء rsync من Master إلى Slave (وقت التوقف عن Master)

  • الخطوة 01: تشغيل reset master; على سيد (Zaps Binary Logs)
  • الخطوة 02: 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: قم بتشغيل أمر تغيير MASTER TO لإعداد النسخ المتماثل من السجل والموضع المحدد من الخطوة 06
  • الخطوة 09: تشغيل start slave; على العبد ودع النسخ يلاحق

الخيار 02: قم بإجراء rsync من Master إلى Slave (الحد الأدنى من وقت التوقف عن Master)

  • الخطوة 01: تشغيل reset master; على سيد (Zaps Binary Logs)
  • الخطوة 02: service mysql stop على العبد
  • الخطوة 03: rsync/var/lib/mysql من السيد إلى العبد
  • الخطوة 04: كرر الخطوة 03 حتى يستغرق rsyncs متتاليان نفس مقدار الوقت
  • الخطوة 05: service mysql stop على السيد
  • الخطوة 06: rsync/var/lib/mysql من السيد إلى العبد
  • الخطوة 07: service mysql start على السيد
  • الخطوة 08: استخدم أول سجل ثنائي على الرئيسي كسجل لبدء النسخ المتماثل منه. استخدم حجم الملف لهذا السجل كموضع لبدء النسخ المتماثل منه
  • الخطوة 09: service mysql stop --skip-slave-start على العبد
  • الخطوة 10: قم بتشغيل الأمر CHANGE MASTER TO لإعداد النسخ المتماثل من السجل والموضع المحدد من الخطوة 08
  • الخطوة 11: تشغيل start slave; على العبد ودع النسخ يلاحق

الخيار 03: استخدم XtraBackup

لن تقوم أداة البرنامج هذه بعمل نسخة غير متداخلة من سيد رئيسي فحسب ، بل ستقوم أيضًا بإنشاء ملفات ib_logfiles المقابلة لك. يجب عليك إعداد النسخ المتماثل

لقد أرسلت إلى StackExchange من قبل حول هذا الموضوع

لقد فعلت هذه الأشياء عدة مرات لشركة استضافة الويب الخاصة بصاحب العمل. عميل واحد لديه 3.7 تيرابايت للتحرك واستغرق حوالي 16 ساعة. 64 جيجابايت صغير جدًا بالمقارنة.

5
RolandoMySQLDBA

اكتشفت أنه ربما تكون هناك طريقة أكثر برودة لحل هذه المشكلة من خلال العمل على الجداول المقسمة. كنت بحاجة إلى إسقاط أقسام من بضع سنوات إلى الوراء ، واضطررت إلى إضافة بعض لعام 2014. تقريبا جميع الأقسام تبلغ عن هذا الخطأ ، وكذلك الأقسام القديمة. تحطم سيئة للغاية.

لذلك أثناء انخفاض العمر واستخدام إعادة تنظيم قسم MAXVALUE (القسم الأخير) ، سيتم إنشاء ملفات جديدة لا بأس بها ، لذلك أحصل على تحذيرات أقل وأقل. في هذه الأثناء ، يساعد في زيادة عداد تسلسل السجل ، لذلك لست بحاجة إلى إدراج بيانات وهمية. لدي هذا يحدث على الخادم الرئيسي راجع للشغل ...

إذا هذا:

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.

إنه منطقي إلى حد ما ، إذا قمت بتغيير ENGINE ، يختفي الجدول من innodb ، لذلك لن تكون مشكلة بعد الآن.

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

يبدو أنه يعمل هنا. يمكنني تأكيد بعض الأشياء على الجداول المقسمة:

  • ALTER TABLE xyz ENGINE = InnoDB بطيء جدًا ، إلى Aria (mariadb) أسرع مرتين ، ولكن بشكل عام بطيء لزيادة عداد تسلسل السجل
  • ALTER TABLE XYZ REBUILD PARTITION ALL هي أسرع طريقة "لإصلاح" الجداول والمساعدة في زيادة العداد
  • ALTER TABLE xyz ANALYZE PARTITION ALL بطيء جدًا بالنسبة إلى السابق ولا يعيد كتابة الأقسام التي تحقق على ما يرام. يضمن REBUILD إعادة كتابة مخطط جدول مؤقت.

لقد استخدمت الأخيرة على عدة جداول. تحدث التحذيرات عندما تحاول فتح الملفات ويوجد واحد لكل تعريف قسم يفتحه مع مشاكل العداد. تدحرجت تقريبا على العداد اليوم للجداول الأخيرة. أعتقد أنه بمجرد معالجة كل شيء ، يحتاج المرء إلى مسح السجلات الثنائية.

تحديث: يمكنني أن أختتم ببعض الأشياء الآن تمكنت من حل هذه المشكلة.

  • كان سبب تحطم الطائرة هو إعادة تنظيم الأقسام على طاولة بتنسيق Aria (MariaDB).
  • (بالنسبة لي) عمل إعادة بناء الأقسام بشكل أفضل وأسرع للحصول على عداد التسلسل. تغيير المحرك بطيء وتحتاج إلى القيام به مرتين للتأثير على innodb. يعد التغيير إلى innoDB بطيئًا جدًا مقابل MyIsam أو Aria.
  • لقد قمت بالترقية إلى MariaDB 5.3 وليس إلى 5.5 (كان: 5.2) ويعمل بشكل جيد. أعتقد أن هناك الكثير من المشاكل مع aria ، أقسام في 5.5 (والأخطاء المؤكدة) لاستخدام هذه المجموعة.
  • يجب أن تكون هناك طريقة أفضل لإعادة تعيين عداد تسلسل السجل.
2
Glenn Plas