共計 2590 個字符,預計需要花費 7 分鐘才能閱讀完成。
行業資訊
數據庫
當 master down 掉后 pt-heartbeat 不斷重試會導致內存緩慢增長的原因及解決辦法
當 master down 掉后,pt-heartbeat 不斷重試會導致內存緩慢增長的原因及解決辦法,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
最近同事反映,在使用 pt-heartbeat 監控主從復制延遲的過程中,如果 master down 掉了,則 pt-heartbeat 則會連接失敗,但會不斷重試。
重試本無可厚非,畢竟從使用者的角度來說,希望 pt-heartbeat 能不斷重試,直到重新連接上數據庫。但是,他們發現,不斷的重試會帶來內存的緩慢增長。
重現
環境:
pt-heartbeat v2.2.19,MySQL 社區版 v5.6.31,Perl v5.10.1,RHEL 6.7,內存 500M
為了避免數據庫啟停對 pt-heartbeat 內存使用率的影響,故 MySQL 和 pt-heartbeat 分別運行在不同的主機上。
運行 pt-heartbeat
# pt-heartbeat –update -h 192.168.244.10 -u monitor -p monitor123 -D test –create-table
監控 pt-heartbeat 的內存使用率
獲取 pid
# ps -ef |grep pt-heartbeatroot 1505 1471 0 19:13 pts/0 00:00:08 perl /usr/local/bin/pt-heartbeat --update -h 192.168.244.10 -u monitor -p monitor123 -D test --create-tableroot 1563 1545 2 19:50 pts/3 00:00:00 grep pt-heartbeat
查看該進程的內存使用率
# top -p 1505
運行了 0:15.00(TIME+ 列),MEM 一直穩定在 3.3%
現關閉數據庫
# service mysqld stop
剛才的 pt-heartbeat 命令不斷輸出以下信息
同樣 CPU 時間后,MEM 增長到 4.4%,增長了 1%,考慮到內存 500M,該進程的內存占用增加了 5M,雖然不是很多,但考慮到進程的內存增加并沒有停止的意思,這個現象還是要引起注意的。
同時,通過 pmap 命令,發現,0000000001331000 地址的 RSS 和 Dirry 也會增長,增長的速率是 4k/s
后來研究 pt-heartbeat 的源碼,才發現代碼有點 bug
my $tries = 2;while ( !$dbh $tries-- ) {PTDEBUG _d($cxn_string, , $user, , $pass,join( , , map { $_= $defaults- {$_} } keys %$defaults ));$dbh = eval { DBI- connect($cxn_string, $user, $pass, $defaults) };if ( !$dbh $EVAL_ERROR ) {if ( $EVAL_ERROR =~ m/locate DBD\/mysql/i ) {die Cannot connect to MySQL because the Perl DBD::mysql module is . not installed or not found. Run perl -MDBD::mysql to see . the directories that Perl searches for DBD::mysql. If . DBD::mysql is not installed, try:\n . Debian/Ubuntu apt-get install libdbd-mysql-perl\n . RHEL/CentOS yum install perl-DBD-MySQL\n . OpenSolaris pgk install pkg:/SUNWapu13dbd-mysql\n}elsif ( $EVAL_ERROR =~ m/not a compiled character set|character set utf8/ ) {PTDEBUG _d( Going to try again without utf8 support delete $defaults- {mysql_enable_utf8};}if ( !$tries ) {die $EVAL_ERROR;}}}
以上代碼摘自 get_dbh 函數,用于獲取數據庫的連接,如果獲取失敗,則重試 1 次,然后通過 die 函數拋異常退出。
但是,通過設置如下斷點,發現當 $tries 為 0 時,if 函數里面的 PTDEBUG _d($EVAL_ERROR) 語句能執行,但 die 函數就是沒有拋出異常,并退出腳本
PTDEBUG _d($tries);if ( !$tries ) {PTDEBUG _d( $EVAL_ERROR die $EVAL_ERROR; }
后來,將上述代碼的最后一個 if 函數修改如下:
if ( !$tries ) {die test:$EVAL_ERROR}
再次測試
啟動數據庫
# service mysqld start
執行 pt-heartbeat 命令
# pt-heartbeat –update -h 192.168.244.10 -u monitor -p monitor123 -D test –create-table
停止數據庫
# service mysqld stop
剛才執行的 pt-heartbeat 命令異常退出
“test:”就是加入的測試字符。
很奇怪,只是單純的 die $EVAL_ERROR 不會拋出異常,并退出腳本,但修改后的 die test:$EVAL_ERROR 卻會退出腳本。
很顯然,這確實是個 bug,不知道是不是與 perl 的版本有關。
很好奇,失敗的連接如何導致內存的不斷增長?
看完上述內容,你們掌握當 master down 掉后,pt-heartbeat 不斷重試會導致內存緩慢增長的原因及解決辦法的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注丸趣 TV 行業資訊頻道,感謝各位的閱讀!