【解決】mysql-connector-pythonでメモリリーク


もはや解決済みなので備忘録程度に。

発生条件

  • バージョン:8.0.17(私が確認した限り)
  • C実装版(接続時にuse_pure=False、あるいは指定なし)
  • named_tuple=True

他にも条件があるのかもしれないが、私が確認した限りはこんな感じだった。

事象

普通にデータベースに接続してカーソルを開いてレコードをフェッチすると思うんだけど、使い終わったカーソルやコネクションをcloseしてもメモリが解放されない。なんとも致命的なメモリリーク・・・。要するに、普通に使ってると、どんどんメモリ使用量が増えてくるということ。数百万件のレコードを処理するバッチを動かしているときに発見できた。

MySQL Bugs: #93711

解決方法

mysql-connector-pythonのアップデート

ができる状況ならアップデートで解決。8.0.18で直ってる。

どうしてもアップデートできない

のなら、デフォルトのC実装ではなくPython実装を使用するという手がある。Python実装版だとメモリリークは発生しない。Python実装を使用する方法はデータベースに接続する際に、use_pure オプションを渡してやればよい。

import mysql.connector

cnx = mysql.connector.connect(user='scott', password='password',
                              host='127.0.0.1',
                              database='employees',
                              use_pure=True)

なお、私の環境だとなぜかSSL関連のエラーが発生したのだが、ssl_disabled=True を指定することで回避できた。

なお当然だけどPython実装はC実装より遅い(だいたい1.5〜2倍程度かなぁ?)ので、可能であるならアップデートをおすすめする。

関連する記事


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください