Move slow deletion purges out of complex DB transactions
authorAaron Schulz <aschulz@wikimedia.org>
Wed, 21 Aug 2013 20:20:40 +0000 (13:20 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Wed, 21 Aug 2013 20:22:05 +0000 (13:22 -0700)
* This should help reduce deletion related deadlock errors

Change-Id: Ie7cafbf87ab0c71cc6c4c4fe1e53af364974a745

includes/filerepo/file/LocalFile.php

index 678a6ad..39ef62c 100644 (file)
@@ -1527,7 +1527,6 @@ class LocalFile extends File {
         * @return FileRepoStatus object.
         */
        function delete( $reason, $suppress = false ) {
-               global $wgUseSquid;
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
                        return $this->readOnlyFatalStatus();
                }
@@ -1545,19 +1544,28 @@ class LocalFile extends File {
                        DeferredUpdates::addUpdate( SiteStatsUpdate::factory( array( 'images' => -1 ) ) );
                }
 
-               $this->purgeEverything();
-               foreach ( $archiveNames as $archiveName ) {
-                       $this->purgeOldThumbnails( $archiveName );
-               }
+               // Hack: the lock()/unlock() pair is nested in a transaction so the locking is not
+               // tied to BEGIN/COMMIT. To avoid slow purges in the transaction, move them outside.
+               $file = $this;
+               $this->getRepo()->getMasterDB()->onTransactionIdle(
+                       function() use ( $file, $archiveNames ) {
+                               global $wgUseSquid;
 
-               if ( $wgUseSquid ) {
-                       // Purge the squid
-                       $purgeUrls = array();
-                       foreach ($archiveNames as $archiveName ) {
-                               $purgeUrls[] = $this->getArchiveUrl( $archiveName );
+                               $file->purgeEverything();
+                               foreach ( $archiveNames as $archiveName ) {
+                                       $file->purgeOldThumbnails( $archiveName );
+                               }
+
+                               if ( $wgUseSquid ) {
+                                       // Purge the squid
+                                       $purgeUrls = array();
+                                       foreach ( $archiveNames as $archiveName ) {
+                                               $purgeUrls[] = $file->getArchiveUrl( $archiveName );
+                                       }
+                                       SquidUpdate::purge( $purgeUrls );
+                               }
                        }
-                       SquidUpdate::purge( $purgeUrls );
-               }
+               );
 
                return $status;
        }