インタビュアー:あなたはどのような大きな取引が問題をもたらすでしょうし、それを解決する方法を知っていますか?

大きな出来事は何ですか?

要するに、長い時間を実行する人々、より多くのデータ操作取引

大規模なトランザクションを照会するには?

一例として、取引の10秒を超えるクエリの実行時間:

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>10

大規模なトランザクションデータベースは、一般的に、任意の問題を引き起こすのでしょうか?

おそらくデッドロックの多くを引き起こし、ロックアウトする、あまりにも多くのデータをロックします

資源依存のサイクルが異なる取引システム間で発生すると、関連する取引は、次のシナリオとして、無限の待機状態に入っているいくつかの取引につながる他のトランザクションリソースを解放し、待っている:
ファイル
この時点では、トランザクションAトランザクションBリリースロックID =行2、行トランザクションBリリース待機トランザクションaのロックID = 1を待っ。リリースを待つために互いのリソースでトランザクションAとBのトランザクションは、デッドロック状態を入力することです

私たちが知っているすべてのまず、デッドロックに対処することができる2つの方法があります。

  • デッドロックのタイムアウトを待ちます。タイムアウト(innodb_lock_wait_timeout)デフォルトは50代ですが、今回は本当にあまりにも長くすることができますが、それは少しずつ、そしてこれが影響を与える可能性がある場合、通常はデッドロックを排除することができます
  • デッドロック検出。デフォルト設定のデッドロック検出がオンになっています。トランザクションがロックされるたびにデッドロック検出は、それは、スレッドが他の人をロックし、そしてその上で、最終的にデッドロックがあるかどうかを決定していない依存を参照する必要があるさ

しかし、デッドロックの検出は問題がある可能性があります:
すべてのトランザクションは、時間の同じ行を更新する必要がある場合。それぞれの新しいスレッドがブロックされ、そのため追加のデッドロックにつながったのと判断されることはありません、これは複雑さはO(n)の操作での時間です。同時に同じ行を更新するために、1000件の同時スレッドがあると仮定し、デッドロックの検出動作は百万この大きさです。最終テストの結果がデッドロックではありませんが、この期間に大量のCPUリソースを消費します。だから、あなたは、CPUの使用率が高いと表示されますが、それは毎秒数のトランザクションを実行することはできません。

ロールバックレコードは、長時間トランザクションのロールバックを収納スペースの多くを取ります

MySQLでは、実際には、アップデートにロールバックを記録しながら、各レコードがあることを行っています。ロールバック操作によって記録された最新の値は、以前の状態の値を得ることができます。
3の値を仮定すると、4が順次1から変更され、ロールバックの内部に次のログレコードに類似が存在するであろう。
ファイル
電流値は4ですが、トランザクションは異なる時間に開始され、クエリ内のこのレコードは、別の読み取りビューを持っています。値2,4のレコードであるビューA、B、Cの内部に見られるに示すように、同一のレコードがシステムの複数のバージョンであることができ、データベースのバージョンは、より多くの並行性制御である(MVCC )。リードビューAのために、順次にでなければならない電流値が得られたすべてのロールバックを実行し、1を得ました
同時に、あなたは今も別のトランザクションが4に5に変更されている、読み取りビューAとの取引は、B、Cに対応するトランザクションが競合しないことがわかります。
あなたは必要のないときにそれを削除するとき、それの遺跡をロールバックすることはできませんログは?答えはのみ削除され、要求されます。言い換えれば、システムは、トランザクションログをロールバックするためにこれらを使用するには、もはや必要がない場合、ロールバックログが削除されます決定します
それが必要でない場合は、システムがロールバック以前の読み取りビューの時間よりも、別の方法は、これらの事の後に提出されたログインしていない場合?それはあります。

マスターからの遅延を引き起こす可能性が高い、長い時間を、実行

masterデータベースのトランザクションが書かれたバイナリログの実装が完了するまで待たなければならないので、そのライブラリを通過。文は10分間のメインライブラリ上で実行されるのであれば、そのトランザクションは、最も可能性の高いライブラリー10分からの遅延が発生します

ソリューション

ツーフェーズロック・プロトコルに基づきます

2フェーズロック・プロトコルは何ですか?
InnoDBのトランザクションでは、ロックが必要な場合にのみ行にあるプラスが、すぐにリリースするが、トランザクションのリリースの終わりまで待つ必要はないではありません

二相ロック・プロトコルの最適化に基づいて、私たちが行うことができます:
あなたのトランザクションが複数の行ロックを必要とする場合は、最も可能性の高い原因の競合に、最も可能性の高い同時実行のロックの度合いに影響を与えるべきでロックが可能な限り戻します

