1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 06:20:56 +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( $tables = queryfx_all(
$conn, $conn,
'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION 'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION, ENGINE
FROM INFORMATION_SCHEMA.TABLES FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA IN (%Ls)', WHERE TABLE_SCHEMA IN (%Ls)',
$databases); $databases);
@ -146,7 +146,8 @@ final class PhabricatorConfigSchemaQuery extends Phobject {
$table_schema = id(new PhabricatorConfigTableSchema()) $table_schema = id(new PhabricatorConfigTableSchema())
->setName($table_name) ->setName($table_name)
->setCollation($table['TABLE_COLLATION']); ->setCollation($table['TABLE_COLLATION'])
->setEngine($table['ENGINE']);
$columns = idx($database_column_info, $table_name, array()); $columns = idx($database_column_info, $table_name, array());
foreach ($columns as $column) { foreach ($columns as $column) {

View file

@ -63,6 +63,7 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
$database = $this->getDatabase($database_name); $database = $this->getDatabase($database_name);
$table = $this->newTable($table_name); $table = $this->newTable($table_name);
$fulltext_engine = 'MyISAM';
foreach ($columns as $name => $type) { foreach ($columns as $name => $type) {
if ($type === null) { if ($type === null) {
@ -85,6 +86,15 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
->setNullable($nullable) ->setNullable($nullable)
->setAutoIncrement($auto); ->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); $table->addColumn($column);
} }
@ -174,7 +184,8 @@ abstract class PhabricatorConfigSchemaSpec extends Phobject {
protected function newTable($name) { protected function newTable($name) {
return id(new PhabricatorConfigTableSchema()) return id(new PhabricatorConfigTableSchema())
->setName($name) ->setName($name)
->setCollation($this->getUTF8BinaryCollation()); ->setCollation($this->getUTF8BinaryCollation())
->setEngine('InnoDB');
} }
protected function newColumn($name) { protected function newColumn($name) {

View file

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

View file

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

View file

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