Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 重命名锁定的表_Mysql_Mariadb - Fatal编程技术网

Mysql 重命名锁定的表

Mysql 重命名锁定的表,mysql,mariadb,Mysql,Mariadb,将表迁移到新模式时,我希望确保使用复制和重命名过程将原子开关切换到新表。因此,我尝试重命名一个锁定的表,如下所示: 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_ne

将表迁移到新模式时,我希望确保使用复制和重命名过程将原子开关切换到新表。因此,我尝试重命名一个锁定的表,如下所示:

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;
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;
不幸的是,这导致错误1192 HY000:无法执行给定命令,因为您有活动的锁定表或活动事务

这应该怎么做呢


这是mariadb:10.1的一部分。

您可以这样做:

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;
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;

正如错误消息所述,锁定同一个表时,不能使用重命名表。

不要重新发明控制盘。。。使用Percona的pt在线模式更改;它会处理细节。

虽然Rick通常使用Percona工具是正确的,请参见,但问题的答案实际上是使用ALTER TABLE。我以为重命名只是一个别名,但是

测试似乎表明该功能正常:

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;

在LOCK和UNLOCK语句之间不应写入或读取任何数据

我遇到了同样的事情,在MySQL文档中找到了原因:

顺便说一下,在MySQL 5.7中,当表被LOCK tables tbl WRITE语句锁定时, 由于执行ALTER TABLE tbl_0 RENAME TO tbl_1,锁将被释放 在同一个会话和新会话中会发生奇怪的行为

# MySQL 5.7

# session 0
mysql> lock tables tbl_0 WRITE;
Query OK, 0 rows affected (0.02 sec)

mysql> ALTER TABLE tbl_0 RENAME TO tbl_1;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from tbl_1;
ERROR 1100 (HY000): Table 'tbl_1' was not locked with LOCK TABLES

# then start new session 
# session 1
mysql> select * from tbl_1;
...
1 row in set (0.01 sec)

# session 0
mysql> unlock tables;

希望能有所帮助

当前方法有什么问题?您的答案中的数据引用是什么?区别在于,您不必使用在锁定表时不可能使用的重命名表。请参见问题中的错误消息。我必须使用重命名表,因为另一个表具有不同的架构。也不确定删除的原因。因为您只在新表中写入id>3个条目,请参阅您的选择以进行插入。模式有什么不同?在你的问题中不要遗漏这些细节。对吧?但是为什么要删除id>3呢?如果删除,则必须是id