1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Make bin/storage dump insert CREATE DATABASE and USE statements

Summary:
Ref T13000. The new approach for dumping database-by-database means that we don't get CREATE DATABASE or USE statements, which makes importing the dump again inconvenient.

Manually stitch these into the dump.

Test Plan:
  - Used `bin/storage dump --namespace ...` to dump a smaller local instance.
  - Used `bin/storage destroy --namespace ...`, to destroy the namespace, then inported the dump cleanly.
  - Verified that each CREATE DATABASE statement appears only once.
  - Verified that `bin/storage renamespace --live` can correctly process this file.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13000

Differential Revision: https://secure.phabricator.com/D18707
This commit is contained in:
epriestley 2017-10-13 13:38:47 -07:00
parent acb145b3d7
commit c5e8de9450

View file

@ -215,7 +215,10 @@ final class PhabricatorStorageManagementDumpWorkflow
$target['table']); $target['table']);
} }
$commands[] = $command; $commands[] = array(
'command' => $command,
'database' => $target['database'],
);
} }
@ -244,9 +247,26 @@ final class PhabricatorStorageManagementDumpWorkflow
$file)); $file));
} }
$created = array();
try { try {
foreach ($commands as $command) { foreach ($commands as $spec) {
$future = new ExecFuture('%C', $command); // Because we're dumping database-by-database, we need to generate our
// own CREATE DATABASE and USE statements.
$database = $spec['database'];
$preamble = array();
if (!isset($created[$database])) {
$preamble[] =
"CREATE DATABASE /*!32312 IF NOT EXISTS*/ `{$database}` ".
"/*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */;\n";
$created[$database] = true;
}
$preamble[] = "USE `{$database}`;\n";
$preamble = implode('', $preamble);
$this->writeData($preamble, $file, $is_compress, $output_file);
$future = new ExecFuture('%C', $spec['command']);
$iterator = id(new FutureIterator(array($future))) $iterator = id(new FutureIterator(array($future)))
->setUpdateInterval(0.100); ->setUpdateInterval(0.100);
@ -258,23 +278,7 @@ final class PhabricatorStorageManagementDumpWorkflow
fwrite(STDERR, $stderr); fwrite(STDERR, $stderr);
} }
if (strlen($stdout)) { $this->writeData($stdout, $file, $is_compress, $output_file);
if (!$file) {
$ok = fwrite(STDOUT, $stdout);
} else if ($is_compress) {
$ok = gzwrite($file, $stdout);
} else {
$ok = fwrite($file, $stdout);
}
if ($ok !== strlen($stdout)) {
throw new Exception(
pht(
'Failed to write %d byte(s) to file "%s".',
new PhutilNumber(strlen($stdout)),
$output_file));
}
}
if ($ready !== null) { if ($ready !== null) {
$ready->resolvex(); $ready->resolvex();
@ -314,4 +318,27 @@ final class PhabricatorStorageManagementDumpWorkflow
return 0; return 0;
} }
private function writeData($data, $file, $is_compress, $output_file) {
if (!strlen($data)) {
return;
}
if (!$file) {
$ok = fwrite(STDOUT, $data);
} else if ($is_compress) {
$ok = gzwrite($file, $data);
} else {
$ok = fwrite($file, $data);
}
if ($ok !== strlen($data)) {
throw new Exception(
pht(
'Failed to write %d byte(s) to file "%s".',
new PhutilNumber(strlen($data)),
$output_file));
}
}
} }