2012-01-05 20 views
9

मेरे पास एक वर्डप्रेस वेबसाइट है जो अचानक काम करना बंद कर देती है। जब मैं लॉग मैं देख रहा हूँ और त्रुटि को देखो:PHP टाइमज़ोन डेटाबेस दूषित त्रुटि

[error] [client 50.78.108.177] PHP Fatal error: strtotime(): Timezone database is corrupt - this should never happen!

गूगल पर पढ़ने के बाद एक व्यक्ति ने कहा कि वे /usr/share/zoneinfo में अनुमतियों की समस्या की खोज की। मैंने 777, 775, 770 पर अनुमतियों को बदलने की कोशिश की और मुझे अभी भी वही त्रुटि मिल रही है। मैं उबंटू 10.04.3 एलटीएस पर PHP PHP 5.3.2 चला रहा हूं। कोई सुझाव या सिफारिशें सहायक होंगी। अगर सब कुछ विफल हो जाता है तो मैं 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) 

string(5) "d.m.y" string(1) "m" string(5) "d.m.y" string(1) "m" string(5) "d.m.y" string(1) "m"

var_dump($mysqlstring) 

string(19) "2011-10-20 05:35:01" string(19) "2011-10-20 05:35:01" string(19) "2011-10-20 05:25:22" string(19) "2011-10-20 05:25:22" string(19) "2011-10-19 05:10:06" string(19) "2011-10-19 05:10:06"

अद्यतन # 4:

:
एक और कोड स्निपेट कि त्रुटि लॉग नीचे पैदा कर रहा है है

PHP Fatal error: date(): Timezone database is corrupt - this should never happen! in /srv/www/motionthink.com/public_html/wp-admin/includes/class-wp-filesystem-direct.php on line 346, referer: wp_root_directory/wp-admin/plugins.php?plugin_status=upgrade

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 रिटर्न

Build Date => Dec 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 फ़ाइल संपादित और इस उत्पादन मिला

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 को पुनरारंभ किया। मैं अभी भी त्रुटि

उत्तर

2

समस्या फ़ाइल अनुमतियां थीं। मैंने apache2 उपयोगकर्ता को & पढ़ने के लिए usr/share/zoneinfo और आदि/localtime तक पहुंच निष्पादित की। इससे पहले, मैंने स्थानीय समय के माता-पिता को सही अनुमतियों पर भी सेट नहीं किया था। यानी मैंने अपनी मूल निर्देशिकाओं की अनुमतियों को बदले बिना लोकलटाइम और जोनिनोफ़ो की अनुमतियों को केवल बदल दिया है। कितना मूर्ख! किसी समस्या से दूर कदम उठाना और इसे वापस लेना हमेशा उपयोगी होता है।

+0

* उदास पांडा *, यह सब डिबगिंग:/ –

0

इस, आप PHP – Set Timezone

+0

इसके लिए धन्यवाद। जब मैं निर्देशों का पालन करता हूं तो यह दिनांक दिखाता है: गुरु, 05 जनवरी 2012 15:20:54 –

1

आप पदावनति 'का उल्लेख मदद कर सकते हैं हाल ही में उन्नयन होने पर हो सकता है? PHP 5.3.x में आपको अपनी php.ini फ़ाइल में date.timezone के लिए मान्य मान सेट करने के लिए मजबूर होना पड़ता है।

यदि आपने हाल ही में अपग्रेड नहीं किया है तो आप tzdata पैकेज को फिर से इंस्टॉल करके इस समस्या को हल करने का प्रयास करें। मैं विशेष रूप से सेंटोस के साथ काम करता हूं, इसलिए मुझे यकीन नहीं है कि उबंटू के पैकेज मैनेजर का नाम क्या है, लेकिन मुझे पूरा यकीन है कि 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 को पुनरारंभ करना चाहेंगे।

- संपादित करें

