diff --git a/src/applications/config/schema/PhabricatorConfigSchemaQuery.php b/src/applications/config/schema/PhabricatorConfigSchemaQuery.php index 2b5fc79f62..6feda7363c 100644 --- a/src/applications/config/schema/PhabricatorConfigSchemaQuery.php +++ b/src/applications/config/schema/PhabricatorConfigSchemaQuery.php @@ -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) { diff --git a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php index e29795b98b..d808f76657 100644 --- a/src/applications/config/schema/PhabricatorConfigSchemaSpec.php +++ b/src/applications/config/schema/PhabricatorConfigSchemaSpec.php @@ -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) { diff --git a/src/applications/config/schema/PhabricatorConfigStorageSchema.php b/src/applications/config/schema/PhabricatorConfigStorageSchema.php index 706be80568..0f8b9c4d63 100644 --- a/src/applications/config/schema/PhabricatorConfigStorageSchema.php +++ b/src/applications/config/schema/PhabricatorConfigStorageSchema.php @@ -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)); diff --git a/src/applications/config/schema/PhabricatorConfigTableSchema.php b/src/applications/config/schema/PhabricatorConfigTableSchema.php index b05e7e1e8e..870c8ebddb 100644 --- a/src/applications/config/schema/PhabricatorConfigTableSchema.php +++ b/src/applications/config/schema/PhabricatorConfigTableSchema.php @@ -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; } diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php index 90dbe7a1d0..caea88a608 100644 --- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php @@ -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(), ); }