上周五HaC我要上线,有一个脚本需要执行,执行前需要备份一个表。
运维大佬:“这个表的备份为什么要这么久,,??”
1秒过去了……2秒过去了……
期间运营反馈系统出现大量订单超时情况。
大佬找到我,问:“你怎么备份的?”
我:“insert into select * from 呀!”
大佬:“??你是不是不想混了?”
又是被大佬嫌弃的一天,为了不卷铺盖走人,我决定去学习一下表备份的常见方法。
MySQL一般我们在生产上备份数据通常会用到 这两种方法:
- INSERT INTO SELECT
- CREATE TABLE AS SELECT
注:本文仅针对MySQL innodb引擎,事务是可重复读RR,数据库版本为5.5
1.INSERT INTO SELECT
insert into Table2(field1,field2,...) select value1,value2,... from Table1
注意
(1)要求目标表Table2必须存在,并且字段field,field2…也必须存在
(2)注意Table2的主键约束,如果Table2有主键而且不为空,则 field1, field2…中必须包括主键
在执行语句的时候,MySQL是逐行加锁的(扫描一个锁一个),直至锁住所有符合条件的数据,执行完毕才释放锁。所以当业务在进行的时候,切忌使用这种方法。
在RR隔离级别下,还会加行锁和间隙锁
举个栗子吧:
CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `c` (`c`)
) ENGINE=InnoDB;
insert into t values(null, 1,1);
insert into t values(null, 2,2);
insert into t values(null, 3