คุณจะระบุความเสียหายของตาราง InnoDB ได้อย่างไร


24

ฉันมีตารางบางส่วนที่แบ่งพาร์ติชันและมีดัชนีหลายรายการในสลาฟที่ถูกจำลอง หลังจากคัดลอกสแน็ปช็อต (ยืนยันความปลอดภัย) ไปยังทาสใหม่และอัปเกรด mysqld จาก 5.1.42 เป็น 5.5.15 และเริ่มการจำลองแบบใหม่ฉันได้รับ InnoDB ขัดข้องพร้อมข้อความแสดงข้อผิดพลาด "ตัวชี้ไม่ถูกต้อง ... "

ข้อผิดพลาดเหล่านี้เกิดขึ้นในเซิร์ฟเวอร์ 2 เครื่องที่มีฮาร์ดแวร์และ O / S ที่แตกต่างกัน หลังจากทำงาน:

ALTER TABLE .... COALESCE PARTION n;

ปัญหาหายไปสำหรับตารางนั้น

คำถามของฉันมีขนาดใหญ่กว่าในขอบเขตและนั่นคือ "คุณจะระบุความเสียหายของตาราง InnoDB ได้อย่างไร" หรือ rephrased "คุณประเมินสุขภาพของตาราง InnoDB อย่างไร" คือ"ตรวจสอบตาราง"เครื่องมือเดียวที่มีอยู่เพื่อแจ้งปัญหา pre-crash?

ไม่แน่ใจว่ามีปัญหาหรือไม่ แต่เกิดปัญหาการทำงาน: รุ่น: ซ็อกเก็ต '5.5.15-55-log': พอร์ต '/opt/mysql.sock': 3306 เซิร์ฟเวอร์ Percona (GPL), รีลีส rel21.0, การแก้ไข 158


2
สวัสดีแรนดี้! ฉันคิดว่าคำตอบที่นี่น่าเชื่อถือ - InnoDB ระบุความเสียหายของตัวเอง บางทีคุณควรเรียบเรียงคำถามของคุณใหม่ทำไมสิ่งที่คุณทำทำให้ InnoDB เสียหาย?
Morgan Tocker

คำตอบ:


18

มอร์แกนให้คำแนะนำในความคิดเห็นของเขาว่า InnoDB ตรวจสอบหน้าเว็บที่เสียหายอยู่เสมอด้วยการทำ checksums บนหน้าเว็บที่อ่าน หาก InnoDB พบการตรวจสอบที่ไม่ตรงกันก็จะผิดพลาดหยุดเซิร์ฟเวอร์

หากคุณต้องการเพิ่มความเร็วในการประมวลผลนั้น (แทนที่จะรอให้ InnoDB อ่านหน้าเว็บที่เสียหาย) คุณสามารถใช้innochecksum:

เนื่องจากการตรวจสอบที่ไม่ตรงกันจะทำให้ InnoDB ปิดเซิร์ฟเวอร์ที่รันอยู่โดยเจตนาจึงสามารถใช้เครื่องมือนี้ได้ดีกว่ารอให้เซิร์ฟเวอร์ในการใช้งานจริงพบหน้าที่เสียหาย

ข้อแม้ที่น่าสนใจ:

innochecksum ไม่สามารถใช้กับไฟล์ tablespace ที่เซิร์ฟเวอร์เปิดอยู่แล้ว สำหรับไฟล์ดังกล่าวคุณควรใช้ตารางตรวจสอบเพื่อตรวจสอบตารางภายใน tablespace

ดังนั้นใช่สำหรับตารางออนไลน์CHECK TABLEอาจเป็นเครื่องมือ (หรือตามที่ระบุไว้ในคำตอบอื่น mysqlcheckถ้าคุณต้องการทำมากกว่าหนึ่งฐานข้อมูลในเวลาเดียวกัน)

หากคุณสามารถปิดฐานข้อมูลของคุณคุณสามารถบังคับให้ใช้เช็คซัมโดยใช้ innochecksum

บันทึกย่อ:บนพื้นที่ตาราง innodb ที่ 29GB (พร้อมinnodb_file_per_table=1) สคริปต์นี้ใช้เวลาประมาณ 2 นาที

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

เป็นโบนัส แต่เนื่องจากคุณกำลังทำงาน Percona พวกเขาดำเนินการวิธีการใหม่สำหรับการตรวจสอบ InnoDB รวดเร็ว ฉันไม่เคยใช้มัน แต่มันอาจทำให้กระบวนการเร็วขึ้น


1
จะลองดูที่นี่ดูเหมือนจะเป็นทางออก @randymelder กำลังมองหา +1
marcio

2
เซิร์ฟเวอร์ Percona มีคุณสมบัติที่ดีอื่น ๆ ดู innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Morgan Tocker

@Dest ทดสอบ: innochecksum เป็นวิธีที่จะไป คนนี้เป็นผู้รักษา +1 !!!
RolandoMySQLDBA

@DTest: ปิดให้คุณวันนี้กับคนนี้ !!!!
RolandoMySQLDBA

