База данных часового пояса PHP повреждена
у меня есть сайт wordpress, который внезапно перестал работать сегодня. Когда я смотрю на журналы, я вижу и ошибку:
[ошибка] [клиент 50.78.108.177] PHP фатальная ошибка: strtotime (): часовой пояс база данных повреждена-это должно никогда произойдет!
после прочтения в google один человек сказал, что они обнаружили проблему с разрешениями в / usr/share / zoneinfo. Я попытался изменить разрешения на 777, 775, 770 и I все еще продолжайте получать ту же ошибку. Я запускаю php PHP 5.3.2 на Ubuntu 10.04.3 LTS. Любые предложения или рекомендации были бы полезны.Если все остальное не удается, я собираюсь попробовать понизить до более ранней версии php, но я хотел попробовать другие вещи, прежде чем делать это.
спасибо, Timnit
обновление
на всякий случай это помогает: ошибка указывает на strtotime
в функции ниже
function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
$m = $mysqlstring;
if ( empty( $m ) )
return false;
if ( 'G' == $dateformatstring )
return strtotime( $m . ' +0000' );
$i = strtotime( $m );
if ( 'U' == $dateformatstring )
return $i;
if ( $translate )
return date_i18n( $dateformatstring, $i );
else
return date( $dateformatstring, $i );
}
обновление#2:
для теперь я исправил проблему, просто имея функцию выше return false;
ничего не выполняя. Однако я до сих пор не выяснили причину этой проблемы.
обновление#3:
var_dump($dateformatstring)
строка(5) "д'.м.г" строка(1) "м" строка(5) "д'.м.г" строка(1) "м" строка (5) " d.м. y " строка(1)"m"
var_dump($mysqlstring)
строка(19) "2011-10-20 05:35:01" струна(19) "2011-10-20 05:35:01" string (19) " 2011-10-20 05: 25: 22" string(19) "2011-10-20 05:25:22" струна(19) "2011-10-19 05:10:06" струна(19) "2011-10-19 05:10:06"
обновление#4:
существует еще один фрагмент кода, который генерирует журнал ошибок ниже:
PHP фатальная ошибка: date (): база данных часового пояса повреждена - это должно никогда произойдет! в /srv/www/motionthink.com/public_html/wp-admin/includes/class-wp-filesystem-direct.php on линия 346, реферера: wp_root_directory / wp-admin / Плагины.РНР?plugin_status=обновление
309 function dirlist($path, $include_hidden = true, $recursive = false) {
310 if ( $this->is_file($path) ) {
311 $limit_file = basename($path);
312 $path = dirname($path);
313 } else {
314 $limit_file = false;
315 }
316
317 if ( ! $this->is_dir($path) )
318 return false;
319
320 $dir = @dir($path);
321 if ( ! $dir )
322 return false;
323
324 $ret = array();
325
326 while (false !== ($entry = $dir->read()) ) {
327 $struc = array();
328 $struc['name'] = $entry;
329
330 if ( '.' == $struc['name'] || '..' == $struc['name'] )
331 continue;
332
333 if ( ! $include_hidden && '.' == $struc['name'][0] )
334 continue;
335
336 if ( $limit_file && $struc['name'] != $limit_file)
337 continue;
338
339 $struc['perms'] = $this->gethchmod($path.'/'.$entry);
340 $struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
341 $struc['number'] = false;
342 $struc['owner'] = $this->owner($path.'/'.$entry);
343 $struc['group'] = $this->group($path.'/'.$entry);
344 $struc['size'] = $this->size($path.'/'.$entry);
345 $struc['lastmodunix']= $this->mtime($path.'/'.$entry);
346 $struc['lastmod'] = date('M j',$struc['lastmodunix']);
347 $struc['time'] = date('h:i:s',$struc['lastmodunix']);
348 $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd:'f';
349
обновление#5:
делать php -i | fgrep -i date
возвращает
Дата Сборки => 13 Дек 2011 18:43:02
date date/time support => enabled date.default_latitude => 31.7667 => 31.7667 date.default_longitude => 35.2333 => 35.2333 date.sunrise_zenith => 90.583333 => 90.583333 date.sunset_zenith => 90.583333 => 90.583333 date.timezone => no value => no value
затем я отредактировал php.ini файл, чтобы установить часовой пояс на "America / Los Angeles" и получил этот вывод
date/time support => enabled
date.default_latitude => 31.7667 => 31.7667
date.default_longitude => 35.2333 => 35.2333
date.sunrise_zenith => 90.583333 => 90.583333
date.sunset_zenith => 90.583333 => 90.583333
date.timezone => America/Los_Angeles => America/Los_Angeles
затем я перезапустил apache2. Я все еще получаю ошибку
6 ответов
эта проблема также может возникнуть при использовании php-fpm в режиме chroot, решение в этом случае должно быть создать что-то вроде /usr/share/zoneinfo/Europe в вашем каталоге chroot, а затем скопировать файл TZ в него, например, London
первопричина: не удалось открыть один из файлов zoneinfo.
также вызвано: слишком много открытых файлов.
у меня была та же проблема сегодня на Ubuntu 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)
- их там не было,не должно быть: "Европа / Roem" - это не допустимый часовой пояс, а опечатка.
- они были там, но с неправильными разрешениями.
- они были там, но процесс не авторизован (SELinux, AppArmor,...)
- они были там, но
fopen
операция временно не работает
мой случай был последним:реальные проблема была в том, что сценарий был открывая слишком много временных файлов, и оставляя их открытыми во время работы. Существует ограничение на количество файлов, которые могут быть открыты одновременно, и файл zoneinfo был пресловутой последней каплей. Быстрое исправление временно разрешило проблему, в то время как я отскочил от проблемы "слишком много файлов" ответственному разработчику.
на самом деле я подозреваю, что это и указывает на PHP, постоянно открывающий и закрывающий базу данных zoneinfo вместо кэширование, но это расследование еще день.
перемежающаяся ошибка "Количество открытых файлов" - это в процессе, а не в php-скрипт. Таким образом, есть два (по крайней мере) сценария, которые могут привести к труднодиагностируемой, возможно, прерывистой/невоспроизводимой ошибке:
- медленная утечка ресурсов каким-то длительным процессом, например, под ракеткой.
- ресурс, захваченный другим скриптом или подпрограммой, запущенной в том же процессе, и возможно!--28-->даже не связано с PHP вообще.
скрипт PHP, который, правильно или неправильно, выделяет 800 файлов, может работать нормально, пока не встретится с другим подпроцессом, который выделил 224 файла. Достигнут предел 1024 открытых файлов на процесс и в этом случае процесс терпит неудачу с таинственной ошибкой (которая только относится, загадочно при этом, к самому последнему симптому в длинной цепи параллельных причин).
Apache: слишком много веб места.
Apache работает с mod_php5
приведет к тому, что файлы, доступные PHP, будут открыты процессом Apache. Но процесс Apache также сохраняет свой лог-файлы открыть, и каждый процесс имеет дескриптор для каждого файла журнала.
Итак, если у вас есть 200 веб-сайтов, каждый с независимым access_log, скажите /var/www/somesite/logs/access_log
, каждый процесс начнется с некоторых 210 дескрипторов, уже взятых для уборки, оставив около 800 бесплатных для использования PHP.
это может привести к ситуация, когда сервер разработки (с одним сайтом) работает, а производственный сервер (с установленными 200 сайтами) - нет, если скрипту необходимо выделить сразу 900 временных файлов.
грязная диагностика (в Unix/Linux): glob
/proc/self/fd
и count()
результат. Уродливый, как грех, но он дает приблизительную цифру о том, сколько дескрипторов файлов на самом деле открыто.
быстрое и грязное исправление (в Unix/Linux): увеличение fdlimit на для каждого процесса откройте файлы, доведя его до 1024 (конечно, вам нужно быть root). Это больше вопрос для Ошибка Сервера.
проблема заключалась в разрешениях файлов. Я дал пользователю apache2 доступ для чтения и выполнения usr/share/zoneinfo и etc / localtime. Раньше я не устанавливал родителям местного времени правильные разрешения. т. е. я только изменил разрешения localtime и zoneinfo без изменения разрешений их родительских каталогов. Так глупо! Уход от проблемы и возвращение к ней всегда полезны.
вы упомянули "понижение", вы недавно обновили? В PHP 5.3.X вы вынуждены установить допустимое значение date.timezone
в вашем php.ini-файл.
если вы недавно не обновили, попробуйте решить проблему, переустановив . Я работаю исключительно с CentOS, поэтому я не уверен, как называется менеджер пакетов Ubuntu, но я уверен tzdata
является стандартным для дистрибутивов.
$ -> yum reinstall tzdata # switch 'yum' for Ubuntu package manager
$ -> rm -f /etc/localtime
$ -> ln -sf /usr/share/zoneinfo/UTC /etc/localtime # 'UTC' can be replaced with what you prefer
$ -> date # check to see that it stuck
вы можете перезапустить httpd после этого, чтобы обеспечить часовой пояс взял.
-- Edit
похоже, что виновником является ваша функция date_i18n (), которая всегда вызывается, если вызывающий код специально не передает 3-й arg 'false'. Я пропустил ваш код через некоторые тестовые данные с $translate, установленным на false, и работал нормально.
function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
$translate = false;
...
if ( $translate )
return 'date_i18n would have been called';
//return date_i18n( $dateformatstring, $i );
...
}
$testPatterns = array(
array(
'dateformatstring' => 'd.m.y',
'mysqlstring' => '2011-10-20 05:35:01'
),
array(
'dateformatstring' => 'm',
'mysqlstring' => '2011-10-20 05:35:01'
),
array(
'dateformatstring' => 'd.m.y',
'mysqlstring' => '2011-10-20 05:25:22'
)
);
foreach ($testPatterns as $testPattern) {
// Not passing arg to over-ride $translate, forces call to date_i18n()
var_dump(mysql2date($testPattern['dateformatstring'], $testPattern['mysqlstring']));
// Forcing $translate to false, makes date() call which works fine
var_dump(mysql2date($testPattern['dateformatstring'], $testPattern['mysqlstring'], false));
}
Я меняю файл localtime для своей настройки GMT, например mv / usr / share/zoneinfo / Азия / Карачи местное время Затем возникает ошибка преследует.
date_default_timezone_get (): база данных часового пояса повреждена - это должно никогда произойдет!
решение : вернуть вам установка местного времени. Советы: Всегда держите резервную копию вашего старого местного времени, чтобы вы могли восстановить любую ожидаемую проблему ОС / программного обеспечения