PHP with open_basedir performance problem

Miroslav Lachman 000.fbsd at quip.cz
Sun Jan 27 04:25:57 PST 2008


Thomas Hurst wrote:

> * Miroslav Lachman (000.fbsd at quip.cz) wrote:
> 
> 
>>I found a painful performance problem with Apache + PHP 5 when
>>open_basedir directive is enabled.
> 
> 
> Looks like it's lstat()/readlink() overhead.  I wrote a simple bit of
> PHP similar to yours, but doing 10 * 1000 require "foo/%d/%d.php" calls
> from the command line:
> 
> -% time ktrace php main.php
> Real: 0:09.61 CPU: 99.8% (3.725/5.885) Page: 0 Swap: 0 I/O: (0/0) Mem:
> 13704
> 
> -% time ktrace php -d open_basedir='/home/freaky/openbasedir/foo'
> main.php
> Real: 0:16.21 CPU: 86.4% (8.185/5.840) Page: 0 Swap: 0 I/O: (0/0) Mem:
> 13696
> 
> Without open_basedir, a simple script to parse the kdump syscall times
> produces:
> 
>    lstat        : 1.147s/70065 calls = 0.000s per call.  Max=0.000s Min=0.0000s
>    fcntl        : 0.408s/60007 calls = 0.000s per call.  Max=0.000s Min=0.0000s
> sigprocmask     : 0.229s/40311 calls = 0.000s per call.  Max=0.000s Min=0.0000s
>     open        : 0.223s/10085 calls = 0.000s per call.  Max=0.000s Min=0.0000s
> 
> With open_basedir:
> 
>    lstat        : 4.182s/270065 calls = 0.000s per call.  Max=0.005s Min=0.0000s
> readlink        : 2.142s/10006 calls = 0.000s per call.  Max=2.020s Min=0.0000s
>    fcntl        : 0.421s/60007 calls = 0.000s per call.  Max=0.002s Min=0.0000s
>    close        : 0.295s/10085 calls = 0.000s per call.  Max=0.115s Min=0.0000s
> sigprocmask     : 0.237s/40311 calls = 0.000s per call.  Max=0.000s Min=0.0000s
>     open        : 0.222s/10085 calls = 0.000s per call.  Max=0.000s Min=0.0000s
> 
> The top two syscalls seem to account for most of the 6.mumble seconds of
> additional runtime; presumably these are much cheaper on Linux.

I did some more research on saturday - test with old PHP 5 version 5.1.4 
on FreeBSD 7.0 machine. It seems there is some significant change in PHP 
code.

(on = with open_basedir / off = without open_basedir):
# real webapplication
FreeBSD 6.0 + PHP 5.1.4  on / off = 6.8 / 13.5 req/s
FreeBSD 7.0 + PHP 5.2.5  on / off = 3.6 / 12.9 req/s
FreeBSD 7.0 + PHP 5.1.4  on / off = 8.0 / 11.8 req/s

# synthetic test
FreeBSD 6.0 + PHP 5.1.4  on / off =  98.3 / 144.2 req/s
FreeBSD 7.0 + PHP 5.2.5  on / off =  20.6 / 245.4 req/s
FreeBSD 7.0 + PHP 5.1.4  on / off = 204.3 / 239.5 req/s

It demonstrates my performance problem from year ago (also reported on 
this list 2007-02-03 with subject "PHP Performance problem after upgrade 
to 5.1.6 or 5.2.0"). It is still unsolved problem, but now I know it is 
influenced by open_basedir.
As I reported a year ago - problem occured in 5.1.6 (maybe 5.1.5 - I 
never tried it, I jumped from 5.1.4 to 5.1.6 or newer). Can somebody 
look at PHP sources of those two versions and find the "bad change"?

This was reported to PHP developers by me 
http://bugs.php.net/bug.php?id=38940 but marked as "bogus" with comment 
"We only support our own sources, not ports or patched source or binary
packages."

Is there any chance to fix this on FreeBSD side (patch in ports) or in 
PHP itself?
I don't want to lose performance with each "security" upgrade of PHP. :(

Miroslav Lachman


More information about the freebsd-performance mailing list