ホームページ データベース mysql チュートリアル Slave SQL线程阻塞时执行Slave相关命令的风险

Slave SQL线程阻塞时执行Slave相关命令的风险

Jun 07, 2016 pm 04:31 PM
sql 注文 埋め込む 関連している ブロック 危険

本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/slave_sql_locked_bug.html 今天做一批备机加主键的工作时,意外发现,如果有一个线程阻塞了Slave SQL 线程应

本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/slave_sql_locked_bug.html

今天做一批备机加主键的工作时,意外发现,如果有一个线程阻塞了Slave SQL线程应用日志,导致Slave SQL在Locked状态,再试图执行Slave Stop命令时,必定导致show slave status/master status等语句执行Hang死。
解决方法是只能等待锁定Slave SQL的线程结束,或者重启数据库,还没试出其他方法可以解决。已经在MySQL 5.0.68、5.1.30/34/40上重现。
搜索了Bug库,确实找到了这个bug,http://bugs.mysql.com/bug.php?id=56676,至少在5.1.50之前都会有这个问题。

查看了源码,主要是由于mi->run_lockLOCK_active_mi两个锁导致的问题。
slave的运行流程是 start_slave_thread函数创建handler_slave_sql线程去轮询日志,handler_slave_sql调用exec_relay_log_event去应用日志事件,exec_relay_log_event又调用apply_event_and_update_pos来具体读取一个日志事件应用日志到存储引擎并更新relay-log的pos信息,最后根据读取的日志类型,调用不同类重载的XXX_log_event::do_apply_event去真正使用解出来的日志。

导致Hang住的原因是这样的:
slave_sql一旦启动成功,就会持有mi->run_lock锁,mi是Master_info的实例,记录主机信息,就是master.info的内容,mi->run_lock被持有表示mi的Slave正在运行(mi定义为Master_info *,注释里也说了,Multi Master写完后,mi是个数组,可以有每个Master分别持有锁,所以MySQL也在做这个事了),由于目前只支持单Master,所以mi的锁是全局的,即LOCK_active_mi。当一条SQL被Locked的时候,Slave SQL持有mi->run_lock,cond_wait等待不到继续进行的条件,于是运行不到if (!sql_slave_killed(thd,rli))这条语句。所以stop_slave发出kill无法被判断到,于是slave stop就Hang住了。由于stop slave持有LOCK_active_mi(关闭Slave需要保存master.info),而show slave status/show status都会先做pthread_mutex_lock(&LOCK_active_mi);因而全部堵住。
还有一个可能存在的风险,Relay_log_info类的tables_to_lock链表存了Slave要锁住的表,如果Slave不能及时继续,tables_to_lock链表就不能及时清理,会带来很多锁问题,可能引起大面积阻塞。上次有个故障,MySQL Hang死,很可能就是我们一个跳过复制错误的脚本show slave status和slave start/stop执行频率很高,突然切换主备需要建立大量连接的时候CPU上下文切换较多,释放LOCK_active_mi锁的速度就跟不上,另一些show slave status采集监控的脚本迅速阻塞,导致tables_to_lock链表不能及时释放,进而导致正常SQL执行被锁阻塞,由于变更量非常大,阻塞迅速蔓延,锁等待几乎把数据库Hang死。

所以我提醒各位,在Slave中有长SQL或Locked的SQL执行时,除show processlist;外千万不要做show slave/master status以及slave stop等slave相关命令。

handler_slave_sql循环执行:
03058 while (!sql_slave_killed(thd,rli))
03059 {
03060 thd_proc_info(thd, “Reading event from the relay log”);
03061 DBUG_ASSERT(rli->sql_thd == thd);
03062 THD_CHECK_SENTRY(thd);
03063
03064 if (saved_skip && rli->slave_skip_counter == 0)
03065 {省略
03076 }
03077
03078 if (exec_relay_log_event(thd,rli))
03079 {
03080 DBUG_PRINT(“info”, (“exec_relay_log_event() failed”));
03081 // do not scare the user if SQL thread was simply killed or stopped
03082 if (!sql_slave_killed(thd,rli))
03083 {省略
03144 }
03145 goto err;
03146 }
03147 }