@ MorganTocker ที่น่าสนใจ จะต้องได้รับความรู้ของฉันสูญญากาศและทำวิจัยบางอย่างในเพอร์โค
Derek Downey

6

คำเตือน: ก่อนที่จะลองทำตามคำแนะนำเหล่านี้ขอแนะนำอย่างยิ่งให้ตรวจสอบว่ามีการสำรองข้อมูลที่สมบูรณ์ของฐานข้อมูลของคุณในมือในกรณีที่ (ขอบคุณ @Nick สำหรับคำเตือน)

ลองใช้mysqlcheckคำสั่ง บนเทอร์มินัล:

mysqlcheck -u username -p --databases database1 database2

คำสั่งนี้จะแสดงรายการของตารางทั้งหมดและสถานะที่แจ้งให้คุณทราบหากมีความเสียหายบางประเภท:

table1  OK
table2  OK
table3  OK
tableN  OK

เมื่ออยู่ในมือคุณจะรู้ว่าต้องซ่อมแซมตารางใด ในกรณีที่คุณต้องการซ่อมแซมทุกอย่างในครั้งเดียว:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

เพิ่มเติมเกี่ยวกับmysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

หมายเหตุ: คุณแท็กคำถามของคุณกับPerconaฉันไม่รู้ว่ามันคืออะไรดังนั้นฉันจึงไปเที่ยว ดูเหมือนว่าจะเป็นทางแยกของ MySQL แต่ฉันไม่มีเหตุผลที่จะเชื่อว่าคำสั่งนั้นเข้ากันไม่ได้


มีใครบางคนชี้ให้ฉันเห็นคู่มือนี้ซึ่งมีคำแนะนำเฉพาะเพิ่มเติมสำหรับการกู้คืนฐานข้อมูล InnoDB สำหรับสถานการณ์ที่สำคัญยิ่งกว่าซึ่งฐานข้อมูลทั้งหมดไม่เริ่มทำงาน: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-InnoDB-1634.html


1
mysqlcheck เป็นคำพ้องความหมายสำหรับ 'check table ... ' -1
randomx


ไม่จริง. อันดับแรก mysqlcheck เป็นโปรแกรมอรรถประโยชน์บรรทัดคำสั่งและตารางตรวจสอบเป็นคำสั่ง SQL (มันก็เหมือนกับการเปรียบเทียบสีส้มกับเลมมอน) นอกจากนี้คุณไม่สามารถตรวจสอบฐานข้อมูลทั้งหมดด้วยตารางตรวจสอบโดยไม่รวมชื่อตารางทั้งหมดในคำสั่ง SQL ( มันจะไม่ผลิตมากเกินไป)
Marcio

และ mysqlcheck มีตัวเลือกให้ - ซ่อมแซมอัตโนมัติตารางที่เสียหายในขณะที่ตรวจสอบตารางตรวจสอบเฉพาะว่าตารางเสียหายหรือไม่ แต่ไม่สามารถทำการซ่อมแซมใด ๆ
marcio

2
@randymelder - คุณจะไม่ถูกต้องที่จะบอกว่าเป็นคำพ้อง mysqlcheck CHECK TABLEสำหรับ เอกสารที่เชื่อมโยงกับรัฐ " mysqlcheckใช้งบ SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLEและOPTIMIZE TABLE. ในวิธีที่สะดวกสำหรับผู้ใช้ที่จะเป็นตัวกำหนดซึ่งงบที่จะใช้สำหรับการดำเนินงานที่คุณต้องการที่จะดำเนินการแล้วส่งงบไปยังเซิร์ฟเวอร์ที่จะดำเนินการ " นั่นไม่ใช่คำพ้องความหมาย นั่นคือส่วนติดต่อผู้ใช้ไปยังชุดคำสั่ง
Nick Chammas

6

ตามคู่มือการศึกษาการรับรอง MySQL 5.0, หน้า 443,444 มาตรา 30.4 :

คุณสามารถตรวจสอบตาราง InnoDB ได้โดยใช้คำสั่ง CHECK TABLE หรือใช้โปรแกรมไคลเอ็นต์เพื่อออกคำสั่งให้คุณ อย่างไรก็ตามถ้าตาราง InnoDB มีปัญหาคุณไม่สามารถแก้ไขได้โดยใช้ REPAIR TABLE เนื่องจากคำสั่งนั้นใช้กับ MyISAM เท่านั้น

หากการตรวจสอบตารางบ่งชี้ว่าตาราง InnoDB มีปัญหาคุณควรจะสามารถกู้คืนตารางให้เป็นสถานะที่สอดคล้องกันโดยการดัมพ์ด้วย mysqldump ปล่อยมันและสร้างมันใหม่จากการถ่ายโอนข้อมูลนั้น

