Opened 7 years ago

Closed 5 years ago

Last modified 2 years ago

#152 closed defect (fixed)

Weird PHP errors when files get deleted and copied again (multiple times in cache)

Reported by: blueyed Owned by: moo
Priority: major Milestone: 1.3.0
Component: cacher Version: 1.2.1
Keywords: timestamps Cc:
Application: b2evolution PHP Version: PHP_5_2
Other Exts: SAPI: FastCGI
Probability: Sometimes Blocked By:
Blocking:

Description (last modified by moo)

I have a demo setup for a PHP application and to reset it, I'm removing all files and copying them anew ("rm /path/to/app -rf && cp -a /source /path/to/app").

This causes weird PHP errors like "call to undefined function", "cannot redeclare foo()" or "Class 'DataObject?' not found".

After removing the xcache cache, it works again.

Looking at the cached files, there a duplicates, e.g.:

  php#0 71  /path/inc/generic/model/_genericcache.class.php  0  0  6.04 K  2.79 K  4 M  2051  508796  8 m  8 m
  php#0 72  /path/inc/generic/model/_genericcache.class.php  2  0  6.04 K  2.79 K  4 M  2051  508795  10 s  8 m

I'm not sure if this is related to the PHP files being accessed during "deletion" and have not tried to create a smaller testcase.

I've tried using xcache.readonly_protection=On, but it still broke.

A workaround appears to be using "/bin/cp -a --no-preserve=timestamps" to copy the files to the same place again (--no-preserve=timestamps is the key here).

My settings:

xcache.admin.enable_auth  On
  xcache.cacher  On
  xcache.coredump_directory  no value
  xcache.count  1
  xcache.gc_interval  0
  xcache.mmap_path  /dev/zero
  xcache.readonly_protection  1
  xcache.shm_scheme  mmap
  xcache.size  10M
  xcache.slots  8K
  xcache.stat  On
  xcache.test  0
  xcache.ttl  0
  xcache.var_count  1
  xcache.var_gc_interval  120
  xcache.var_maxttl  0
  xcache.var_size  64K
  xcache.var_slots  8K
  xcache.var_ttl  0

I'm using the 1.2 branch and PHP_5_2 (both uptodate).

Attachments (1)

inode_swap.diff (1.3 KB) - added by thomasb 5 years ago.
Patch

Download all attachments as: .zip

Change History (7)

Changed 5 years ago by thomasb

Patch

comment:1 follow-up: Changed 5 years ago by thomasb

I have added a patch which could solve the problem. I had the same problem
which happened when I did an rpm update of my php-code.

The problem is that in some cases (more likely with many php-files) inodes
are reused between files, and if the files should happen to have the
same mtime (this is why --no-preserve=timestamps helps), xcache will return
opcodes for the wrong file.

The patch adds a filename-check on top of the mtime-check.

comment:2 in reply to: ↑ 1 Changed 5 years ago by thomasb

Replying to thomasb:

I have added a patch which could solve the problem. I had the same problem
which happened when I did an rpm update of my php-code.

[snip]
I forgot to mention that the patch is for 1.2.2, but I suspect that the problem
is the same for 1.2.1.

comment:3 follow-up: Changed 5 years ago by moo

  • Description modified (diff)

there is already a patch in 1.3 that check sourcesize: if (p->type == XC_TYPE_VAR || /* PHP */ (p->data.php->mtime == xce->data.php->mtime && p->data.php->sourcesize == xce->data.php->sourcesize)) {

do you think it enough? checking filename is the "right" option for hashing but not for md5+hardlink patch in 2.0

in 2.0, it can do md5 to cache multiple same content file in 1 copy of shared memory, filename (path) is absolute not equal.

comment:4 in reply to: ↑ 3 Changed 5 years ago by thomasb

Replying to moo:

In theory checking mtime and sourcesize is not really enough. When I check
my own source-tree, I have 4 file-pairs with the exact same size, so I could still
end up in the same situation, but it would be very unlikely.

The 2.0 approach sounds interesting. I will take a look at the code!

comment:5 Changed 5 years ago by moo

  • Milestone set to 1.3.0
  • Resolution set to fixed
  • Status changed from new to closed

i didn't mean 2.0 have solve this problem perfectly. i just said 2.0 md5+hardlink feature will not work if file path is checked instead of inode+mtime+sourcesize. for this reason, i should mark it fixed in 1.3.0 that already released

comment:6 Changed 2 years ago by moo

this is fixed perfectly in 2.0.1. see bug #284

Note: See TracTickets for help on using tickets.