MySQL InnoDB kehilangan tabel tetapi file ada

33

Saya memiliki InnoDB MySQL yang memiliki semua file tabel database, tetapi MySQL tidak melihatnya, dan tidak memuatnya.

Masalahnya terjadi karena saya dihapus tiga file: ibdata1, ib_logfile0danib_logfile1

karena saya mengalami masalah dengan mysql memulai, dan apa yang saya baca adalah menghapusnya karena MySQL hanya akan memperbaruinya (saya tahu saya harus membuat cadangan tetapi tidak melakukannya).

Apa yang bisa saya lakukan untuk membuat MySQL melihat tabel lagi?

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
Lepaskan Rumput Saya
sumber
Sudahkah Anda mencoba mengembalikan file-file itu? File log dapat tetap dihapus. Anda benar-benar tidak boleh menghapus ibdata1
Ramhound
Saya telah menyalin file dari versi mysql lama tempat file itu berada tetapi tabel tidak muncul.
Turun Lawn saya

Jawaban:

36

Inilah mengapa MySQL tidak dapat melihat file-file itu: tablespace sistem (ibdata1) memiliki kamus data spesifik Storage-Engine yang memungkinkan InnoDB memetakan potensi penggunaan tabel:

Arsitektur InnoDB

Memindahkan tabel InnoDB dari satu tempat ke tempat lain membutuhkan perintah seperti

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

Berikut adalah bagian dari Dokumentasi MySQL 5.5 yang menjelaskan apa yang perlu dipertimbangkan

Pertimbangan Portabilitas untuk File .ibd

Anda tidak dapat dengan bebas memindahkan file .ibd di antara direktori database seperti yang Anda bisa dengan file tabel MyISAM. Definisi tabel yang disimpan dalam tablespace bersama InnoDB termasuk nama database. ID transaksi dan nomor urutan log yang disimpan dalam file tablespace juga berbeda di antara basis data.

Untuk memindahkan file .ibd dan tabel terkait dari satu database ke yang lain, gunakan pernyataan RENAME TABLE:

RENAME TABLE db1.tbl_name TO db2.tbl_name; Jika Anda memiliki cadangan "bersih" dari file .ibd, Anda dapat mengembalikannya ke instalasi MySQL dari mana asalnya sebagai berikut:

Tabel tidak boleh jatuh atau terpotong sejak Anda menyalin file .ibd, karena hal itu mengubah ID tabel yang disimpan di dalam tablespace.

Terbitkan pernyataan ALTER TABLE ini untuk menghapus file .ibd saat ini:

ALTER TABLE tbl_name DISCARD TABLESPACE; Salin file .ibd cadangan ke direktori database yang tepat.

Berikan pernyataan ALTER TABLE ini untuk memberi tahu InnoDB agar menggunakan file .ibd baru untuk tabel:

ALTER TABLE tbl_name IMPORT TABLESPACE; Dalam konteks ini, cadangan file .ibd "clean" adalah salah satu yang memenuhi persyaratan berikut:

Tidak ada modifikasi tanpa komitmen oleh transaksi dalam file .ibd.

Tidak ada entri buffer penyisipan yang tidak dihapus dalam file .ibd.

Purge telah menghapus semua catatan indeks yang ditandai dari file .ibd.

mysqld telah mem-flush semua halaman yang dimodifikasi dari file .ibd dari kumpulan buffer ke file.

Dengan adanya peringatan dan protokol ini, berikut adalah tindakan yang disarankan

Untuk contoh ini, mari kita coba mengembalikan tagstabel ke mydbdatabase

LANGKAH 1

Pastikan Anda memiliki cadangannya .frmdan .ibdfile di dalamnya/tmp/innodb_data

LANGKAH 2

Dapatkan CREATE TABLE tagspernyataan itu dan jalankan sebagai CREATE TABLE mydb.tags .... Pastikan strukturnya sama persis seperti aslinyatags.frm

LANGKAH # 3

Hapus yang kosong tags.ibdmenggunakan MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

LANGKAH # 4

Bawa salinan cadangan tags.ibd

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

LANGKAH # 5

Tambahkan tagstabel ke Kamus Data InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

LANGKAH 6

Uji aksesibilitas tabel

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

