[wp-trac] [WordPress Trac] #56924: get_attached_file(): New call to path_join() can have poor performance on NFS file systems

WordPress Trac noreply at wordpress.org
Thu Oct 27 23:28:40 UTC 2022


#56924: get_attached_file(): New call to path_join() can have poor performance on
NFS file systems
--------------------------+---------------------
 Reporter:  mreishus      |       Owner:  (none)
     Type:  defect (bug)  |      Status:  new
 Priority:  normal        |   Milestone:  6.1
Component:  General       |     Version:  6.1
 Severity:  normal        |  Resolution:
 Keywords:                |     Focuses:
--------------------------+---------------------
Description changed by SergeyBiryukov:

Old description:

> In changeset https://core.trac.wordpress.org/changeset/53934/ , this
> change was made to get_attached_file():
>
> {{{#!diff
> -                       $file = $uploads['basedir'] . "/$file";
> +                       $file = path_join( $uploads['basedir'], $file );
> }}}
>
> Each call to path_join() calls path_is_absolute(), which calls
> realpath().  Most of the time this is not a problem, as realpath runs
> very fast, on the order of 0.003 milliseconds. However, if your uploads
> directory is on an NFS fileshare, I'm seeing calls to realpath() be
> 1000-2000x slower, or on the order of 2ms-4ms.
>
> One call to a 4ms realpath() is not an issue, but get_attached_file() can
> run on each post in a list in some APIs, causing significant slowdowns.
> Additionally, the path_join() file can be called on the same file several
> times in a row, each creating a new call to realpath() without caching or
> memoizing the results.
>
> Rough debugging code:
>
> {{{#!diff
> diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
> index a67d7a79a1..f728e80a7a 100644
> --- a/src/wp-includes/post.php
> +++ b/src/wp-includes/post.php
> @@ -728,7 +728,20 @@ function get_attached_file( $attachment_id,
> $unfiltered = false ) {
>                 $uploads = wp_get_upload_dir();
>
>                 if ( false === $uploads['error'] ) {
> +
> +                       $url =
> "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
> +                       error_log("path join: Called from $url");
> +                       $t1 = microtime( true );
> +
>                         $file = path_join( $uploads['basedir'], $file );
> +
> +                       $t2 = microtime( true );
> +                       $e = ( $t2 - $t1 ) * 1000;
> +                       error_log("Elasped $e");
> +                       error_log( print_r( [
> +                               $uploads['basedir'],
> +                               $file,
> +                       ], true ) );
>                 }
>         }
> }}}
>
> Have a site with some posts and some images in those posts. Browse around
> and look for the calls, for example, while visiting media library. Note
> that the speeds will appear fast unless there are network-mounted
> filesystems using NFS being queried.

New description:

 In changeset [53934], this change was made to get_attached_file():

 {{{#!diff
 -                       $file = $uploads['basedir'] . "/$file";
 +                       $file = path_join( $uploads['basedir'], $file );
 }}}

 Each call to path_join() calls path_is_absolute(), which calls realpath().
 Most of the time this is not a problem, as realpath runs very fast, on the
 order of 0.003 milliseconds. However, if your uploads directory is on an
 NFS fileshare, I'm seeing calls to realpath() be 1000-2000x slower, or on
 the order of 2ms-4ms.

 One call to a 4ms realpath() is not an issue, but get_attached_file() can
 run on each post in a list in some APIs, causing significant slowdowns.
 Additionally, the path_join() file can be called on the same file several
 times in a row, each creating a new call to realpath() without caching or
 memoizing the results.

 Rough debugging code:

 {{{#!diff
 diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
 index a67d7a79a1..f728e80a7a 100644
 --- a/src/wp-includes/post.php
 +++ b/src/wp-includes/post.php
 @@ -728,7 +728,20 @@ function get_attached_file( $attachment_id,
 $unfiltered = false ) {
                 $uploads = wp_get_upload_dir();

                 if ( false === $uploads['error'] ) {
 +
 +                       $url =
 "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
 +                       error_log("path join: Called from $url");
 +                       $t1 = microtime( true );
 +
                         $file = path_join( $uploads['basedir'], $file );
 +
 +                       $t2 = microtime( true );
 +                       $e = ( $t2 - $t1 ) * 1000;
 +                       error_log("Elasped $e");
 +                       error_log( print_r( [
 +                               $uploads['basedir'],
 +                               $file,
 +                       ], true ) );
                 }
         }
 }}}

 Have a site with some posts and some images in those posts. Browse around
 and look for the calls, for example, while visiting media library. Note
 that the speeds will appear fast unless there are network-mounted
 filesystems using NFS being queried.

--

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/56924#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list