r4079 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r4078‎ | r4079 | r4080 >
Date:15:00, 15 June 2004
Author:timstarling
Status:old
Tags:
Comment:
Bringing the load balancer to the main branch. Still doesn't do much. I needed a DB connection cache for my Article.php alterations, which LoadBalancer provides.
Modified paths:
  • /trunk/phase3/includes/Database.php (modified) (history)
  • /trunk/phase3/includes/DatabaseFunctions.php (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/LoadBalancer.php (modified) (history)
  • /trunk/phase3/includes/Setup.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/DefaultSettings.php
@@ -60,6 +60,10 @@
6161 $wgDBuser = 'wikiuser';
6262 $wgDBtype = "mysql"; # "mysql" for working code and "pgsql" for development/broken code
6363
 64+# Database load balancer
 65+$wgDBservers = false; # e.g. array(0 => "larousse", 1 => "pliny")
 66+$wgDBloads = false; # e.g. array(0 => 0.6, 1 => 0.4);
 67+
6468 # Sysop SQL queries
6569 $wgAllowSysopQueries = false; # Dangerous if not configured properly.
6670 $wgDBsqluser = 'sqluser';
Index: trunk/phase3/includes/Setup.php
@@ -58,6 +58,7 @@
5959 require_once( 'Parser.php' );
6060 require_once( 'ParserCache.php' );
6161 require_once( 'WebRequest.php' );
 62+require_once( 'LoadBalancer.php' );
6263
6364 $wgRequest = new WebRequest();
6465
@@ -70,7 +71,8 @@
7172 global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
7273 global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
7374 global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode;
74 -global $wgBlockCache, $wgParserCache, $wgParser, $wgDontTrustMemcachedWithImportantStuff;
 75+global $wgBlockCache, $wgParserCache, $wgParser, $wgDBConnections;
 76+global $wgLoadBalancer, $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword;
7577
7678 # Useful debug output
7779 if ( $wgCommandLineMode ) {
@@ -141,6 +143,16 @@
142144 }
143145
144146 wfProfileOut( $fname.'-memcached' );
 147+wfProfileIn( $fname.'-database' );
 148+
 149+if ( !$wgDBservers ) {
 150+ $wgDBservers = array( $wgDBserver );
 151+ $wgDBloads = array( 1 );
 152+}
 153+$wgLoadBalancer = LoadBalancer::newFromParams( $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword, $wgDBname );
 154+$wgLoadBalancer->force(0);
 155+
 156+wfProfileOut( $fname.'-database' );
145157 wfProfileIn( $fname.'-language' );
146158 require_once( 'languages/Language.php' );
147159
@@ -218,6 +230,7 @@
219231 $wgParserCache = new ParserCache();
220232 $wgParser = new Parser();
221233 $wgOut->setParserOptions( ParserOptions::newFromUser( $wgUser ) );
 234+$wgDBConnections = array();
222235
223236 # Placeholders in case of DB error
224237 $wgTitle = Title::newFromText( wfMsg( 'badtitle' ) );
Index: trunk/phase3/includes/LoadBalancer.php
@@ -1,10 +1,27 @@
22 <?php
33 # Database load balancing object
44
 5+# Valid database indexes
 6+# Operation-based indexes
 7+define( "DB_READ", -1 ); # Read from the slave (or only server)
 8+define( "DB_WRITE", -2 ); # Write to master (or only server)
 9+define( "DB_LAST", -3 ); # Whatever database was used last
 10+
 11+# Task-based indexes
 12+# ***NOT USED YET, EXPERIMENTAL***
 13+# These may be defined in $wgDBservers. If they aren't, the default reader or writer will be used
 14+# Even numbers are always readers, odd numbers are writers
 15+define( "DB_TASK_FIRST", 1000 ); # First in list
 16+define( "DB_SEARCH_R", 1000 ); # Search read
 17+define( "DB_SEARCH_W", 1001 ); # Search write
 18+define( "DB_ASKSQL_R", 1002 ); # Special:Asksql read
 19+define( "DB_WATCHLIST_R", 1004 ); # Watchlist read
 20+define( "DB_TASK_LAST", 1004) ; # Last in list
 21+
522 class LoadBalancer {
623 /* private */ var $mServers, $mConnections, $mLoads;
724 /* private */ var $mUser, $mPassword, $mDbName, $mFailFunction;
8 - /* private */ var $mForce, $mReadIndex;
 25+ /* private */ var $mForce, $mReadIndex, $mLastConn;
926
1027 function LoadBalancer()
1128 {
@@ -17,6 +34,7 @@
1835 $this->mFailFunction = false;
1936 $this->mReadIndex = -1;
2037 $this->mForce = -1;
 38+ $this->mLastConn = false;
2139 }
2240
2341 function newFromParams( $servers, $loads, $user, $password, $dbName, $failFunction = false )
@@ -38,6 +56,7 @@
3957 $this->mWriteIndex = -1;
4058 $this->mForce = -1;
4159 $this->mConnections = array();
 60+ $this->mLastConn = false;
4261 wfSeedRandom();
4362 }
4463
@@ -96,21 +115,49 @@
97116 }
98117 return $conn;
99118 }
100 -
 119+
