binlog_cache_sizeにメモリを食われた話

  • 8
    Like
  • 0
    Comment
More than 1 year has passed since last update.

この記事はMySQL Casual Advent Calendar 2015の17日目です。

マスタのメモリが減っていく

MyISAM+マスタ—スレーブ構成のMySQLを使っているサービスがあったんですが、さすがにMyISAMを使い続けるのもアレなので、InnoDBへバージョンアップすることになりました。

まずはスレーブをInnoDBにしてサービスに投入。問題がないことを確認してからメンテナンスに入れてマスタをInnoDBに変更。
サービスを再開してからしばらく様子を見ていたところ、一見が問題ないように見えたんですが、どうもじわじわメモリが減っている…

グローバルバッファを減らしたり、スレッドバッファを減らしたり、再接続してみたり、テーブルをクローズしてみたりといろいろしてみたんですが、全然メモリの減りが止まらなくて焦りながらいろいろと調査していました。

binlog_cache_sizeが原因だった

検証環境を用意して、大量のコネクションをはってパラメータをいろいろといじってみたところ、なんでかかなり大きく設定されていたbinlog_cache_sizeののサイズを減らすと、メモリ使用量が減ることが分かりました。

ちなみに再現時のMySQL(5.6.27)の設定はこんな感じ。

[mysqld]
...
innodb_buffer_pool_size = 5G
max_connections = 5000
log-bin
binlog_cache_size = 16M
thread_cache_size = 0

検証用のRubyプログラムはこんな感じ。

#!/usr/bin/env ruby
require 'mysql2'
require 'thread'

options = {host: '10.0...', port: 3306, database: 'test', username: 'scott', password: 'tiger'}
data = 'X' * 255

4000.times.map {
  Thread.start do
    client = Mysql2::Client.new(options)
    loop do
      begin
        client.query("SELECT * FROM test LIMIT 10000")
        client.query("INSERT INTO test VALUES ('#{data}')")
        sleep 1
      rescue => e
        p e
      end
    end
    client.close
  end
}.each {|t| t.join }

※ちなみにこのプログラムをmysql2 4.2で動かすとなんでかSEGVします

binlog_cache_sizeを変更してみた

binlog_cache_sizeは動的に変更できるので、稼働しているサーバでset global binlog_cache_size=...を実行して、コネクションを再接続してみました。

15bffbde.JPG

メモリのじわ減りは止まらずっ………!

検証環境でも再現したんですが、set global binlog_cache_size=...でサイズ変更しても、じわじわ減っていくんですよね。flush logsしたり、binlogをパージしたりすると少し回復するんですが、全体の傾向としてはメモリは増え続けたままでした。

結局

結局、待機系のMySQLの設定を変更して再起動して、そちらの方にフェイルオーバーするということをやりました。変更して再起動したあとのMySQLでは、同様の状況は発生していません。

すいません、この件原因を追い切れていません…
何かご存じの方がいましたらご教授ください :bow:

あまり知見のない記事ですが、もし同様の状況で困っている方がいましたら、参考になれば幸いです。

This post is the No.17 article of MySQL Casual Advent Calendar 2015