mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-24 22:40: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:
parent
ff3333548f
commit
9d0752063e
5 changed files with 44 additions and 5 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue