繁体   English   中英

如何交换MySQL表并自动更改auto_increment?

[英]How to swap MySQL table and change auto_increment atomically?

我有两个表:

CREATE TABLE table_a (
    id SERIAL
);
CREATE TABLE table_b (
    id SERIAL
);

我想换出表并将新table_a的auto_increment设置为table_b的MAX(id)+1。 例如

SELECT @A:=MAX(id) FROM table_a;
SET @qry = CONCAT('ALTER TABLE table_b AUTO_INCREMENT =', @A+1);
PREPARE stmt FROM @qry;
EXECUTE stmt;
RENAME TABLE table_a TO table_b_tmp, table_b TO table_a, table_b_tmp TO table_a;

不幸的是,我无法锁定表,也无法在事务中执行此操作,因为RENAME TABLE在锁定的表上不起作用,并且ALTER TABLE隐式提交。

我唯一想到的避免重叠id的解决方案是设置auto_increment + 50,但是由于此过程频繁发生,所以我宁愿在id中不要有很多漏洞。

有任何想法吗?

只要服务器不在MS Windows版本上并且坚持使用非事务处理表,就应该能够使用表锁和ALTER TABLE table_name RENAME TO new_table_name语句。

LOCK TABLES table_a WRITE, table_b WRITE;
SELECT @A:=MAX(id)+1 FROM table_a;
ALTER TABLE table_a RENAME TO table_a_tmp;
LOCK TABLES table_b WRITE, table_a_tmp WRITE;
PREPARE stmt FROM 'ALTER TABLE table_b RENAME TO table_a, AUTO_INCREMENT = ?';
EXECUTE stmt USING @A;
ALTER TABLE table_a_tmp RENAME TO table_b;
UNLOCK TABLES;

第二把锁让我担心。 如果还有其他挂起的会话,那么在锁定之前,他们是否有机会在桌子旁? 对于上述工作,我也很容易出错。 我将以上内容基于以下有关锁,事务和ALTER语句的页面。

我的另一个想法是,您可以为插入创建MERGE表,将merge方法更新为FIRST或LAST,而不是(以及?)交换表。 那行得通吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM