Performance problem in path_delete when deleting unaliased node

Created on 29 September 2011, almost 14 years ago
Updated 29 August 2023, almost 2 years ago

My node deletions were taking 30 seconds (or something minutes) each (for just a single node) and I tracked the performance problem down to path_delete.

The site has over 1 million path aliases, but many nodes have no alias. When deleting a node without an alias, path_node_delete calls path_delete which attempts a path_load. It doesn't get back a result, so it ends up calling
drupal_clear_path_cache($path['source']);
with no $path['source'].

The passing of a source here was added in #723634: path_save() performance β†’ to prevent unnecessary work in drupal_path_alias_whitelist_rebuild, which runs a very slow query if you have a lot of path aliases. We're now accidentally running that when deleting nodes without any alias.

Attached patch fixes it for me.

πŸ› Bug report
Status

Closed: outdated

Version

11.0 πŸ”₯

Component
PathΒ  β†’

Last updated 12 days ago

  • Maintained by
  • πŸ‡¬πŸ‡§United Kingdom @catch
Created by

πŸ‡ΊπŸ‡ΈUnited States Jody Lynn

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¬πŸ‡§United Kingdom catch

    Took me a few minutes to figure out where the equivalent code is, it's here:

      /**
       * {@inheritdoc}
       */
      public function postSave(EntityStorageInterface $storage, $update = TRUE) {
        parent::postSave($storage, $update);
    
        $alias_manager = \Drupal::service('path_alias.manager');
        $alias_manager->cacheClear($this->getPath());
        if ($update) {
          $alias_manager->cacheClear($this->original->getPath());
        }
      }
    
      /**
       * {@inheritdoc}
       */
      public static function postDelete(EntityStorageInterface $storage, array $entities) {
        parent::postDelete($storage, $entities);
    
        $alias_manager = \Drupal::service('path_alias.manager');
        foreach ($entities as $entity) {
          $alias_manager->cacheClear($entity->getPath());
        }
      }
    
    

    However PathAlias::clearCache() will always get a source $path from $entity->getPath() and no longer tries to load path aliases, so I think this is outdated and marking as such.

Production build 0.71.5 2024