Jika Anda mendapatkan hasil yang normal, selamat Anda mengimpor tabel InnoDB.

LANGKAH 7

Di masa depan, tolong jangan hapus ibdata1 dan log-nya

Cobalah !!!

Saya sudah membahas hal-hal seperti ini sebelumnya

CAVEAT

Bagaimana jika Anda tidak tahu struktur tabel tags?

Ada alat untuk mendapatkan pernyataan CREATE TABLE hanya dengan menggunakan .frmfile. Saya menulis posting tentang ini juga: Bagaimana cara mengekstrak skema tabel hanya dari file .frm? . Dalam posting itu, saya menyalin file .frm ke mesin Windows dari kotak Linux, menjalankan alat Windows dan mendapatkan CREATE TABLEpernyataan.

RolandoMySQLDBA
sumber
Terima kasih atas Jawabannya yang luar biasa! Saya masih dalam proses mendapatkan satu meja yang diimpor, karena saya terus menciptakan masalah, tetapi saya akan sampai di sana pada akhirnya, dan saya akan memberi tahu Anda cara kerjanya! Terima kasih!
Turun Lawn saya
1
Ketika saya menjalankan buat saya mendapatkan: ERROR 1813 (HY000): Tablespace for table ' weblyize. tags'ada. Harap LAYAR tablespace sebelum IMPOR. Jadi saya mencoba menjalankan alter tablespace terlebih dahulu, dan mendapatkan kesalahan ini: ERROR 1146 (42S02): Tabel 'weblyize.tags' tidak ada . Apa yang dapat saya?
Turunkan Lawn Saya
Terima kasih! Untuk memperbaiki kesalahan saya, saya membuat database baru, jalankan CREATE TABLE ...kemudian ikuti langkah-langkah Anda! Anda menyelamatkan saya dari keharusan menulis ulang mereka 100% dari awal! Itu tidak mengimpor kunci asing tetapi tidak apa-apa saya bisa melakukannya sendiri! Sekali lagi terima kasih!
Turunkan Lawn Saya
Bagaimana jika saya memiliki 100 tabel yang harus diperbaiki dengan cara ini. Saya tidak akan melakukan operasi untuk setiap tabel dengan tangan. Bagaimana bisa otomatis?
Oleg Abrazhaev
10

Saya memiliki situasi yang sama, Tidak dapat menjatuhkan atau membuat tblname tertentu. Prosedur perbaikan saya adalah:

  1. Hentikan MySQL.

    service mysql stop
    
  2. Hapus ib_logfile0 dan ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Hapus file tblname. PERINGATAN: INI AKAN SEGERA HAPUS DATA ANDA

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Mulai MySQL.

    service mysql start
    
pengguna293871
sumber
1
Terima kasih sudah memperbaiki masalah saya, saya tidak melakukan langkah 3, saya hanya menghapus file log dan mulai mysql kembali.
Jeff Wilbert
Anda benar-benar fantastis! Memecahkan masalah saya.
Alex GP
2

Saya punya masalah ini juga. Saya menghapus ibdata1secara tidak sengaja dan semua data saya hilang.

Setelah pencarian 1-2 hari di google dan SO, akhirnya saya menemukan solusi yang menyelamatkan hidup saya (saya punya begitu banyak database dan tabel dengan catatan besar).

  1. ambil cadangan dari /var/lib/mysql

  2. pulihkan skema tabel dari .frmfile dengan dbsake (ada pilihan lain! mysqlfrm . tapi tidak berhasil untuk saya)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. buat tabel baru (dengan nama baru) dengan skema yang diekspor.

  2. Buang data tabel baru dengan perintah ini:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. salin data tabel lama dan tempel bukan yang baru dan atur izin yang tepat untuknya
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
  1. impor data ke tabel baru.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. baik! kami memiliki data di tabel baru dan kami bisa menjatuhkan yang lama.
DROP TABLE `tbl`;
  1. periksa /var/lib/mysql/database-namedan apakah ada data ( .ibdfile) untuk tabel lama, hapus itu.
rm tbl.ibd
  1. dan akhirnya mengubah nama tabel baru menjadi nama asli
ALTER TABLE `tbl-new` RENAME `tbl`;
mostafaznv
sumber