http://www.mediawiki.org/wiki/Special:Code/MediaWiki/96645

Revision: 96645
Author:   tstarling
Date:     2011-09-09 03:51:45 +0000 (Fri, 09 Sep 2011)
Log Message:
-----------
* Added a script to reduce disk space on a MySQL parser cache setup such as the 
one at Wikimedia at the moment, by removing all objects which expire before a 
given time. 
* Fixed unintentional shortcut evaluation in MultiWriteBagOStuff::doWrite(). It 
would have caused writes to be skipped on the second cache if the first cache 
failed, now writes should be attempted on all caches.

Modified Paths:
--------------
    trunk/phase3/includes/objectcache/BagOStuff.php
    trunk/phase3/includes/objectcache/MultiWriteBagOStuff.php
    trunk/phase3/includes/objectcache/SqlBagOStuff.php

Added Paths:
-----------
    trunk/phase3/maintenance/purgeParserCache.php

Modified: trunk/phase3/includes/objectcache/BagOStuff.php
===================================================================
--- trunk/phase3/includes/objectcache/BagOStuff.php     2011-09-09 02:47:34 UTC 
(rev 96644)
+++ trunk/phase3/includes/objectcache/BagOStuff.php     2011-09-09 03:51:45 UTC 
(rev 96645)
@@ -91,6 +91,16 @@
                return array();
        }
 
+       /**
+        * Delete all objects expiring before a certain date. 
+        *
+        * @return true on success, false if unimplemented
+        */
+       public function deleteObjectsExpiringBefore( $date ) {
+               // stub
+               return false;
+       }
+
        /* *** Emulated functions *** */
 
        public function add( $key, $value, $exptime = 0 ) {

Modified: trunk/phase3/includes/objectcache/MultiWriteBagOStuff.php
===================================================================
--- trunk/phase3/includes/objectcache/MultiWriteBagOStuff.php   2011-09-09 
02:47:34 UTC (rev 96644)
+++ trunk/phase3/includes/objectcache/MultiWriteBagOStuff.php   2011-09-09 
03:51:45 UTC (rev 96645)
@@ -89,9 +89,25 @@
                array_shift( $args );
 
                foreach ( $this->caches as $cache ) {
-                       $ret = $ret && call_user_func_array( array( $cache, 
$method ), $args );
+                       if ( !call_user_func_array( array( $cache, $method ), 
$args ) ) {
+                               $ret = false;
+                       }
                }
                return $ret;
        }
 
+       /**
+        * Delete objects expiring before a certain date. 
+        *
+        * Succeed if any of the child caches succeed.
+        */
+       public function deleteObjectsExpiringBefore( $date ) {
+               $ret = false;
+               foreach ( $this->caches as $cache ) {
+                       if ( $cache->deleteObjectsExpiringBefore( $date ) ) {
+                               $ret = true;
+                       }
+               }
+               return $ret;
+       }
 }

Modified: trunk/phase3/includes/objectcache/SqlBagOStuff.php
===================================================================
--- trunk/phase3/includes/objectcache/SqlBagOStuff.php  2011-09-09 02:47:34 UTC 
(rev 96644)
+++ trunk/phase3/includes/objectcache/SqlBagOStuff.php  2011-09-09 03:51:45 UTC 
(rev 96645)
@@ -305,21 +305,29 @@
        }
 
        public function expireAll() {
+               $this->deleteObjectsExpiringBefore( wfTimestampNow() );
+       }
+
+       /**
+        * Delete objects from the database which expire before a certain date.
+        */
+       public function deleteObjectsExpiringBefore( $timestamp ) {
                $db = $this->getDB();
-               $now = $db->timestamp();
+               $dbTimestamp = $db->timestamp( $timestamp );
 
                try {
                        for ( $i = 0; $i < $this->shards; $i++ ) {
                                $db->begin();
                                $db->delete(
                                        $this->getTableByShard( $i ), 
-                                       array( 'exptime < ' . $db->addQuotes( 
$now ) ), 
+                                       array( 'exptime < ' . $db->addQuotes( 
$dbTimestamp ) ), 
                                        __METHOD__ );
                                $db->commit();
                        }
                } catch ( DBQueryError $e ) {
                        $this->handleWriteError( $e );
                }
+               return true;
        }
 
        public function deleteAll() {

Added: trunk/phase3/maintenance/purgeParserCache.php
===================================================================
--- trunk/phase3/maintenance/purgeParserCache.php                               
(rev 0)
+++ trunk/phase3/maintenance/purgeParserCache.php       2011-09-09 03:51:45 UTC 
(rev 96645)
@@ -0,0 +1,43 @@
+<?php
+
+require( dirname( __FILE__ ) . '/Maintenance.php' );
+
+class PurgeParserCache extends Maintenance {
+       function __construct() {
+               parent::__construct();
+               $this->addDescription( "Remove old objects from the parser 
cache. " . 
+                       "This only works when the parser cache is in an SQL 
database." );
+               $this->addOption( 'expiredate', 'Delete objects expiring before 
this date.', false, true );
+               $this->addOption( 'age', 
+                       'Delete objects created more than this many seconds 
ago, assuming $wgParserCacheExpireTime '.
+                               'has been consistent.', 
+                       false, true );
+       }
+
+       function execute() {
+               $inputDate = $this->getOption( 'expiredate' );
+               $inputAge = $this->getOption( 'age' );
+               if ( $inputDate !== null ) {
+                       $date = wfTimestamp( TS_MW, strtotime( $inputDate ) );
+               } elseif ( $inputAge !== null ) {
+                       global $wgParserCacheExpireTime;
+                       $date = wfTimestamp( TS_MW, time() + 
$wgParserCacheExpireTime - intval( $inputAge ) );
+               } else {
+                       echo "Must specify either --expiredate or --age\n";
+                       exit( 1 );
+               }
+
+               $english = Language::factory( 'en' );
+               echo "Deleting objects expiring before " . 
$english->timeanddate( $date ) . "\n";
+
+               $pc = wfGetParserCacheStorage();
+               $success = $pc->deleteObjectsExpiringBefore( $date );
+               if ( !$success ) {
+                       echo "Cannot purge this kind of parser cache.\n";
+                       exit( 1 );
+               }
+               echo "Done\n";
+       }
+}
+$maintClass = 'PurgeParserCache';
+require_once( RUN_MAINTENANCE_IF_MAIN );


Property changes on: trunk/phase3/maintenance/purgeParserCache.php
___________________________________________________________________
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to