Well ... For many years no one has mentioned one subtle thing.
Despite the DROP TABLE IF EXISTS 'bla'; CREATE TABLE 'bla' (... ); DROP TABLE IF EXISTS 'bla'; CREATE TABLE 'bla' (... ); DROP TABLE IF EXISTS 'bla'; CREATE TABLE 'bla' (... ); it seems reasonable, this leads to a situation where the old table has already disappeared and the new one has not yet been created: some client may try to access the object table right now.
It is best to create a new table and replace it with the old one (the contents of the table are lost):
CREATE TABLE 'bla__new' (id int); RENAME TABLE 'bla__new' to 'bla'; RENAME TABLE 'bla' to 'bla__old', 'bla__new' to 'bla'; DROP TABLE IF EXISTS 'bla__old';
- You should check the result of
CREATE... and not continue in case of an error, because a failure means that the other thread did not complete the same script: either because it crashed in the middle, or simply has not completed yet - it is a good idea to check things out by yourself. - Then you should check the result of the first
RENAME... and not continue if successful: the whole operation completed successfully; Moreover, starting the next RENAME... may (and will) be unsafe if another thread has already started the same sequence (it is better to cover this case than not to close, see the blocking note below). - The second
RENAME... atomically replaces the table definition; see the MySQL manual for details. - Finally,
DROP... just clears the old table, obviously.
Wrapping all statements with something like SELECT GET_LOCK('__upgrade', -1);... DO RELEASE_LOCK('__upgrade'); SELECT GET_LOCK('__upgrade', -1);... DO RELEASE_LOCK('__upgrade'); allows you to simply call all statements sequentially without error checking, but I donβt think itβs a good idea: complexity is increased, and the lock functions in MySQL are not safe for statement-based replication.
If the table data should survive updating the table definition ... In general, this is a much more complicated story about comparing table definitions to identify differences and creating the correct ALTER... operator, which is not always possible automatically, for example, when renaming columns.
Alex Offshore Dec 26 '18 at 14:01 2018-12-26 14:01
source share