Performance problem in path_delete when deleting unaliased node

Created on 29 September 2011, over 12 years ago
Updated 29 August 2023, 10 months 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 6 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.69.0 2024