mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Allow InnoDB for FULLTEXT indexes
MyISAM used to be the only one to support it, now InnoDB has caught up. Unless an engine is set specifically in create_table_options, this will auto-convert existing MyISAM tables to InnoDb. Fixes #9242
This commit is contained in:
parent
f1c74c3570
commit
c6b698cb02
55
docs/en/04_Changelogs/4.6.0.md
Normal file
55
docs/en/04_Changelogs/4.6.0.md
Normal file
@ -0,0 +1,55 @@
|
||||
# 4.6.0 (Unreleased)
|
||||
|
||||
## Overview {#overview}
|
||||
|
||||
* [MySQL tables are auto-converted from MyISAM to InnoDB](#myisam)
|
||||
|
||||
## MySQL tables are auto-converted from MyISAM to InnoDB {#myisam}
|
||||
|
||||
Beginning with [4.4.0](https://docs.silverstripe.org/en/4/changelogs/4.4.0/),
|
||||
our minimum requirement for MySQL is 5.6 (since MySQL 5.5 end of life reached in December 2018).
|
||||
Starting with MySQL 5.6, [InnoDB](https://dev.mysql.com/doc/refman/5.6/en/innodb-introduction.html)
|
||||
is the new default storage engine,
|
||||
replacing the older [MyISAM](https://dev.mysql.com/doc/refman/5.6/en/myisam-storage-engine.html) engine.
|
||||
|
||||
Silverstripe CMS already creates InnoDB tables by default,
|
||||
mainly in order to benefit from their better support for database transactions.
|
||||
Before MySQL 5.6, InnoDB didn't have a `FULLTEXT` search index,
|
||||
requiring us to enforce the MyISAM engine when devs opted into this index type
|
||||
in their particular setup. There are a few ways in which this opt-in can happen:
|
||||
|
||||
* Adding the [FulltextSearchable](https://github.com/silverstripe/silverstripe-framework/blob/4/src/ORM/Search/FulltextSearchable.php)
|
||||
extension to a DataObject, as described in our
|
||||
[search docs](https://docs.silverstripe.org/en/4/developer_guides/search/fulltextsearch/)
|
||||
* Defining `'type' => 'fulltext'` in `DataObject::$db` column definitions
|
||||
* Implementing [DBIndexable](https://github.com/silverstripe/silverstripe-framework/blob/4/src/ORM/FieldType/DBIndexable.php)
|
||||
on a custom `DBField` subclass.
|
||||
* Setting `'ENGINE=MyISAM'` in `DataObject::$create_table_options`
|
||||
|
||||
This search index is not required to enable simple text search
|
||||
in the "Pages" section of the CMS, or any ModelAdmin implementations.
|
||||
We generally recommend to choose a more powerful
|
||||
[search addon](https://addons.silverstripe.org/add-ons?search=fulltext&type=&sort=downloads)
|
||||
(e.g. based on Solr or ElasticSearch) for website frontend search use cases.
|
||||
|
||||
As of 4.6.0, a `dev/build` will automatically switch MyISAM tables to InnoDB,
|
||||
which automatically recreates any indexes required. If you have large indexes,
|
||||
this can extend the duration if this task. As usual, back up your database
|
||||
before upgrading, and test upgrades on non-production systems first.
|
||||
Our tests indicate that indexes with thousands of records and screen pages
|
||||
worth of content (15MB index size) are converted in a few seconds.
|
||||
|
||||
In order to opt out of this change, you can set the engine explicitly
|
||||
for your DataObject implementations:
|
||||
|
||||
```php
|
||||
use SilverStripe\ORM\Connect\MySQLSchemaManager;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class MyDataObject extends DataObject
|
||||
{
|
||||
private static $create_table_options = [
|
||||
MySQLSchemaManager::ID => 'ENGINE=MyISAM'
|
||||
];
|
||||
}
|
||||
```
|
@ -40,10 +40,6 @@ class MySQLSchemaManager extends DBSchemaManager
|
||||
}
|
||||
if ($indexes) {
|
||||
foreach ($indexes as $k => $v) {
|
||||
// force MyISAM if we have a fulltext index
|
||||
if ($v['type'] === 'fulltext') {
|
||||
$addOptions = 'ENGINE=MyISAM';
|
||||
}
|
||||
$indexSchemas .= $this->getIndexSqlDefinition($k, $v) . ",\n";
|
||||
}
|
||||
}
|
||||
@ -104,31 +100,12 @@ class MySQLSchemaManager extends DBSchemaManager
|
||||
|
||||
$dbID = self::ID;
|
||||
if ($alteredOptions && isset($alteredOptions[$dbID])) {
|
||||
$indexList = $this->indexList($tableName);
|
||||
$skip = false;
|
||||
foreach ($indexList as $index) {
|
||||
if ($index['type'] === 'fulltext') {
|
||||
$skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($skip) {
|
||||
$this->alterationMessage(
|
||||
sprintf(
|
||||
"Table %s options not changed to %s due to fulltextsearch index",
|
||||
$tableName,
|
||||
$alteredOptions[$dbID]
|
||||
),
|
||||
"changed"
|
||||
);
|
||||
} else {
|
||||
$this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID]));
|
||||
$this->alterationMessage(
|
||||
sprintf("Table %s options changed: %s", $tableName, $alteredOptions[$dbID]),
|
||||
"changed"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$alterations = implode(",\n", $alterList);
|
||||
$this->query("ALTER TABLE \"$tableName\" $alterations");
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace SilverStripe\ORM\Filters;
|
||||
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\ORM\DataQuery;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use Exception;
|
||||
@ -10,8 +9,7 @@ use Exception;
|
||||
/**
|
||||
* Filters by full-text matching on the given field.
|
||||
*
|
||||
* Full-text indexes are only available with MyISAM tables. The following column types are
|
||||
* supported:
|
||||
* The following column types are supported:
|
||||
* - Char
|
||||
* - Varchar
|
||||
* - Text
|
||||
|
@ -25,12 +25,6 @@ class DataObjectSchemaGenerationTest extends SapphireTest
|
||||
// Start tests
|
||||
static::start();
|
||||
|
||||
// enable fulltext option on this table
|
||||
TestIndexObject::config()->update(
|
||||
'create_table_options',
|
||||
array(MySQLSchemaManager::ID => 'ENGINE=MyISAM')
|
||||
);
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,4 @@ class TestObject extends DataObject implements TestOnly
|
||||
],
|
||||
);
|
||||
|
||||
private static $create_table_options = array(
|
||||
MySQLSchemaManager::ID => "ENGINE=MyISAM",
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user