将数据从一个表移动到另一个表而不会丢失数据

Mat*_*ino 4 sql-server migration best-practices partitioning sql-server-2016

我有一个当前保存数百万条记录的日志表。我想在那个表上启用分区,所以我现在做的是:

  1. 创建了分区函数和分区方案。
  2. 在该分区方案上创建了一个具有相同结构的空表。
  3. 从当前日志表复制的数据从这个时间点(让我们称之为T1)倒退到新的分区表。

接下来的步骤将是最后剩余的记录从复制T1Tnow和重命名这两个表,以便应用程序开始写入新的分区表。

当然日志表经常被访问,所以我的问题是:

如何确保在此过程中不会丢失任何数据?我是否可以做到让用户不会注意到任何事情,或者我是否必须在这短暂的时间内停止应用程序?或者我可以阻止该表以便应用程序继续运行吗?如果是这样,如何?

Bre*_*zar 9

考虑使用您想要的分区策略创建一个新表,并在两个表上添加一个视图,以执行联合所有操作。让人们使用视图,并针对基础表和视图编写替代触发器。

插入应该发送到新表,更新应该将数据移动到新表,删除应该应用于两个表。

然后在后台进行批量移动,一次将尽可能多的记录移动到新表中。在此过程中,您仍然可能遇到并发问题,以及一些糟糕的执行计划,但它可以让您在移动发生时保持在线状态。

理想情况下,您在周五下午开始该流程以尽量减少对最终用户的影响,并尽量在周一早上之前完成。一旦它就位,您可以将视图更改为仅指向新表,可怕的执行计划就会消失。理想情况下。

为避免在批量迁移数据时触发触发器,请查看触发器中已删除/插入的表中的行数,如果活动接近批处理中的行数,则跳过这些活动。

您希望它对最终用户越透明,它需要做的工作(和测试)就越多。如果您使用分区,则尤其如此:人们通常认为这会使他们的所有查询更快,但其中一些最终会慢得多。如果可以,请尝试使用分区表在开发服务器上测试尽可能多的工作负载。

  • @MattiaNocerino `sp_rename` 是我最近处理这个问题的方式。1) 创建新表 2) 重命名基表 3) 用旧基表的名称创建视图 (3认同)
  • 从作业中的每个批次的设置表中选择行限制、等待时间和日志记录标志。我们只是增加了每次传递的行数,直到我们看到阻塞,然后再减少一点。我们记录了时间/行/循环并找到了最佳位置。夜间 50k/0sec,白天 4.5k/0.1sec。100 亿行需要 9 天。从未停止工作!:-) (2认同)