MySQL InnoDBはテーブルを失いましたが、ファイルは存在します


33

すべてのデータベーステーブルファイルを持つMySQL InnoDBがありますが、MySQLはそれらを認識せず、ロードしません。

この問題は、次の3つのファイルを削除したために発生しました:ibdata1ib_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がこれらのファイルを表示できない理由は次のとおりです。システムテーブルスペース(ibdata1)には、InnoDBが潜在的なテーブル使用をマッピングできるStorage-Engine固有のデータディクショナリがあります。

InnoDBアーキテクチャ

InnoDBテーブルをある場所から別の場所に移動するには、次のようなコマンドが必要です

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

ここにの一部です 考慮する必要があるものを説明するMySQL 5.5ドキュメントの

.ibdファイルの移植性に関する考慮事項

MyISAMテーブルファイルのように、データベースディレクトリ間で.ibdファイルを自由に移動することはできません。InnoDB共有テーブルスペースに保存されているテーブル定義には、データベース名が含まれています。テーブルスペースファイルに格納されているトランザクションIDとログシーケンス番号も、データベースによって異なります。

.ibdファイルと関連付けられたテーブルをあるデータベースから別のデータベースに移動するには、RENAME TABLEステートメントを使用します。

RENAME TABLE db1.tbl_name TO db2.tbl_name; .ibdファイルの「クリーンな」バックアップがある場合、次のように、元のMySQLインストールに復元できます。

.ibdファイルをコピーしてからテーブルを削除または切り捨ててはなりません。コピーすると、テーブルスペース内に格納されているテーブルIDが変更されるためです。

次のALTER TABLEステートメントを発行して、現在の.ibdファイルを削除します。

ALTER TABLE tbl_name DISCARD TABLESPACE; バックアップ.ibdファイルを適切なデータベースディレクトリにコピーします。

次のALTER TABLEステートメントを発行して、テーブルに新しい.ibdファイルを使用するようInnoDBに指示します。

ALTER TABLE tbl_name IMPORT TABLESPACE; このコンテキストでは、「クリーン」な.ibdファイルバックアップは、次の要件が満たされているバックアップです。

.ibdファイルには、トランザクションによるコミットされていない変更はありません。

.ibdファイルには、マージされていない挿入バッファエントリはありません。

削除は、すべての削除マークされたインデックスレコードを.ibdファイルから削除しました。

mysqldは、.ibdファイルの変更されたすべてのページをバッファープールからファイルにフラッシュしました。

これらの警告とプロトコルを考えると、ここに推奨される一連のアクションがあります

この例では、tagsテーブルをmydbデータベースに復元してみましょう

ステップ1

それらのバックアップがあることを確認し.frm.ibdファイルファイルの/tmp/innodb_data

ステップ2

CREATE TABLE tagsステートメントを取得し、として実行しますCREATE TABLE mydb.tags ...。元の構造とまったく同じ構造であることを確認してくださいtags.frm

ステップ3

tags.ibdMySQLを使用して空を削除します

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

tagsInnoDBデータディクショナリにテーブルを追加する

ALTER TABLE mydb.tags IMPORT TABLESPACE;

ステップ6

テーブルのアクセシビリティをテストする

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

正常な結果が得られたら、InnoDBテーブルをインポートしておめでとうございます。

ステップ7

将来的には、ibdata1とそのログを削除しないでください。

試してみる !!!

私は以前にこのようなことを議論しました

警告

テーブル構造がわからない場合 tagsか?

.frmファイルを使用するだけでCREATE TABLEステートメントを取得するツールがあります。私もこれについての記事を書きました:.frmファイルだけからテーブルスキーマを抽出するにはどうすればよいですか?。その投稿では、Linuxボックスから.frmファイルをWindowsマシンにコピーし、Windowsツールを実行してCREATE TABLEステートメントを取得しました。


素晴らしい回答をありがとう!私はまだ1つのテーブルをインポートするプロセスに取り組んでいます。なぜなら、私は問題を作成し続けているからです。ありがとう!
私の芝生を

1
作成を実行すると、「エラー1813(HY000):テーブルのテーブルスペース」というメッセージが表示されますweblyizetags'存在します。IMPORTの前に表領域を破棄してください。そのため、最初にalter tablespaceを実行し、次のエラーを取得しようとします:エラー1146(42S02):テーブル 'weblyize.tags'は存在しません。私に何ができる?
芝生

ありがとう!私のエラーを修正するために、私は新しいデータベースを作成し、実行してCREATE TABLE ...からあなたの手順に従った!あなたはそれらを最初から100%書き直さなくてすむようになりました!それは外部キーをインポートしませんでしたが、私はそれを自分で行うことができます!再びありがとう!
私の芝生

この方法で修正する必要がある100個のテーブルがある場合はどうなりますか。各テーブルの操作を手作業で行うことはありません。どのように自動化できますか?
オレグアブラーザエフ

10

同じ状況があります。特定のtblnameをドロップまたは作成できません。私の修正手順は次のとおりです。

  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を実行しませんでした。単にログファイルを削除し、mysqlのバックアップを開始しました。
ジェフウィルバート

あなたは絶対に素晴らしいです!私の問題を解決しました。
アレックスGP

2

私もこの問題を抱えていました。ibdata1誤って削除したため、データがすべて失われました。

グーグルとSOで1〜2日検索した後、最終的に私はそれが私の命を救う解決策を見つけました(私は膨大な記録を持つ非常に多くのデータベースとテーブルを持っていました)。

  1. からバックアップを取る /var/lib/mysql

  2. dbsake.frm使用してファイルからテーブルスキーマを回復します(別のオプションがありました!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.