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 を有効にするコード

推薦する

PSSHを使用してLinuxサーバーを一括管理する

pssh は、多数のマシンでのバッチ ssh 操作に使用される、Python で実装されたオープン ...

雨滴効果を実現する JavaScript キャンバス

この記事の例では、雨滴効果を実現するためのキャンバスの具体的なコードを参考までに共有しています。具体...

Dockerイメージの作成とプロジェクト全体のワンクリックパッケージングとデプロイ

一般的な Dockerfile 命令の紹介命令説明するから新しいイメージが構築される基となるイメージ...

mysql indexof関数の使用手順

以下のように表示されます。 LOCATE(部分文字列、文字列)文字列 str 内の部分文字列 sub...

MySQL で複数のテーブルにビューを作成する方法

MySQLでは、2つ以上のベーステーブルにビューを作成します。学生テーブルとstu_infoテーブル...

MySQL 5.7.21 解凍版のインストールと設定方法のグラフィックチュートリアル

私は頻繁にシステムをインストールするので、インストールのたびにいくつかのソフトウェアを再インストール...

Vueフィルターとカスタム命令の使用

目次フィルター01.とは02. やり方(1)フィルターを定義する(2)使用方法(3)フィルタパラメー...

Node.js で MySQL データベースにバッチデータを挿入する方法

プロジェクト(nodejs)では、一度に複数のデータをデータベースに挿入する必要があります。データベ...

Ubuntuのバックアップ方法(4種類)のまとめ

方法1:リスピンを使用するには、次の手順に従ってください。 sudo add-apt-reposit...

Node.js コード実行をバイパスするためのヒントのまとめ

目次1. 子プロセス2. nodejsでのコマンド実行2.1 16進数エンコード2.2 ユニコードエ...

ウェブページの画像の回転を実現するjs

この記事では、Webページの画像の回転を実現するためのjsの具体的なコードを参考までに共有します。具...

JavaScript はクラス宝くじアプレットを実装します

この記事では、クラス抽選アプレットを実装するためのJavaScriptの具体的なコードを参考までに紹...

win10 での mysql5.7.21 の詳細なインストール手順

この記事では、MySQL 5.7.21のインストールとインストール中に発生した問題を参考までに紹介し...

nginxディレクトリパスをリダイレクトする方法

ドメイン名に続くパスがデフォルトの Web ディレクトリではなく、ローカル ディスク上の他のディレク...

Mysql5.7 以降での ONLY_FULL_GROUP_BY エラーの解決方法

最近、開発プロセス中に、プロジェクト開発環境に接続されている MySQL データベースは Aliba...