[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Database load monitoring. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 * @ingroup Database 22 */ 23 24 /** 25 * An interface for database load monitoring 26 * 27 * @ingroup Database 28 */ 29 interface LoadMonitor { 30 /** 31 * Construct a new LoadMonitor with a given LoadBalancer parent 32 * 33 * @param LoadBalancer $parent 34 */ 35 public function __construct( $parent ); 36 37 /** 38 * Perform pre-connection load ratio adjustment. 39 * @param array $loads 40 * @param string|bool $group The selected query group. Default: false 41 * @param string|bool $wiki Default: false 42 */ 43 public function scaleLoads( &$loads, $group = false, $wiki = false ); 44 45 /** 46 * Return an estimate of replication lag for each server 47 * 48 * @param array $serverIndexes 49 * @param string $wiki 50 * 51 * @return array 52 */ 53 public function getLagTimes( $serverIndexes, $wiki ); 54 } 55 56 class LoadMonitorNull implements LoadMonitor { 57 public function __construct( $parent ) { 58 } 59 60 public function scaleLoads( &$loads, $group = false, $wiki = false ) { 61 } 62 63 public function getLagTimes( $serverIndexes, $wiki ) { 64 return array_fill_keys( $serverIndexes, 0 ); 65 } 66 } 67 68 /** 69 * Basic MySQL load monitor with no external dependencies 70 * Uses memcached to cache the replication lag for a short time 71 * 72 * @ingroup Database 73 */ 74 class LoadMonitorMySQL implements LoadMonitor { 75 /** @var LoadBalancer */ 76 public $parent; 77 /** @var BagOStuff */ 78 protected $cache; 79 80 public function __construct( $parent ) { 81 global $wgMemc; 82 83 $this->parent = $parent; 84 $this->cache = $wgMemc ?: wfGetMainCache(); 85 } 86 87 public function scaleLoads( &$loads, $group = false, $wiki = false ) { 88 } 89 90 public function getLagTimes( $serverIndexes, $wiki ) { 91 if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) { 92 // Single server only, just return zero without caching 93 return array( 0 => 0 ); 94 } 95 96 $section = new ProfileSection( __METHOD__ ); 97 98 $expiry = 5; 99 $requestRate = 10; 100 101 $cache = $this->cache; 102 $masterName = $this->parent->getServerName( 0 ); 103 $memcKey = wfMemcKey( 'lag_times', $masterName ); 104 $times = $cache->get( $memcKey ); 105 if ( is_array( $times ) ) { 106 # Randomly recache with probability rising over $expiry 107 $elapsed = time() - $times['timestamp']; 108 $chance = max( 0, ( $expiry - $elapsed ) * $requestRate ); 109 if ( mt_rand( 0, $chance ) != 0 ) { 110 unset( $times['timestamp'] ); // hide from caller 111 112 return $times; 113 } 114 wfIncrStats( 'lag_cache_miss_expired' ); 115 } else { 116 wfIncrStats( 'lag_cache_miss_absent' ); 117 } 118 119 # Cache key missing or expired 120 if ( $cache->add( "$memcKey:lock", 1, 10 ) ) { 121 # Let this process alone update the cache value 122 $unlocker = new ScopedCallback( function () use ( $cache, $memcKey ) { 123 $cache->delete( $memcKey ); 124 } ); 125 } elseif ( is_array( $times ) ) { 126 # Could not acquire lock but an old cache exists, so use it 127 unset( $times['timestamp'] ); // hide from caller 128 129 return $times; 130 } 131 132 $times = array(); 133 foreach ( $serverIndexes as $i ) { 134 if ( $i == 0 ) { # Master 135 $times[$i] = 0; 136 } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) { 137 $times[$i] = $conn->getLag(); 138 } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) { 139 $times[$i] = $conn->getLag(); 140 // Close the connection to avoid sleeper connections piling up. 141 // Note that the caller will pick one of these DBs and reconnect, 142 // which is slightly inefficient, but this only matters for the lag 143 // time cache miss cache, which is far less common that cache hits. 144 $this->parent->closeConnection( $conn ); 145 } 146 } 147 148 # Add a timestamp key so we know when it was cached 149 $times['timestamp'] = time(); 150 $cache->set( $memcKey, $times, $expiry + 10 ); 151 unset( $times['timestamp'] ); // hide from caller 152 153 return $times; 154 } 155 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |