Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
With a diversity of MySQL compatible databases it'd be desirable to be able to a pick a database engine on table creation.
Proposed resolution
Add the ability to specify the table engine to be used when connection to a MySQL, MariaDB or an equivalent databases in the settings.php file. The default table is InnoDB and that will not be changed.
Remaining tasks
None
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
TBD
Comment | File | Size | Author |
---|---|---|---|
#62 | 2152443-62.patch | 5.2 KB | dhirendra.mishra |
#62 | interdiff_52-62.txt | 658 bytes | dhirendra.mishra |
#52 | interdiff_46-52.txt | 3.24 KB | raman.b |
#52 | 2152443-52.patch | 5.19 KB | raman.b |
Comments
Comment #1
xjmComment #2
chx CreditAttribution: chx commentedPushing to Crell's plate for review.
Comment #3
Crell CreditAttribution: Crell commentedI can't think of when I'd want to do this. But I can't think of a compelling argument to now allow it, so...
My only thought would be that it should be documented somewhere. Probably in the settings.php docblock where we have examples of setting the collation already. Let's add that, and then we can commit this.
Comment #4
danblack CreditAttribution: danblack commentedNeeds documentation as Crell said.
Anyone using this for MyISAM probably needs to look properly at what INNODB offers over MyISAM + attempt a recovery of corrupted my MyISAM to re-enforce the distain for the antiquated engine.
There's potentially some cases for MEMORY, Archive and some MariaDB plugins like OQGraph, SphinxSE and Cassandra though all the MariaDB ones require arguments to be also accessible as an array of key/value pairs.
SQLite supports WITHOUT ROWID. Postgresql has storage parameters. So perhaps an array of table options would be a better interface for all.
These should be arguments to createTable / db_create_table rather than a setttings.php setting.
Comment #5
mikeytown2 CreditAttribution: mikeytown2 commentedOn a semi-related note using the memory engine for the semaphore table is a good fit
#1898204: Do not use InnoDB for the semaphore table, use Memory
Comment #6
danblack CreditAttribution: danblack commentedmoved my previous comments to #2232461 as it was going off the setting.php topic of this issue.
I'm thinking this can be closed?
Comment #7
xjmAccording to #697220: Run tests on all supported database servers, this is blocking testbot support for MyISAM. If that's the case and it's a hard blocker, this should probably be elevated to critical.
Comment #8
Crell CreditAttribution: Crell commentedI don't believe this is a hard-block for that issue. If we wanted a MyISAM testbot (why?), that would be a database-level setting not table-level. This issue *would* be a blocker for #1898204: Do not use InnoDB for the semaphore table, use Memory, but there's no reason that's a release-blocking issue.
The use case here is, as #4 noted, using more new/esoteric engines in specialized cases (cache tables, semaphore table, log table, etc.), not converting the whole DB to an engine that dates from the Clinton presidency.
Comment #9
xjmBecause we support MyISAM, and we break it once every month or so, which also means breaking http://simplytest.me/.
I believe @jthorson is the one who suggested it's blocking the MyISAM testbot. (?)
Comment #10
danblack CreditAttribution: danblack commentedComment #11
jthorson CreditAttribution: jthorson commentedIf I recall correctly (but this is stretching the limits of what I remember), when we attempted to build a dedicated MyISAM bot at BADCamp, we discovered that the installation process was hardcoded somewhere to use InnoDB ... and thus, when the installation process ran, we ended up with InnoDB tables even if the DB default was MyISAM. Thus, we need a way to override the default in the core installation process, if we want a dedicated MyISAM testbot.
If this is accurate (and again, it's a foggy recollection), this would still be an issue in the new architecture as well.
Comment #12
Crell CreditAttribution: Crell commentedRummaging in the back of my brain covered in cobwebs was this recollection: I think we made the decision years ago that InnoDB was always better (because of transactions and row-level locking). However, if you specify InnoDB but InnoDB is not available MySQL will, helpfully(?), silently give you MyISAM instead. So if we always ask for InnoDB, people who don't know what a table engine is will get the better one and people on POS hosts that only offer MyISAM (do those even still exist?) will get MyISAM. I believe that memory is filed under "things we do to protect ignorant users from themselves and not ask them to think".
The current patch would only allow for varying the default engine; #5/#8 mistakenly confuse it with varying the engine per-table, which is an advanced and tricky feature to get right. (My bad for #8, sorry.) Let's save that for another issue.
Regardless, this still needs docs and a way to verify that it works (since testbot can't in this case) before it can be committed, regardless of whether it blocks anything.
Comment #13
stefan.r CreditAttribution: stefan.r commentedI haven't tested this but wouldn't setting
$databases['default']['default']['mysql_engine'] = 'MyISAM';
in settings.php override the hardcoded InnoDB default? In that case testbot wouldn't need this patch in order to test on MyISAM would it?
Comment #14
stefan.r CreditAttribution: stefan.r commentedNevermind that, I misread. It would still need a patch.
Comment #15
stefan.r CreditAttribution: stefan.r commentedSince testbot can't test this:
Using the stock settings.php:
While defining $databases['default']['default']['mysql_engine'] = 'MyISAM'; in settings.php:
Comment #17
stefan.r CreditAttribution: stefan.r commentedAnd the Drupal 8 version
Comment #18
xjm#17 looks good to me. Leaving for @Crell to RTBC though.
Comment #19
Crell CreditAttribution: Crell commentedClose enough for government work. Thanks!
I think this is safely backportable, so tagging. (David is free to disagree with me.)
Comment #20
stefan.r CreditAttribution: stefan.r commented#14 was actually a D7 patch, here it is again with updated wording so it matches the D8 patch in #17.
Comment #21
stefan.r CreditAttribution: stefan.r commentedComment #22
t@nh@. . CreditAttribution: t@nh@. . commented17: drupal-myisam-D8-2152443.patch queued for re-testing.
Comment #23
sunWondering whether this patch shouldn't add a unit test for the expectation, at least for D8?
Comment #24
Crell CreditAttribution: Crell commentedActually... sorry, but per #2275535: [policy, no patch] Drop support for non-transactional database engines (including MyISAM) we should probably not use MyISAM as our example alternate engine, since we're very likely going to drop support for that anyway.
Comment #25
stefan.r CreditAttribution: stefan.r commentedNDB then?
Comment #26
Crell CreditAttribution: Crell commentedNDB then. :-) sun, what kind of test would you want to see here? Do you mean a full install test or... what unit would you test?
Comment #27
sunThe processing of settings.php values into Database connection info is a separate concern, not touched here, and hopefully covered by tests already.
Thus, essentially just that a mysql_engine in Database connection info is taken over into a CREATE TABLE statement. Ideally as a phpunit test, since we just want to assert the effective SQL statement without creating an actual table. Looks like that should be easily possible.
Comment #28
webchickBased on the fact that we removed support for MyISAM in Drupal 8 at #2275535: [policy, no patch] Drop support for non-transactional database engines (including MyISAM), I think this is now relevant for D7 only.
Comment #29
Crell CreditAttribution: Crell at Palantir.net commentedNo, there's other useful engines in MySQL that still support transactions. Hence #25.
Comment #30
PeterZaitsev CreditAttribution: PeterZaitsev commentedHi,
One other transactional storage engine which would be good to support is TokuDB
There is also work on RocksDB at Facebook which will offer even more choices.
On other hand I would consider to support only transactional storage engines, especially over time - having 2 code paths for MyISAM and everything else is quite a pain in the ass and error prone. Plus I would say majority of the users running MyISAM are doing this because it was created for them by default not recognizing the risks they have (like risk of ruined data if server is restarted without proper shutdown)
Comment #31
Crell CreditAttribution: Crell at Palantir.net commentedPeter: We already dropped MyISAM for Drupal 8 over a year ago. :-) Right now, everything is InnoDB. This issue is about allowing site admins to pick another engine if they want to.
Comment #38
andypostComment #41
daffie CreditAttribution: daffie commentedComment #42
sokru CreditAttribution: sokru as a volunteer commentedJust a reroll.
Comment #44
andypostSummary needs update because myisam is not supported in d8 and must not so the no reason to allow it (IMO core should prevent it) but other engines should be allowed to allow experiment with new abilities
Comment #45
daffie CreditAttribution: daffie commented@sokru: If you change the
default.settings.php
file, you also have to change the same file incore/assets/scaffold/files/default.settings.php
Comment #46
sokru CreditAttribution: sokru as a volunteer commentedShould solve #45 and failing tests.
Comment #47
andypostisset($info['mysql_engine']) ? $info['mysql_engine'] : 'InnoDB'
Could be written as
$info['mysql_engine'] ?? 'InnoDB'
Comment #48
daffie CreditAttribution: daffie commentedLets change the text to something like: "The default storage engine is InnoDB, it will be used for all database tables unless otherwise specified in settings.php. InnoDB provides features over MyISAM such as transaction support, row-level locks, and consistent non-locking reads."
I do not know in which version of MySQL InnoDB was not available, but it was a very long time ago.
The test should do something like:
1. Create a table using the default database connection.
2. Test that the table is created with the InnoDB storage engine.
3. Get the default connection info.
4. Add the mysql_engine setting to the connection info.
5. Use the changed connection info to create a new connnection.
6. Create for the new connection a simple table.
7. Test that the new table is created with the other storage engine.
Comment #51
alexpottI don't think we should be talking about MyISAM here - modern Drupal doesn't support it.
Comment #52
raman.b CreditAttribution: raman.b at OpenSense Labs commentedAdding test coverage based on #48
Also addressing pointers from #47 and #51
Comment #53
daffie CreditAttribution: daffie commentedI have added a CR and updated the IS.
The added tests the added functionality.
All changes look good to me.
For me it is RTBC.
@raman.b: Thank you for writing the test.
Comment #54
johnwebdev CreditAttribution: johnwebdev commentedTo follow up on #51, should we explicitly state which engines Drupal DOES support?
Comment #55
daffie CreditAttribution: daffie commented@johnwebdev: In the patch is stated that the default table engine is InnoDB and the same for the CR. I have updated the IS with the same information.
Comment #56
johnwebdev CreditAttribution: johnwebdev commented#55 Yeah it does, but I think it would be helpful to list a set of engines that are supported by Drupal, where i.e. MySIAM is not one of them.
Comment #57
daffie CreditAttribution: daffie commented@johnwebdev: The only supported table engine for MySQL is InnoDB. For all others it is go and try for yourself and see if it works. Good luck and please report back how it went.
Comment #58
johnwebdev CreditAttribution: johnwebdev commentedRight. Do we want to say that in the documentation? Something like: Drupal has only been tested and actively supports the use of InnoDB table engine.
Comment #59
daffie CreditAttribution: daffie commentedLets add this text or something similar to the setting.php file.
I have already updated the CR with the text.
@johnwebdev: Thank you for your input.
Comment #60
alexpottand to use the NDB storage engine as the default for MySQL tables:
We should add the word default. This can be overridden on the table specification level. There's no test of this function but it will definitely work. We could add a followup to add it to the test added here.
I wonder whether setting the default in \Drupal\Core\Database\Driver\mysql\Connection::__construct() is worth it. For example:
That way this info will always be set on the connection options and we don't have to test for its existence. OTOH this at least makes easy to see what is used as a default.
Not sure.
Comment #62
dhirendra.mishra CreditAttribution: dhirendra.mishra at Valuebound for Valuebound commentedHere i have re-rolled it against 9.3.x and also updated the 1st point from comment #60 above..