MySQL当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-heartbeat

root       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-table
root       1563   1545  2 19:50 pts/3    00:00:00 grep pt-heartbeat

查阅该过程的内存使用率

# top -p 1505

运行了0:15.00(TIME+列),MEM一直平稳在3.3%

MySQL 1

 

临时关闭数据库

# service mysqld stop

 

刚才之pt-heartbeat命令不断输出以下信息

MySQL 2

 

同一CPU时间晚,MEM增长至4.4%,
增长了1%,考虑到内存500M,该过程的内存占用多了5M,虽然非是群,但考虑到过程的内存增加并不曾停歇的意思,这个状况还是要引注意的。

MySQL 3

 

以,通过pmap命令,发现,0000000001331000地址的RSS和Dirry也会见增进,增长之速率是4k/s

MySQL 4

 

新生研究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命令异常退出

MySQL 5

“test:”就是在的测试字符。

 

结论

死奇怪,只是一味的die
$EVAL_ERROR不会见扔来老,并退脚本,但修改后底die
“test:$EVAL_ERROR”却会脱离脚本。

万分明朗,这实在是单bug,不明白凡是不是同perl的本子有关。

那个奇异,失败的连如何造成内存的缕缕增强?

最终,给percona官方提了只bug

https://bugs.launchpad.net/percona-toolkit/+bug/1629164

 

网站地图xml地图