MySQLはテーブルデータを復元するためにfrmファイルとibdファイルを使用します

MySQLはテーブルデータを復元するためにfrmファイルとibdファイルを使用します

frm ファイルと ibd ファイルの紹介

MySQL では、デフォルトのストレージ エンジン innodb を使用してテーブルを作成すると、フォルダーに table name.frm と table name.ibd の 2 つのファイルが表示されます。Myisam ストレージ エンジンを使用すると、3 つのファイルが表示されます。次に例を示します。

[root@ /data/yeyz]#ll
合計 580
-rw-rw---- 1 mysql mysql 8586 4月3日 17:44 a.frm
-rw-rw---- 1 mysql mysql 0 4月3日 17:44 a.MYD
-rw-rw---- 1 mysql mysql 1024 4月3日 17:44 a.MYI
-rw-rw---- 1 mysql mysql 8586 4月3日 17:44 b.frm
-rw-rw---- 1 mysql mysql 98304 4月3日 17:45 b.ibd
-rw-rw---- 1 mysql mysql 61 11月 23 09:54 db.opt
-rw-rw---- 1 mysql mysql 8556 4月29日 21:37 tbl_test_2.frm
-rw-rw---- 1 mysql mysql 98304 4月29日 21:37 tbl_test_2.ibd
-rw-rw---- 1 mysql mysql 8556 4月29日 21:33 tbl_test.frm
-rw-rw---- 1 mysql mysql 98304 4月29日 21:33 tbl_test.ibd
-rw-rw---- 1 mysql mysql 8614 4月29日 21:40 test.frm
-rw-rw---- 1 mysql mysql 98304 4月29日 21:43 test.ibd
-rw-rw---- 1 mysql mysql 8666 4月2日 15:13 unstandard_ins.frm
-rw-rw---- 1 mysql mysql 98304 4月3日 11:46 unstandard_ins.ibd
-rw-rw---- 1 mysql mysql 8586 4月3日 17:44 yeyz.frm
-rw-rw---- 1 mysql mysql 28 4月 3 17:44 yeyz.MYD
-rw-rw---- 1 mysql mysql 2048 4月 3日 17:44 yeyz.MYI

このうち、ibd ファイルは innodb テーブルのデータ ファイルであり、frm ファイルは innodb テーブルの構造ファイルです。mysiam ストレージ エンジンのテーブルでは、frm はテーブル構造、MYI ファイルはインデックス ファイル、MYD ファイルはデータ ファイルです。ここでも、innodb ストレージ エンジンのインデックスとデータは一緒になっているのに対し、Myisam ストレージ エンジンのインデックスとデータは別々になっていることがわかります。

frm ファイルも ibd ファイルも直接開くことはできないことに注意してください。

データベースでテーブル内のデータを迅速に回復する必要があるという要件を考えてみましょう。ただし、テーブルが配置されているデータベースには大量のデータがあり、回復に長い時間がかかる可能性があります。したがって、完全なデータベース回復は間違いなく最適なオプションではありません。では、このような状況では私たちは何をすべきでしょうか? frm ファイルと ibd ファイルを使用してデータを回復できます。以下でこのプロセスを分析してみましょう。

frm ファイル回復テーブル構造

もちろん、テーブル構造は frm ファイルを使用して復元する必要があります。私たちの最初の反応は、これらの 2 つのファイルを新しいデータベース インスタンスに直接コピーし、インスタンスを直接起動できるというものでした。これは可能ですか?もちろん違います。もし私の甥がそれをできるなら、DBA は全員解雇されるでしょうね。ハハハ、では早速操作手順を見てみましょう。

まず、データ復元専用のインスタンスを新規作成します。オンラインマシンを使用してリカバリを実行すると、データベースの再起動や DML ブロックのリスクを負わなければならないため、リカバリ専用のインスタンスを使用するのが最善の方法です。では、frm ファイルから必要なテーブル構造を取得するにはどうすればよいでしょうか?

オンラインスローログテーブルを例に挙げてみましょう。書きやすいように、テーブル名を「aaa」と書きました。このテーブルの構造は次のとおりです。

mysql--root@localhost:test_recover 12:08:43>>テーブル aaa\G の作成を表示
************************** 1. 行 ****************************
  表: aaa
