2012-01-05 25 views
9

Tôi có trang web wordpress đột ngột ngừng hoạt động ngay hôm nay. Khi tôi nhìn vào các bản ghi tôi nhìn thấy và báo lỗi:Cơ sở dữ liệu múi giờ PHP là lỗi bị lỗi

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

Sau khi đọc lên trên google một người nói rằng họ đã phát hiện ra một vấn đề quyền trong /usr/share/zoneinfo. Tôi đã thử thay đổi các điều khoản cho 777, 775, 770 và tôi vẫn tiếp tục nhận được lỗi tương tự. Tôi đang chạy php PHP 5.3.2 trên Ubuntu 10.04.3 LTS. Bất kỳ đề xuất hoặc đề xuất nào đều hữu ích. Nếu mọi thứ khác không thành công, tôi sẽ cố gắng hạ cấp xuống phiên bản cũ hơn của php nhưng tôi muốn thử những thứ khác trước khi thực hiện điều đó.

cảm ơn, Timnit

Cập nhật
chỉ trong trường hợp nó giúp: các điểm lỗi để strtotime trong hàm dưới

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

Cập nhật # 2:
cho bây giờ tôi đã khắc phục sự cố bằng cách chỉ cần có hàm ở trên return false; mà không thực hiện bất kỳ điều gì. Tuy nhiên tôi vẫn chưa tìm ra nguyên nhân gốc rễ của vấn đề.

cập nhật # 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"

cập nhật # 4:
có một đoạn mã được tạo ra các bản ghi lỗi dưới đây:

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 

Cập nhật # 5:
làm một php -i | fgrep -i date lợi nhuận

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 

sau đó tôi đã chỉnh sửa file php.ini để thiết lập múi giờ để "Châu Mỹ/Los Angeles" và nhận được kết quả này

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 

Tôi sau đó khởi động lại apache2. Tôi vẫn nhận được lỗi

Trả lời

2

Sự cố là quyền của tệp. Tôi đã cho người dùng apache2 đọc & thực hiện quyền truy cập vào usr/share/zoneinfo và vv/localtime. Trước đây, tôi đã không đặt cha mẹ của thời gian địa phương để quyền truy cập là tốt. tức là tôi chỉ thay đổi quyền của localtime và zoneinfo mà không thay đổi quyền của thư mục cha mẹ. Thật ngu ngốc! Bước ra khỏi một vấn đề và nhận được trở lại với nó luôn luôn là hữu ích.

+0

* panda buồn *, tất cả những gì đang gỡ lỗi:/ –

0

có thể điều này có thể giúp bạn PHP – Set Timezone

+0

cảm ơn vì điều đó. Khi tôi làm theo các hướng dẫn nó hiển thị ngày: Thu, 05 Jan 2012 15:20:54 –

1

Bạn đề cập đến 'hạ cấp', gần đây bạn đã nâng cấp? Trong PHP 5.3.x, bạn buộc phải đặt giá trị hợp lệ cho date.timezone trong tệp php.ini của mình.

Nếu gần đây bạn không nâng cấp, hãy thử giải quyết sự cố bằng cách cài đặt lại gói tzdata. Tôi làm việc độc quyền với CentOS, vì vậy tôi không chắc chắn tên của người quản lý gói của Ubuntu là gì, nhưng tôi khá chắc chắn tzdata là tiêu chuẩn trên các bản phân phối.

$ -> 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 

Bạn có thể muốn khởi động lại httpd của bạn sau này để đảm bảo thông tin múi giờ được chọn.

- Sửa

Hình như thủ phạm là date_i18n() chức năng của bạn, mà luôn luôn được gọi là, trừ khi mã gọi đặc biệt đi một arg thứ 3 của 'false'. Tôi đã chạy mã của bạn thông qua một số dữ liệu thử nghiệm với $ dịch được đặt thành false và hoạt động tốt.

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

xin lỗi tôi muốn nói rằng bạn có nghĩ rằng tôi vẫn nên cài đặt lại tzdata thậm chí nghĩ rằng tập lệnh php trong nhận xét của tôi ở trên đã trả về ngày chưa? Ngoài ra, gần đây tôi đã thực hiện cập nhật apt-get –

+0

Tôi đã cài đặt lại tzdata (cài đặt apt-get --reinstall tzdata) và nó cho tôi biết Giờ địa phương hiện là: Thứ năm 5 tháng 1 15:39:24 PST 2012. Giờ Hiện tại là: Thứ Năm 5 Tháng 1 23:39:24 UTC 2012. –

13

Vấn đề này cũng có thể xảy ra khi sử dụng php-fpm trong chế độ chroot, giải pháp trong trường hợp này là tạo một cái gì đó như/usr/share/zoneinfo/Europe trong thư mục chroot của bạn rồi sao chép tệp TZ của bạn. London

+0

Tuyệt vời, đây chính xác là những gì tôi cần sau khi chroot máy chủ Apache của tôi và chỉ một số tập lệnh PHP bị phá vỡ. Bật đăng nhập lỗi Tôi thấy đây là vấn đề (mặc dù tôi chỉ đơn giản là sao chép tất cả mọi thứ từ '/ usr/share/zoneinfo/*' vào tù chroot của tôi thay thế). – Breakthrough

