1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +01:00

Record how long storage patches took to apply

Summary:
It's hard for us to predict how long patches and migrations will take in the general case since it varies a lot from install to install, but we can give installs some kind of rough heads up about longer patches. I'm planning to just put a sort of hint for things in the changelog, something like this:

{F905579}

To make this easier, start storing how long stuff took. I'll write a little script to dump this into a table for the changelog.

Test Plan:
Ran `bin/storage status`:

{F905580}

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D14320
This commit is contained in:
epriestley 2015-10-24 05:58:44 -07:00
parent b038041dc6
commit ad53e7b878
5 changed files with 55 additions and 5 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_meta_data.patch_status
ADD duration BIGINT UNSIGNED;

View file

@ -17,6 +17,8 @@ final class PhabricatorStorageManagementAPI extends Phobject {
const COLLATE_SORT = 'COLLATE_SORT'; const COLLATE_SORT = 'COLLATE_SORT';
const COLLATE_FULLTEXT = 'COLLATE_FULLTEXT'; const COLLATE_FULLTEXT = 'COLLATE_FULLTEXT';
const TABLE_STATUS = 'patch_status';
public function setDisableUTF8MB4($disable_utf8_mb4) { public function setDisableUTF8MB4($disable_utf8_mb4) {
$this->disableUTF8MB4 = $disable_utf8_mb4; $this->disableUTF8MB4 = $disable_utf8_mb4;
return $this; return $this;
@ -118,13 +120,26 @@ final class PhabricatorStorageManagementAPI extends Phobject {
try { try {
$applied = queryfx_all( $applied = queryfx_all(
$this->getConn('meta_data'), $this->getConn('meta_data'),
'SELECT patch FROM patch_status'); 'SELECT patch FROM %T',
self::TABLE_STATUS);
return ipull($applied, 'patch'); return ipull($applied, 'patch');
} catch (AphrontQueryException $ex) { } catch (AphrontQueryException $ex) {
return null; return null;
} }
} }
public function getPatchDurations() {
try {
$rows = queryfx_all(
$this->getConn('meta_data'),
'SELECT patch, duration FROM %T WHERE duration IS NOT NULL',
self::TABLE_STATUS);
return ipull($rows, 'duration', 'patch');
} catch (AphrontQueryException $ex) {
return array();
}
}
public function createDatabase($fragment) { public function createDatabase($fragment) {
$info = $this->getCharsetInfo(); $info = $this->getCharsetInfo();
@ -168,13 +183,30 @@ final class PhabricatorStorageManagementAPI extends Phobject {
return $legacy; return $legacy;
} }
public function markPatchApplied($patch) { public function markPatchApplied($patch, $duration = null) {
$conn = $this->getConn('meta_data');
queryfx( queryfx(
$this->getConn('meta_data'), $conn,
'INSERT INTO %T (patch, applied) VALUES (%s, %d)', 'INSERT INTO %T (patch, applied) VALUES (%s, %d)',
'patch_status', self::TABLE_STATUS,
$patch, $patch,
time()); time());
// We didn't add this column for a long time, so it may not exist yet.
if ($duration !== null) {
try {
queryfx(
$conn,
'UPDATE %T SET duration = %d WHERE patch = %s',
self::TABLE_STATUS,
(int)floor($duration * 1000000),
$patch);
} catch (AphrontQueryException $ex) {
// Just ignore this, as it almost certainly indicates that we just
// don't have the column yet.
}
}
} }
public function applyPatch(PhabricatorStoragePatch $patch) { public function applyPatch(PhabricatorStoragePatch $patch) {

View file

@ -29,15 +29,26 @@ final class PhabricatorStorageManagementStatusWorkflow
->setShowHeader(false) ->setShowHeader(false)
->addColumn('id', array('title' => pht('ID'))) ->addColumn('id', array('title' => pht('ID')))
->addColumn('status', array('title' => pht('Status'))) ->addColumn('status', array('title' => pht('Status')))
->addColumn('duration', array('title' => pht('Duration')))
->addColumn('type', array('title' => pht('Type'))) ->addColumn('type', array('title' => pht('Type')))
->addColumn('name', array('title' => pht('Name'))); ->addColumn('name', array('title' => pht('Name')));
$durations = $api->getPatchDurations();
foreach ($patches as $patch) { foreach ($patches as $patch) {
$duration = idx($durations, $patch->getFullKey());
if ($duration === null) {
$duration = '-';
} else {
$duration = pht('%s us', new PhutilNumber($duration));
}
$table->addRow(array( $table->addRow(array(
'id' => $patch->getFullKey(), 'id' => $patch->getFullKey(),
'status' => in_array($patch->getFullKey(), $applied) 'status' => in_array($patch->getFullKey(), $applied)
? pht('Applied') ? pht('Applied')
: pht('Not Applied'), : pht('Not Applied'),
'duration' => $duration,
'type' => $patch->getType(), 'type' => $patch->getType(),
'name' => $patch->getName(), 'name' => $patch->getName(),
)); ));

View file

@ -187,9 +187,13 @@ final class PhabricatorStorageManagementUpgradeWorkflow
echo pht("DRYRUN: Would apply patch '%s'.", $key)."\n"; echo pht("DRYRUN: Would apply patch '%s'.", $key)."\n";
} else { } else {
echo pht("Applying patch '%s'...", $key)."\n"; echo pht("Applying patch '%s'...", $key)."\n";
$t_begin = microtime(true);
$api->applyPatch($patch); $api->applyPatch($patch);
$t_end = microtime(true);
if (!$skip_mark) { if (!$skip_mark) {
$api->markPatchApplied($key); $api->markPatchApplied($key, ($t_end - $t_begin));
} }
} }

View file

@ -10,6 +10,7 @@ final class PhabricatorStorageSchemaSpec
array( array(
'patch' => 'text128', 'patch' => 'text128',
'applied' => 'uint32', 'applied' => 'uint32',
'duration' => 'uint64?',
), ),
array( array(
'PRIMARY' => array( 'PRIMARY' => array(