Page MenuHomePhabricator

D16913.id40716.diff
No OneTemporary

D16913.id40716.diff

diff --git a/src/docs/user/cluster/cluster_partitioning.diviner b/src/docs/user/cluster/cluster_partitioning.diviner
--- a/src/docs/user/cluster/cluster_partitioning.diviner
+++ b/src/docs/user/cluster/cluster_partitioning.diviner
@@ -31,6 +31,13 @@
should review and understand how replication works before you partition. For
details, see @{Cluster:Databases}.
+Databases also support some advanced configuration options. Briefly:
+
+ - `persistent`: Allows use of persistent connections, reducing pressure on
+ outbound ports.
+
+See "Advanced Configuration", below, for additional discussion.
+
What Partitioning Does
======================
@@ -196,6 +203,37 @@
physical host or different physical hosts.
+Advanced Configuration
+======================
+
+Separate from partitioning, some advanced configuration is supported. These
+options must be set on database specifications in `cluster.databases`. You can
+configure them without actually building a cluster by defining a cluster with
+only one master.
+
+`persistent` //(bool)// Enables persistent connections. Defaults to off.
+
+With persitent connections enabled, Phabricator will keep a pool of database
+connections open between web requests and reuse them when serving subsequent
+requests.
+
+The primary benefit of using persistent connections is that it will greatly
+reduce pressure on how quickly outbound TCP ports are opened and closed. After
+a TCP port closes, it normally can't be used again for about 60 seconds, so
+rapidly cycling ports can cause resource exuastion. If you're seeing failures
+because requests are unable to bind to an outbound port, enabling this option
+is likely to fix the issue. This option may also slightly increase performance.
+
+The cost of using persistent connections is that you may need to raise the
+MySQL `max_connections` setting: although Phabricator will make far fewer
+connections, the connections it does make will be longer-lived. Raising this
+setting will increase MySQL memory requirements and may run into other limits,
+like `open_files_limit`, which may also need to be raised.
+
+Persistent connections are enabled per-database. If you always want to use
+them, set the flag on each configured database in `cluster.databases`.
+
+
Next Steps
==========
diff --git a/src/infrastructure/cluster/PhabricatorClusterDatabasesConfigOptionType.php b/src/infrastructure/cluster/PhabricatorClusterDatabasesConfigOptionType.php
--- a/src/infrastructure/cluster/PhabricatorClusterDatabasesConfigOptionType.php
+++ b/src/infrastructure/cluster/PhabricatorClusterDatabasesConfigOptionType.php
@@ -37,6 +37,7 @@
'disabled' => 'optional bool',
'master' => 'optional string',
'partition' => 'optional list<string>',
+ 'persistent' => 'optional bool',
));
} catch (Exception $ex) {
throw new Exception(
diff --git a/src/infrastructure/cluster/PhabricatorDatabaseRef.php b/src/infrastructure/cluster/PhabricatorDatabaseRef.php
--- a/src/infrastructure/cluster/PhabricatorDatabaseRef.php
+++ b/src/infrastructure/cluster/PhabricatorDatabaseRef.php
@@ -40,6 +40,7 @@
private $applicationMap = array();
private $masterRef;
private $replicaRefs = array();
+ private $usePersistentConnections;
public function setHost($host) {
$this->host = $host;
@@ -171,6 +172,15 @@
return $this->isDefaultPartition;
}
+ public function setUsePersistentConnections($use_persistent_connections) {
+ $this->usePersistentConnections = $use_persistent_connections;
+ return $this;
+ }
+
+ public function getUsePersistentConnections() {
+ return $this->usePersistentConnections;
+ }
+
public function setApplicationMap(array $application_map) {
$this->applicationMap = $application_map;
return $this;
@@ -582,7 +592,8 @@
->setPort($default_port)
->setIsIndividual(true)
->setIsMaster(true)
- ->setIsDefaultPartition(true);
+ ->setIsDefaultPartition(true)
+ ->setUsePersistentConnections(false);
}
public static function getAllReplicaDatabaseRefs() {
@@ -672,9 +683,31 @@
'database' => null,
'retries' => $default_retries,
'timeout' => $default_timeout,
+ 'persistent' => $this->getUsePersistentConnections(),
);
- return self::newRawConnection($spec);
+ $is_cli = (php_sapi_name() == 'cli');
+
+ $use_persistent = false;
+ if (!empty($spec['persistent']) && !$is_cli) {
+ $use_persistent = true;
+ }
+ unset($spec['persistent']);
+
+ $connection = self::newRawConnection($spec);
+
+ // If configured, use persistent connections. See T11672 for details.
+ if ($use_persistent) {
+ $connection->setPersistent($use_persistent);
+ }
+
+ // Unless this is a script running from the CLI, prevent any query from
+ // running for more than 30 seconds. See T10849 for details.
+ if (!$is_cli) {
+ $connection->setQueryTimeout(30);
+ }
+
+ return $connection;
}
public static function newRawConnection(array $options) {
diff --git a/src/infrastructure/cluster/PhabricatorDatabaseRefParser.php b/src/infrastructure/cluster/PhabricatorDatabaseRefParser.php
--- a/src/infrastructure/cluster/PhabricatorDatabaseRefParser.php
+++ b/src/infrastructure/cluster/PhabricatorDatabaseRefParser.php
@@ -58,13 +58,16 @@
$role = $server['role'];
$is_master = ($role == 'master');
+ $use_persistent = (bool)idx($server, 'persistent', false);
+
$ref = id(new PhabricatorDatabaseRef())
->setHost($host)
->setPort($port)
->setUser($user)
->setPass($pass)
->setDisabled($disabled)
- ->setIsMaster($is_master);
+ ->setIsMaster($is_master)
+ ->setUsePersistentConnections($use_persistent);
if ($is_master) {
$master_count++;
diff --git a/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php b/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php
--- a/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php
+++ b/src/infrastructure/storage/lisk/PhabricatorLiskDAO.php
@@ -73,21 +73,6 @@
$connection->setReadOnly(true);
}
- // Unless this is a script running from the CLI:
- // - (T10849) Prevent any query from running for more than 30 seconds.
- // - (T11672) Use persistent connections.
- if (php_sapi_name() != 'cli') {
-
- // TODO: For now, disable this until after T11044: it's better at high
- // load, but causes us to use slightly more connections at low load and
- // is pushing users over limits like MySQL "max_connections".
- $use_persistent = false;
-
- $connection
- ->setQueryTimeout(30)
- ->setPersistent($use_persistent);
- }
-
return $connection;
}

File Metadata

Mime Type
text/plain
Expires
Wed, May 7, 4:14 PM (6 h, 51 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7475963
Default Alt Text
D16913.id40716.diff (6 KB)

Event Timeline