X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fdb%2FMWLBFactory.php;h=bbb3d2f7b75adc02307991397b994be4991217bf;hp=a930b3b0eb47aa6c7f6c6250acf9d5f5b4ed13fe;hb=a38af7ba26579bb3004f673e44d39710887763aa;hpb=b9789f9c562aecf08c1080430d6b85be06d4ae90 diff --git a/includes/db/MWLBFactory.php b/includes/db/MWLBFactory.php index a930b3b0eb..bbb3d2f7b7 100644 --- a/includes/db/MWLBFactory.php +++ b/includes/db/MWLBFactory.php @@ -77,16 +77,27 @@ abstract class MWLBFactory { 'defaultGroup' => $mainConfig->get( 'DBDefaultGroup' ), ]; + $serversCheck = []; // When making changes here, remember to also specify MediaWiki-specific options // for Database classes in the relevant Installer subclass. // Such as MysqlInstaller::openConnection and PostgresInstaller::openConnectionWithParams. if ( $lbConf['class'] === Wikimedia\Rdbms\LBFactorySimple::class ) { + $httpMethod = $_SERVER['REQUEST_METHOD'] ?? null; + // T93097: hint for how file-based databases (e.g. sqlite) should go about locking. + // See https://www.sqlite.org/lang_transaction.html + // See https://www.sqlite.org/lockingv3.html#shared_lock + $isReadRequest = in_array( $httpMethod, [ 'GET', 'HEAD', 'OPTIONS', 'TRACE' ] ); + if ( isset( $lbConf['servers'] ) ) { // Server array is already explicitly configured; leave alone } elseif ( is_array( $mainConfig->get( 'DBservers' ) ) ) { + $lbConf['servers'] = []; foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) { if ( $server['type'] === 'sqlite' ) { - $server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ]; + $server += [ + 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ), + 'trxMode' => $isReadRequest ? 'DEFERRED' : 'IMMEDIATE' + ]; } elseif ( $server['type'] === 'postgres' ) { $server += [ 'port' => $mainConfig->get( 'DBport' ), @@ -98,20 +109,6 @@ abstract class MWLBFactory { 'port' => $mainConfig->get( 'DBport' ), 'useWindowsAuth' => $mainConfig->get( 'DBWindowsAuthentication' ) ]; - } elseif ( $server['type'] === 'mysql' ) { - // A DB name is not needed to connect to mysql; 'dbname' is useless. - // This field only defines the DB to use for unspecified DB domains. - $ldDB = $mainConfig->get( 'DBname' ); // local domain DB - $srvDB = $server['dbname'] ?? null; // server DB - if ( $srvDB !== null && $srvDB !== $ldDB ) { - self::reportMismatchedDBs( $srvDB, $ldDB ); - } - } - - $ldTP = $mainConfig->get( 'DBprefix' ); // local domain prefix - $srvTP = $server['tablePrefix'] ?? null; // server table prefix - if ( $srvTP !== '' && $srvTP !== $ldTP ) { - self::reportMismatchedPrefixes( $srvTP, $ldTP ); } if ( in_array( $server['type'], $typesWithSchema, true ) ) { @@ -122,7 +119,6 @@ abstract class MWLBFactory { 'tablePrefix' => $mainConfig->get( 'DBprefix' ), 'flags' => DBO_DEFAULT, 'sqlMode' => $mainConfig->get( 'SQLMode' ), - 'utf8Mode' => $mainConfig->get( 'DBmysql5' ) ]; $lbConf['servers'][$i] = $server; @@ -142,7 +138,7 @@ abstract class MWLBFactory { 'load' => 1, 'flags' => $flags, 'sqlMode' => $mainConfig->get( 'SQLMode' ), - 'utf8Mode' => $mainConfig->get( 'DBmysql5' ) + 'trxMode' => $isReadRequest ? 'DEFERRED' : 'IMMEDIATE' ]; if ( in_array( $server['type'], $typesWithSchema, true ) ) { $server += [ 'schema' => $mainConfig->get( 'DBmwschema' ) ]; @@ -162,16 +158,19 @@ abstract class MWLBFactory { if ( !isset( $lbConf['externalClusters'] ) ) { $lbConf['externalClusters'] = $mainConfig->get( 'ExternalServers' ); } + + $serversCheck = $lbConf['servers']; } elseif ( $lbConf['class'] === Wikimedia\Rdbms\LBFactoryMulti::class ) { if ( isset( $lbConf['serverTemplate'] ) ) { if ( in_array( $lbConf['serverTemplate']['type'], $typesWithSchema, true ) ) { $lbConf['serverTemplate']['schema'] = $mainConfig->get( 'DBmwschema' ); } $lbConf['serverTemplate']['sqlMode'] = $mainConfig->get( 'SQLMode' ); - $lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get( 'DBmysql5' ); } + $serversCheck = $lbConf['serverTemplate'] ?? []; } + self::sanityCheckServerConfig( $serversCheck, $mainConfig ); $lbConf = self::applyDefaultCaching( $lbConf, $srvCace, $mainStash, $wanCache ); return $lbConf; @@ -201,6 +200,50 @@ abstract class MWLBFactory { return $lbConf; } + /** + * @param array $servers + * @param Config $mainConfig + */ + private static function sanityCheckServerConfig( array $servers, Config $mainConfig ) { + $ldDB = $mainConfig->get( 'DBname' ); // local domain DB + $ldTP = $mainConfig->get( 'DBprefix' ); // local domain prefix + + foreach ( $servers as $server ) { + $type = $server['type'] ?? null; + $srvDB = $server['dbname'] ?? null; // server DB + $srvTP = $server['tablePrefix'] ?? ''; // server table prefix + + if ( $type === 'mysql' ) { + // A DB name is not needed to connect to mysql; 'dbname' is useless. + // This field only defines the DB to use for unspecified DB domains. + if ( $srvDB !== null && $srvDB !== $ldDB ) { + self::reportMismatchedDBs( $srvDB, $ldDB ); + } + } elseif ( $type === 'postgres' ) { + if ( $srvTP !== '' ) { + self::reportIfPrefixSet( $srvTP, $type ); + } + } + + if ( $srvTP !== '' && $srvTP !== $ldTP ) { + self::reportMismatchedPrefixes( $srvTP, $ldTP ); + } + } + } + + /** + * @param string $prefix Table prefix + * @param string $dbType Database type + */ + private static function reportIfPrefixSet( $prefix, $dbType ) { + $e = new UnexpectedValueException( + "\$wgDBprefix is set to '$prefix' but the database type is '$dbType'. " . + "MediaWiki does not support using a table prefix with this RDBMS type." + ); + MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY ); + exit; + } + /** * @param string $srvDB Server config database * @param string $ldDB Local DB domain database @@ -210,8 +253,8 @@ abstract class MWLBFactory { "\$wgDBservers has dbname='$srvDB' but \$wgDBname='$ldDB'. " . "Set \$wgDBname to the database used by this wiki project. " . "There is rarely a need to set 'dbname' in \$wgDBservers. " . - "Functions like wfWikiId(), remote wiki database access, the use " . - "of Database::getDomainId(), and other features are not reliable when " . + "Cross-wiki database access, use of WikiMap::getCurrentWikiDbDomain(), " . + "use of Database::getDomainId(), and other features are not reliable when " . "\$wgDBservers does not match the local wiki database/prefix." ); MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY ); @@ -227,8 +270,8 @@ abstract class MWLBFactory { "\$wgDBservers has tablePrefix='$srvTP' but \$wgDBprefix='$ldTP'. " . "Set \$wgDBprefix to the table prefix used by this wiki project. " . "There is rarely a need to set 'tablePrefix' in \$wgDBservers. " . - "Functions like wfWikiId(), remote wiki database access, the use " . - "of Database::getDomainId(), and other features are not reliable when " . + "Cross-wiki database access, use of WikiMap::getCurrentWikiDbDomain(), " . + "use of Database::getDomainId(), and other features are not reliable when " . "\$wgDBservers does not match the local wiki database/prefix." ); MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );