MySQL InnoDB ทำตารางหาย แต่มีไฟล์อยู่


33

ฉันมี MySQL InnoDB ซึ่งมีไฟล์ตารางฐานข้อมูลทั้งหมด แต่ MySQL ไม่เห็นพวกเขาและไม่โหลด

ปัญหาเกิดขึ้นเพราะฉันลบทั้งสามไฟล์: ibdata1, ib_logfile0และib_logfile1

เพราะฉันมีปัญหากับการเริ่มต้น mysql และสิ่งที่ฉันอ่านคือการลบพวกเขาเพราะ MySQL เพิ่งจะสร้างพวกเขาใหม่ (ฉันรู้ว่าฉันควรจะสำรองไว้ แต่ไม่ได้)

ฉันจะทำอย่างไรเพื่อให้ MySQL ดูตารางอีกครั้ง

about_member.frm                              site_stories.frm
about_member.ibd                              site_stories.ibd
db.opt                                        stories.frm
FTS_00000000000000bb_BEING_DELETED_CACHE.ibd  stories.ibd
FTS_00000000000000bb_BEING_DELETED.ibd        story_comments.frm
FTS_00000000000000bb_CONFIG.ibd               story_comments.ibd
FTS_00000000000000bb_DELETED_CACHE.ibd        story_likes.frm
FTS_00000000000000bb_DELETED.ibd              story_likes.ibd
FTS_00000000000000f5_BEING_DELETED_CACHE.ibd  story_tags.frm
FTS_00000000000000f5_BEING_DELETED.ibd        story_tags.ibd
FTS_00000000000000f5_CONFIG.ibd               story_views.frm
FTS_00000000000000f5_DELETED_CACHE.ibd        story_views.ibd
FTS_00000000000000f5_DELETED.ibd              story_view_totals.frm
member_favorites.frm                          story_view_totals.ibd
member_favorites.ibd                          tags.frm
members.frm                                   tags.ibd
members.ibd

คุณพยายามกู้คืนไฟล์เหล่านั้นหรือไม่ ไฟล์บันทึกสามารถลบอยู่ได้ คุณไม่ควรลบ ibdata1
Ramhound

ฉันได้คัดลอกไฟล์จากเวอร์ชันเก่าของ mysql ซึ่งเป็นที่ตั้งของไฟล์ แต่ตารางไม่แสดงขึ้นมา
ลงสนามของฉัน

คำตอบ:


36

นี่คือสาเหตุที่ MySQL ไม่สามารถมองเห็นไฟล์เหล่านั้น: tablespace ระบบ (ibdata1) มีพจนานุกรมข้อมูลเฉพาะเครื่องมือจัดเก็บข้อมูลที่ช่วยให้ InnoDB แมปการใช้งานตารางที่เป็นไปได้:

สถาปัตยกรรม InnoDB

การย้ายตาราง InnoDB จากที่หนึ่งไปอีกที่หนึ่งต้องใช้คำสั่งเช่น

ALTER TABLE tblname DISCARD TABLESPACE;
ALTER TABLE tblname IMPORT TABLESPACE;

นี่เป็นส่วนหนึ่งของMySQL 5.5 เอกสารอธิบายสิ่งที่ต้องพิจารณา

ข้อควรพิจารณาในการพกพาสำหรับไฟล์. ibd

คุณไม่สามารถย้ายไฟล์. ibd ระหว่างไดเรกทอรีฐานข้อมูลได้อย่างอิสระเท่าที่จะทำได้ด้วยไฟล์ตาราง MyISAM คำจำกัดความของตารางที่จัดเก็บในพื้นที่ตารางที่ใช้ร่วมกันของ InnoDB มีชื่อฐานข้อมูล ID ธุรกรรมและหมายเลขลำดับการบันทึกที่เก็บในไฟล์ tablespace จะแตกต่างกันระหว่างฐานข้อมูล

หากต้องการย้ายไฟล์. ibd และตารางที่เกี่ยวข้องจากฐานข้อมูลหนึ่งไปยังอีกฐานข้อมูลให้ใช้คำสั่ง RENAME TABLE:

