end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

mysqldump: Got error: 1016: Can't open file: './〜/〜.frm' (errno: 24) when using LOCK TABLES

show tablesすると、953テーブルもあるサービスのmysqldumpを実行したら、次のようなエラーが発生しました。

$ mysqldump -u ないしょ -p ないしょ | gzip -c > ~/tmp/db.dmp.gz
Enter password: 
mysqldump: Got error: 1016: Can't open file: './〜/〜.frm' (errno: 24) when using LOCK TABLES

mysqldumpは実行時にテーブルロックしてるらしい

http://backslash.ddo.jp/wordpress/archives/211
↑このurlによると、mysqldumpでは実行時にテーブルロックを行なっており、テーブル数が多すぎると、今回のようなエラーが発生するらしい。

対策1) --skip-lock-tables をつけてmysqldump実行

実行中にデータが変更されるおそれがありますが...

$ mysqldump --skip-lock-tables -u ないしょ -p ないしょ | gzip -c > ~/tmp/db.dmp.gz

対策2) my.cnfのopen_files_limit を増やす

mysql> show variables like 'open_%' ;
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1185  |
+------------------+-------+

show tables=953で、open_files_limit=1185だから足りているように思えますが、open_files_limitに関しては、次のurlに分かりやすく記載されています。

http://d.hatena.ne.jp/tmtms/20090605/1244215294

mysqld が同時に使用可能なファイル数は open_files_limit というパラメータで指定します。
ただし、mysqld は最低でも table_cache*2+max_connections+10 --- (a) は必要だと考えるので、open_files_limit が (a) よりも小さければ、黙って (a) の値まで大きくします。
table_cache を2倍しているのは、MyISAM が1テーブルにつき2ファイル使用するためでしょう。
10 を足しているのは標準入出力エラー出力と、ログファイル等の分でしょうか。

また、max_connections*5 --- (b) の方が (a) よりも大きければ、open_files_limit は (b) になります。

(a), (b) よりも現在のファイル記述子の制限値(getrlimit(2) の rlim_cur の値) --- (c) が大きければ、(c) が採用されます。

なので、my.cnfに次のような記述を追加しても解消できそうです。

[mysqld]
open_files_limit=2048