テーブルの作成: CREATE TABLE `aaa` (
 `maintain_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分列',
 `slowquery_filename` varchar(50) DEFAULT NULL COMMENT 'スローログファイル名',
 `slowquery_path` varchar(150) DEFAULT NULL COMMENT 'スローログのフルパス',
 `slowquery_process` tinyint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'スローログが解析されるかどうか',
 `slowquery_uploadtime` 日時 DEFAULT CURRENT_TIMESTAMP、
 `slowquery_analyzetime` 日付 デフォルト NULL コメント 'スローログ分析時間',
 `slowquery_starttime` 日付 デフォルト NULL、
 `slowquery_endtime` 日付 デフォルト NULL、
 `instance_ip` varchar(15) DEFAULT NULL COMMENT 'スローログIPアドレス',
 `instance_port` int(11) DEFAULT NULL COMMENT 'スローログポート番号アドレス',
 主キー (`maintain_id`)
) エンジン=InnoDB デフォルト文字セット=utf8
セットに 1 行、警告 1 回 (0.01 秒)

frm ファイルからこのようなテーブルを取得するには、次の手順を実行する必要があります。

1. インスタンスにaaaと同じ名前のテーブルを作成します。このテーブルの構造は不明なので、フィールドIDを1つだけ持つように設定できます。

テーブル aaa (id int) を作成します。

この時点で、対応するデータ ディレクトリに新しい aaa.frm ファイルと aaa.ibd ファイルが生成されることがわかります。次に、バックアップされた aaa.frm を使用して以前の aaa.frm を置き換え、データベースを再起動します。

はい、その通りです。バックアップ テーブル構造ファイルを使用して、生成されたテーブル構造ファイルを置き換えます。

2. 再起動後のエラー ログ出力を次のように確認します。

2019-03-22T03:17:28.652390Z 16 
[警告] InnoDB: テーブル test_recover/store_goods_price に 1 人のユーザーが含まれています 
InnoDBでは列が定義されていますが、MySQLでは12列です。 
問題を解決する方法については、INFORMATION_SCHEMA.INNODB_SYS_COLUMNS および http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html を参照してください。
2019-04-02T07:56:31.558461Z 41 
[警告] InnoDB: テーブル test_recover/dv_control には 1 つのユーザー定義が含まれています 
InnoDBでは14列ですが、MySQLでは14列です。
 問題を解決する方法については、INFORMATION_SCHEMA.INNODB_SYS_COLUMNS および http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html を参照してください。
2019-05-23T03:14:10.161122Z 92 
[警告] InnoDB: テーブル test_recover/aaa には 1 が含まれています 
InnoDBではユーザー定義の列がありますが、MySQLでは10列です。ご確認ください 
問題を解決する方法については、INFORMATION_SCHEMA.INNODB_SYS_COLUMNS および http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html を参照してください。

ご覧のとおり、10 行目から 12 行目のエラー ログには、テーブル aaa にはフィールドが 1 つしか含まれていないのに対し、frm にはフィールドが 10 個含まれており、フィールド数が一致していないことが示されています。

これは予想された結果と一致しています。テーブル aaa を作成したときに、フィールド ID を 1 つだけ指定しましたが、復元する aaa テーブルには 10 個のフィールドがあり、frm から読み取ることができないためです。この時点で、この aaa テーブルのフィールドを 10 に調整すると、最終結果はどうなるかを簡単に想像できるでしょう。

3. aaa テーブルのフィールド数を 10 に更新し、frm ファイルを再コピーして、構成ファイルのパラメータ innodb_force_recovery=6 を変更します。最終結果を見てみましょう。

mysql--root:(なし) 12:04:20>>test_recoverを使用します。
データベースが変更されました
mysql--root:test_recover 12:04:25>>テーブルaaa(id1 int、id2 int、id3 int、id4 int、id5 int、id6 int、id7 int、id8 int、id9 int、id10 int)を作成します。
クエリは正常、影響を受けた行は 0 行 (0.03 秒)

mysql--root@localhost:test_recover 12:05:08>>テーブル aaa\G の作成を表示
************************** 1. 行 ****************************
  表: aaa
テーブルの作成: CREATE TABLE `aaa` (
 `id1` int(11) デフォルト NULL,
 `id2` int(11) デフォルト NULL,
 `id3` int(11) デフォルト NULL,
 `id4` int(11) デフォルト NULL,
 `id5` int(11) デフォルト NULL,
 `id6` int(11) デフォルト NULL,
 `id7` int(11) デフォルト NULL,
 `id8` int(11) デフォルト NULL,
 `id9` int(11) デフォルト NULL,
 `id10` int(11) デフォルト NULL
) エンジン=InnoDB デフォルト文字セット=utf8
セット内の 1 行 (0.00 秒)

次に、インスタンスを再起動してテーブル aaa を再度確認すると、次の結果が表示されます。

mysql--root:test_recover 12:08:43>>テーブル aaa\G の作成を表示
************************** 1. 行 ****************************
  表: aaa
テーブルの作成: CREATE TABLE `aaa` (
 `maintain_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自動増分列',
 `slowquery_filename` varchar(50) DEFAULT NULL COMMENT 'スローログファイル名',
 `slowquery_path` varchar(150) DEFAULT NULL COMMENT 'スローログのフルパス',
 `slowquery_process` tinyint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'スローログが解析されるかどうか',
 `slowquery_uploadtime` 日時 DEFAULT CURRENT_TIMESTAMP、
 `slowquery_analyzetime` 日付 デフォルト NULL コメント 'スローログ分析時間',
 `slowquery_starttime` 日付 デフォルト NULL、
 `slowquery_endtime` 日付 デフォルト NULL、
 `instance_ip` varchar(15) DEFAULT NULL COMMENT 'スローログIPアドレス',
 `instance_port` int(11) DEFAULT NULL COMMENT 'スローログポート番号アドレス',
 主キー (`maintain_id`)
) エンジン=InnoDB デフォルト文字セット=utf8
セットに 1 行、警告 1 回 (0.01 秒)

