Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15422007
D15714.id37862.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D15714.id37862.diff
View Options
diff --git a/scripts/sql/manage_storage.php b/scripts/sql/manage_storage.php
--- a/scripts/sql/manage_storage.php
+++ b/scripts/sql/manage_storage.php
@@ -31,6 +31,12 @@
'Do not prompt before performing dangerous operations.'),
),
array(
+ 'name' => 'host',
+ 'param' => 'hostname',
+ 'help' => pht(
+ 'Connect to __host__ instead of the default host.'),
+ ),
+ array(
'name' => 'user',
'short' => 'u',
'param' => 'username',
@@ -75,10 +81,37 @@
// First, test that the Phabricator configuration is set up correctly. After
// we know this works we'll test any administrative credentials specifically.
-$ref = PhabricatorDatabaseRef::getMasterDatabaseRef();
-if (!$ref) {
- throw new Exception(
- pht('No database master is configured.'));
+$host = $args->getArg('host');
+if (strlen($host)) {
+ $ref = null;
+
+ $refs = PhabricatorDatabaseRef::getLiveRefs();
+
+ // Include the master in case the user is just specifying a redundant
+ // "--host" flag for no reason and does not actually have a database
+ // cluster configured.
+ $refs[] = PhabricatorDatabaseRef::getMasterDatabaseRef();
+
+ foreach ($refs as $possible_ref) {
+ if ($possible_ref->getHost() == $host) {
+ $ref = $possible_ref;
+ break;
+ }
+ }
+
+ if (!$ref) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'There is no configured database on host "%s". This command can '.
+ 'only interact with configured databases.',
+ $host));
+ }
+} else {
+ $ref = PhabricatorDatabaseRef::getMasterDatabaseRef();
+ if (!$ref) {
+ throw new Exception(
+ pht('No database master is configured.'));
+ }
}
$default_user = $ref->getUser();
diff --git a/src/docs/user/cluster/cluster_databases.diviner b/src/docs/user/cluster/cluster_databases.diviner
--- a/src/docs/user/cluster/cluster_databases.diviner
+++ b/src/docs/user/cluster/cluster_databases.diviner
@@ -296,10 +296,15 @@
be slow, so offloading it to a replica can make the performance of the master
more consistent.
-To dump from a replica, wait for this TODO to be resolved and then do whatever
-it says to do:
-
-TODO: Make `bin/storage dump` replica-aware. See T10758.
+To dump from a replica, you can use `bin/storage dump --host <host>` to
+control which host the command connects to. (You may still want to execute
+this command //from// that host, to avoid sending the whole dump over the
+network).
+
+With the `--for-replica` flag, the `bin/storage dump` command creates dumps
+with `--dump-slave`, which includes a `CHANGE MASTER` statement in the output.
+This may be helpful when initially setting up new replicas, as it can make it
+easier to change the binlog coordinates to the correct position for the dump.
With recent versions of MySQL, it is also possible to configure a //delayed//
replica which intentionally lags behind the master (say, by 12 hours). In the
diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php
--- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php
+++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php
@@ -7,11 +7,20 @@
$this
->setName('dump')
->setExamples('**dump** [__options__]')
- ->setSynopsis(pht('Dump all data in storage to stdout.'));
+ ->setSynopsis(pht('Dump all data in storage to stdout.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'for-replica',
+ 'help' => pht(
+ 'Add __--dump-slave__ to the __mysqldump__ command, '.
+ 'generating a CHANGE MASTER statement in the output.'),
+ ),
+ ));
}
public function didExecute(PhutilArgumentParser $args) {
- $api = $this->getAPI();
+ $api = $this->getAPI();
$patches = $this->getPatches();
$console = PhutilConsole::getConsole();
@@ -33,26 +42,44 @@
list($host, $port) = $this->getBareHostAndPort($api->getHost());
- $flag_password = '';
$password = $api->getPassword();
if ($password) {
if (strlen($password->openEnvelope())) {
- $flag_password = csprintf('-p%P', $password);
+ $has_password = true;
}
}
- $flag_port = $port
- ? csprintf('--port %d', $port)
- : '';
-
- return phutil_passthru(
- 'mysqldump --hex-blob --single-transaction --default-character-set=utf8 '.
- '-u %s %C -h %s %C --databases %Ls',
- $api->getUser(),
- $flag_password,
- $host,
- $flag_port,
- $databases);
+ $argv = array();
+ $argv[] = '--hex-blob';
+ $argv[] = '--single-transaction';
+ $argv[] = '--default-character-set=utf8';
+
+ if ($args->getArg('for-replica')) {
+ $argv[] = '--dump-slave';
+ }
+
+ $argv[] = '-u';
+ $argv[] = $api->getUser();
+ $argv[] = '-h';
+ $argv[] = $host;
+
+ if ($port) {
+ $argv[] = '--port';
+ $argv[] = $port;
+ }
+
+ $argv[] = '--databases';
+ foreach ($databases as $database) {
+ $argv[] = $database;
+ }
+
+ if ($has_password) {
+ $err = phutil_passthru('mysqldump -p%P %Ls', $password, $argv);
+ } else {
+ $err = phutil_passthru('mysqldump %Ls', $argv);
+ }
+
+ return $err;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 23, 4:28 AM (1 d, 16 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7679688
Default Alt Text
D15714.id37862.diff (5 KB)
Attached To
Mode
D15714: Give bin/storage some replica-aware options
Attached
Detach File
Event Timeline
Log In to Comment