mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 14:26:54 +08:00
Fix #17991: Improve yii\db\Connection
master and slave failover, no connection attempt was made when all servers are marked as unavailable
This commit is contained in:
@ -13,6 +13,7 @@ Yii Framework 2 Change Log
|
|||||||
- Bug #17960: Fix unsigned primary key type mapping for SQLite (bizley)
|
- Bug #17960: Fix unsigned primary key type mapping for SQLite (bizley)
|
||||||
- Enh #17758: `Query::withQuery()` can be used for CTE (sartor)
|
- Enh #17758: `Query::withQuery()` can be used for CTE (sartor)
|
||||||
- Bug #17974: Fix ActiveRelationTrait compatibility with PHP 7.4 (Ximich)
|
- Bug #17974: Fix ActiveRelationTrait compatibility with PHP 7.4 (Ximich)
|
||||||
|
- Bug #17991: Improve `yii\db\Connection` master and slave failover, no connection attempt was made when all servers are marked as unavailable (cebe)
|
||||||
- Enh #17993: Added `yii\i18n\Formatter::$currencyDecimalSeparator` to allow setting custom symbols for currency decimal in IntlNumberFormatter (XPOHOC269)
|
- Enh #17993: Added `yii\i18n\Formatter::$currencyDecimalSeparator` to allow setting custom symbols for currency decimal in IntlNumberFormatter (XPOHOC269)
|
||||||
- Bug #18000: PK value of Oracle ActiveRecord is missing after save (mankwok)
|
- Bug #18000: PK value of Oracle ActiveRecord is missing after save (mankwok)
|
||||||
- Enh #18006: Allow SameSite cookie pre PHP 7.3 (scottix)
|
- Enh #18006: Allow SameSite cookie pre PHP 7.3 (scottix)
|
||||||
|
@ -332,6 +332,8 @@ class Connection extends Component
|
|||||||
* the health status of the DB servers specified in [[masters]] and [[slaves]].
|
* the health status of the DB servers specified in [[masters]] and [[slaves]].
|
||||||
* This is used only when read/write splitting is enabled or [[masters]] is not empty.
|
* This is used only when read/write splitting is enabled or [[masters]] is not empty.
|
||||||
* Set boolean `false` to disabled server status caching.
|
* Set boolean `false` to disabled server status caching.
|
||||||
|
* @see openFromPoolSequentially() for details about the failover behavior.
|
||||||
|
* @see serverRetryInterval
|
||||||
*/
|
*/
|
||||||
public $serverStatusCache = 'cache';
|
public $serverStatusCache = 'cache';
|
||||||
/**
|
/**
|
||||||
@ -1099,12 +1101,16 @@ class Connection extends Component
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the connection to a server in the pool.
|
* Opens the connection to a server in the pool.
|
||||||
* This method implements the load balancing among the given list of the servers.
|
*
|
||||||
|
* This method implements load balancing and failover among the given list of the servers.
|
||||||
* Connections will be tried in random order.
|
* Connections will be tried in random order.
|
||||||
|
* For details about the failover behavior, see [[openFromPoolSequentially]].
|
||||||
|
*
|
||||||
* @param array $pool the list of connection configurations in the server pool
|
* @param array $pool the list of connection configurations in the server pool
|
||||||
* @param array $sharedConfig the configuration common to those given in `$pool`.
|
* @param array $sharedConfig the configuration common to those given in `$pool`.
|
||||||
* @return Connection the opened DB connection, or `null` if no server is available
|
* @return Connection the opened DB connection, or `null` if no server is available
|
||||||
* @throws InvalidConfigException if a configuration does not specify "dsn"
|
* @throws InvalidConfigException if a configuration does not specify "dsn"
|
||||||
|
* @see openFromPoolSequentially
|
||||||
*/
|
*/
|
||||||
protected function openFromPool(array $pool, array $sharedConfig)
|
protected function openFromPool(array $pool, array $sharedConfig)
|
||||||
{
|
{
|
||||||
@ -1114,13 +1120,26 @@ class Connection extends Component
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the connection to a server in the pool.
|
* Opens the connection to a server in the pool.
|
||||||
* This method implements the load balancing among the given list of the servers.
|
*
|
||||||
* Connections will be tried in sequential order.
|
* This method implements failover among the given list of servers.
|
||||||
|
* Connections will be tried in sequential order. The first successful connection will return.
|
||||||
|
*
|
||||||
|
* If [[serverStatusCache]] is configured, this method will cache information about
|
||||||
|
* unreachable servers and does not try to connect to these for the time configured in [[serverRetryInterval]].
|
||||||
|
* This helps to keep the application stable when some servers are unavailable. Avoiding
|
||||||
|
* connection attempts to unavailable servers saves time when the connection attempts fail due to timeout.
|
||||||
|
*
|
||||||
|
* If none of the servers are available the status cache is ignored and connection attempts are made to all
|
||||||
|
* servers (Since version 2.0.35). This is to avoid downtime when all servers are unavailable for a short time.
|
||||||
|
* After a successful connection attempt the server is marked as avaiable again.
|
||||||
|
*
|
||||||
* @param array $pool the list of connection configurations in the server pool
|
* @param array $pool the list of connection configurations in the server pool
|
||||||
* @param array $sharedConfig the configuration common to those given in `$pool`.
|
* @param array $sharedConfig the configuration common to those given in `$pool`.
|
||||||
* @return Connection the opened DB connection, or `null` if no server is available
|
* @return Connection the opened DB connection, or `null` if no server is available
|
||||||
* @throws InvalidConfigException if a configuration does not specify "dsn"
|
* @throws InvalidConfigException if a configuration does not specify "dsn"
|
||||||
* @since 2.0.11
|
* @since 2.0.11
|
||||||
|
* @see openFromPool
|
||||||
|
* @see serverStatusCache
|
||||||
*/
|
*/
|
||||||
protected function openFromPoolSequentially(array $pool, array $sharedConfig)
|
protected function openFromPoolSequentially(array $pool, array $sharedConfig)
|
||||||
{
|
{
|
||||||
@ -1134,8 +1153,8 @@ class Connection extends Component
|
|||||||
|
|
||||||
$cache = is_string($this->serverStatusCache) ? Yii::$app->get($this->serverStatusCache, false) : $this->serverStatusCache;
|
$cache = is_string($this->serverStatusCache) ? Yii::$app->get($this->serverStatusCache, false) : $this->serverStatusCache;
|
||||||
|
|
||||||
foreach ($pool as $config) {
|
foreach ($pool as $i => $config) {
|
||||||
$config = array_merge($sharedConfig, $config);
|
$pool[$i] = $config = array_merge($sharedConfig, $config);
|
||||||
if (empty($config['dsn'])) {
|
if (empty($config['dsn'])) {
|
||||||
throw new InvalidConfigException('The "dsn" option must be specified.');
|
throw new InvalidConfigException('The "dsn" option must be specified.');
|
||||||
}
|
}
|
||||||
@ -1158,6 +1177,30 @@ class Connection extends Component
|
|||||||
// mark this server as dead and only retry it after the specified interval
|
// mark this server as dead and only retry it after the specified interval
|
||||||
$cache->set($key, 1, $this->serverRetryInterval);
|
$cache->set($key, 1, $this->serverRetryInterval);
|
||||||
}
|
}
|
||||||
|
// exclude server from retry below
|
||||||
|
unset($pool[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cache instanceof CacheInterface) {
|
||||||
|
// if server status cache is enabled and no server is available
|
||||||
|
// ignore the cache and try to connect anyway
|
||||||
|
// $pool now only contains servers we did not already try in the loop above
|
||||||
|
foreach ($pool as $config) {
|
||||||
|
|
||||||
|
/* @var $db Connection */
|
||||||
|
$db = Yii::createObject($config);
|
||||||
|
try {
|
||||||
|
$db->open();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Yii::warning("Connection ({$config['dsn']}) failed: " . $e->getMessage(), __METHOD__);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark this server as available again after successful connection
|
||||||
|
$cache->delete([__METHOD__, $config['dsn']]);
|
||||||
|
|
||||||
|
return $db;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user