เปลี่ยนชื่อตาราง db1.tbl_name เป็น db2.tbl_name; หากคุณมีการสำรองข้อมูล“ สะอาด” ของไฟล์. ibd คุณสามารถกู้คืนไฟล์นั้นไปยังการติดตั้ง MySQL ซึ่งมีต้นกำเนิดดังนี้:

ตารางจะต้องไม่ถูกดร็อปหรือถูกตัดทิ้งเนื่องจากคุณคัดลอกไฟล์. ibd เนื่องจากการทำเช่นนั้นจะเปลี่ยน ID ตารางที่จัดเก็บไว้ใน tablespace

ออกคำสั่ง ALTER TABLE นี้เพื่อลบไฟล์. ibd ปัจจุบัน:

แก้ไขตาราง tbl_name TABLESPACE DISCARD; คัดลอกไฟล์. ibd สำรองไปยังไดเรกทอรีฐานข้อมูลที่เหมาะสม

ออกคำสั่ง ALTER TABLE นี้เพื่อบอกให้ InnoDB ใช้ไฟล์. ibd ใหม่สำหรับตาราง:

แก้ไขตาราง tbl_name นำเข้า TABLESPACE; ในบริบทนี้การสำรองข้อมูลไฟล์“ clean” .ibd เป็นสิ่งที่ตรงตามข้อกำหนดต่อไปนี้:

ไม่มีการแก้ไขที่ไม่มีข้อผูกมัดโดยธุรกรรมในไฟล์. ibd

ไม่มีรายการบัฟเฟอร์การแทรกที่ไม่ได้ถูกตัดทิ้งในไฟล์. ibd

Purge ได้ลบระเบียนดัชนีที่ทำเครื่องหมายการลบทั้งหมดออกจากไฟล์. ibd

mysqld ได้ล้างหน้าแก้ไขทั้งหมดของไฟล์. ibd จากบัฟเฟอร์พูลไปยังไฟล์

ให้คำเตือนและโปรโตคอลเหล่านี้นี่คือแนวทางปฏิบัติที่แนะนำ

สำหรับตัวอย่างนี้ลองกู้คืนtagsตารางไปยังmydbฐานข้อมูล

ขั้นตอนที่ 1

ตรวจสอบให้แน่ใจว่าคุณมีข้อมูลสำรองของไฟล์.frmและ.ibdไฟล์เหล่านั้น/tmp/innodb_data

ขั้นตอนที่ 2

ได้รับคำสั่งและดำเนินการเป็นCREATE TABLE tags CREATE TABLE mydb.tags ...ตรวจสอบให้แน่ใจว่ามันเป็นโครงสร้างเดียวกับของจริงtags.frm

ขั้นตอนที่ 3

ลบค่าว่างtags.ibdโดยใช้ MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

ขั้นตอนที่ # 4

นำสำเนาสำรองของ tags.ibd

cd /var/lib/mysql/mydb
cp /tmp/innodb_data.tags.ibd .
chown mysql:mysql tags.ibd

ขั้นตอนที่ # 5

เพิ่มtagsตารางลงในพจนานุกรมข้อมูล InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

ขั้นตอนที่ 6

ทดสอบการเข้าถึงของตาราง

SHOW CREATE TABLE mydb.tags\G
SELECT * FROM mydb.tags LIMIT 10;

หากคุณได้รับผลลัพธ์ปกติขอแสดงความยินดีที่คุณนำเข้าตาราง InnoDB

ขั้นตอนที่ 7

ในอนาคตโปรดอย่าลบ ibdata1 และบันทึกของมัน

ให้มันลอง !!!

ก่อนหน้านี้ฉันเคยพูดถึงเรื่องนี้

ข้อแม้

เกิดอะไรขึ้นถ้าคุณไม่ทราบว่าโครงสร้างของตารางของtags?

มีเครื่องมือสำหรับรับคำสั่ง CREATE TABLE เพียงแค่ใช้.frmไฟล์ ฉันเขียนโพสต์เกี่ยวกับเรื่องนี้ด้วย: จะแยกสคีมาจากไฟล์. frm ได้อย่างไร . ในโพสต์นั้นฉันคัดลอกไฟล์. frm ไปยังเครื่อง Windows จากกล่อง Linux เรียกใช้เครื่องมือ Windows และได้รับคำCREATE TABLEสั่ง


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

