mysql - MYSQL 6.2 如何在不锁定表的情况下从另一个表复制数据?

标签 mysql innodb

我有一个表,其中包含 Mysql 服务器中的所有历史数据,而且它非常庞大(大约 7 亿行)。我正在创建一个具有相同列但具有分区的新表,然后我需要将旧表中的所有数据复制到新的分区表中。我已经有了正确的脚本来执行此操作,但我认为它可能会锁定表。我不希望发生这种情况,因为它在生产服务器上。我应该怎么做才能避免锁定表?

最佳答案

假定表格具有完全相同的列,您可以执行如下操作:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
INSERT INTO NEW_TABLE (SELECT * FROM OLD_TABLE);
COMMIT ;

我根据 Wistar's 添加了一些额外的解释评论。这里可以使用的读取级别是:

  • READ COMMITTED:在一致性(非锁定)读取方面有点类似于 Oracle 的隔离级别:每个一致性读取,即使在同一事务中,也会设置和读取其自己的新快照
  • READ UNCOMMITTED:SELECT 语句以非锁定方式执行,但可能会使用行的可能较早版本。因此,使用这个隔离级别,这样的读取是不一致的。这也称为脏读。否则,此隔离级别的工作方式类似于 READ COMMITTED。
  • REPEATABLE READ:这是 InnoDB 的默认隔离级别。对于一致性读,与READ COMMITTED隔离级别有一个重要区别:同一个事务内的所有一致性读都读取第一次读建立的快照。此约定意味着,如果您在同一事务中发出多个普通(非锁定)SELECT 语句,则这些 SELECT 语句也彼此一致。
  • SERIALIZABLE:这个级别类似于 REPEATABLE READ,但如果禁用自动提交,InnoDB 会将所有普通 SELECT 语句隐式转换为 SELECT ... LOCK IN SHARE MODE。如果启用了自动提交,则 SELECT 是它自己的事务。因此已知它是只读的,如果作为一致(非锁定)读取执行并且不需要为其他事务阻塞,则可以序列化。 (如果其他事务修改了所选行,要强制普通 SELECT 阻塞,请禁用自动提交。)

希望对您有所帮助。

关于mysql - MYSQL 6.2 如何在不锁定表的情况下从另一个表复制数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35803996/

相关文章:

mysql - 提高 MySQL 中的 count() 性能

php - Laravel 与外键的 Eloquent 关系

mysql - 下面给出的表中给出了要使用什么查询来获取输出?

Mysql InnoDB 合并/复制数据

mysql - MariaDB - 找不到 innodb_log_file_size

mysql - 产品表的 MyIsam VS INNODB

mysql - 使用 InnoDB 修复 MySQL 高 CPU 使用率

MySQL 行大小太大

mysql - 更新查询需要太长时间才能更新mysql中的大量数据

python - 我怎样才能在 pymysql 中开始交易? (mysql)