База данных часового пояса 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));
}

может быть это может помочь вам PHP-установить часовой пояс


Я меняю файл localtime для своей настройки GMT, например mv / usr / share/zoneinfo / Азия / Карачи местное время Затем возникает ошибка преследует.

date_default_timezone_get (): база данных часового пояса повреждена - это должно никогда произойдет!

решение : вернуть вам установка местного времени. Советы: Всегда держите резервную копию вашего старого местного времени, чтобы вы могли восстановить любую ожидаемую проблему ОС / программного обеспечения