映画のチケットをオンライントレーディング業務の実現のためにあなたが責任を負うとし、劇場B.で映画のチケットを購入する顧客A 私たちは、次のように関与するには、このビジネスの必要性を、それを簡素化:

  1. 口座の残高から差し引か顧客のチケット価格。
  2. 劇場にBの口座残高を、この映画の運賃上昇; 3.録音トランザクションログ。
    言い換えれば、このトランザクションを完了するために、我々は2つのレコードを更新し、レコードを挿入する必要があります。もちろん、アトミックトランザクションを確実にするために、我々は1つのトランザクションでこれらの3つの操作をしたいです。だから、どのようにトランザクションそれでこれらの3つのステートメントの順序を調整しますか?
    C Bは、これら2つのトランザクションの紛争の一部が2文ですながら劇場でチケットを買うために別の顧客がある場合を想像してみてください。彼らは同じ劇場の口座残高を更新したいので、あなたは、データの同じ行を変更する必要があります。
    トランザクションが提出されリリースされたとき、2フェーズロック・プロトコル、あなたは文の順序を調整どんなにによると、行ロックは、すべての操作が必要とされています。あなたはこのために、このようなとして3,1,2、最後の2つの構成で文を置くのであれば、その後、ロック時間劇場口座残高の行が少なくともだろう。これは、トランザクション間のロック待ちを最小限に抑え、同時実行の度を高めます。

ベースのデッドロックの検出

同時時間のデッドロック検出の小さな数が非常に低くなりますとき、それが唯一のO(n)は、同じ行のコストの量を制御することができますデッドロック検出の問題を解決したいです

しかし、同時かなり良いコントロールの数:

  1. 分散システムにおけるクライアントの数が不明であるので、クライアントを限定するものではありません
  2. あなたがソースコードを変更する必要があり、最終的にそうするが、これは非ダニエルのためではありませんMySQLの
  3. 参照のConcurrentHashMap JDK1.7は、ロックの設計をセグメント化ロック競合を低減するために、複数のライン上の論理データへのデータの行を
    第3の実施形態劇場アカウント続いて、ほとんど意味のものである、請求、例えば、アカウント情報であってもよいです例えばレコード10のような複数のレコード上に、合計10件のレコードの劇場値をアカウントに等しいです。アカウントプラスランダムにレコードを追加するために、選択した時間の量を、与えるために、各劇場はそう。各衝突確率が1/10になるように、ロック待ちの数を減らすことができ、それは、CPUの消費デッドロック検出を低減します。

このプログラムは、ロスレスように見えますが、実際には、このようなプログラムは、ビジネスロジックに基づいて詳細設計を行う必要があります。口座残高は、返金・ロジックとして、減少させることができる場合は、この時間は、あなたのコードは、特別な治療でなければならないときの行の一部が0になったときに検討する必要があります。

トランザクション分離レベルに基づいて、

この分離レベルでのデータ書き込みがこれらの質問を持っている場合我々は、MySQLのデフォルトのトランザクション分離レベルが反復可能読み取りであることを知っています:

  1. インデックスが存在する場合、インデックス更新データとして条件は、ギャップロック、行ロック、次のキーロックの問題が存在することになる場合、いくつかの行をロックして、(主キーインデックスは含みます)
  2. 何のインデックス、更新データが存在しない場合は、テーブル全体をロックします

分離レベルが提出これら二つの質問を読み取るために変更された場合でも、存在せず、各書き込みデータ線をロックします

しかし同時に、あなたが発生する可能性があり決意データとログの不整合のために、我々はバイナリログ行の書式を設定する必要がありますしています

あなたはこの記事を参照することができ、セットのbinlogにする理由について、MySQLのバイナリログ形式は、行に変更しなければならない理由

他の

  1. いくつかの読み取り専用操作まで開いて物事に必要はありません
  2. SETMAX_EXECUTION_TIMEコマンドによって、長すぎる単一のステートメントを誤って実行を避けるために、実行される各ステートメントの最大時間を制御します
  3. information_schema.Innodb_trxテーブルの監視、それは警報/または死滅を超え、長いトランザクションのしきい値を提供
  4. ビジネス機能テスト・フェーズでは、すべてのgeneral_logの出力を必要とし、ログ解析は、事前にその行動上の問題を発見しました
  5. 値を設定Innodb_undo_tablespacesは、アンドゥログは別のテーブルスペースを単離しました。本当に大規模なトランザクションのロールバック・セグメントに存在つながる場合は、この設定後にクリーンアップするにはあまりにも、大規模な簡単です。

おすすめ

転載: www.cnblogs.com/zhixiang-org-cn/p/12454275.html