なぜinnodb_file_per_tableを使用するのですか?


26

の必要性を誇張する(もちろん私見)多くの記事がありますinnodb_file_per_table。を使用するとinnodb_file_per_table、個々のテーブルをより適切に制御できるはずです。各テーブルを個別にバックアップするようにします。ただし、パフォーマンスを向上させるという主張には疑問があります。

私のテストでは、性能の差はないinnodb_file_per_tableibdata160ギガバイトのデータベースのために。もちろん、通常のクエリを使用した簡単なテストであり、実際の複雑なクエリでは状況が異なる場合があります(これがこの質問をした理由です)。64ビットLinuxは、ext4大きなファイルを効果的に処理できます。

ではinnodb_file_per_table、より多くのディスクI / O操作が必要です。そして、これは複雑なJOINsとFOREIGN KEY制約で重要です。

テーブルスペースはsingleで共有されibdataます。個別のテーブル専用のテーブルスペースがディスクスペースを節約する方法 もちろん、を使用して各テーブルのテーブルスペースを解放する方が簡単ALTERですが、それでも(テーブルロックを伴う)高価なプロセスです。

QUESTION: DOESはinnodb_file_per_tablemysqlののより良いパフォーマンスに影響を持っていますか?はいの場合、なぜですか?


私の質問へのこの回答を参照してください:dba.stackexchange.com/questions/7924/…も同様に役立つかもしれません。
KM。

回答:


19

パフォーマンスの問題ではなく、管理の問題だと思います。

テーブルごとに個別のファイルを使用すると、たとえば、異なるストレージデバイスに異なるデータベースを保存できます。

大きなファイルを処理できないファイルシステム内の非常に大きなデータベースの場合に対処できます(少なくとも1つのテーブルがファイルサイズの制限に達するまで問題を延期します)。

制御されていないテーブルスペースの増加はありません。ドロップする大きなテーブルがある場合、ibdataファイルは小さくなります。

パフォーマンスに何らかの影響を与える可能性がある1つの側面は、テーブルデータとインデックスの断片化であり、テーブルごとに制限されます。ただし、テストを確認する必要があります。


表領域の増加がまさにその理由ですinnodb_file_per_table
sjas

13

なぜinnodb_file_per_tableを使用するのですか?

ファイルレベルで実行できるため、個々の管理が簡単だからです。つまり、サーバーがダウンしている場合でも、テーブルファイルをコピーすることでデータをコピーできますが、共有テーブルスペースを使用すると、不必要に大量になる可能性のあるものすべてをコピーするか、サーバーを実行してデータを抽出する方法を見つけることを意味します(あなたは本当に16進エディタで手動でデータを抽出したくありません)。

