@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+79
+2
src/__phutil_library_map__.php
··· 4088 4088 'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php', 4089 4089 'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php', 4090 4090 'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php', 4091 + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php', 4091 4092 'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php', 4092 4093 'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php', 4093 4094 'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php', ··· 9679 9680 'PhabricatorStorageFixtureScopeGuard' => 'Phobject', 9680 9681 'PhabricatorStorageManagementAPI' => 'Phobject', 9681 9682 'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow', 9683 + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'PhabricatorStorageManagementWorkflow', 9682 9684 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', 9683 9685 'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow', 9684 9686 'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
+19
src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php
··· 1 + <?php 2 + 3 + final class PhabricatorStorageManagementAnalyzeWorkflow 4 + extends PhabricatorStorageManagementWorkflow { 5 + 6 + protected function didConstruct() { 7 + $this 8 + ->setName('analyze') 9 + ->setExamples('**analyze**') 10 + ->setSynopsis( 11 + pht('Run "ANALYZE TABLE" on tables to improve performance.')); 12 + } 13 + 14 + public function didExecute(PhutilArgumentParser $args) { 15 + $this->analyzeTables(); 16 + return 0; 17 + } 18 + 19 + }
+58
src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php
··· 137 137 138 138 try { 139 139 $err = $this->doAdjustSchemata($api, $unsafe); 140 + 141 + // Analyze tables if we're not doing a dry run and adjustments are either 142 + // all clear or have minor errors like surplus tables. 143 + if (!$this->dryRun) { 144 + $should_analyze = (($err == 0) || ($err == 2)); 145 + if ($should_analyze) { 146 + $this->analyzeTables(); 147 + } 148 + } 140 149 } catch (Exception $ex) { 141 150 $lock->unlock(); 142 151 throw $ex; ··· 1161 1170 return PhabricatorGlobalLock::newLock($lock_name) 1162 1171 ->useSpecificConnection($api->getConn(null)) 1163 1172 ->lock(); 1173 + } 1174 + 1175 + final protected function analyzeTables() { 1176 + // Analyzing tables can sometimes have a significant effect on query 1177 + // performance, particularly for the fulltext ngrams tables. See T12819 1178 + // for some specific examples. 1179 + 1180 + $api = $this->getSingleAPI(); 1181 + $conn = $api->getConn(null); 1182 + 1183 + $patches = $this->getPatches(); 1184 + $databases = $api->getDatabaseList($patches, true); 1185 + 1186 + $this->logInfo( 1187 + pht('ANALYZE'), 1188 + pht('Analyzing tables...')); 1189 + 1190 + $targets = array(); 1191 + foreach ($databases as $database) { 1192 + queryfx($conn, 'USE %C', $database); 1193 + $tables = queryfx_all($conn, 'SHOW TABLE STATUS'); 1194 + foreach ($tables as $table) { 1195 + $table_name = $table['Name']; 1196 + 1197 + $targets[] = array( 1198 + 'database' => $database, 1199 + 'table' => $table_name, 1200 + ); 1201 + } 1202 + } 1203 + 1204 + $bar = id(new PhutilConsoleProgressBar()) 1205 + ->setTotal(count($targets)); 1206 + foreach ($targets as $target) { 1207 + queryfx( 1208 + $conn, 1209 + 'ANALYZE TABLE %T.%T', 1210 + $target['database'], 1211 + $target['table']); 1212 + 1213 + $bar->update(1); 1214 + } 1215 + $bar->done(); 1216 + 1217 + $this->logOkay( 1218 + pht('ANALYZED'), 1219 + pht( 1220 + 'Analyzed %d table(s).', 1221 + count($targets))); 1164 1222 } 1165 1223 1166 1224 }