ในกรณีที่เกิดความผิดพลาดของเซิร์ฟเวอร์ MySQL หรือโฮสต์ที่มันทำงานตาราง InnoDB บางตัวอาจต้องซ่อมแซม โดยปกติแล้วเพียงแค่รีสตาร์ทเซิร์ฟเวอร์เพราะเครื่องมือจัดเก็บข้อมูล InnoDB ทำการกู้คืนอัตโนมัติซึ่งเป็นส่วนหนึ่งของลำดับการเริ่มต้น ในบางกรณีเซิร์ฟเวอร์อาจไม่เริ่มต้นขึ้นเนื่องจากความล้มเหลวในการกู้คืนอัตโนมัติของ InnoDB หากเกิดขึ้นใช้ขั้นตอนต่อไปนี้:

  • รีสตาร์ทเซิร์ฟเวอร์ด้วยตัวเลือก --innodb_force_recovery ตั้งค่าเป็นค่าใน rage จาก 1 ถึง 6 ค่าเหล่านี้บ่งชี้ระดับความระมัดระวังที่เพิ่มขึ้นในการหลีกเลี่ยงความผิดพลาดและเพิ่มระดับความอดทนสำหรับความไม่สอดคล้องที่เป็นไปได้ในตารางที่กู้คืน ค่าที่ดีในการเริ่มต้นคือ 4

  • เมื่อคุณเริ่มต้นเซิร์ฟเวอร์โดยตั้งค่า --innodb_force_recovery เป็นค่าที่ไม่เป็นศูนย์ InnoDB จะปฏิบัติกับ tablespace เป็นแบบอ่านอย่างเดียว ดังนั้นคุณควรถ่ายโอนข้อมูลตาราง InnoDB ด้วย mysqldump แล้ววางลงในขณะที่ตัวเลือกมีผล จากนั้นรีสตาร์ทเซิร์ฟเวอร์โดยไม่มีตัวเลือก --innodb_force_recovery เมื่อเซิร์ฟเวอร์เกิดขึ้นให้กู้คืนตาราง InnoDB จากไฟล์ดัมพ์

  • หากขั้นตอนก่อนหน้านี้ล้มเหลวจำเป็นต้องเรียกคืนตาราง InnoDB จากการสำรองข้อมูลก่อนหน้า

โปรดอ่าน MySQL เอกสารในการกู้คืน InnoDB บังคับ  


3
FWIW คำแนะนำการรับรองมีคำตอบที่ถูกต้องทางการเมือง :) ถ้าคุณตรวจสอบตารางในตาราง InnoDB และจริง ๆ แล้วมันเสียหายจริง ๆ มันจะไม่กลับมาเป็น "เสียหาย" มันจะพังเซิร์ฟเวอร์ คำสั่งนี้เกือบจะล้าสมัยใน InnoDB เพราะทุกครั้งที่คุณอ่านหน้า InnoDB จะมีการตรวจสอบความเสียหาย (ผ่านการตรวจสอบหน้า)
Morgan Tocker

2

ฉันสงสัยว่าจะเกิดอะไรขึ้นถ้ามีคนใช้ข้อมูล InnoDB ที่สร้างผ่านปลั๊กอิน InnoDB แล้วเปลี่ยนเป็น InnoDB รุ่นอื่น ที่สามารถสร้างความเสียหายหน้าเป็นไปได้ในสายตาของ mysqld

สังเกตสิ่งที่เอกสาร MySQL ในรูปแบบไฟล์ InnoDBพูดถึงความเป็นไปได้นี้:

โดยทั่วไปแล้ว InnoDB รุ่นใหม่กว่าอาจสร้างตารางหรือดัชนีที่ไม่สามารถอ่านหรือเขียนด้วย InnoDB เวอร์ชันก่อนหน้าได้อย่างปลอดภัยโดยไม่มีความเสี่ยงจากการขัดข้องแฮงค์ผลลัพธ์ที่ผิดหรือเสียหาย ปลั๊กอิน InnoDB แนะนำกลไกใหม่เพื่อป้องกันเงื่อนไขเหล่านี้และช่วยรักษาความเข้ากันได้ระหว่างไฟล์ฐานข้อมูลและรุ่นของ InnoDB

ฉันจะทิ้งข้อมูลลงบนทาส ในความเป็นจริงฉันจะใช้กำลังดุร้ายโดยรับตรรกะการถ่ายโอนข้อมูล (mysqldump) ของข้อมูล:

  • ดร็อปฐานข้อมูลทั้งหมดโดยใช้ InnoDB บนสลาฟ
  • ปิด mysql บนทาส
  • ลบ ibdata1, ib_logfile0 และ ib_logfile1 บนสลาฟ
  • เริ่ม mysql บนทาสปล่อยให้ ibdata1, ib_logfile0 และ ib_logfile1 รับการสร้างขึ้นมาใหม่
  • mysqldump ข้อมูลจากมาสเตอร์เข้าสู่สลาฟ

ผู้ประกาศดั้งเดิมของฉันที่โพสต์นั้นถือว่าเป็น 'โรงเรียนเก่า' แต่ในกรณีนี้ฉันจะดูรูปแบบไฟล์ที่ใช้โดย. ibd และ / หรือ ibdata1 อย่างแน่นอน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.