web-dev-qa-db-ja.com

サイト冗長ガレラクラスターでsync_binlogs、innodb_flush_log_at_trx_commit、innodb_doublewriteを無効にしても安全ですか?

サイト冗長ガレラクラスターでは、データベースノードのクォーラムがトランザクションを受け入れた後でのみコミットが返されます。 1つのデータベースノードがダウンすると、すべてのコミットが残りのクラスターによって保持され、データベースを再起動すると、ダウンしたデータベースノードが残りのクラスターと同期します。データベースが破損した場合、常にmysqlデータディレクトリをnukeして空のデータベースで開始することができ、最終的にはクラスタの残りの部分に追いつきます。したがって、ローカルのACID準拠を保証するオプションをオフにすることで、パフォーマンスを調整できるように思えます。

それで、ここでの質問は本当に...「何がうまくいかないのでしょうか?」

:-)


コメントに基づいて、私たちの特定のセットアップに関するいくつかの情報を提供します。

  • クラスターは3つのノードで構成されます。それらの2つは本番環境で積極的に使用され、1つは他よりも頻繁に使用されます。 3番目のノードは、クォーラムとバックアップの目的でのみ使用されます。

  • サイトの冗長性とは、ノードが異なるサーバーセンターにあることを意味します。 2つのノードが同時にダウンするようなことを考えるのは難しいと思います-深刻なmysqlのバグを除いて、それはどの程度の可能性がありますか?確かに、2つのノードは10 km未満の間隔で配置されています(バックアップ/クォーラムノードは数百kmと国境で隔てられています)。中型の核爆弾は、2つのノードを同時に取り出す可能性があります。この場合も、「データベースに問題があります」が、このようなシナリオにおける懸念の中で最も少ないものです。太陽嵐がサーバーの両方またはすべてを同時に取り出す可能性はありますか?

  • 私たちのパフォーマンスの問題は、SAN=の書き込みキャッシュが時々満杯になるためです。この問題の軽減に取り組んでいますが、再び発生しないことを保証することはできません。 。時々、トランザクションが約10〜30秒待機する「ヒカップ」が発生します。

  • この特定のセットアップでは、30秒の遅延は実際には生と死の問題である可能性があります。おそらく、そうではありませんが、顧客がそれをそのように認識した場合、それは十分に悪いことです。クラスタ全体が落ちた場合の合理的な低レイテンシと迅速なリカバリが最も緊急の優先事項です。いくつかのトランザクションを失うことは十分に悪いかもしれませんが、それは生と死の問題ではありません。

  • 発生しているパフォーマンスの問題は、書き込みトランザクションが「wsrep in pre-commit」状態でスタックしていることです。これはフロー制御の問題ではありません。問題があるのは1つのノードだけです。ノードについてリモートのチェンジセットをデータベースに書き込んでいる間、すべてのローカル書き込みクエリがロックを待機しているようです。この問題はgalera 4で修正する必要がありますが、アップグレードは現在のところオプションではありません。

  • 私たちのパフォーマンスの問題は1つのノードでのみ発生するので、それらをオフにすることを検討している1つのノードでのみ発生します。何が起こっても、そのノードをクラスターのブートストラップに使用しないでください。

  • シャーディングは行っていません。また、シャーディングを行うつもりもありません。これらの問題を除いて、パフォーマンス上の問題はありません。

3
tobixen

これについていくつか調査を行ったので、自分の質問に答えます。

最初に要約

パフォーマンスの問題が1つのノードでのみ観察される場合、影響を受けるノードでinnodb_doublewriteとinnodb_flush_log_at_trx_commitをオフにすることは完全に安全です。クラスタ全体が失敗します。

# echo "[server]" >> /etc/mysql/conf.d/temp_perfomance_hax.cnf
# echo "innodb_doublewrite = 0" >> /etc/mysql/conf.d/temp_performance_hax.cnf
# echo "innodb_flush_log_at_trx_commit = 2" >> /etc/mysql/conf.d/temp_performance_hax.cnf
# systemctl restart mysql # innodb_doublewrite cannot be set run-time

また、真のサイト冗長ガレラクラスターでは、任意の数のノードでinnodb_flush_log_at_trx_commitを2に、sync_binlogを0に設定することは合理的に安全である必要があります。パフォーマンスの問題が発生している場合、稼働時間とパフォーマンスが重要であり、トランザクションの損失が生死の問題ではない場合-ためらう必要はありません。先に進んでください。

set global sync_binlog = '0';
set global innodb_flush_log_at_trx_commit = 2;

aCID準拠よりもパフォーマンスが重要な場合は、おそらく先に進んで二重書き込みをオフにすることもできます。災害の可能性はかなり低いです。

「安全な」設定に固執する2つの理由がわかります。

  • 最悪のシナリオへの準備:クラスタ全体が同時に溶けたらどうなるか?
  • ノードの堅牢性が向上

ノードの堅牢性:innodb_doublewriteをオンにしておく

innodb_doublewriteは、ACID準拠を失うことなく、1つのノードで安全にオフにすることができますが、オンにする方がよい場合があります。 InnoDB doublewriteバッファリングを無効にするのはいつ安全ですか? innodb-doublewriteをオフにすると、データが破損する可能性があります。その場合、ダウンしたノードのデータパーティションをワイプして再起動する必要があります。 。これには3つのコストが伴います。

  • システム管理者による手動介入
  • 破損したノードがSSTを実行している間、クラスターのレベルがIO
  • クラスタは、ノードが完全に機能するまで、冗長性を減らして実行する必要があります。