show slave status命令
07409 static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
07410 {
07411 var->type= SHOW_MY_BOOL;
07412 pthread_mutex_lock(&LOCK_active_mi);
07413 var->value= buff;
07414 *((my_bool *)buff)= (my_bool) (active_mi &&
07415 active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
07416 active_mi->rli.slave_running);
07417 pthread_mutex_unlock(&LOCK_active_mi);
07418 return 0;
07419 }

清除锁定表的clear_tables_to_lcok
01222 void Relay_log_info::clear_tables_to_lock()
01223 {
01224 while (tables_to_lock)
01225 {
01226 uchar* to_free= reinterpret_cast(tables_to_lock);
01227 if (tables_to_lock->m_tabledef_valid)
01228 {
01229 tables_to_lock->m_tabledef.table_def::~table_def();
01230 tables_to_lock->m_tabledef_valid= FALSE;
01231 }
01232 tables_to_lock=
01233 static_cast(tables_to_lock->next_global);
01234 tables_to_lock_count–;
01235 my_free(to_free, MYF(MY_WME));
01236 }
01237 DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
01238 }

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Hibernate フレームワークにおける HQL と SQL の違いは何ですか? Hibernate フレームワークにおける HQL と SQL の違いは何ですか? Apr 17, 2024 pm 02:57 PM

HQL と SQL は Hibernate フレームワークで比較されます。HQL (1. オブジェクト指向構文、2. データベースに依存しないクエリ、3. タイプ セーフティ)、SQL はデータベースを直接操作します (1. データベースに依存しない標準、2. 複雑な実行可能ファイル)。クエリとデータ操作)。

Windows 11/10でSUDOコマンドを実行する方法 Windows 11/10でSUDOコマンドを実行する方法 Mar 09, 2024 am 09:50 AM

sudo コマンドを使用すると、ユーザーはスーパーユーザー モードに切り替えることなく、昇格された特権モードでコマンドを実行できます。この記事では、Windows システムで sudo コマンドに似た機能をシミュレートする方法を紹介します。修道コマンドとは何ですか? Sudo (「スーパーユーザー do」の略) は、Linux や MacOS などの Unix ベースのオペレーティング システムのユーザーが、通常は管理者が持つ昇格した権限でコマンドを実行できるようにするコマンド ライン ツールです。 Windows 11/10 での SUDO コマンドの実行 ただし、最新の Windows 11 Insider Preview バージョンのリリースにより、Windows ユーザーはこの機能を体験できるようになりました。この新機能により、ユーザーは次のことが可能になります。

Oracle SQLでの除算演算の使用法 Oracle SQLでの除算演算の使用法 Mar 10, 2024 pm 03:06 PM

「OracleSQLでの除算演算の使用方法」 OracleSQLでは、除算演算は一般的な数学演算の1つです。データのクエリと処理中に、除算演算はフィールド間の比率を計算したり、特定の値間の論理関係を導出したりするのに役立ちます。この記事では、OracleSQL での除算演算の使用法を紹介し、具体的なコード例を示します。 1. OracleSQL における除算演算の 2 つの方法 OracleSQL では、除算演算を 2 つの異なる方法で実行できます。

Oracle と DB2 の SQL 構文の比較と相違点 Oracle と DB2 の SQL 構文の比較と相違点 Mar 11, 2024 pm 12:09 PM

Oracle と DB2 は一般的に使用される 2 つのリレーショナル データベース管理システムであり、それぞれに独自の SQL 構文と特性があります。この記事では、Oracle と DB2 の SQL 構文を比較し、相違点を示し、具体的なコード例を示します。データベース接続 Oracle では、次のステートメントを使用してデータベースに接続します: CONNECTusername/password@database DB2 では、データベースに接続するステートメントは次のとおりです: CONNECTTOdataba

