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エラーに基づいていますか?
前もって感謝します!
エラーメッセージを詳しく説明しましょう
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 / ステップ付き。
次に、破損したテーブルを削除し、空のテーブルを作成して、リカバリされたダンプをロードします。