r79518 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r79517‎ | r79518 | r79519 >
Date:19:50, 3 January 2011
Author:ialex
Status:resolved (Comments)
Tags:brion 
Comment:
* Modified Article::loadPageData() to use a slave database connection and pageDataFromTitle() instead of pageDataFromId() in the default case, as in Wiki.php (this also saves a query since the ID will be fetched with other fileds)
* Removed the loadPageData() call for the initial article in Wiki.php, will be triggered by the isRedirect() call 7 lines below if needed (this was not needed if $target is set by the InitializeArticleMaybeRedirect hook), but kept the second one (same as above, Article::exists() triggers Title::getArticleId() that would use one query to get id and a second one is needed to get the complete page data)
* Modified Article::fetchContent() to use common code (loadPageData()) and to only call it if really needed
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/Wiki.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Article.php
@@ -468,8 +468,8 @@
469469 */
470470 public function loadPageData( $data = 'fromdb' ) {
471471 if ( $data === 'fromdb' ) {
472 - $dbr = wfGetDB( DB_MASTER );
473 - $data = $this->pageDataFromId( $dbr, $this->getId() );
 472+ $dbr = wfGetDB( DB_SLAVE );
 473+ $data = $this->pageDataFromTitle( $dbr, $this->mTitle );
474474 }
475475
476476 $lc = LinkCache::singleton();
@@ -506,8 +506,6 @@
507507 return $this->mContent;
508508 }
509509
510 - $dbr = wfGetDB( DB_MASTER );
511 -
512510 # Pre-fill content with error message so that if something
513511 # fails we'll have something telling us what we intended.
514512 $t = $this->mTitle->getPrefixedText();
@@ -521,28 +519,29 @@
522520 return false;
523521 }
524522
525 - $data = $this->pageDataFromId( $dbr, $revision->getPage() );
 523+ if ( !$this->mDataLoaded || $this->getID() != $revision->getPage() ) {
 524+ $data = $this->pageDataFromId( wfGetDB( DB_SLAVE ), $revision->getPage() );
526525
527 - if ( !$data ) {
528 - wfDebug( __METHOD__ . " failed to get page data linked to revision id $oldid\n" );
529 - return false;
530 - }
531 -
532 - $this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title );
533 - $this->loadPageData( $data );
534 - } else {
535 - if ( !$this->mDataLoaded ) {
536 - $data = $this->pageDataFromTitle( $dbr, $this->mTitle );
537 -
538526 if ( !$data ) {
539 - wfDebug( __METHOD__ . " failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
 527+ wfDebug( __METHOD__ . " failed to get page data linked to revision id $oldid\n" );
540528 return false;
541529 }
542530
 531+ $this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title );
543532 $this->loadPageData( $data );
544533 }
 534+ } else {
 535+ if ( !$this->mDataLoaded ) {
 536+ $this->loadPageData();
 537+ }
 538+
 539+ if ( $this->mLatest === false ) {
 540+ wfDebug( __METHOD__ . " failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
 541+ return false;
 542+ }
 543+
545544 $revision = Revision::newFromId( $this->mLatest );
546 - if ( $revision === null ) {
 545+ if ( $revision === null ) {
547546 wfDebug( __METHOD__ . " failed to retrieve current page, rev_id {$this->mLatest}\n" );
548547 return false;
549548 }
Index: trunk/phase3/includes/Wiki.php
@@ -349,9 +349,6 @@
350350 // Give extensions a change to ignore/handle redirects as needed
351351 $ignoreRedirect = $target = false;
352352
353 - $dbr = wfGetDB( DB_SLAVE );
354 - $article->loadPageData( $article->pageDataFromTitle( $dbr, $title ) );
355 -
356353 wfRunHooks( 'InitializeArticleMaybeRedirect',
357354 array(&$title,&$request,&$ignoreRedirect,&$target,&$article) );
358355
@@ -370,7 +367,7 @@
371368 if( is_object($target) ) {
372369 // Rewrite environment to redirected article
373370 $rarticle = self::articleFromTitle( $target );
374 - $rarticle->loadPageData( $rarticle->pageDataFromTitle( $dbr, $target ) );
 371+ $rarticle->loadPageData();
375372 if( $rarticle->exists() || ( is_object( $file ) && !$file->isLocal() ) ) {
376373 $rarticle->setRedirectedFrom( $title );
377374 $article = $rarticle;

Follow-up revisions

RevisionCommit summaryAuthorDate
r92083Added 'fromdbmaster' param option to WikiPage::loadPageData()aaron19:14, 13 July 2011
r93093Follow-up r79518: added getCachedLastEditTime/getCachedLastEditTime methods t...aaron19:24, 25 July 2011

Comments

#Comment by Aaron Schulz (talk | contribs)   21:35, 14 June 2011

I like the idea here, but I worry if something calls an accessor of Article that needs DB_MASTER data.

#Comment by Brion VIBBER (talk | contribs)   18:45, 13 July 2011

I'm pretty sure we've gone back and forth on this sort of thing several times over the years...

Reading page data from the slave is dangerous as it may be out of date.

Reading page data from the master is potentially slow as it slams the master with more activity.

"In theory" what we're supposed to be doing I think is something like 'grab the most basic page/revision row from master' for reliability, followed by being able to load the page text and do rendering existence checks etc etc on the slave.

#Comment by Aaron Schulz (talk | contribs)   19:03, 13 July 2011

With chronology protection and the session key having the db position, it normally should be fine to use a slave. I suppose if the slave lag gets really bad (as it does on occasion) you want to fall back to the master.

It might be nice to have some kind cache key or something that's set if the lag gets really bad; when the key isn't set, the lag is checked every other X hits. I can't see why we have to use the master for a simple page view.

Also, I'd like it if the functions let you choose master or slave.

Status & tagging log