mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Add "persistence" types (data, cache, or index) to tables, and tweak what "storage dump" dumps
Summary: Ref T13000. This marks each table as either "data" (normal data), "cache" (automatically rebuilt, no need to ever dump) or "index" (can be manually rebuilt). By default, `bin/storage dump` dumps data and index tables, but not cache tables. With `--no-indexes`, it dumps only data tables. Indexes can be rebuilt after a restore with `bin/search index --all ...`. Test Plan: - Ran `--no-indexes` and normal dumps with `--trace`, verified that cache and index (former case) or cache only (latter case) tables were dumped with `--no-data`. - Verified dump has the same number of `CREATE TABLE` statements as before the changes. - Reviewed persistence tags in the web UI (note Ferret engine tables are "Index"): {F5210886} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13000 Differential Revision: https://secure.phabricator.com/D18682
This commit is contained in:
parent
02e1440ef2
commit
c767c971ca
8 changed files with 138 additions and 9 deletions
|
@ -30,6 +30,9 @@ final class PhabricatorCacheSchemaSpec extends PhabricatorConfigSchemaSpec {
|
||||||
'key_ttl' => array(
|
'key_ttl' => array(
|
||||||
'columns' => array('cacheExpires'),
|
'columns' => array('cacheExpires'),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_CACHE,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,7 @@ final class PhabricatorConfigDatabaseStatusController
|
||||||
$this->renderAttr(
|
$this->renderAttr(
|
||||||
$table->getCollation(),
|
$table->getCollation(),
|
||||||
$table->hasIssue($collation_issue)),
|
$table->hasIssue($collation_issue)),
|
||||||
|
$table->getPersistenceTypeDisplayName(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,12 +271,14 @@ final class PhabricatorConfigDatabaseStatusController
|
||||||
null,
|
null,
|
||||||
pht('Table'),
|
pht('Table'),
|
||||||
pht('Collation'),
|
pht('Collation'),
|
||||||
|
pht('Persistence'),
|
||||||
))
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
null,
|
null,
|
||||||
'wide pri',
|
'wide pri',
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
));
|
));
|
||||||
|
|
||||||
$title = $database_name;
|
$title = $database_name;
|
||||||
|
|
|
@ -338,6 +338,8 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
|
||||||
$comp_table->addKey($comp_key);
|
$comp_table->addKey($comp_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$comp_table->setPersistenceType($expect_table->getPersistenceType());
|
||||||
|
|
||||||
$comp_database->addTable($comp_table);
|
$comp_database->addTable($comp_table);
|
||||||
}
|
}
|
||||||
$comp_server->addDatabase($comp_database);
|
$comp_server->addDatabase($comp_database);
|
||||||
|
|
|
@ -56,36 +56,52 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
protected function buildFerretIndexSchema(PhabricatorFerretEngine $engine) {
|
||||||
|
$index_options = array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_INDEX,
|
||||||
|
);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getDocumentTableName(),
|
$engine->getDocumentTableName(),
|
||||||
$engine->getDocumentSchemaColumns(),
|
$engine->getDocumentSchemaColumns(),
|
||||||
$engine->getDocumentSchemaKeys());
|
$engine->getDocumentSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getFieldTableName(),
|
$engine->getFieldTableName(),
|
||||||
$engine->getFieldSchemaColumns(),
|
$engine->getFieldSchemaColumns(),
|
||||||
$engine->getFieldSchemaKeys());
|
$engine->getFieldSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getNgramsTableName(),
|
$engine->getNgramsTableName(),
|
||||||
$engine->getNgramsSchemaColumns(),
|
$engine->getNgramsSchemaColumns(),
|
||||||
$engine->getNgramsSchemaKeys());
|
$engine->getNgramsSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
$engine->getApplicationName(),
|
$engine->getApplicationName(),
|
||||||
$engine->getCommonNgramsTableName(),
|
$engine->getCommonNgramsTableName(),
|
||||||
$engine->getCommonNgramsSchemaColumns(),
|
$engine->getCommonNgramsSchemaColumns(),
|
||||||
$engine->getCommonNgramsSchemaKeys());
|
$engine->getCommonNgramsSchemaKeys(),
|
||||||
|
$index_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildRawSchema(
|
protected function buildRawSchema(
|
||||||
$database_name,
|
$database_name,
|
||||||
$table_name,
|
$table_name,
|
||||||
array $columns,
|
array $columns,
|
||||||
array $keys) {
|
array $keys,
|
||||||
|
array $options = array()) {
|
||||||
|
|
||||||
|
PhutilTypeSpec::checkMap(
|
||||||
|
$options,
|
||||||
|
array(
|
||||||
|
'persistence' => 'optional string',
|
||||||
|
));
|
||||||
|
|
||||||
$database = $this->getDatabase($database_name);
|
$database = $this->getDatabase($database_name);
|
||||||
|
|
||||||
$table = $this->newTable($table_name);
|
$table = $this->newTable($table_name);
|
||||||
|
@ -144,6 +160,11 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
|
||||||
$table->addKey($key);
|
$table->addKey($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$persistence_type = idx($options, 'persistence');
|
||||||
|
if ($persistence_type !== null) {
|
||||||
|
$table->setPersistenceType($persistence_type);
|
||||||
|
}
|
||||||
|
|
||||||
$database->addTable($table);
|
$database->addTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,11 @@ final class PhabricatorConfigTableSchema
|
||||||
private $engine;
|
private $engine;
|
||||||
private $columns = array();
|
private $columns = array();
|
||||||
private $keys = array();
|
private $keys = array();
|
||||||
|
private $persistenceType = self::PERSISTENCE_DATA;
|
||||||
|
|
||||||
|
const PERSISTENCE_DATA = 'data';
|
||||||
|
const PERSISTENCE_CACHE = 'cache';
|
||||||
|
const PERSISTENCE_INDEX = 'index';
|
||||||
|
|
||||||
public function addColumn(PhabricatorConfigColumnSchema $column) {
|
public function addColumn(PhabricatorConfigColumnSchema $column) {
|
||||||
$key = $column->getName();
|
$key = $column->getName();
|
||||||
|
@ -45,6 +50,27 @@ final class PhabricatorConfigTableSchema
|
||||||
return idx($this->getKeys(), $key);
|
return idx($this->getKeys(), $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPersistenceType($persistence_type) {
|
||||||
|
$this->persistenceType = $persistence_type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPersistenceType() {
|
||||||
|
return $this->persistenceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPersistenceTypeDisplayName() {
|
||||||
|
$map = array(
|
||||||
|
self::PERSISTENCE_DATA => pht('Data'),
|
||||||
|
self::PERSISTENCE_CACHE => pht('Cache'),
|
||||||
|
self::PERSISTENCE_INDEX => pht('Index'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$type = $this->getPersistenceType();
|
||||||
|
|
||||||
|
return idx($map, $type, $type);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getSubschemata() {
|
protected function getSubschemata() {
|
||||||
// NOTE: Keys and columns may have the same name, so make sure we return
|
// NOTE: Keys and columns may have the same name, so make sure we return
|
||||||
// everything.
|
// everything.
|
||||||
|
|
|
@ -21,6 +21,9 @@ final class DifferentialSchemaSpec extends PhabricatorConfigSchemaSpec {
|
||||||
'dateCreated' => array(
|
'dateCreated' => array(
|
||||||
'columns' => array('dateCreated'),
|
'columns' => array('dateCreated'),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'persistence' => PhabricatorConfigTableSchema::PERSISTENCE_CACHE,
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->buildRawSchema(
|
$this->buildRawSchema(
|
||||||
|
|
|
@ -145,6 +145,24 @@ present a risk. If you restrict access to the Phabricator host or database, you
|
||||||
should also restrict access to the backups.
|
should also restrict access to the backups.
|
||||||
|
|
||||||
|
|
||||||
|
Skipping Indexes
|
||||||
|
================
|
||||||
|
|
||||||
|
By default, `bin/storage dump` does not dump all of the data in the database:
|
||||||
|
it skips some caches which can be rebuilt automatically and do not need to be
|
||||||
|
backed up. Some of these caches are very large, so the size of the dump may
|
||||||
|
be significantly smaller than the size of the databases.
|
||||||
|
|
||||||
|
If you have a large amount of data, you can specify `--no-indexes` when taking
|
||||||
|
a database dump to skip additional tables which contain search indexes. This
|
||||||
|
will reduce the size (and increase the speed) of the backup. This is an
|
||||||
|
advanced option which most installs will not benefit from.
|
||||||
|
|
||||||
|
This index data can be rebuilt after a restore, but will not be rebuilt
|
||||||
|
automatically. If you choose to use this flag, you must manually rebuild
|
||||||
|
indexes after a restore (for details, see ((reindex))).
|
||||||
|
|
||||||
|
|
||||||
Next Steps
|
Next Steps
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,13 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
'With __--output__, write a compressed file to disk instead '.
|
'With __--output__, write a compressed file to disk instead '.
|
||||||
'of a plaintext file.'),
|
'of a plaintext file.'),
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'no-indexes',
|
||||||
|
'help' => pht(
|
||||||
|
'Do not dump data in rebuildable index tables. This means '.
|
||||||
|
'backups are smaller and faster, but you will need to manually '.
|
||||||
|
'rebuild indexes after performing a restore.'),
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'overwrite',
|
'name' => 'overwrite',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
|
@ -49,6 +56,8 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
|
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
|
|
||||||
|
$with_indexes = !$args->getArg('no-indexes');
|
||||||
|
|
||||||
$applied = $api->getAppliedPatches();
|
$applied = $api->getAppliedPatches();
|
||||||
if ($applied === null) {
|
if ($applied === null) {
|
||||||
$namespace = $api->getNamespace();
|
$namespace = $api->getNamespace();
|
||||||
|
@ -65,18 +74,58 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
$ref = $api->getRef();
|
$ref = $api->getRef();
|
||||||
$ref_key = $ref->getRefKey();
|
$ref_key = $ref->getRefKey();
|
||||||
|
|
||||||
$schemata_map = id(new PhabricatorConfigSchemaQuery())
|
$schemata_query = id(new PhabricatorConfigSchemaQuery())
|
||||||
->setAPIs(array($api))
|
->setAPIs(array($api))
|
||||||
->setRefs(array($ref))
|
->setRefs(array($ref));
|
||||||
->loadActualSchemata();
|
|
||||||
$schemata = $schemata_map[$ref_key];
|
$actual_map = $schemata_query->loadActualSchemata();
|
||||||
|
$expect_map = $schemata_query->loadExpectedSchemata();
|
||||||
|
|
||||||
|
$schemata = $actual_map[$ref_key];
|
||||||
|
$expect = $expect_map[$ref_key];
|
||||||
|
|
||||||
$targets = array();
|
$targets = array();
|
||||||
foreach ($schemata->getDatabases() as $database_name => $database) {
|
foreach ($schemata->getDatabases() as $database_name => $database) {
|
||||||
|
$expect_database = $expect->getDatabase($database_name);
|
||||||
foreach ($database->getTables() as $table_name => $table) {
|
foreach ($database->getTables() as $table_name => $table) {
|
||||||
|
|
||||||
|
// NOTE: It's possible for us to find tables in these database which
|
||||||
|
// we don't expect to be there. For example, an older version of
|
||||||
|
// Phabricator may have had a table that was later dropped. We assume
|
||||||
|
// these are data tables and always dump them, erring on the side of
|
||||||
|
// caution.
|
||||||
|
|
||||||
|
$persistence = PhabricatorConfigTableSchema::PERSISTENCE_DATA;
|
||||||
|
if ($expect_database) {
|
||||||
|
$expect_table = $expect_database->getTable($table_name);
|
||||||
|
if ($expect_table) {
|
||||||
|
$persistence = $expect_table->getPersistenceType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($persistence) {
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_CACHE:
|
||||||
|
// When dumping tables, leave the data in cache tables in the
|
||||||
|
// database. This will be automatically rebuild after the data
|
||||||
|
// is restored and does not need to be persisted in backups.
|
||||||
|
$with_data = false;
|
||||||
|
break;
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_INDEX:
|
||||||
|
// When dumping tables, leave index data behind of the caller
|
||||||
|
// specified "--no-indexes". These tables can be rebuilt manually
|
||||||
|
// from other tables, but do not rebuild automatically.
|
||||||
|
$with_data = $with_indexes;
|
||||||
|
break;
|
||||||
|
case PhabricatorConfigTableSchema::PERSISTENCE_DATA:
|
||||||
|
default:
|
||||||
|
$with_data = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$targets[] = array(
|
$targets[] = array(
|
||||||
'database' => $database_name,
|
'database' => $database_name,
|
||||||
'table' => $table_name,
|
'table' => $table_name,
|
||||||
|
'data' => $with_data,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +196,10 @@ final class PhabricatorStorageManagementDumpWorkflow
|
||||||
foreach ($targets as $target) {
|
foreach ($targets as $target) {
|
||||||
$target_argv = $argv;
|
$target_argv = $argv;
|
||||||
|
|
||||||
|
if (!$target['data']) {
|
||||||
|
$target_argv[] = '--no-data';
|
||||||
|
}
|
||||||
|
|
||||||
if ($has_password) {
|
if ($has_password) {
|
||||||
$commands[] = csprintf(
|
$commands[] = csprintf(
|
||||||
'mysqldump -p%P %Ls -- %R %R',
|
'mysqldump -p%P %Ls -- %R %R',
|
||||||
|
|
Loading…
Reference in a new issue