win11 ウィジェットを削除する方法 Windows 11 ウィジェットをアンインストールする 1 つのコマンド機能のヒント win11 ウィジェットを削除する方法 Windows 11 ウィジェットをアンインストールする 1 つのコマンド機能のヒント Apr 11, 2024 pm 05:19 PM

ウィジェットは Win11 システムの新機能で、デフォルトでオンになっていますが、ウィジェットをあまり使用しないユーザーや、スペースを占有するためウィジェットを無効にしたいというユーザーがいることは避けられません。以下のエディターで操作方法が説明されているので、実際に試してみることができます。ウィジェットとは何ですか?ウィジェットは、Windows デスクトップ上のお気に入りのアプリやサービスの動的コンテンツを表示する小さなカードです。これらはウィジェット ボードに表示され、興味を反映するようにウィジェットの検索、固定、固定解除、配置、サイズ変更、カスタマイズを行うことができます。ウィジェット ボードは、使用状況に基づいて関連するウィジェットとパーソナライズされたコンテンツを表示するように最適化されています。タスクバーの左隅からウィジェットパネルを開くと、ライブ天気が表示されます

Linux でサービスを再起動する正しい方法は何ですか? Linux でサービスを再起動する正しい方法は何ですか? Mar 15, 2024 am 09:09 AM

Linux でサービスを再起動する正しい方法は何ですか? Linux システムを使用していると、特定のサービスを再起動する必要がある状況がよく発生しますが、サービスの再起動時に実際にサービスが停止しない、または開始しないなどの問題が発生することがあります。したがって、サービスを再起動する正しい方法を習得することが非常に重要です。 Linux では、通常、systemctl コマンドを使用してシステム サービスを管理できます。 systemctl コマンドは systemd システム マネージャーの一部です

LSOF を使用してポートをリアルタイムで監視する方法 LSOF を使用してポートをリアルタイムで監視する方法 Mar 20, 2024 pm 02:07 PM

LSOF (ListOpenFiles) は、主に Linux/Unix オペレーティング システムと同様のシステム リソースを監視するために使用されるコマンド ライン ツールです。 LSOF コマンドを使用すると、ユーザーはシステム内のアクティブなファイルと、これらのファイルにアクセスしているプロセスに関する詳細情報を取得できます。 LSOF は、ユーザーが現在ファイル リソースを占有しているプロセスを特定するのに役立ち、それによってシステム リソースの管理が改善され、起こり得る問題のトラブルシューティングが可能になります。 LSOF は強力かつ柔軟であり、システム管理者がファイル リーク、閉じられていないファイル記述子などのファイル関連の問題を迅速に特定するのに役立ちます。 LSOF コマンド経由 LSOF コマンド ライン ツールを使用すると、システム管理者と開発者は次のことを行うことができます。 ポートの競合が発生した場合に、どのプロセスが現在特定のファイルまたはポートを使用しているかを確認する

Linuxのldconfigコマンドの詳しい説明 Linuxのldconfigコマンドの詳しい説明 Mar 14, 2024 pm 12:18 PM

Linuxldconfigコマンドの詳細説明 1. 概要 Linuxシステムにおいて、ldconfigは共有ライブラリを設定するためのコマンドです。これは、共有ライブラリのリンクとキャッシュを更新し、システムが動的にリンクされた共有ライブラリを正しくロードできるようにするために使用されます。 ldconfig の主な機能は、ダイナミック リンク ライブラリを検索し、プログラムで使用するシンボリック リンクを作成することです。この記事では、ldconfig コマンドの使用法と動作原理を詳しく説明し、読者が ldconfig の機能をよりよく理解できるように、具体的なコード例を使用します。

See all articles