(私が理解できる限り、ログファイルでフラッシュが欠落しても、dbノードの起動に問題は発生しません。つまり、innodb_flush_log_at_trx_commitの場合、マニュアルには「値に関係なくInnoDBのクラッシュリカバリが機能する」と明記されています)

クラスタ全体が一度に焼き尽くされる理由

激しい爆発

Innodb_flush_log_at_trx_commitを2に設定し、binlog_syncを0に設定し、innodb-doublewrite-bufferingを1に設定することを検討してください。これにより、パフォーマンスが向上する可能性があります。のノードで電力損失またはカーネルパニックが発生しています。真のマルチサイト設定の場合、それらを無視することができるほどまれなようです。

  • ノードが近くにある場合、停電、洪水、火災などの局所的な問題により、すべてのノードが同時に故障する可能性があります。すべてが冗長であると想定されていたにもかかわらず、奇妙な理由でサーバーサイト全体がダウンするのを何度か目撃しました。

  • 太陽嵐が同時にクラスター全体に影響を与える可能性はありますか?特にクラスターが同じ都市と極地にある場合はどうでしょうか? 2台のラップトップが同時にクラッシュし、太陽嵐の最中に極域にあり、他に考えられる理由はありません(OSが異なる、うるう秒に達していないなど)。

  • すべてのノードが同じOSを実行している場合、OSカーネルの問題が原因で、すべてのノードがカーネルパニックでまったく同時にクラッシュする可能性があります。

ソフトウェアがクラッシュする

Innodb_flush_log_at_trx_commitが0に設定されている場合、またはinnodb_flush_log_at_trx_commitが0に設定されている場合、すべてのノードに同時に影響を与えるmysqlクラッシュによりデータが失われる可能性があると思います。

誰かがそのような方法でガレラがクラッシュするのを見たことがありますか?

すべてのノードのmysqlで同時に「kill -9」を実行するシステム管理者またはバグの多いスクリプト...しかし、システム管理者がデータ損失を引き起こしたい場合は、それらの設定に関係なく方法を見つけるでしょう。

他の理由でクラスターがダウンしている

そのような場合、それらの設定は重要ではありません。

  • 3つすべてのノード間の突然の完全なネットワーク分離、またはクラスターを断片化したままにして、クォーラムを検出できない。 bootstrapクラスタはこのようなインシデントの後で発生する必要があり、トランザクションが失われないことを100%確実にしたい場合は、手動でバイナリログを調査する必要があります(以下の詳細を参照) -しかし、mysqlもOSもクラッシュしていないため、同期設定に関係なく、すべての状態が最終的に同期されます。

  • タイミングが悪い-つまり、1つのノードがダウンし、そのダウン中に別のノードがダウンするか、ネットワークが分離されている可能性があります。その後、クラスターをブートストラップする必要があります。ただし、ノードが受け取ったものはすべてディスクに書き込まれるため、上記の設定は何にも影響しません。 (私たちはこれを一度経験しました)。

クラスター障害には手動での介入が必要

設定に関係なく、壊滅的なクラスター障害の後にトランザクションが失われないことを100%確実にするために、実際には手動でバイナリログを検査/マージする必要があります。 bootstrap 1つのノードのみを使用するクラスターが必要ですが、このノードがすべてのチェンジセットを取得したかどうかはわかりません。この情報は、すべてのノードからのbinlogを調査することによってのみ利用できます(log_slave_updatesがオンになっている場合、ノードのクォーラムからのバイナリログでおそらく実行できます)。

これは、事前に決定を下す必要があることを意味します-壊滅的なクラスターのメルトダウンが発生した場合の優先事項は何ですか?クラスターをできるだけ早く稼働させるための優先順位ですか、それともクラスターをブートストラップする前にトランザクションが失われていないことを100%確認するための優先順位ですか?

あなたのマイレージは異なる場合があります

極端な状況下である程度のダウンタイムが許容される場合(完全な壊滅的なDBクラスターのメルトダウンが極端な場合)、本番モードに戻る前にすべてのトランザクションを確実に実行することが最重要である場合、binlogが同期され、維持されることを100%確認する必要があります。 、そしてバックアップ体制は良好です。その場合、innodbログと二重書き込みの同期は重要ではなく、パフォーマンス上の利点がある場合はオフにすることができます。

「できるだけ早くクラスタを稼働させる」ことが重要な場合は、ノードのクォーラムでset innodb_flush_log_at_trx_commit = 1およびset innodb_doublewrite = 1を実行することが重要です。クラスターがダウンした場合、それらの設定がオンになっているサーバーからクラスターをすばやくブートストラップできます。 (いくつかの検討が必要な場合があります。以前のメルトダウンノードCが落ちて再び立ち上がった。ノードCがクラスタに適切に参加する前にノードAとノードBの間のネットワークグリッチが発生し、シャットダウンした。明らかに、bootstrapデータ損失なしでAまたはBから、ただしCからではない)。

3
tobixen

「サイト冗長」とは、3つの異なるデータセンターのそれぞれに1つのノードがあることを意味しますか?

単一障害点を乗り切るという目標はありますか? 1つのサーバーまたは1つのデータセンターのハードクラッシュを含みますか?

ハードクラッシュが発生した場合、強制的にSSTを強制しますか?

次に、これらの3つの設定を高速ではあるが安全ではない設定に設定できると「信じる」。

(私の助言の返金保証。)

1
Rick James