mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 08:12:40 +01:00
Give bin/storage some replica-aware options
Summary: Fixes T10758. - Adds a "--host" flag. If you specify this, we read your cluster config. This lets you dump from a replica. - Adds a "--for-replica" flag to `storage dump`. This makes `mysqldump` include a `CHANGE MASTER ...` statement in the output, which is useful when setting up a replica for the first time. Test Plan: - Dumped master and replica cluster databases. - Dumped non-cluster databases. - Ran various other commands (help, status, etc). Reviewers: chad Reviewed By: chad Maniphest Tasks: T10758 Differential Revision: https://secure.phabricator.com/D15714
This commit is contained in:
parent
1b2b84ce1f
commit
5a0b7398ca
3 changed files with 87 additions and 22 deletions
|
@ -30,6 +30,12 @@ try {
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
'Do not prompt before performing dangerous operations.'),
|
'Do not prompt before performing dangerous operations.'),
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'host',
|
||||||
|
'param' => 'hostname',
|
||||||
|
'help' => pht(
|
||||||
|
'Connect to __host__ instead of the default host.'),
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'user',
|
'name' => 'user',
|
||||||
'short' => 'u',
|
'short' => 'u',
|
||||||
|
@ -75,11 +81,38 @@ try {
|
||||||
// First, test that the Phabricator configuration is set up correctly. After
|
// First, test that the Phabricator configuration is set up correctly. After
|
||||||
// we know this works we'll test any administrative credentials specifically.
|
// we know this works we'll test any administrative credentials specifically.
|
||||||
|
|
||||||
|
$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();
|
$ref = PhabricatorDatabaseRef::getMasterDatabaseRef();
|
||||||
if (!$ref) {
|
if (!$ref) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht('No database master is configured.'));
|
pht('No database master is configured.'));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$default_user = $ref->getUser();
|
$default_user = $ref->getUser();
|
||||||
$default_host = $ref->getHost();
|
$default_host = $ref->getHost();
|
||||||
|
|
|
@ -296,10 +296,15 @@ safely pull dumps from a replica instead of the master. This operation can
|
||||||
be slow, so offloading it to a replica can make the performance of the master
|
be slow, so offloading it to a replica can make the performance of the master
|
||||||
more consistent.
|
more consistent.
|
||||||
|
|
||||||
To dump from a replica, wait for this TODO to be resolved and then do whatever
|
To dump from a replica, you can use `bin/storage dump --host <host>` to
|
||||||
it says to do:
|
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).
|
||||||
|
|
||||||
TODO: Make `bin/storage dump` replica-aware. See T10758.
|
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//
|
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
|
replica which intentionally lags behind the master (say, by 12 hours). In the
|
||||||
|
|
|
@ -7,7 +7,16 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$this
|
$this
|
||||||
->setName('dump')
|
->setName('dump')
|
||||||
->setExamples('**dump** [__options__]')
|
->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) {
|
public function didExecute(PhutilArgumentParser $args) {
|
||||||
|
@ -33,26 +42,44 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
|
|
||||||
list($host, $port) = $this->getBareHostAndPort($api->getHost());
|
list($host, $port) = $this->getBareHostAndPort($api->getHost());
|
||||||
|
|
||||||
$flag_password = '';
|
|
||||||
$password = $api->getPassword();
|
$password = $api->getPassword();
|
||||||
if ($password) {
|
if ($password) {
|
||||||
if (strlen($password->openEnvelope())) {
|
if (strlen($password->openEnvelope())) {
|
||||||
$flag_password = csprintf('-p%P', $password);
|
$has_password = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$flag_port = $port
|
$argv = array();
|
||||||
? csprintf('--port %d', $port)
|
$argv[] = '--hex-blob';
|
||||||
: '';
|
$argv[] = '--single-transaction';
|
||||||
|
$argv[] = '--default-character-set=utf8';
|
||||||
|
|
||||||
return phutil_passthru(
|
if ($args->getArg('for-replica')) {
|
||||||
'mysqldump --hex-blob --single-transaction --default-character-set=utf8 '.
|
$argv[] = '--dump-slave';
|
||||||
'-u %s %C -h %s %C --databases %Ls',
|
}
|
||||||
$api->getUser(),
|
|
||||||
$flag_password,
|
$argv[] = '-u';
|
||||||
$host,
|
$argv[] = $api->getUser();
|
||||||
$flag_port,
|
$argv[] = '-h';
|
||||||
$databases);
|
$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue