InnoDBがすべてのデータベースを1つのファイルに保存するのはなぜですか?


51

MyISAMを使用して各テーブルを対応するファイルに保存すると便利でした。InnoDBは多くの面で進歩を遂げましたが、なぜInnoDBがすべてのデータベースを1つのファイルに保存するのか疑問に思います(ibdata1デフォルト)。

InnoDBがテーブルの個々のインデックスファイルによってファイル内のデータの場所をマップすることは理解していますが、1つのファイルにすべてのデータが混在する理由はわかりません。さらに重要なのは、なぜサーバー上のすべてのデータベースのデータを混合するのですか?

MyISAMの興味深い機能は、データベースフォルダーを別のマシンにコピー/貼り付けしてから、データベースを(ダンプなしで)使用できることです。

回答:


66

InnoDBのアーキテクチャでは、4つの基本的な種類の情報ページを使用する必要があります

  • テーブルデータページ
  • テーブルインデックスページ
  • テーブルメタデータ
  • MVCCデータ(トランザクション分離と ACIDコンプライアンスをサポートするため)
    • ロールバックセグメント
    • スペースを元に戻す
    • ダブルライトバッファー(OSキャッシュへの依存を防ぐためのバックグラウンド書き込み)
    • バッファーの挿入(一意でないセカンダリインデックスへの変更の管理)

ibdata1の図解をご覧ください

デフォルトでは、もしinnodb_file_per_tableが無効になっています。これにより、4つの情報ページタイプすべてがibdata1という単一のファイルを取得します。多くの人々は、複数のibdataファイルを作成してデータを分散させようとします。これは、データおよびインデックスページの断片化につながる可能性があります。

これが、デフォルトのibdata1ファイルのみを使用してInnoDBインフラストラクチャをクリーンアップすることをよく推奨する理由です

InnoDBが機能するインフラストラクチャのため、コピーは非常に危険です。2つの基本的なインフラストラクチャがあります

  • innodb_file_per_tableは無効です
  • innodb_file_per_tableが有効になっています

InnoDB(innodb_file_per_tableが無効)

ではinnodb_file_per_tableを無効にすると、InnoDBの情報のすべてのこれらのタイプは、ibdata1と内に住んでいます。ibdata1以外のInnoDBテーブルの唯一の症状は、InnoDBテーブルの.frmファイルです。すべてのInnoDBデータを一度にコピーするには、/ var / lib / mysqlをすべてコピーする必要があります。

個々のInnoDBテーブルをコピーすることはまったく不可能です。テーブルのダンプをデータとそれに対応するインデックス定義の論理表現として抽出するには、MySQLダンプする必要があります。次に、そのダンプを同じサーバーまたは別のサーバー上の別のデータベースにロードします。

InnoDB(innodb_file_per_table有効)

ではもしinnodb_file_per_tableが有効になって、テーブルのデータとそのインデックスは次の.frmファイルにデータベースフォルダに住んでいます。たとえば、テーブルdb1.mytableの場合、ibdata1以外のInnoDBテーブルのマニフェストは次のようになります。

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

システム表領域 ibdata1

db1.mytableのすべてのメタデータはまだibdata1にあり、それを回避する方法はまったくありません。REDOログとMVCCデータもibdata1と共に存続します。

テーブルの断片化に関しては、ibdata1に何が起こるかを示します。

  • innodb_file_per_tableが有効ALTER TABLE db1.mytable ENGINE=InnoDB;またはでdb1.mytablesを縮小できますOPTIMIZE TABLE db1.mytable;。これにより、/ var / lib / mysql / db1 / mytable.ibdは物理的に小さくなり、断片化は発生しません。
  • innodb_file_per_tableが無効になっています。db1.mytablesをibdata1と一緒に、ALTER TABLE db1.mytable ENGINE=InnoDB;またはibdata1と一緒に圧縮することはできませんOPTIMIZE TABLE db1.mytable;。どちらかのコマンドを実際に実行して、テーブルを連続させ、読み書きを高速化します。残念ながら、それはibdata1の最後に発生します。これにより、ibdata1は急速に成長します。これは私のInnoDB Cleanup Postで完全に説明されています

警告(またはロストインスペースでロボットが言うような危険性)

.frmおよび.ibdファイルを単にコピーすることを考えているなら、あなたは痛む世界に並んでいます。InnoDBテーブルの.frmおよび.ibdファイルのコピーは、.ibdファイルのテーブルスペースIDがibdata1ファイルのメタデータのテーブルスペースIDエントリと正確に一致することを保証できる場合にのみ有効です

このテーブルスペースIDの概念について、DBA StackExchangeに2つの投稿を書きました。

テーブルスペースIDが一致しない場合に.ibdファイルをibdata1に再アタッチする方法については、http://www.chriscalender.com/?tag = innodb-error-tablespace-id-in-fileを参照してください。これを読んだ後、.ibdファイルをコピーすることは単純にクレイジーであることにすぐに気付くはずです。

