mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Provide "bin/storage analyze" and make "bin/storage upgrade" run analysis automatically
Summary: Ref T12819. Normallly "ANALYZE TABLE" is like sprinkling magic pixie dust on the database and hoping it will make "good vibes" that cause it to go faster, but in at least some concrete cases with the ngrams tables there really was a key cardinality issue which ANALYZE TABLE corrected, fixing bogus query plans. Add `bin/storage analyze` to analyze all tables, and make `bin/storage upgrade` run it after adjustment if `--no-adjust` is not specified, and make `bin/storage adjust` run it always. This runs in a couple seconds and should never hurt anything, so it should be fine to sprinkle lots of pixie dust into the `bin/storage` workflow. Test Plan: Ran `bin/storage analyze`. Ran `bin/storage upgrade`, saw analyze run. Totally felt great vibes and really aligned chakras on the database. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12819 Differential Revision: https://secure.phabricator.com/D18573
This commit is contained in:
parent
f1193afa94
commit
8e9f049626
3 changed files with 79 additions and 0 deletions
|
@ -4088,6 +4088,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
|
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
|
||||||
'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php',
|
'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php',
|
||||||
'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php',
|
'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php',
|
||||||
|
'PhabricatorStorageManagementAnalyzeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php',
|
||||||
'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
|
'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
|
||||||
'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
|
'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
|
||||||
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
|
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
|
||||||
|
@ -9679,6 +9680,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageFixtureScopeGuard' => 'Phobject',
|
'PhabricatorStorageFixtureScopeGuard' => 'Phobject',
|
||||||
'PhabricatorStorageManagementAPI' => 'Phobject',
|
'PhabricatorStorageManagementAPI' => 'Phobject',
|
||||||
'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
|
'PhabricatorStorageManagementAnalyzeWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorStorageManagementAnalyzeWorkflow
|
||||||
|
extends PhabricatorStorageManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('analyze')
|
||||||
|
->setExamples('**analyze**')
|
||||||
|
->setSynopsis(
|
||||||
|
pht('Run "ANALYZE TABLE" on tables to improve performance.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function didExecute(PhutilArgumentParser $args) {
|
||||||
|
$this->analyzeTables();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -137,6 +137,15 @@ abstract class PhabricatorStorageManagementWorkflow
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$err = $this->doAdjustSchemata($api, $unsafe);
|
$err = $this->doAdjustSchemata($api, $unsafe);
|
||||||
|
|
||||||
|
// Analyze tables if we're not doing a dry run and adjustments are either
|
||||||
|
// all clear or have minor errors like surplus tables.
|
||||||
|
if (!$this->dryRun) {
|
||||||
|
$should_analyze = (($err == 0) || ($err == 2));
|
||||||
|
if ($should_analyze) {
|
||||||
|
$this->analyzeTables();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
$lock->unlock();
|
$lock->unlock();
|
||||||
throw $ex;
|
throw $ex;
|
||||||
|
@ -1163,4 +1172,53 @@ abstract class PhabricatorStorageManagementWorkflow
|
||||||
->lock();
|
->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final protected function analyzeTables() {
|
||||||
|
// Analyzing tables can sometimes have a significant effect on query
|
||||||
|
// performance, particularly for the fulltext ngrams tables. See T12819
|
||||||
|
// for some specific examples.
|
||||||
|
|
||||||
|
$api = $this->getSingleAPI();
|
||||||
|
$conn = $api->getConn(null);
|
||||||
|
|
||||||
|
$patches = $this->getPatches();
|
||||||
|
$databases = $api->getDatabaseList($patches, true);
|
||||||
|
|
||||||
|
$this->logInfo(
|
||||||
|
pht('ANALYZE'),
|
||||||
|
pht('Analyzing tables...'));
|
||||||
|
|
||||||
|
$targets = array();
|
||||||
|
foreach ($databases as $database) {
|
||||||
|
queryfx($conn, 'USE %C', $database);
|
||||||
|
$tables = queryfx_all($conn, 'SHOW TABLE STATUS');
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
$table_name = $table['Name'];
|
||||||
|
|
||||||
|
$targets[] = array(
|
||||||
|
'database' => $database,
|
||||||
|
'table' => $table_name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar = id(new PhutilConsoleProgressBar())
|
||||||
|
->setTotal(count($targets));
|
||||||
|
foreach ($targets as $target) {
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'ANALYZE TABLE %T.%T',
|
||||||
|
$target['database'],
|
||||||
|
$target['table']);
|
||||||
|
|
||||||
|
$bar->update(1);
|
||||||
|
}
|
||||||
|
$bar->done();
|
||||||
|
|
||||||
|
$this->logOkay(
|
||||||
|
pht('ANALYZED'),
|
||||||
|
pht(
|
||||||
|
'Analyzed %d table(s).',
|
||||||
|
count($targets)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue