株式会社オズビジョンのユッコ (@terra_yucco) です。
CodeIgniter の DB_Driver 及び config/database.php をデフォルト設定のまま使っていたので、DB オブジェクトを引き回しすぎてバッチ処理がメモリ不足で乙りました。というお話。
CodeIgniter
PHP の軽量フレームワークです。
DB_Driver
名前の通り、DB に接続するためのあれこれが詰まったクラスです。
この中の save_queries
で今回嵌りました。
定義部分
/**
* Save queries flag
*
* Whether to keep an in-memory history of queries for debugging purposes.
*
* @var bool
*/
public $save_queries = TRUE;
利用箇所
上記コードから抜粋
この処理の少し前で SQL を作って $sql
に入れている。
作成した $sql
はこのインスタンスの寿命がある限りどんどん追加されていく。
if ($this->save_queries === TRUE)
{
$this->queries[] = $sql;
}
その他、実行時間も以下のような 2 箇所で保存。
クエリ発行失敗時。
// Run the Query
if (FALSE === ($this->result_id = $this->simple_query($sql)))
{
if ($this->save_queries === TRUE)
{
$this->query_times[] = 0;
}
クエリ発行成功時。
if ($this->save_queries === TRUE)
{
$this->query_times[] = $time_end - $time_start;
}
これもどんどん領域に追加されます。
対処するには
以下のようにすればよいと思われます。最後のところだけ、オリジナルのコードは TRUE
ですが false
にしています。
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => '',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => false, #TRUE
);
実は注意書きもあった
['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
NOTE: Disabling this will also effectively disable both
$this->db->last_query() and profiling of DB queries.
When you run a query, with this setting set to TRUE (default),
CodeIgniter will store the SQL statement for debugging purposes.
However, this may cause high memory usage, especially if you run
a lot of SQL queries ... disable this to avoid that problem.
['save_queries'] true または false
実行されたすべてのクエリを保存するかどうか。
メモ:これを false にすると last_query()
が使えなくなり、またクエリのプロファイリングも使えなくなる。
この設定が true の状態でクエリを走らせると CodeIgniter は SQL ステートメントを debug のために保管する。しかし、特に実行クエリが多い場合、メモリ使用量の高騰の原因になるので、その場合はこの項目を無効にしてその問題を回避してください。
Conclusion
last_query()
が使えなくなるのは地味に痛いので、環境によって変更したり、接続単位で変更してあげるなどの工夫は必要そうです。
ただ、本番環境でデバッグ情報を大量に保持する必要はないので、基本的には設定を切っていきたいなと思った次第…。