必要なテーブル構造が frm ファイルから復元されていることがわかります。このプロセスでは ibd ファイルを使用していないことに注意してください。

frm ファイルを使用してテーブル構造を復元する手順をまとめます。

1. まず同じ名前のテーブルを作成し、インスタンスを起動します

2. バックアップしたfrmファイルを使用して生成されたfrmファイルを置き換え、インスタンスを再起動します。

3. エラーログを確認し、エラーログからバックアップされたfrmファイル内のフィールド数mを取得します。

4. 同じ名前でテーブルを再作成し、フィールド数がmでバックアップテーブルと一致していることを確認し、バックアップfrmファイルを対応するディレクトリに再コピーします。

5. インスタンス構成ファイルでパラメータ innodb_force_recovery=6 を変更し、データベースを再起動します。対応するテーブル構造作成ステートメントが表示されます。これを保存し、次の手順でデータを復元するときに使用します。このステップは非常に重要である

6. パラメータ innodb_force_recovery=6 をコメントアウトし、デフォルト値を再度使用して、データベースを再起動し、テーブル データを回復する準備をします。

この時点で、テーブル構造が復元されました。

innodb_force_recovery パラメータについて説明します。このパラメータの最大値は 6 です。このレベルでは、一部のクエリ関数のみがサポートされ、DML はサポートされません。名前が示すように、このパラメータは一部の強制リカバリ シナリオで使用されます。一般に、このパラメータは省略でき、デフォルト値を使用できます。さらに詳しく知りたい学生は、公式ドキュメントを参照してください。

ibd ファイル回復テーブルデータ

前の手順が完了すると、対応するテーブル構造が取得されます。次に、テーブル データを復元する方法を見てみましょう。

テーブル データを復元する方法は比較的簡単で、一般的な手順は次のとおりです。

1. 前の手順で取得したテーブル作成ステートメントを使用してテーブルを再作成し、次を実行します。

エクスポート用にテーブル aaa をフラッシュします。

この構文は、テーブル内のデータをディスクに書き込み、その後のリカバリに備えてテーブルのロックを取得するために使用されます。

2. 次に、次のステートメントを使用します。

テーブル aaa を変更してテーブルスペースを破棄します。

このステートメントは現在の ibd ファイルを削除します。

3. 次に、先ほどバックアップしたibdファイルを使用して、対応するインスタンスディレクトリにコピーします。

4. 最後に、ibd ファイルをリロードし、次のステートメントを使用します。

テーブル aaa を変更してテーブルスペースをインポートします。

データベースを再起動すると、データが正常に復元されます。

概要

