Bug #49383 [Nab]: Lots of empty fstat() calls slow performance

From: Date: Wed, 17 Jul 2019 09:25:51 +0000
Subject: Bug #49383 [Nab]: Lots of empty fstat() calls slow performance
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-221826@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=49383&edit=1

 ID:                 49383
 Updated by:         nikic@php.net
 Reported by:        olga at metacafe dot com
 Summary:            Lots of empty fstat() calls slow performance
 Status:             Not a bug
 Type:               Bug
 Package:            Performance problem
 Operating System:   Red Hat 3.4.6-10
 PHP Version:        5.3, 6
 Block user comment: N
 Private report:     N

 New Comment:

I've dropped two fstat() calls per include in 7.4, so only a single fstat() call should be
happening now.


Previous Comments:
------------------------------------------------------------------------
[2019-01-23 02:54:28] 593948970 at qq dot com

我也遇到了这个问题好像是opchache无法使用的情况下
access("/data/web/releases/20190122_1036111_2/src/application/Models/LocalModel.php",
F_OK) = 0
open("/data/web/releases/20190122_1036111_2/src/application/Models/LocalModel.php",
O_RDONLY) = 9
fstat(9, {st_mode=S_IFREG|0755, st_size=416, ...}) = 0
fstat(9, {st_mode=S_IFREG|0755, st_size=416, ...}) = 0
fstat(9, {st_mode=S_IFREG|0755, st_size=416, ...}) = 0
mmap(NULL, 416, PROT_READ, MAP_SHARED, 9, 0) = 0x7fea60241000
munmap(0x7fea60241000, 416)             = 0
close(9)                                = 0

------------------------------------------------------------------------
[2018-12-17 22:01:45] mtausk at gmail dot com

I wonder if this has been fixed.

I've noticed the same behavior in php5.6 (PHP 5.6.39-1+ubuntu16.04.1+deb.sury.org+1). I know
it's an old version but I am just checking if some solution was proposed.

- opcache enabled
- open_basedir disabled

after open() is issued, 4 exactly same fstat() calls occur. I guess 3 of them are not necessary and
in long-term it eats sys% like this:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 20.23    0.008665           2      5511           fstat
 18.91    0.008097           3      2382           poll
 14.58    0.006244           3      2382           recvfrom
 10.25    0.004390           3      1341           munmap
  9.69    0.004151           3      1467           open
  9.34    0.004000         222        18           shutdown
  7.20    0.003083          10       318           brk
  4.07    0.001741           1      1481           sendto
  2.55    0.001093           1      1072        19 access
  1.30    0.000555           6        90           write
  0.72    0.000308           0      1341           mmap
...

See the time CPU mostly spent in syscalls is at the very fast but redundant fstat() call.

...
access("luigisBoxHtmlBodyEnd.php", R_OK) = 0
open("luigisBoxHtmlBodyEnd.php", O_RDONLY) = 7
fstat(7, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0
fstat(7, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0
fstat(7, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0
fstat(7, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0
mmap(NULL, 438, PROT_READ, MAP_SHARED, 7, 0) = 0x7f8560433000
...


Would this be fixed in php7 if the site is moved there?

Thanks.

------------------------------------------------------------------------
[2010-08-12 16:36:14] rasmus@php.net

The reason open_basedir affects this is because for security reasons we can't 
enable the stat cache when open_basedir is enabled which will also affect stats 
after the file is opened since it isn't the open_basedir check itself causing 
the stat but the fact that the open_basedir feature forces the stat cache to be 
disabled.

The main thing that changed between 5.2.x and 5.3.x with respect to stats is 
that we rewrote the stat cache to be more efficient.  It now does intra-path 
caching of realpath() lookups as opposed to just caching the return of the 
realpath() call, but it doesn't sound like this is the issue here.

One thing you can try is to compile PHP without phar support.  ./configure --
disable-phar and see if that changes things.  Beyond that you would need to set 
a gdb breakpoint and get a backtrace of those calls.  Generally we are not too 
concerned about fstat calls since they tend to be extremely fast in most 
environments.  It is the full stat/lstat calls that need to hit the disk that 
tend to be slow.

------------------------------------------------------------------------
[2010-08-12 15:58:41] a dot rogge at solvention dot de

First of all: No, we don't use open_basedir or safe_mode or stuff like that.
But I still do not understand what this has to do with the issue.

The redundant fstat() calls are obviously *not* from open_basedir, because the fstat() calls are
done after the file was opened.

I run 5.1.6, 5.2.14 and 5.3.2 with the same configuration. For 5.1.6 and 5.2.14 everything looks
normally, in 5.3.2 there are suddenly three instead of one fstat() call after opening the file. The
calls are identical and adjacent with no other syscalls in between. The two successive calls do not
provide any more information than the first one and thus are redundant and useless.

This is obviously a performance regression. Do you want to tell me that this is a new feature?

------------------------------------------------------------------------
[2010-08-12 01:24:32] rasmus@php.net

Do you have openbase_dir enabled?  If so, for security reasons we can't use the 
stat cache which is going to cause a lot of stats.  For a setup with slow stats, I 
suggest chroot/jail or something along those lines rather than open_basedir to 
keep users separated.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=49383


--
Edit this bug report at https://bugs.php.net/bug.php?id=49383&edit=1


Thread (25 messages)

« previous php.bugs (#221826) next »