web-dev-qa-db-ja.com

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

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

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

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

55
Googlebot

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 enabledALTER TABLE db1.mytable ENGINE=InnoDB;またはOPTIMIZE TABLE db1.mytable;を使用してdb1.mytablesを圧縮できます。その結果、/ var/lib/mysql/db1/mytable.ibdは物理的に小さくなり、断片化されません。
  • innodb_file_per_table 無効:db1.mytablesは、ALTER TABLE db1.mytable ENGINE=InnoDB;またはOPTIMIZE TABLE db1.mytable;で圧縮できないので、 ibdata1。どちらかのコマンドを実際に実行すると、テーブルが連続し、読み書きが速くなります。残念ながら、これは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-ファイル 。これを読んだ後は、.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インスタンス内の別のデータベースの別のテーブルに制約がマップされているMySQLクライアントを1つ持っています。 1つの共通メタデータリポジトリにより、トランザクションのサポートとMVCCの操作性が複数のデータベースにわたって可能になります。

69
RolandoMySQLDBA

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

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

最適化によって使用済みスペースをより簡単に回復できるなど、ファイルのテーブルを保存すると便利です。

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

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

14
atxdba

これはデフォルトの動作ですが、必須ではありません。 From MySQL docs、Using Per-Table Tablespaces

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

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

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

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

10
ypercubeᵀᴹ