.ibdあるサーバーから別のサーバーにファイルを単純にコピーして貼り付けることはできないと誰かが警告しました。これは真実かもしれませんが、同じサーバー上のバックアップには適用すべきではありません(ここでは、コピーを作成するという従来の意味でバックアップという用語を使用しています。さらに、ほとんどの「テーブルごとのファイルへの変換」ガイドibdata1削除ibdata1手順で見られるように、起動時に自動的に再作成されます。そのため、ファイル(および対応するなどのファイル)に加えてコピーする必要ありませibdata1.ibd.frm

失われたテーブルを回復しようとする場合、そのコピーするのに十分であるべき.ibd.frmファイルを、だけでなく、information_schema(これはずっとより小さいibdata1)。そうすれば、それらをダミーサーバーに入れて、大規模なもの全体をコピーすることなくテーブルを抽出できます。

ただし、パフォーマンスを向上させるという主張には疑問があります。…innodb_file_per_tableでは、より多くのディスクI / O操作が必要です。これは、複雑なJOINと外部キー制約で重要です。

当然のことながら、パフォーマンスは使用中の特定のデータベースに完全に依存します。ある人は、別の人とは(非常に)異なる結果になります。

file-per-tableではより多くのディスクI / O操作があることは事実ですが、ほんの少しだけです。システムの仕組みを考えてください。

  • モノリシックデータベースの場合:

    1. サーバーが起動しました
    2. ibdata1 開かれている
    3. ヘッダーとメタデータが読み込まれます
    4. 構造とメタデータはメモリにキャッシュされます
    5. クエリが発生します
      1. サーバーはディスクにアクセスし、既に開いているデータを読み取ります ibdata1
      2. サーバーはデータをメモリにキャッシュする場合があります
  • テーブルごとのデータベースの場合:

    1. サーバーが起動しました
    2. ibdata1 開かれている
    3. ヘッダーとメタデータが読み込まれます
    4. 個々の.ibdファイルが開かれます
    5. ヘッダーとメタデータは各.ibdファイルから読み取られます
    6. 構造とメタデータはメモリにキャッシュされます
    7. クエリが発生します
      1. サーバーはディスクにアクセスし、既に開いている.ibdファイルからデータを読み取ります
      2. サーバーはデータをメモリにキャッシュする場合があります

サーバーの実行中は、サーバーが開いているハンドルがあるため、データファイルを移動できません。これは、起動時にそれらを開き、開いたままにするためです。個々のクエリごとに開いたり閉じたりすることはありません。

そのため、サーバーの起動時に最初に行われるI / O操作はいくつかあります。実行中ではありません。さらに、個々の.ibdファイルには独自のオーバーヘッド(ファイルシグネチャ、構造など)がありますが、メモリにキャッシュされ、クエリごとに再読み取りされることはありません。さらに、共有テーブルスペースでも同じ構造が読み取られるため、必要なメモリはほとんどありません(もしあれば)。

innodb_file_per_tableはmysqlのパフォーマンス向上に影響しますか?

実際には、どちらかといえば、実際にはパフォーマンス悪化する可能性あります。

共有テーブルスペースを使用する場合、サーバーが複数のテーブルからデータの見本を一度に読み取るように、読み取り操作と書き込み操作を組み合わせることができますibdata

ただし、データが複数のファイルに分散している場合は、ファイルごとに個別のI / O操作を個別に実行する必要があります。

もちろん、これも問題のデータベースに完全に依存しています。実際のパフォーマンスへの影響は、サイズ、クエリの頻度、および共有テーブルスペースの内部断片化に依存します。大きな違いに気付く人もいれば、まったく影響を感じない人もいます。

テーブルスペースは単一のibdataで共有されます。別々のテーブル専用のテーブルスペースがディスクスペースを節約する方法は?

ありません。どちらかといえば、それディスク使用量をいくらか増やします。

テストする60GBのデータベースはありませんが、WordPressのインストールと、個人使用および開発テスト用のいくつかの小さなテーブルを含む「控えめな」個人データベースは、共有テーブルスペースを使用している間、約30MBの重さでした。file-per-tableに変換した後、最大85MBに膨れ上がりました。すべてをドロップして再インポートしても、依然として60 MBを超えていました。

この増加は、次の2つの要因によるものです。

  • 絶対最小サイズibdata1は、なんらかの理由で、information_schema格納する以外に何もない場合でも10MBです。

  • 共有テーブルスペースでは、ibdata1ファイル署名、メタデータなどのオーバーヘッドのみがありますが、テーブルごとに、個々の.ibdファイルにはすべてがあります。これは、合計が(仮に<10MBであってもibdata1)少なくとも次の値だけ大きくなることを意味します

    GetTotalSizeofOverhead() * GetNumTables()

明らかに、これらは大幅に増加することはありません(データベースサイズを制限するホストを使用したり、フラッシュドライブに保存したりする場合を除きます)が、それでも増加している一方で、(すべての)テーブルをファイルに切り替えることで-テーブルごとibdata1に10MBまで縮小できますが、全体の合計は常にそれより大きくなります。


11

これが常にinnodb_file_per_tableを使用する理由です。

テーブルごとのファイルがない場合、ibdataファイルは決してスペースを圧縮、縮小、または縮小することはありません。行を削除したり、テーブルやデータベースを削除したりするときではありません。アクティブなキューシステムがある場合、2GBのデータはすぐに20GBのファイルになります。

変更前に現在の1GBのテーブルのバックアップを作成し、その後それを削除するとします。ibdataにGBの未使用スペースが残っています。残念。

一時的な措置が単一のデータファイルを膨らませるインスタンスの例はおそらく無限にありますが、私の意見では、innodb_file_per_tableを使用しない理由はないということで十分です。

また、読むのに良い投稿があります:http : //code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
常にそうするのは良いことだと思いました。SSDを使用した磁気ストレージアレイは、テーブルの小さいファイルに対してより効果的に読み取り/書き込みキャッシュを処理できます。%99.99の時間だけが「読み取り」されるが書き込まれないテーブルの束については、それらは常にストレージコントローラーのキャッシュにあるため、応答時間が大幅に短縮されます。
sdkks

5

innodb_file_per_tableを使用しない理由はパフォーマンスです。

mysql 5.5.45 Linux CentOS release 6.7で450個のテーブルを使用してデータベースのテストを行いました

ためのユニットテストデータベースで作業を行う(すべての表毎回を使用していない)各テストの前にデータベースへの挿入器具も、それ自体をテストロット(挿入、更新、削除、選択)性能が良好3〜5倍であったデータベーステーブルがなかった場合より多くのファイルに分けられます。

innodb_file_per_tableを使用する前に、使用するクエリでデータベースをテストし、比較することをお勧めします

実稼働サーバーではinnodb_file_per_tableを使用できますが、単体テストを開始する(DBを頻繁に使用する)CI環境(統合を継続する)で使用でき、単体テストを多く開始する開発者はパフォーマンスのために使用しない方がよいことがわかります。


2
これは、450個すべてのテーブルに初期ファイルを割り当てるのに必要な時間と、1つのファイルを割り当てるのに時間がかかっているためだと思います。本番環境ではこれは一度しか発生しないので問題にはなりませんが、データベースを迅速に作成し、完全に破棄して単一のibdataファイルを何度も繰り返すことをお勧めします。
ColinM

2

使用されていないスペースを再利用できるため、データをより管理しやすくなります。

データベースが主に選択クエリに使用される場合、パフォーマンスに大きな影響はないと思います。ほぼ同じ量のデータを読み取る必要があります。どのファイルからデータを読み込んでいるのかはあまり重要ではないと思います。

ただし、多くの挿入と更新を行うデータベースでは、パフォーマンスが低下する可能性があります。これは、トランザクションをコミットした後、mysqlがストレージファイルでfsync()を呼び出すためです。単一のファイルがある場合は、1つの呼び出しを行い、呼び出しが完了するのを待ちます。多くのファイルがある場合、複数回呼び出しを行い、commitコマンドが戻る前にすべての呼び出しが戻るのを待つ必要があります。

この問題を経験した人の投稿は次のとおりです。http//umangg.blogspot.com/2010/02/innodbfilepertable.html


2

以下の記事にあるように、パフォーマンスはデータの管理(crud操作自体)ではなく、オブジェクトの作成とドロップに関するものです。

innodb_file_per_tableを使用すると、大量のオブジェクトの作成とドロップがibdataストレージよりも遅くなり、本番環境には適用できませんが、継続的なテストには適切です。

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.