InnoDBの場合、移動するのはこれだけです。

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

InnoDBテーブルのコピーを作成します。

別のDBサーバーに移行する場合は、mysqldumpを使用します。

すべてのデータベースのすべてのInnoDBテーブルを混合することに関して、実際にそうすることの知恵を見ることができます。雇用主のDB / Webホスティング会社には、1つのデータベースにテーブルがあり、その制約が同じMySQLインスタンス内の別のデータベースの別のテーブルにマッピングされている1つのMySQLクライアントがあります。1つの共通のメタデータリポジトリにより、複数のデータベース間でトランザクションサポートとMVCC操作性が可能になります。


有効なテーブルごとにinnodbファイルを使用し、サーバー間でデータをインポートする必要がある場合、mysqldumpのみを使用する必要があり、Percona xtrabackupなどの他のツールを使用する必要はありませんか?
tesla747

14

cnfにinnodb-file-per-tableを追加することにより、ファイルごとにテーブルを保存するようにInnoDBを切り替えることができます。

Innodbは本当に基本的なレベルでデータのページを気にしているだけです。実際、InnoDBをセットアップして、ファイルシステムのないrawブロックデバイスのみを使用することができます。http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

最適化によって使用済みの領域をより簡単に取り戻すことができるなど、ファイル用のテーブルを保存すると便利です。

テーブルごとのファイルを使用しても、InnoDBはトランザクション対応であり、その状態に関する情報をグローバルに共有されるibdata / logファイルに保存するため、ibdファイルを簡単にコピーすることはできません。

それができないと言っているわけではありません。テーブルがオフラインの場合、テーブルスペースを破棄/インポートし、http: //dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.htmlの周りに.idbsをコピーできます。


InnoDBは柔軟なエンジンであることは間違いありませんが、すべてのデータを1つのファイルに保存することが有益であることはわかりません(この新しい構造はMyISAMと比較してInnoDBに実装されているため)。
Googlebot

後知恵の1つは20/20のものだと思います。テーブルごとのファイルオプションは、innodbが最初にシェルフをロールオフした後に追加されました。ファイルシステムのオーバーヘッドを回避するために独自のブロックデバイスを与えること以外は、それらを一緒にダンプする方が良い理由を説明することはできません(そして、ブロックデバイス全体の問題はそれ自身の議論です)。すべてのinnodbセットアップでは、テーブルごとのファイルが有効になっています。
-atxdba

これがポイントです。ファイルシステムに依存しないことは非常に貴重ですが、デフォルトではアクティブではありません。したがって、少数のユーザーが使用します。
Googlebot

1
多くのテーブルがあり、RAMがあまりない場合、テーブルオプションごとに1つのファイルが害を及ぼす可能性があります(たとえば、Magentoストアには約1000のテーブルがある場合があります)。また、オープンファイルの設定も最適化する必要があります(OSの制限を考慮)。そのため、注意して使用してください。
ypercubeᵀᴹ

それは確かに回復努力にダンパーを置くことができます。はい、バックアップが必要ですが、そうでない場合、InnoDBはこの構造のために物事を難しくします。
ミカト

10

これはデフォルトの動作ですが、必須ではありません。MySQLドキュメント、テーブルごとのテーブルスペースの使用から:

デフォルトでは、すべてのInnoDBテーブルとインデックスはシステムテーブルスペースに保存されます。別の方法として、各InnoDBテーブルとそのインデックスを独自のファイルに保存できます。この設定が有効なときに作成される各テーブルには独自のテーブルスペースがあるため、この機能は「複数のテーブルスペース」と呼ばれます。

理由については、おそらく2つのエンジン(MyISAMとInnoDB)の異なるアーキテクチャが原因です。たとえば、InnoDBでは、.ibdファイルを別のデータベースまたはインストールに単にコピーすることはできません。説明(同じページから):

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

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


非常に有益な答えと問題を明らかにしましたが、すべてのデータベースを含む大きなファイルがパフォーマンスを向上させる方法を知りたいのですが、それでも興味があります。
Googlebot

すべてのファイルが1つあるため、パフォーマンスは向上しません。テーブルレベルではなく、行レベルのロックなどのさまざまな特性がパフォーマンスを向上させます。そしてもちろん、主な利点はトランザクションとFKの制約です(したがってデータベースの整合性)。
ypercubeᵀᴹ

1
あなたは誠実さについて全く正しいです!データベースのすべてのテーブルを1つの単一ファイルに入れる方が良い理由を理解しています。しかし、すべてのデータベース(完全に独立している)を同じファイルに配置する理由はわかりません。InnoDBはデフォルトで、データの保存に1つのファイルのみを使用します。
Googlebot
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.