101120 function &getConnection( $i, $fail = false )
102121 {
103 - if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
104 - $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
105 - $this->mPassword, $this->mDbName, 1 );
106 - }
107 - if ( !$this->mConnections[$i]->isOpen() ) {
108 - wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
109 - if ( $fail ) {
110 - $this->reportConnectionError( $this->mConnections[$i] );
 122+ /*
 123+ # Task-based index
 124+ if ( $i >= DB_TASK_FIRST && $i < DB_TASK_LAST ) {
 125+ if ( $i % 2 ) {
 126+ # Odd index use writer
 127+ $i = DB_WRITE;
 128+ } else {
 129+ # Even index use reader
 130+ $i = DB_READ;
111131 }
112 - $this->mConnections[$i] = false;
 132+ }*/
 133+
 134+ # Operation-based index
 135+ # Note, getReader() and getWriter() will re-enter this function
 136+ if ( $i == DB_READ ) {
 137+ $this->mLastConn =& $this->getReader();
 138+ } elseif ( $i == DB_WRITE ) {
 139+ $this->mLastConn =& $this->getWriter();
 140+ } elseif ( $i == DB_LAST ) {
 141+ # Just use $this->mLastConn, which should already be set
 142+ if ( $this->mLastConn === false ) {
 143+ # Oh dear, not set, best to use the writer for safety
 144+ $this->mLastConn =& $this->getWriter();
 145+ }
 146+ } else {
 147+ # Explicit index
 148+ if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
 149+ $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
 150+ $this->mPassword, $this->mDbName, 1 );
 151+ }
 152+ if ( !$this->mConnections[$i]->isOpen() ) {
 153+ wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
 154+ if ( $fail ) {
 155+ $this->reportConnectionError( $this->mConnections[$i] );
 156+ }
 157+ $this->mConnections[$i] = false;
 158+ }
 159+ $this->mLastConn =& $this->mConnections[$i];
113160 }
114 - return $this->mConnections[$i];
 161+ return $this->mLastConn;
115162 }
116163
117164 function reportConnectionError( &$conn )
@@ -140,4 +187,9 @@
141188 {
142189 $this->mForce = $i;
143190 }
 191+
 192+ function haveIndex( $i )
 193+ {
 194+ return array_key_exists( $i, $this->mServers );
 195+ }
144196 }
Index: trunk/phase3/includes/DatabaseFunctions.php
@@ -11,6 +11,7 @@
1212 # NB: This file follows a connect on demand scheme. Do
1313 # not access the $wgDatabase variable directly unless
1414 # you intend to set it. Use wfGetDB().
 15+$wgDatabase = false;
1516
1617 $wgIsMySQL=false;
1718 $wgIsPg=false;
@@ -23,46 +24,33 @@
2425 $wgIsPg=true;
2526 }
2627
27 -# Query the database
28 -# $db: DB_READ = -1 read from slave (or only server)
29 -# DB_WRITE = -2 write to master (or only server)
30 -# 0,1,2,... query a database with a specific index
 28+
3129 # Replication is not actually implemented just yet
3230 # Usually aborts on failure
3331 # If errors are explicitly ignored, returns success
3432 function wfQuery( $sql, $db, $fname = "" )
3533 {
36 - global $wgDatabase, $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname,
37 - $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors;
38 -
3934 if ( !is_numeric( $db ) ) {
4035 # Someone has tried to call this the old way
4136 $wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params", $db, $sql ) );
4237 }
43 -
44 - $db =& wfGetDB();
45 - return $db->query( $sql, $fname );
 38+ $c =& wfGetDB( $db );
 39+ return $c->query( $sql, $fname );
4640 }
4741
48 -# Connect on demand
49 -function &wfGetDB()
 42+function &wfGetDB( $db = DB_LAST )
