阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

当master down掉后,pt-heartbeat不断重试会导致内存缓慢增长

167次阅读
没有评论

共计 2354 个字符,预计需要花费 6 分钟才能阅读完成。

最近同事反映,在使用 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%

当 master down 掉后,pt-heartbeat 不断重试会导致内存缓慢增长

现关闭数据库

# service mysqld stop

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

当 master down 掉后,pt-heartbeat 不断重试会导致内存缓慢增长

同样 CPU 时间后,MEM 增长到 4.4%,增长了 1%,考虑到内存 500M,该进程的内存占用增加了 5M,虽然不是很多,但考虑到进程的内存增加并没有停止的意思,这个现象还是要引起注意的。

当 master down 掉后,pt-heartbeat 不断重试会导致内存缓慢增长

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

当 master down 掉后,pt-heartbeat 不断重试会导致内存缓慢增长

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

当 master down 掉后,pt-heartbeat 不断重试会导致内存缓慢增长

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

结论

很奇怪,只是单纯的 die $EVAL_ERROR 不会抛出异常,并退出脚本,但修改后的 die “test:$EVAL_ERROR” 却会退出脚本。

很显然,这确实是个 bug,不知道是不是与 perl 的版本有关。

很好奇,失败的连接如何导致内存的不断增长?

最后,给 percona 官方提了个 bug

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

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-10/135866.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2354字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中