web-dev-qa-db-ja.com

「テーブルスペース境界外」のMySQLエラーを解決しようとしていますが、mysqldumpを使用してテーブルをリカバリすると失敗します

MySQLをWindows 2008サーバーで実行しています。テーブルの1つ(100万件を超えるレコード)が破損しているようです。 mysqlエラーログはこれを示します:

_InnoDB: Error: trying to access page number 197105 in space 89,
InnoDB: space name dbname/tablename,
InnoDB: which is outside the tablespace bounds.
InnoDB: Byte offset 0, len 16384, i/o type 10.
InnoDB: If you get this error at mysqld startup, please check that
InnoDB: your my.cnf matches the ibdata files that you have in the
InnoDB: MySQL server.
_

このエラーメッセージに基づいて、関連する行についてmy.cnfを確認しました。

_innodb_data_home_dir = "C:/xampp/mysql/data"
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = "C:/xampp/mysql/data"
_

これはまさにデータが存在する場所です。 ibdata1のサイズは約208 MB、tablename.ibdは約サイズは4 GB。私はこのサーバーを何ヶ月もうまく使ってきました。

このサイトや他の場所で検索した後、私は次のように回復を実行しようとしました:

  • _innodb_force_recovery=1_を設定し、次に_6_まで設定します。
  • 次に、mysqldumpで特定のテーブルをダンプします。私は次のコマンドを使用しています:_mysqldump dbname tablename --user=root --password=blahblah._このダンプ中に、リカバリレベル1から3の場合、mysqlがクラッシュします(「なくなる」)。 4で、最初の23992レコードをなんとかダンプしましたが、その後、

    行23992でテーブルtablenameをダンプするときにクエリ中にMySQLサーバーへの接続が失われました。

    ログには、上記で示した内容の前にいくつかの追加行があります。

    _InnoDB: Failed to find tablespace for table "dbname"."tablename" in the cache. Attempting to load the tablespace with space id 89. InnoDB: Error: trying to access page number 0 in space 89, InnoDB: space name dbname/tablename, InnoDB: which is outside the tablespace bounds._

  • Php、pythonまたはphpMyAdminのいずれかを介して、このテーブルをタッチまたは(選択)クエリするとすぐに、mysqlがクラッシュします。

誰かが他の提案をしていますか?おそらく上記のtablespace boundsエラーに基づいていますか?

前もって感謝します!

6
Erjen

エラーメッセージを詳しく説明しましょう

InnoDB:エラー:スペース89のページ番号197105にアクセスしようとすると、

InnoDBは、このエラーメッセージで.ibdファイルを「テーブルスペース」または単に「スペース」と呼びます。したがって、スペース89があり、そのページの1つが、存在しないページ番号197105を参照しています。エラーメッセージには、スペース89に対応するテーブルが示されていません。MySQLのバージョンによっては、 InnoDB辞書から。

mysql> select NAME from information_schema.INNODB_SYS_TABLESPACES WHERE SPACE=4304;
+----------------------+
| NAME                 |
+----------------------+
| sakila/film_category |
+----------------------+
1 row in set (0.01 sec)

ここで、どのテーブルが破損しているかがわかっているので、問題はそれを修正する方法です。 InnoDBは(MyISAMがREPAIR TABLEで行うように)テーブルスペースを修復しません。唯一の方法は、テーブルスペース(=テーブル)を削除して再作成することです。

この特定のケースでは、MySQLをinnodb_force_recoveryモードで起動する必要はありません。通常どおり起動して、テーブルをドロップします。ただし、最初に、おそらくこのテーブルにデータを保存する必要があります。

2つの方法があります。最初に、破損していない主キー値の範囲を選択し、それらを別のテーブルまたはテキストダンプにダンプできます。私はこのような回復ケースがあり、 それを行うためのスクリプト と書きました。スクリプトはPK範囲を反復処理し、できるだけ多くのレコードを別の(MyISAM)テーブルにダンプします。

2番目の方法は、より多くの時間とスキルが必要です。ツール( https://github.com/twindb/undrop-for-innodb )とブログ投稿 https://twindb.com/recover-corrupt-mysqlが必要です。 -database / ステップ付き。

次に、破損したテーブルを削除し、空のテーブルを作成して、リカバリされたダンプをロードします。

1
akuzminsky