5043 {
51 - global $wgDatabase, $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname,
52 - $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors;
53 - if ( !$wgDatabase ) {
54 - $wgDatabase = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword,
55 - $wgDBname, false, $wgDebugDumpSql, $wgBufferSQLResults, $wgIgnoreSQLErrors );
56 - }
57 - return $wgDatabase;
 44+ global $wgLoadBalancer;
 45+ return $wgLoadBalancer->getConnection( $db );
5846 }
5947
6048 # Turns buffering of SQL result sets on (true) or off (false). Default is
6149 # "on" and it should not be changed without good reasons.
6250 # Returns the previous state.
6351
64 -function wfBufferSQLResults( $newstate )
 52+function wfBufferSQLResults( $newstate, $dbi = DB_LAST )
6553 {
66 - $db =& wfGetDB();
 54+ $db =& wfGetDB( $dbi );
6755 return $db->setBufferResults( $newstate );
6856 }
6957
@@ -73,122 +61,122 @@
7462 # situation as appropriate.
7563 # Returns the previous state.
7664
77 -function wfIgnoreSQLErrors( $newstate )
 65+function wfIgnoreSQLErrors( $newstate, $dbi = DB_LAST )
7866 {
79 - $db =& wfGetDB();
 67+ $db =& wfGetDB( $dbi );
8068 return $db->setIgnoreErrors( $newstate );
8169 }
8270
83 -function wfFreeResult( $res )
 71+function wfFreeResult( $res, $dbi = DB_LAST )
8472 {
85 - $db =& wfGetDB();
 73+ $db =& wfGetDB( $dbi );
8674 $db->freeResult( $res );
8775 }
8876
89 -function wfFetchObject( $res )
 77+function wfFetchObject( $res, $dbi = DB_LAST )
9078 {
91 - $db =& wfGetDB();
92 - return $db->fetchObject( $res );
 79+ $db =& wfGetDB( $dbi );
 80+ return $db->fetchObject( $res, $dbi = DB_LAST );
9381 }
9482
95 -function wfFetchRow( $res )
 83+function wfFetchRow( $res, $dbi = DB_LAST )
9684 {
97 - $db =& wfGetDB();
98 - return $db->fetchRow ( $res );
 85+ $db =& wfGetDB( $dbi );
 86+ return $db->fetchRow ( $res, $dbi = DB_LAST );
9987 }
10088
101 -function wfNumRows( $res )
 89+function wfNumRows( $res, $dbi = DB_LAST )
10290 {
103 - $db =& wfGetDB();
104 - return $db->numRows( $res );
 91+ $db =& wfGetDB( $dbi );
 92+ return $db->numRows( $res, $dbi = DB_LAST );
10593 }
10694
107 -function wfNumFields( $res )
 95+function wfNumFields( $res, $dbi = DB_LAST )
10896 {
109 - $db =& wfGetDB();
 97+ $db =& wfGetDB( $dbi );
11098 return $db->numFields( $res );
11199 }
112100
113 -function wfFieldName( $res, $n )
 101+function wfFieldName( $res, $n, $dbi = DB_LAST )
114102 {
115 - $db =& wfGetDB();
116 - return $db->fieldName( $res, $n );
 103+ $db =& wfGetDB( $dbi );
 104+ return $db->fieldName( $res, $n, $dbi = DB_LAST );
117105 }
118106
119 -function wfInsertId()
 107+function wfInsertId( $dbi = DB_LAST )
120108 {
121 - $db =& wfGetDB();
 109+ $db =& wfGetDB( $dbi );
122110 return $db->insertId();
123111 }
124 -function wfDataSeek( $res, $row )
 112+function wfDataSeek( $res, $row, $dbi = DB_LAST )
125113 {
126 - $db =& wfGetDB();
 114+ $db =& wfGetDB( $dbi );
127115 return $db->dataSeek( $res, $row );
128116 }
129117
130 -function wfLastErrno()
 118+function wfLastErrno( $dbi = DB_LAST )
131119 {
132 - $db =& wfGetDB();
 120+ $db =& wfGetDB( $dbi );
133121 return $db->lastErrno();
134122 }
135123
136 -function wfLastError()
 124+function wfLastError( $dbi = DB_LAST )
137125 {
138 - $db =& wfGetDB();
 126+ $db =& wfGetDB( $dbi );
139127 return $db->lastError();
140128 }
141129
142 -function wfAffectedRows()
 130+function wfAffectedRows( $dbi = DB_LAST )