6

Nguyên nhân gốc: không thể mở một trong các tệp zoneinfo.

cũng gây ra bởi: quá nhiều tệp đang mở.

Tôi đã có cùng một vấn đề ngày hôm nay trên Ubuntu 14.04.01-LTS "Trusty Tahr" và thử các câu trả lời khác không có lợi ích. Quyền đã được OK, các tập tin đã có, nội dung như mong đợi.

Cuối cùng tôi đã quyết định chạy tập lệnh từ bên trong khai thác dòng lệnh, để tôi có thể thử với strace. Và đây là kết quả:

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 

gì đang xảy ra

Khi PHP "truy cập vào cơ sở dữ liệu zoneinfo" nó thực sự cố gắng để mở một thư mục và một số tác phẩm. Nếu một số các hoạt động này không thành công, "zoneinfo tham nhũng" sẽ xuất hiện, nhưng nó chỉ đơn giản có nghĩa là quá trình PHP không thể mở các tập tin:

  • họ không có (chroot tù, zoneinfo cài đặt lỗi)
  • họ không có ở đó, cũng không nên là: "Châu Âu/Roem" không phải là múi giờ hợp lệ mà là lỗi chính tả.
  • họ đã ở đó, nhưng có quyền sai.
  • họ ở đó, nhưng quá trình này không được ủy quyền (SELinux, AppArmor, ...)
  • họ ở đó, nhưng các hoạt động fopen tạm thời không làm việc

trường hợp của tôi là người cuối cùng : thực sự vấn đề là kịch bản đã được mở quá nhiều tệp tạm thời và để chúng mở trong khi chạy. Có giới hạn về số lượng tệp có thể được mở cùng một lúc và tệp zoneinfo là rơm cuối cùng.Một sửa chữa nhanh chóng tạm thời giải quyết được vấn đề trong khi tôi đã trả lại "quá nhiều tệp" cho nhà phát triển chịu trách nhiệm.

Thật sự tôi nghi ngờ rằng đây cũng điểm để PHP liên tục mở và đóng cửa cơ sở dữ liệu zoneinfo thay vì bộ nhớ đệm nó, nhưng đó là một cuộc điều tra cho một ngày khác.

lỗi liên tục Các "số lượng tập tin mở" thingy là mỗi quá trình, không mỗi PHP script. Vì vậy, có hai (ít nhất) kịch bản có thể dẫn đến một khó chẩn đoán, có thể lỗi liên tục/không thể sản xuất:

  • một sự rò rỉ tài nguyên chậm bởi một số quy trình chạy dài, ví dụ: dưới vợt.
  • một tài nguyên hogging bởi một tập lệnh hoặc chương trình con khác đang chạy trong cùng một quá trình và có thể là thậm chí không liên quan đến PHP ở tất cả.

Tập lệnh PHP, đúng hay sai, phân bổ 800 tệp có thể hoạt động tốt cho đến khi nó đáp ứng một quy trình con khác đã cấp 224 tệp. Giới hạn 1024 tập tin mở cho mỗi quá trình đạt được và trong trường hợp đó quá trình không thành công với một lỗi bí ẩn (chỉ đề cập đến, khó hiểu ở đó, đến triệu chứng cuối cùng trong chuỗi dài nguyên nhân đồng thời).

Apache: quá nhiều trang web.

Apache đang chạy với mod_php5 sẽ khiến tệp được truy cập bởi PHP sẽ được mở bởi quy trình Apache. Tuy nhiên, quá trình Apache cũng giữ các tệp nhật ký của bạn mở và mọi quy trình đều có thể xử lý mọi tệp nhật ký. Vì vậy, nếu bạn có 200 trang web, mỗi trang có access_log độc lập, nói /var/www/somesite/logs/access_log, mỗi quá trình sẽ bắt đầu với 210 xử lý đã được thực hiện cho việc dọn phòng, để lại 800 miễn phí cho PHP để sử dụng. Điều này có thể dẫn đến tình huống máy chủ phát triển (với một trang web) hoạt động và máy chủ sản xuất (với 200 trang web được cài đặt) không, nếu tập lệnh cần phân bổ 900 tệp tạm thời cùng một lúc.

chẩn đoán bẩn (trên Unix/Linux): glob/proc/self/fdcount() kết quả. Xấu xí như tội lỗi, nhưng nó cho một hình bóng chày về số lượng các bộ mô tả tập tin thực sự đang mở.

Sửa lỗi nhanh và bẩn (trên Unix/Linux): tăng fdlimit trên mỗi tệp mở quy trình, đưa nó lên 1024 (tất nhiên bạn cần phải là gốc). Nó là một vấn đề cho Server Fault.

+0

Thực tế điều này đã trở thành trường hợp, khi tôi viết mã cho người tải lên có hỗ trợ chunk và concurrency. –

Các vấn đề liên quan