Mysqlのコミット中にIO待機が非常に遅くなる(99%IOのEXT4 JDB2)


14

私はPythonを使用して、ドキュメントをインデックス付けしてデータベースに挿入するインデクサーを書いています。単一プロセスになる前に、4つの並列プロセスが実行されているマルチプロセッシングになりました。すべてのテキスト抽出の後、データベースに挿入してコミットします。

今ではIOの問題にぶつかります。主なIOの問題は私のプロセスではなく、EXT4のjdb2ジャーナリングシステムです。これは99.99%で、MySQLコミットごとにIOを待機するようCPUに要求します。

私は多くの人がインターネット上でその問題を抱えているのを見て、それらの解決策はbarrier = 0を使用してマウントすることです。それはジャーナリングを完全に無効にしますか?私のサーバーにはUPSがあり、それをしたいと思っていますか?


すべてのデータはInnoDB ???
RolandoMySQLDBA

回答:


4

データベースを非ジャーナリングファイルシステムに配置します。少なくとも大規模なサーバー(oracle、sqlサーバー)には独自のジャーナル機能(トランザクションログ)があり、それに応じてIOを最適化します。ログとデータベースは別々のファイルシステムとディスクにあり、不良IOを処理するためにデータベースの内部機能に依存しています。通常、ファイルは拡張されないため、書き込み日を除いて(より大きなセットアップ)ファイルシステムの変更はありません-それらは「最終」サイズで生成され(OK、管理者はそれを変更できます)、変更はデータベースが追跡したとおりですレベルのトランザクションログ。

また、ハードウェアレイヤーを教えてください。ほとんどの人は、IOPSがデータベースの制限要因であると過小評価しており、小さなディスクセットは大きなデータベースに適した環境だと考えています。私たちの中には、より多くのディスクを使用してデータベースを操作しているため、潜在的にはより多くのIOPSをサポートしています。


これを修正して、データのジャーナルではなくメタデータのみを使用するファイルシステムを使用します。Ext4もこの方法で構成できます。
the-wabbit

はい。最後に、jouirnalはIOを2倍にします。データベースログは再び同じことを行うため、必要以上に多くのIOPSが得られます。そして、基本的に不要な冗長性。システムのjouirnallingは、ファイルを保護するためのNICEです。しかし、アプリケーションがすでにデータベースを保護している場合、アプリケーションがすでに保護している場合は役に立ちません。
トムトム

非ジャーナリングで最高のパフォーマンスを提供するのはどれですか?ありがとう!
ピョーアルカールウィン

4

復元力とパフォーマンスの間には常にトレードオフがあります。

ext4でMySQLを使用している場合、barriers = 1のデフォルトは実際にスローダウンを引き起こしますが、最初のアクションはジャーナリングを無効にすることやdata = writebackをオンにすることではありません。

第一に、復元力が非常に重要な場合、バッテリーバックアップRAIDは確かに価値があります。

私が選択したマウントオプションは、特にバッテリーを使用しないRAIDでの選択です。

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

これは、意図的にdata = writebackを使用していないためです。ファイルシステムが破損して「クラッシュおよびジャーナルリカバリの後にファイルに表示される古いデータ」(引用元はman mount)になるリスクを回避したいからです。

I / O関連の設定を完全に復元するためのmy.cnfの理想的な構成は次のとおりです。

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

パフォーマンスを向上させるために、次の一連のトレードオフを選択しました。

  1. sync_binlog = 0:これは、完全な復元力から変更した最初のMySQL構成です。この理由は、特にbinlog_format=row(残念ながらJiraに必要な)パフォーマンスが大幅に向上するためです。クラスターで十分なMySQLレプリカを使用しているため、電力損失シナリオによってバイナリログが破損した場合、別のレプリカからバイナリコピーを作成します。
  2. innodb_flush_log_at_trx_commit = 2:ACIDに完全に準拠するには値1が必要ですが、値2は「コミットごとにログバッファーがファイルに書き出されますが、ディスクへのフラッシュ操作は実行されません。ただし、値が2の場合も、ログファイルは1秒間に1回発生します。プロセスのスケジューリングの問題により、1秒間に1回のフラッシュは毎秒100%発生するとは限りません。(MySQLドキュメントからの引用)
  3. を使用するようにマウントオプションを更新しますdata=writeback。これがルートファイルシステムである場合は、カーネルコマンドラインオプションも渡す必要があることに注意してください。coderwallでいくつかの手順をまとめました。
  4. のさまざまな値をテストしますinnodb_flush_method。O_DIRECTは、一部のワークロードでパフォーマンスを改善することが示されていますが、これが環境で機能することは当然ではありません。
  5. その場合、あなたはまた増加することをお勧めします、のSSDへのアップグレードinnodb_io_capacityなど、とチューンinnodb_adaptive_flushinginnodb_read_io_threadsinnodb_write_io_threadsinnodb_purge_threads、、その他の可能な設定。

