From f50573c33dea232fb160e4d71767706a2410ef65 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Thu, 25 Jun 2009 00:40:12 +0000 Subject: [PATCH] * Move lock()/unlock() to DatabaseMysql, declare abstract * Introduce lockTables() and unlockTables(), define in DatabaseMysql * (bug 19372) updateSearchIndex has MySQLisms. --- includes/db/Database.php | 45 ++++++++++++++++--------------- includes/db/DatabaseMysql.php | 38 ++++++++++++++++++++++++++ maintenance/updateSearchIndex.inc | 19 +++---------- 3 files changed, 65 insertions(+), 37 deletions(-) diff --git a/includes/db/Database.php b/includes/db/Database.php index 7d07816446..d6789c17cf 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -2176,7 +2176,7 @@ abstract class DatabaseBase { } /** - * Acquire a lock + * Acquire a named lock * * Abstracted from Filestore::lock() so child classes can implement for * their own needs. @@ -2185,33 +2185,36 @@ abstract class DatabaseBase { * @param $method String: Name of method calling us * @return bool */ - public function lock( $lockName, $method ) { - $lockName = $this->addQuotes( $lockName ); - $result = $this->query( "SELECT GET_LOCK($lockName, 5) AS lockstatus", $method ); - $row = $this->fetchObject( $result ); - $this->freeResult( $result ); + abstract public function lock( $lockName, $method, $timeout = 5 ); - if( $row->lockstatus == 1 ) { - return true; - } else { - wfDebug( __METHOD__." failed to acquire lock\n" ); - return false; - } - } /** * Release a lock. * - * @todo fixme - Figure out a way to return a bool - * based on successful lock release. - * * @param $lockName String: Name of lock to release * @param $method String: Name of method calling us + * + * FROM MYSQL DOCS: http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock + * @return Returns 1 if the lock was released, 0 if the lock was not established + * by this thread (in which case the lock is not released), and NULL if the named + * lock did not exist */ - public function unlock( $lockName, $method ) { - $lockName = $this->addQuotes( $lockName ); - $result = $this->query( "SELECT RELEASE_LOCK($lockName)", $method ); - $this->freeResult( $result ); - } + abstract public function unlock( $lockName, $method ); + + /** + * Lock specific tables + * + * @param $read Array of tables to lock for read access + * @param $write Array of tables to lock for write access + * @param $method String name of caller + */ + abstract public function lockTables( $read, $write, $method ); + + /** + * Unlock specific tables + * + * @param $method String the caller + */ + abstract public function unlockTables( $method ); /** * Get search engine class. All subclasses of this diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index 6508eb234e..ecd3485c37 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -293,6 +293,44 @@ class DatabaseMysql extends DatabaseBase { $this->query( "SET net_read_timeout=$timeout" ); $this->query( "SET net_write_timeout=$timeout" ); } + + public function lock( $lockName, $method, $timeout = 5 ) { + $lockName = $this->addQuotes( $lockName ); + $result = $this->query( "SELECT GET_LOCK($lockName, $timeout) AS lockstatus", $method ); + $row = $this->fetchObject( $result ); + $this->freeResult( $result ); + + if( $row->lockstatus == 1 ) { + return true; + } else { + wfDebug( __METHOD__." failed to acquire lock\n" ); + return false; + } + } + + public function unlock( $lockName, $method ) { + $lockName = $this->addQuotes( $lockName ); + $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method ); + $row = $this->fetchObject( $result ); + return $row->lockstatus; + } + + public function lockTables( $read, $write, $method ) { + $items = array(); + + foreach( $write as $table ) { + $items[] = $this->tableName( $table ) . ' LOW_PRIORITY WRITE'; + } + foreach( $read as $table ) { + $items[] = $this->tableName( $table ) . ' READ'; + } + $sql = "LOCK TABLES " . implode( ',', $items ); + $db->query( $sql, $method ); + } + + public function unlockTables( $method ) { + $this->query( "UNLOCK TABLES", $method ); + } } /** diff --git a/maintenance/updateSearchIndex.inc b/maintenance/updateSearchIndex.inc index 0cac4508cd..21e2df481b 100644 --- a/maintenance/updateSearchIndex.inc +++ b/maintenance/updateSearchIndex.inc @@ -75,7 +75,7 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) { # Unlock searchindex if ( $maxLockTime ) { output( " --- Unlocking --" ); - unlockSearchindex( $dbw ); + $dbw->unlockTables( 'updateSearchIndex.inc ' . __METHOD__ ); output( "\n" ); } output( "Done\n" ); @@ -84,27 +84,14 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) { function lockSearchindex( &$db ) { $write = array( 'searchindex' ); $read = array( 'page', 'revision', 'text', 'interwiki' ); - $items = array(); - - foreach( $write as $table ) { - $items[] = $db->tableName( $table ) . ' LOW_PRIORITY WRITE'; - } - foreach( $read as $table ) { - $items[] = $db->tableName( $table ) . ' READ'; - } - $sql = "LOCK TABLES " . implode( ',', $items ); - $db->query( $sql, 'updateSearchIndex.inc ' . __METHOD__ ); -} - -function unlockSearchindex( &$db ) { - $db->query( "UNLOCK TABLES", 'updateSearchIndex.inc ' . __METHOD__ ); + $db->lockTables( $read, $write, 'updateSearchIndex.inc ' . __METHOD__ ); } # Unlock and lock again # Since the lock is low-priority, queued reads will be able to complete function relockSearchindex( &$db ) { unlockSearchindex( $db ); - lockSearchindex( $db ); + $db->unlockTables( 'updateSearchIndex.inc ' . __METHOD__ ); } function output( $text ) { -- 2.20.1