1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 20:10:55 +01:00

Allow bin/storage adjust to adjust table engines

Summary:
Ref T11741. On recent-enough versions of MySQL, we would prefer to use InnoDB for fulltext indexes instead of MyISAM.

Allow `bin/storage adjust` to read actual and expected table engines, and apply adjustments as necessary.

We have one existing bad table that uses the wrong engine, `metamta_applicationemail`. This change corrects that table.

Test Plan:
  - Ran `bin/storage upgrade`.
  - Saw the adjustment phase apply this change properly:

```
>>>[463] <query> ALTER TABLE `local_metamta`.`metamta_applicationemail` COLLATE = 'utf8mb4_bin', ENGINE = 'InnoDB'
```

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11741

Differential Revision: https://secure.phabricator.com/D16941
This commit is contained in:
epriestley 2016-11-24 09:00:53 -08:00
parent ff3333548f
commit 9d0752063e
5 changed files with 44 additions and 5 deletions

View file

@ -68,7 +68,7 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
$tables = queryfx_all(
$conn,
'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION
'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION, ENGINE
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA IN (%Ls)',
$databases);
@ -146,7 +146,8 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
$table_schema = id(new PhabricatorConfigTableSchema())
->setName($table_name)
->setCollation($table['TABLE_COLLATION']);
->setCollation($table['TABLE_COLLATION'])
->setEngine($table['ENGINE']);
$columns = idx($database_column_info, $table_name, array());
foreach ($columns as $column) {

View file

@ -63,6 +63,7 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
$database = $this->getDatabase($database_name);
$table = $this->newTable($table_name);
$fulltext_engine = 'MyISAM';
foreach ($columns as $name => $type) {
if ($type === null) {
@ -85,6 +86,15 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
->setNullable($nullable)
->setAutoIncrement($auto);
// If this table has any FULLTEXT fields, we expect it to use the best
// available FULLTEXT engine, which may not be InnoDB.
switch ($type) {
case 'fulltext':
case 'fulltext?':
$table->setEngine($fulltext_engine);
break;
}
$table->addColumn($column);
}
@ -174,7 +184,8 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
protected function newTable($name) {
return id(new PhabricatorConfigTableSchema())
->setName($name)
->setCollation($this->getUTF8BinaryCollation());
->setCollation($this->getUTF8BinaryCollation())
->setEngine('InnoDB');
}
protected function newColumn($name) {

View file

@ -18,6 +18,7 @@ abstract class PhabricatorConfigStorageSchema extends Phobject {
const ISSUE_AUTOINCREMENT = 'autoincrement';
const ISSUE_UNKNOWN = 'unknown';
const ISSUE_ACCESSDENIED = 'accessdenied';
const ISSUE_ENGINE = 'engine';
const STATUS_OKAY = 'okay';
const STATUS_WARN = 'warn';
@ -133,6 +134,8 @@ abstract class PhabricatorConfigStorageSchema extends Phobject {
return pht('Column Has No Specification');
case self::ISSUE_ACCESSDENIED:
return pht('Access Denied');
case self::ISSUE_ENGINE:
return pht('Better Table Engine Available');
default:
throw new Exception(pht('Unknown schema issue "%s"!', $issue));
}
@ -170,6 +173,8 @@ abstract class PhabricatorConfigStorageSchema extends Phobject {
return pht('This column has the wrong autoincrement setting.');
case self::ISSUE_UNKNOWN:
return pht('This column is missing a type specification.');
case self::ISSUE_ENGINE:
return pht('This table can use a better table engine.');
default:
throw new Exception(pht('Unknown schema issue "%s"!', $issue));
}
@ -194,6 +199,7 @@ abstract class PhabricatorConfigStorageSchema extends Phobject {
case self::ISSUE_KEYCOLUMNS:
case self::ISSUE_LONGKEY:
case self::ISSUE_AUTOINCREMENT:
case self::ISSUE_ENGINE:
return self::STATUS_WARN;
default:
throw new Exception(pht('Unknown schema issue "%s"!', $issue));

View file

@ -4,6 +4,7 @@ final class PhabricatorConfigTableSchema
extends PhabricatorConfigStorageSchema {
private $collation;
private $engine;
private $columns = array();
private $keys = array();
@ -62,6 +63,15 @@ final class PhabricatorConfigTableSchema
return $this->collation;
}
public function setEngine($engine) {
$this->engine = $engine;
return $this;
}
public function getEngine() {
return $this->engine;
}
protected function compareToSimilarSchema(
PhabricatorConfigStorageSchema $expect) {
@ -70,6 +80,10 @@ final class PhabricatorConfigTableSchema
$issues[] = self::ISSUE_COLLATION;
}
if ($this->getEngine() != $expect->getEngine()) {
$issues[] = self::ISSUE_ENGINE;
}
return $issues;
}

View file

@ -308,10 +308,11 @@ abstract class PhabricatorStorageManagementWorkflow
if ($phase == 'main') {
queryfx(
$conn,
'ALTER TABLE %T.%T COLLATE = %s',
'ALTER TABLE %T.%T COLLATE = %s, ENGINE = %s',
$adjust['database'],
$adjust['table'],
$adjust['collation']);
$adjust['collation'],
$adjust['engine']);
}
break;
case 'column':
@ -480,6 +481,7 @@ abstract class PhabricatorStorageManagementWorkflow
$issue_unique = PhabricatorConfigStorageSchema::ISSUE_UNIQUE;
$issue_longkey = PhabricatorConfigStorageSchema::ISSUE_LONGKEY;
$issue_auto = PhabricatorConfigStorageSchema::ISSUE_AUTOINCREMENT;
$issue_engine = PhabricatorConfigStorageSchema::ISSUE_ENGINE;
$adjustments = array();
$errors = array();
@ -543,6 +545,10 @@ abstract class PhabricatorStorageManagementWorkflow
$issues[] = $issue_collation;
}
if ($table->hasIssue($issue_engine)) {
$issues[] = $issue_engine;
}
if ($issues) {
$adjustments[] = array(
'kind' => 'table',
@ -550,6 +556,7 @@ abstract class PhabricatorStorageManagementWorkflow
'table' => $table_name,
'issues' => $issues,
'collation' => $expect_table->getCollation(),
'engine' => $expect_table->getEngine(),
);
}