3

I / Oバックエンドが負荷にそれほどうまく対処していない可能性があります。ファイルシステムがデータをジャーナリングしていないことを確認する必要があります。data=writeback,relatime,nobarrier最初のクイック&ダーティ最適化として、パラメータを使用してデータベースのデータパーティションにマウントすることをお勧めします。

また、症状から推測すると、コントローラーで書き込みキャッシュを使用していないようです。コントローラーでバッテリーバックアップまたはフラッシュバックアップの書き込みキャッシュを使用していることを確認し、有効にしてください。これにより、データの損失や破損のリスクを大幅に増加させることなく、パフォーマンスを大幅に向上させることができます。バッテリまたはフラッシュバックアップなしで書き込みキャッシュを使用すると、データの損失または破損のリスクが大幅に増加することに注意してください。これは、テスト目的および/または損失を被ることができる場合にのみ行ってください。


data = writeback、relatime、nobarrierについてはどうでしょうか。それからmysqlロギングを完全に無効にしますか?これは物事を大幅にスピードアップすると思いますか?
ピョーアルカールウィン

hdpram -iは、書き込みキャッシュを使用していることを示します。うーん?
ピョーアルカルルウィン

@ V3ss0nトランザクションエンジンのロギングを無効にすることはできません-それがまさに心臓部です。メインデータベースデータ(ランダムな読み取り/書き込み)とはまったく異なるアクセスパターン(ほとんどが線形書き込み)であるため、トランザクションログをのディスクセットに移動することを選択できます。これは一般的に推奨される構成です。ストレージのセットアップに関しては、RAIDコントローラーを使用しているのではなく、書き込みキャッシュがオンになっている個々のディスクを使用していますか?これは、明示的なキャッシュフラッシュ要求を伴うため、同期書き込みのいずれにも役立ちません。
-wabbit

nobarrier同じbarrier=0ですか?
ニックコットレル14年

@NicCottrellはい、それらは同じです。
kouton

3

これは古い質問ですが、先週新しい専用サーバーで同じ問題(高いIO待機、ひどい挿入/更新速度)に直面しました。このソリューションはこの問題に直接対処します。

tune2fs -O "^has_journal" /dev/<drive>JDB2プロセスによるIO待機がなくなるため、ジャーナリングを無効にすることが最も迅速なソリューションでした。しかし、クラッシュした場合にデータが失われるため、バッテリーバックアップドライブがない限り、これは推奨されません。doublewriteMySQLで有効にした場合、InnoDBテーブルは安全です。ただし、.frm、ログなどのファイルは安全ではありません。これらのファイルを別のドライブ(特にbinログ)に移動しようとしましたが、jdb2 IOの待機はまだ持続していました。そのため、私たちは非常に快適になれませんでした。

data=writeback,relatime,nobarrierパーティション全体でジャーナリングを無効にするのと同じくらい、書き込み/読み取りの速度を上げる助けにはなりませんでした。ext4のその他のオプションはEXT4 docにあります。

私たちの場合の本当の犯人はでしたsync_binlog。私たちが設定したものはそのまま1/etc/mysql/my.cnfあり、パフォーマンスを殺していました。

Perconaはこれをここで検証します。デフォルトに設定し0、パフォーマンスが500%以上向上しました。


0

このデータの挿入に使用しているデータベースエンジンは何ですか?

MyISAMの場合:書き込み中にテーブル全体をロックする必要があるため、同時挿入スレッドを実行すると、どんなに強力なシステムでも強制終了されます。

これらのテーブルにInnoDBを使用していることを確認してください。


彼はトランザクションをコミットしているため、MyISAMはトランザクションをサポートしていないため、エンジンはMyISAMではありません。
the-wabbit

Arr、brainfart。
アダプター

私はinnodbを使用していますが、mysql5.5のデフォルトはinnodbです。
ピョーアルカルルウィン

0

また、mysqlとは直接関係ありませんが、一部のHDでは、積極的な電源管理のためにext4で問題が発生します。

無効にしてみてください。(再起動せずに元に戻す必要がある場合)まず、持っている値をチェックしてから無効にします。

現在の値を確認します。

    hdparm -B /dev/sda

無効にする

   hdparm -B 255 /dev/sda

(またはHD)をテストします。おそらくほとんどの問題には役立ちませんが、世の中の一部のユーザーには役立つかもしれません。再起動すると、値がリセットされるか、以前の値の255が手動で置き換えられます。

それが助け場合は、チェック/etc/default/hdparmまたは/etc/hdparm.confより恒久的な設定のために、ブート時にそれを設定することによって。

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