1
เมื่อผมทำงานสร้างฉันได้รับ: ข้อผิดพลาด 1813 (HY000): Tablespace สำหรับตาราง weblyize' tags'มีอยู่แล้ว กรุณาทิ้งพื้นที่ตารางก่อนที่จะนำเข้า ดังนั้นแล้วฉันพยายามที่จะเรียกใช้ตารางการเปลี่ยนแปลงครั้งแรกและได้รับข้อผิดพลาดนี้: ข้อผิดพลาด 1146 (42S02): Table 'weblyize.tags' ไม่มีอยู่ ฉันควรทำอย่างไร
ลงสนามของฉัน

ขอบคุณ! เพื่อแก้ไขข้อผิดพลาดของฉันฉันได้สร้างฐานข้อมูลใหม่CREATE TABLE ...แล้ววิ่งตามขั้นตอนของคุณ! คุณช่วยให้ฉันไม่ต้องเขียนใหม่ 100% ตั้งแต่ต้น! มันไม่ได้นำเข้ากุญแจต่างประเทศ แต่ก็ไม่เป็นไรฉันสามารถทำได้ด้วยตัวเอง! ขอบคุณอีกครั้ง!
ลงสนามของฉัน

ถ้าฉันมีตาราง 100 ตารางซึ่งควรแก้ไขด้วยวิธีนี้ ฉันจะไม่ดำเนินการสำหรับแต่ละตารางด้วยมือ มันจะเป็นไปโดยอัตโนมัติได้อย่างไร?
Oleg Abrazhaev

10

ฉันมีสถานการณ์เดียวกันไม่สามารถวางหรือสร้างชื่อเฉพาะได้ ขั้นตอนการแก้ไขของฉันคือ:

  1. หยุด MySQL

    service mysql stop
    
  2. ลบ ib_logfile0 และ ib_logfile1

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. ลบไฟล์ tblname คำเตือน: สิ่งนี้จะลบข้อมูลของคุณเป็นระยะ ๆ

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. เริ่ม MySQL

    service mysql start
    

1
ขอบคุณได้รับการแก้ไขปัญหาของฉันฉันไม่ได้ทำขั้นตอนที่ 3 ฉันเพียงแค่ลบ logfiles และเริ่ม mysql สำรอง
Jeff Wilbert

คุณยอดเยี่ยมจริงๆ! แก้ไขปัญหาของฉัน
Alex GP

2

ฉันมีปัญหานี้เช่นกัน ฉันลบibdata1โดยไม่ตั้งใจและข้อมูลทั้งหมดของฉันหายไป

หลังจากค้นหา 1-2 วันใน google และดังนั้นในที่สุดฉันก็พบโซลูชันที่ช่วยชีวิตฉันได้ (ฉันมีฐานข้อมูลและตารางจำนวนมากที่มีบันทึกจำนวนมาก)

  1. สำรองข้อมูลจาก /var/lib/mysql

  2. กู้คืนคีมาตารางจาก.frmไฟล์ด้วยdbsake (มีตัวเลือกอื่น! mysqlfrm . แต่มันไม่ได้ผลสำหรับฉัน)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. สร้างตารางใหม่ (พร้อมชื่อใหม่) ด้วยสคีมาที่ส่งออก

  2. ทิ้งข้อมูลตารางใหม่ด้วยคำสั่งนี้:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. คัดลอกข้อมูลของตารางเก่าและวางแทนการสร้างใหม่และตั้งค่าสิทธิ์ที่ถูกต้องสำหรับมัน
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. นำเข้าข้อมูลไปยังตารางใหม่
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. ไม่เป็นไร! เรามีข้อมูลในตารางใหม่และเราสามารถดรอปอันเก่าได้
DROP TABLE `tbl`;
  1. ตรวจสอบ/var/lib/mysql/database-nameและหากมีข้อมูล ( .ibdไฟล์) สำหรับตารางเก่าให้ลบออก
rm tbl.ibd
  1. และในที่สุดก็เปลี่ยนชื่อตารางใหม่เป็นชื่อเดิม
ALTER TABLE `tbl-new` RENAME `tbl`;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.