ऐसा लगता है कि अपराधी, अपने date_i18n() फ़ंक्शन, जो हमेशा कहा जाता है किया जा रहा है जब तक बुला कोड विशेष रूप से 'गलत' की एक 3 आर्ग से गुजरता है। मैंने आपके डेटा को कुछ टेस्ट डेटा के माध्यम से $ अनुवाद सेट के साथ गलत पर सेट किया, और ठीक काम किया।

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)); 
} 
+0

+0

क्षमा करें मेरा कहना है कि क्या आपको लगता है कि मुझे अभी भी tzdata को पुनर्स्थापित करना चाहिए, यहां तक ​​कि सोचा था कि ऊपर दी गई मेरी टिप्पणी में php स्क्रिप्ट ने तिथि वापस कर दी है? इसके अलावा, मैंने हाल ही में एक एपीटी-अपडेट अपडेट –

+0

किया है, मैंने tzdata (apt-get install --reinstall tzdata) को पुनर्स्थापित किया है और यह मुझे बताता है कि स्थानीय समय अब ​​है: गुरु जनवरी 5 15:39:24 पीएसटी 2012। यूनिवर्सल टाइम अब है: गुरु जनवरी 5 23:39:24 यूटीसी 2012. –

13

यह समस्या क्रोट मोड में php-fpm का उपयोग करते समय भी हो सकती है, इस मामले में समाधान आपके chroot dir में/usr/share/zoneinfo/यूरोप जैसे कुछ बनाने के लिए हो सकता है, फिर अपनी टीजेड फ़ाइल को इसमें कॉपी करें। लंदन

+0

बहुत बढ़िया है, यह वही है जो मुझे अपने अपाचे सर्वर को chrooting के बाद आवश्यक था और केवल कुछ PHP स्क्रिप्ट तोड़ रहे थे। त्रुटि लॉगिंग चालू करने पर मैंने पाया कि यह मुद्दा था (हालांकि मैंने इसके बजाय मेरी क्रोट जेल में '/ usr/share/zoneinfo/*' से सब कुछ कॉपी किया है)। – Breakthrough

6

रूट कारण: ज़ोनिन्फो फ़ाइलों में से एक खोला नहीं जा सका।

के कारण भी: बहुत सारी खुली फ़ाइलें।

मुझे उबंटू 14.04.01-एलटीएस "ट्रस्टी ताहर" पर आज भी यही समस्या थी, और बिना किसी लाभ के अन्य उत्तरों की कोशिश की। अनुमतियां ठीक थीं, फाइलें थीं, सामग्री की अपेक्षा की गई थी।

आखिर में मैंने स्क्रिप्ट को कमांड लाइन दोहन के भीतर से चलाने का संकल्प किया, ताकि मैं 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 

क्या

हो रहा है जब पीएचपी "zoneinfo डेटाबेस तक पहुँचता है" यह वास्तव में एक निर्देशिका और कुछ फ़ाइलों को खोलने की कोशिश करता है: और यह परिणाम था। अगर इनमें से कुछ अभियान असफल, "भ्रष्ट zoneinfo" संदेश दिखाई देता है, लेकिन यह केवल कि PHP प्रक्रिया नहीं उन फ़ाइलों को खोल सकते अर्थ है:

  • वे वहाँ नहीं थे (क्रूट जेल त्रुटि स्थापित zoneinfo,)
  • वे वहां नहीं थे, और न ही होना चाहिए: "यूरोप/रोम" वैध टाइमज़ोन नहीं है लेकिन एक टाइपो है।
  • वे वहां थे, लेकिन गलत अनुमतियों के साथ।
  • वे वहाँ थे, लेकिन इस प्रक्रिया के लिए अधिकृत है नहीं (SELinux, निकल रहा, ...)
  • वे वहाँ थे, लेकिन fopen कार्य अस्थायी रूप से काम नहीं कर रहा