リカバリプロセス全体が紹介されました。より巧妙な部分は、frm ファイルからテーブル構造情報を取得することです。テーブル作成ステートメントを 2 回組み合わせる方法を使用し、最終的にリカバリするテーブルのテーブル構造を取得し、alter table discard tablespace および alter table import tablespace メソッドを使用してテーブル内のデータをリカバリしました。全体のプロセスは複雑に見えますが、実際には、手順に応じてスクリプトを抽象化できます。このようにして、次回復元するときに、復元するテーブルの名前を入力するだけで、テーブル構造とデータをすばやく復元できます。これは、緊急のデータ復旧計画と見なすことができます。

上記は、MySQL が frm ファイルと ibd ファイルを使用してテーブル データを回復する方法の詳細です。MySQL テーブル データ回復の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL 全体または単一のテーブルデータのエクスポート
  • MySQLデータベースが予期せずクラッシュし、テーブルデータファイルが破損して起動できなくなる問題を解決します。
  • MySQLでデータを削除してもディスク領域が解放されないのはなぜですか
  • Ubuntu でディスク容量不足により MySQL が起動しない場合の解決策
  • MySQL ストレージ エンジン MyISAM の一般的な問題 (テーブル破損、アクセス不能、ディスク容量不足)
  • lnmp でディスク領域を保護するために MySQL ログをオフにする方法
  • ディスク容量を節約するためにMySQLを縮小するためのいくつかの提案
  • Mysql InnoDB のデータを削除した後にディスク領域を解放する方法
  • MySQL でテーブル データを削除した後もディスク領域がまだ占有されているのはなぜですか?

<<:  VUEの基本を理解するのに役立つ記事

>>:  IE7 互換モードで IE8 を有効にするコード

推薦する

Vueはスライダードラッグ検証機能の全プロセスを実現します

レンダリング 骨組みを定義し、HTMLとCSSを記述するHTML部分 <テンプレート> ...

MySQL コマンドラインでよく使われる 18 個のコマンド

日常的なウェブサイトの保守と管理では、多くの SQL ステートメントが使用されます。熟練して使用する...

Docker execは複数のコマンドを実行します

docker exec コマンドは、実行中のコンテナ内でコマンドを実行できます。 docker ex...

MySQL でよく使用されるデータベースとテーブル シャーディング ソリューションの概要

目次1. データベースのボトルネック2. サブライブラリとサブテーブル2. 横長テーブル3. 垂直サ...

JSのアンカーリンクをクリックするとスムーズにスクロールし、自由にトップ位置に調整できます。

アンカーリンクをクリックするとスムーズにスクロールし、自由にトップ位置に調整できます。 1. アンカ...

Linux CentOS 6.5 のアンインストール、tar、および MySQL のインストールチュートリアル

システム提供のMySQLをアンインストールする1. MySQLがシステムにインストールされているかど...

HTML_PowerNode Java アカデミーでテーブルを動的に追加する

さっそく、コードを直接投稿します。具体的なコードは次のとおりです。 <html> <...

MySQL 5.7.20 zip インストール チュートリアル

MySQL 5.7.20 zipインストール、具体的な内容は次のとおりです(1)圧縮パッケージを解凍...

LayUI+Shiroは動的なメニューを実装し、メニュー拡張の例を記憶します

目次1. Maven 依存関係2. メニュー関連クラス1. メインメニュー2. サブメニュー3. S...

MySQLでデータベースデータ保存ディレクトリを変更する方法

序文MySQL データベースのデフォルトのデータベース ファイルは /var/lib/mysql に...

完全なMySQL学習ノート

目次MyISAM と InnoDBパフォーマンスの低下と SQL の速度低下の理由: MySQL 実...

CSS3 でクールなスライス画像カルーセル効果を実現

今日は、CSS を使用してクールな画像カルーセル コンポーネントを作成する方法を学びます。その原理は...

nginxプロキシsocket.ioサービスの落とし穴の詳細な説明

目次Nginx は 2 つの socket.io サーバーをプロキシします。 socket.ioの動...

mysql ルートユーザーを認証できず、Navicat リモート認証プロンプト 1044 の問題を解決します

まず解決策を見てみましょう #------------mysql の root ユーザーに権限を付与...

よくある MySQL テーブル設計エラーの概要

目次間違い1: データの列が多すぎる誤解2: 共同クエリが多すぎる誤解3: ENUMの代わりにSET...