143131 {
144 - $db =& wfGetDB();
 132+ $db =& wfGetDB( $dbi );
145133 return $db->affectedRows();
146134 }
147135
148 -function wfLastDBquery()
 136+function wfLastDBquery( $dbi = DB_LAST )
149137 {
150 - $db =& wfGetDB();
 138+ $db =& wfGetDB( $dbi );
151139 return $db->lastQuery();
152140 }
153141
154 -function wfSetSQL( $table, $var, $value, $cond )
 142+function wfSetSQL( $table, $var, $value, $cond, $dbi = DB_WRITE )
155143 {
156 - $db =& wfGetDB();
 144+ $db =& wfGetDB( $dbi );
157145 return $db->set( $table, $var, $value, $cond );
158146 }
159147
160 -function wfGetSQL( $table, $var, $cond="" )
 148+function wfGetSQL( $table, $var, $cond="", $dbi = DB_LAST )
161149 {
162 - $db =& wfGetDB();
 150+ $db =& wfGetDB( $dbi );
163151 return $db->get( $table, $var, $cond );
164152 }
165153
166 -function wfFieldExists( $table, $field )
 154+function wfFieldExists( $table, $field, $dbi = DB_LAST )
167155 {
168 - $db =& wfGetDB();
 156+ $db =& wfGetDB( $dbi );
169157 return $db->fieldExists( $table, $field );
170158 }
171159
172 -function wfIndexExists( $table, $index )
 160+function wfIndexExists( $table, $index, $dbi = DB_LAST )
173161 {
174 - $db =& wfGetDB();
 162+ $db =& wfGetDB( $dbi );
175163 return $db->indexExists( $table, $index );
176164 }
177165
178 -function wfInsertArray( $table, $array )
 166+function wfInsertArray( $table, $array, $fname = "wfInsertArray", $dbi = DB_WRITE )
179167 {
180 - $db =& wfGetDB();
181 - return $db->insertArray( $table, $array );
 168+ $db =& wfGetDB( $dbi );
 169+ return $db->insertArray( $table, $array, $fname );
182170 }
183171
184 -function wfGetArray( $table, $vars, $conds, $fname = "wfGetArray" )
 172+function wfGetArray( $table, $vars, $conds, $fname = "wfGetArray", $dbi = DB_LAST )
185173 {
186 - $db =& wfGetDB();
 174+ $db =& wfGetDB( $dbi );
187175 return $db->getArray( $table, $vars, $conds, $fname );
188176 }
189177
190 -function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray" )
 178+function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray", $dbi = DB_WRITE )
191179 {
192 - $db =& wfGetDB();
 180+ $db =& wfGetDB( $dbi );
193181 $db->updateArray( $table, $values, $conds, $fname );
194182 }
195183
Index: trunk/phase3/includes/Database.php
@@ -5,10 +5,6 @@
66 #
77 require_once( "CacheManager.php" );
88
9 -define( "DB_READ", -1 );
10 -define( "DB_WRITE", -2 );
11 -define( "DB_LAST", -3 );
12 -
139 define( "LIST_COMMA", 0 );
1410 define( "LIST_AND", 1 );
1511 define( "LIST_SET", 2 );
@@ -143,10 +139,11 @@
144140 {
145141 if ( $this->mFailFunction ) {
146142 if ( !is_int( $this->mFailFunction ) ) {
147 - $this->$mFailFunction( $this );
 143+ $ff = $this->mFailFunction;
 144+ $ff( $this, mysql_error() );
148145 }
149146 } else {
150 - wfEmergencyAbort( $this );
 147+ wfEmergencyAbort( $this, mysql_error() );
151148 }
152149 }
153150
@@ -459,7 +456,7 @@
460457
461458 /* Standard fail function, called by default when a connection cannot be established
462459 Displays the file cache if possible */
463 -function wfEmergencyAbort( &$conn ) {
 460+function wfEmergencyAbort( &$conn, $error ) {
464461 global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgSiteNotice, $wgOutputEncoding;
465462
466463 if( !headers_sent() ) {
@@ -470,7 +467,7 @@
471468 header( "Pragma: nocache" );
472469 }
473470 $msg = $wgSiteNotice;
474 - if($msg == "") $msg = wfMsgNoDB( "noconnect" );
 471+ if($msg == "") $msg = wfMsgNoDB( "noconnect", $error );
475472 $text = $msg;
476473
477474 if($wgUseFileCache) {

Status & tagging log