Основная причина: не удалось открыть один из файлов zoneinfo.
также вызвано : слишком много открытых файлов.
У меня сегодня была такая же проблемаУбунту 14.04.01-LTS "Trusty Tahr" и пробовал другие ответы безрезультатно.Разрешения были в порядке, файлы были там, содержимое было таким, как ожидалось.
Наконец-то я решил запустить скрипт из жгута проводов командной строки, чтобы можно было попробовать с strace
.И это было результатом:
openat(AT_FDCWD, "/usr/share/zoneinfo/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = -1 EMFILE (Too many open files)
open("/usr/share/zoneinfo/zone.tab", O_RDONLY) = -1 EMFILE (Too many open files)
stat("/usr/share/zoneinfo/Europe/Rome", {st_mode=S_IFREG|0644, st_size=2652, ...}) = 0
open("/usr/share/zoneinfo/Europe/Rome", O_RDONLY) = -1 EMFILE (Too many open files)
write(1, "\nFatal error: Unknown: Timezone "..., 104) = 104
Что происходит
Когда PHP «обращается к базе данных zoneinfo», он фактически пытается открыть каталог и некоторые файлы.Если некоторые из этих операций завершаются неудачно, появляется сообщение «zoneinfo повреждено», но это просто означает, что процесс PHP не смог открыть эти файлы:
- их там не было (chroot jail, ошибка установки zoneinfo)
- их там не было, и не должно быть : "Europe / Roem" - не действительный часовой пояс, а опечатка.
- они были там, но с неправильными разрешениями.
- они были там, но процесс не авторизован (SELinux, AppArmor, ...)
- они были там, но операция
fopen
временно не работает
Мой случай был последним: проблема real заключалась в том, что скрипт открывал слишком много временных файлов и оставлял их открытыми во время работы.Существует ограничение на количество файлов, которые могут быть открыты одновременно, и файл zoneinfo был последней пресловутой каплей.Быстрое исправление временно решило проблему, в то время как я передал проблему «слишком много файлов» ответственному разработчику.
На самом деле я подозреваю, что этот также указывает на PHP, постоянно открывающий и закрывающий базу данных zoneinfo.вместо кеширование это, но это расследование на другой день.
Прерывистая ошибка Количество "открытых файлов" составляет на процесс , не для скрипта PHP .Таким образом, существует два (по крайней мере) сценария, которые могут привести к трудно диагностируемой, возможно, прерывистой / невоспроизводимой ошибке:
- медленная утечка ресурсов из-за какого-то длительного процесса, например, в Racket.
- ресурс, захваченный другим скриптом или подпрограммой, работающей в том же процессе, и, возможно, даже не связанный с PHP вообще .
PHP-скрипт, который,правильно или неправильно, выделение 800 файлов может работать нормально, пока не встретится другой подпроцесс, который выделил 224 файла.Достигнуто ограничение в 1024 открытых файла на процесс, и в в этом случае процесс завершается с загадочной ошибкой (которая при этом загадочно относится к самому последнему признаку в длинной цепочке параллельных причин).
Apache: слишком много веб-сайтов.
Apache, работающий с mod_php5
, приведет к открытию файлов, к которым обращается PHP, процессом Apache.Но процесс Apache также сохраняет свои файлы журнала открытыми, и каждый процесс имеет дескриптор для каждого файла журнала.
Так что если у вас есть 200 веб-сайтов, каждый с независимым access_log, скажем /var/www/somesite/logs/access_log
, каждый процесс будет начинаться с 210 дескрипторов, уже занятых для ведения домашнего хозяйства, в результате чего около PHP будет свободно для использования.
.Производственный сервер (с 200 установленными сайтами) этого не делает, если сценарию необходимо выделить сразу 900 временных файлов.
Грязная диагностика (в Unix / Linux) : glob
/proc/self/fd
и count()
результат.Ужасно, как грех, но он показывает приблизительное число открытых файловых дескрипторов.
Быстрое и грязное исправление (в Unix / Linux) : увеличение fdlimit при открытии каждого процессафайлы, доведя его до 1024 (конечно, вы должны быть root).Это скорее вопрос Ошибка сервера .