問題の説明ユーザーはプライマリ データベースに対して変更操作を実行しましたが、これには約 1 時間かかりました。操作が完了すると、スレーブ データベースは同期遅延があることを検出しますが、監視チャートの Seconds_Behind_Master インジケーターは 0 を示し、binlog の遅延距離は継続的に増加しています。 原理分析遅延時間を分析しているので、当然、遅延を計算する方法から始めます。便宜上、公式バージョン 5.7.31 のソース コードを引用してここに示します。遅延時間を計算するためのコードを見つけます: ./sql/rpl_slave.cc ブール show_slave_status_send_data(THD *thd, Master_info *mi, char* io_gtid_set_buffer、 char*sql_gtid_set_buffer) の引数 ...... if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) && (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name()))) { mi->slave_running == MYSQL_SLAVE_RUN_CONNECT の場合 プロトコル->store(0LL); それ以外 プロトコル->store_null(); } それ以外 { 長いtime_diff = ((long)(time(0) - mi->rli->last_master_timestamp) - mi->clock_diff_with_master); protocol->store((longlong)(mi->rli->last_master_timestamp ? 最大値(0L、時間差):0)); } ...... time_diff の計算方法から、この遅延は基本的に時間差であり、その後マスターとスレーブ間の時間差が計算されることがわかります。ただし、if ステートメントが多数あるため、ソース コード ファイル内のコメントを使用します。 /* Seconds_Behind_Master を計算する疑似コード: if (SQL スレッドが実行中) { if (SQL スレッドが利用可能なすべてのリレー ログを処理した場合) { if (IOスレッドが実行中) 0 を印刷します。 それ以外 NULLを印刷します。 } それ以外 Seconds_Behind_Masterを計算します。 } それ以外 NULLを印刷します。 */ Seconds_Behind_Master の計算は 2 つの部分に分かれていることがわかります。
最後に遅延時間を計算するときに、これらの変数の意味を確認します。
遅延を計算する際、実際には、マスター上で再生されたイベントが実行された時刻をスレーブのローカル時刻から減算し、両者の時間差を補正することで値が得られることがわかります。論理的には問題はありません。time(0) と clock_diff_with_master がほとんどの場合にエラーを起こす可能性はないので、今回の問題は last_master_timestamp にあるはずです。 PS: ほとんどの場合は問題ありませんが、time(0) はローカル時間を取得します。そのため、スレーブのローカル時間に問題がある場合は、最終的な値も間違ったものになりますが、今回のケースの範囲ではありません。 次に、イベント実行時に last_master_timestamp を計算するロジックを見つけます。コメントと組み合わせると、通常のレプリケーションと並列レプリケーションでは異なる計算方法が使用されていることがわかります。1 つ目は通常のレプリケーションで、計算時点はイベントの実行前です。 ./sql/rpl_slave.cc ...... もし(もし) { enum_slave_apply_event_and_update_pos_retval exec_res; 列挙型 enum_slave_apply_event_and_update_pos_retval exec_res; ptr_ev = &ev; です。 /* このイベントを実行しなくても、マスタータイムスタンプは保持されます。 マスターの秒数が正しいデルタを示すようにする(イベントがある 再生されないため、遅れを取り続けます。 人工的なイベント、またはリレーログイベント(IOスレッドによって生成されたイベント)の場合 イベント)またはev->whenが0に設定されている場合、またはマスターからのFD、またはハートビート server_id が '0' のイベントの場合、last_master_timestamp は更新されません。 並列実行の場合、last_master_timestampは次の場合にのみ更新されます。 ジョブはGAQから取り出されます。したがって、last_master_timestampが0( GAQが空であることを示し、すべてのスレーブワーカーはイベントを待機しています コーディネーターの場合、最初のタイムスタンプで初期化する必要があります 並行して実行されるイベント。 */ if ((!rli->is_parallel_exec() || rli->last_master_timestamp == 0) && !(ev->is_artificial_event() || ev->is_relay_log_event() || (ev->common_header->when.tv_sec == 0) || ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT || ev->server_id == 0)) { rli->last_master_timestamp = ev->common_header->when.tv_sec + (time_t)ev->exec_time; DBUG_ASSERT(rli->last_master_timestamp >= 0); } ...... last_master_timestamp の値は、イベントの開始時刻と実行時刻を足した値です。5.7 では、多くのイベントに実行時刻の値はありませんでした。8.0 では、多くのイベントにこの値が追加されているため、8.0 にアップグレードすることでもたらされたメリットと言えます。 並列レプリケーションの計算方法は次のとおりです。 ./sql/rpl\_スレーブ.cc ...... /* この時点でこれが呼び出されないようにする必要があります cntはゼロです。この値はチェックポイント情報 完全にリセットされます。 */ /* 正しい Seconds_behind_master を報告するために rli->last_master_timestamp を更新します。 GAQ が空の場合はゼロに設定します。 それ以外の場合は、Slave_job_queueの最初のジョブのタイムスタンプで更新します。 これは Log_event::get_slave_worker() 関数で割り当てられました。 */ ts = rli->gaq->空() ? 0 : reinterpret_cast<Slave_job_group*>(rli->gaq->head_queue())->ts; rli->reset_notified_checkpoint(cnt、ts、need_data_lock、true); /* "Coordinator::"commit_positions" の終了 */ ...... コーディネーターの commit_positions ロジックでは、gaq キューが空の場合、last_master_timestamp は直接 0 に設定され、それ以外の場合は gaq キューの最初のジョブのタイムスタンプが選択されます。この計算はリアルタイムではなく、断続的に行われることを付け加えておきます。計算ロジックの前に、次のロジックがあります。 /* 現在、チェックポイント ルーチンは SQL スレッドによって呼び出されています。 そのため、この関数は適切なポイントから呼び出されます SQLスレッドの実行パスで経過時間が計算されます ここで、実行するタイミングを確認します。 */ set_timespec_nsec(&curr_clock, 0); ulonglong diff = diff_timespec(&curr_clock, &rli->last_clock); if (!force && diff < ピリオド) { /* チェックポイントを今すぐ実行する必要はありません。 経過時間が十分ではありません。 */ DBUG_RETURN(偽); } つまり、この期間の時間間隔内では、last_master_timestamp は更新されずに直接返されます。そのため、並列レプリケーションでは、Seconds_Behind_Master の値が時々 0 から 1 に変化することが時々あります。 gaq キューの操作はスタックのプッシュおよびポップ操作に似ているため、gaq に残されたトランザクションは常に未完了のトランザクションです。したがって、一般的なシナリオの観点からは、時間計算は問題ありません。 問題分析原理分析では、全体の計算ロジックを簡単に説明します。それでは、質問自体に戻りましょう。Tencent Cloud Database MySQLでは、デフォルトで並列レプリケーションが有効になっているため、gaqキューが存在し、alter操作に非常に長い時間がかかります。alter操作が並列トランザクションのグループで実行されるかどうかに関係なく(おそらく、DDLは常に別のトランザクショングループです)、gaqキューは最終的に空になり、last_master_timestampは0に設定されます。Seconds_Behind_Masterの計算ロジックを参照すると、最終的なtime_diffも0に設定されるため、alter操作が終了するまでの遅延時間は常に0になります。変更操作が実行されると、gaq キューは新しいイベントとトランザクションでいっぱいになるため、遅延は以前は 0 であったとしても、突然非常に高い値に跳ね上がる可能性があります。 拡大する通常のレプリケーションと並列レプリケーションの計算方法の違いを比較すると、次の特性がわかります。
総括する厳密な遅延判断には、GTIDギャップとbinlog位置ギャップに頼る方が良いでしょう。8.0でのイベント実行時間の変化から判断すると、少なくともOracleの担当者はまだ懸命に取り組んでいます。これらの小さな問題ができるだけ早く修正されることを願っています。 上記は、MySQL 同期遅延が発生したときに Seconds_Behind_Master が 0 のままである理由の詳細な内容です。MySQL 同期遅延 Seconds_Behind_Master が 0 である理由の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
>>: HTMLとリソースがどのように読み込まれるかを理解します
1. まず、お使いのマシンに応じて、MySQL 公式サイトから対応するデータベースをダウンロードしま...
序文Linux システムの運用および保守エンジニア職の面接を受ける場合は、次の 10 個の最も一般的...
IPSec の概要IPSec (インターネット プロトコル セキュリティ): ネットワーク層と適用さ...
目次1. MySQLインストールパッケージをダウンロードする2. MySQLのアンインストール手順3...
序文:多くのビジネス テーブルでは、歴史的またはパフォーマンス上の理由により、最初のパラダイムに違反...
CentOS7 システムを使用するのは今回が初めてで、ネットワーク構成を行う際に多くの問題が発生し...
CenOS6.7 は MySQL8.0.22 (推奨コレクション) をインストールします1. MyS...
最近、jQuery を学習しているときに、show()、hide()、toggle() 関数に出会い...
目次概要(ループモード - 共通)配列と非同期メソッドを宣言して反復するforループで使用するマップ...
Nginx は、IP ベースの仮想ホスト構成、ポート ベースの仮想ホスト構成、ドメイン名ベースの仮...
最適化する理由:実際のプロジェクトが開始され、データベースが一定期間稼働した後、初期のデータベース設...
ショートハンドプロパティは、複数のプロパティに同時に値を割り当てるために使用されます。たとえば、fo...
簡単な説明<br />IE6および7では、一般的なaタグ(HTMLで記述され、DOM操作...
目次1. コンセプト1.1 定義1.2 デコレータファクトリー1.3 デコレータの組み合わせ1.4 ...
ヒント: MySQL では、ユーザーの作成と削除が頻繁に必要になります。ユーザーを作成するときは、通...