When migrating a table to a new schema I want to make sure to have an atomic switch to the new table using the copy and rename procedure. Hence I am trying to rename a locked table like this:
CREATE TABLE foo_new (...)
-- copy data to new table, might take very long
INSERT INTO foo_new (id,created_at,modified_at)
SELECT * FROM foo WHERE id <= 3;
LOCK TABLES foo WRITE, foo_new WRITE;
-- quickly copy the tiny rest over
INSERT INTO foo_new (id,created_at,modified_at)
SELECT * FROM foo WHERE id > 3;
-- now switch to the new table
RENAME TABLE foo TO foo_old, foo_new TO foo;
UNLOCK TABLES;
Unfortunately that results in ERROR 1192 (HY000): Can't execute the given command because you have active locked tables or an active transaction
.
How should this be done differently?
This is with mariadb:10.1
.
While in general Rick is right to use the Percona Tools (see 1 and 2), the answer to the question really is to use ALTER TABLE
. I thought RENAME
was just an alias - but it seems like that's not the case.
Test seem to indicate that this works OK:
CREATE TABLE foo_new (...)
-- copy data to new table, might take very long
INSERT INTO foo_new (id,created_at,modified_at)
SELECT * FROM foo WHERE id <= 3;
LOCK TABLES foo WRITE, foo_new WRITE;
-- quickly copy the tiny rest over
INSERT INTO foo_new (id,created_at,modified_at)
SELECT * FROM foo WHERE id > 3;
-- now switch to the new table
ALTER TABLE foo RENAME TO foo_old;
ALTER TABLE foo_new RENAME TO foo;
UNLOCK TABLES;
You can do it like this:
CREATE TABLE foo_old (...)
LOCK TABLES foo WRITE;
INSERT INTO foo_old (id,created_at,modified_at)
SELECT * FROM foo;
DELETE FROM foo WHERE id <= 3;
UNLOCK TABLES;
As the error message states, you can't use RENAME TABLE
while having the same table locked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With