मेरे मामले पिछले एक था : वास्तविक समस्या यह थी कि स्क्रिप्ट बहुत अधिक अस्थायी फ़ाइलों को खोलने खोल रही थी, और चलते समय उन्हें खुली छोड़ दी गई थी। एक ही समय में कितनी फाइलें खोली जा सकती हैं इस पर एक सीमा है, और जोनिनोफ़ो फ़ाइल पिछली स्ट्रॉ कहलाती थी।एक त्वरित फिक्स ने समस्या को अस्थायी रूप से हल किया, जबकि मैंने डेवलपर को "बहुत सारी फाइलें" समस्या को बाउंस किया।

वास्तव में मुझे लगता है कि पीएचपी को यह भी अंक लगातार खोलने और कैशिंग यह करने के बजाय zoneinfo डेटाबेस को बंद करने, लेकिन यह एक और दिन के लिए एक जांच है।

आंतरायिक त्रुटि "खुला फ़ाइलों की संख्या" thingy प्रक्रिया प्रति, नहीं PHP स्क्रिप्ट प्रति है। तो दो (कम से कम) परिदृश्यों जो एक मुश्किल से निदान, संभवतः रुक-रुक कर/nonreproducible त्रुटि हो सकती हैं:

  • कुछ लंबी चलने वाली प्रक्रिया है, उदा एक धीमी गति से संसाधन रिसाव रैकेट के नीचे।
  • एक ही प्रक्रिया में चल रहे किसी अन्य स्क्रिप्ट या सबराउटिन द्वारा संसाधन संसाधन हो रहा है, और संभवतः सभी पर PHP से संबंधित नहीं है।

एक PHP स्क्रिप्ट जो सही या गलत है, 800 फाइल आवंटित कर सकती है ठीक है जब तक कि यह 224 फ़ाइलों को आवंटित करने वाले किसी अन्य उपप्रोसेस को पूरा न करे। प्रति प्रक्रिया 1024 खुली फाइलों की सीमा तक पहुंच जाती है और उस मामले में प्रक्रिया एक रहस्यमय त्रुटि के साथ विफल हो जाती है (जो केवल उस पर क्रिप्टिक रूप से संदर्भित करती है, समवर्ती कारणों की लंबी श्रृंखला में अंतिम लक्षण के लिए)।

अपाचे: बहुत सारी वेबसाइटें।

mod_php5 के साथ चल रहे अपाचे अपाचे प्रक्रिया द्वारा PHP को खोले जाने वाले फ़ाइलों का उपयोग करेगा। लेकिन अपाचे प्रक्रिया भी लॉग फ़ाइलों को खोलती है, और प्रत्येक प्रक्रिया में प्रत्येक लॉग फ़ाइल के लिए एक हैंडल होता है।

तो यदि आपके पास 200 वेब साइटें हैं, प्रत्येक एक स्वतंत्र access_log के साथ, /var/www/somesite/logs/access_log कहें, प्रत्येक प्रक्रिया हाउसकीपिंग के लिए पहले से ही 210 हैंडल के साथ शुरू होगी, PHP के उपयोग के लिए कुछ 800 मुक्त छोड़ देंगी।

इससे ऐसी स्थिति हो सकती है जहां विकास सर्वर (एक साइट के साथ) काम करता है, और उत्पादन सर्वर (200 साइटों के साथ स्थापित) नहीं होता है, अगर स्क्रिप्ट को एक बार में 900 अस्थायी फ़ाइलों को आवंटित करने की आवश्यकता होती है।

गंदा निदान (यूनिक्स/लिनक्स पर): glob/proc/self/fd और count() परिणाम। पाप के रूप में बदसूरत, लेकिन यह एक ballpark आंकड़ा देता है कि कितने फ़ाइल वर्णनकर्ता वास्तव में खुले हैं।

त्वरित और गंदे फिक्स (यूनिक्स/लिनक्स पर): प्रति-प्रक्रिया खुली फ़ाइलों पर fdlimit बढ़ाएं, इसे 1024 तक लाएं (बेशक आपको जड़ की आवश्यकता है)। यह Server Fault के लिए एक और बात है।

+0

दरअसल यह मामला बन गया, जब मैं एक अपलोडर को चंक और समवर्ती समर्थन के साथ कोडिंग कर रहा था। –

संबंधित मुद्दे