在sql server中同步2个表

时间:2011-11-03 14:25:43

标签: sql sql-server sql-server-2008

我在服务器A上有一个表,在另一个服务器B上有相同的表。 我想每天用服务器B的数据更新服务器A上的表。服务器A上的表有超过1亿条记录。我该如何做到这一点,以便在我更新服务器A上的表格数据时,它仍可用以前的信息阅读。

预期行为:

服务器A:

create table tbl_transaction_test (
    tabid int identity,
    first_name nvarchar(255),
    last_name nvarchar(255),
    [address] nvarchar(255),
    update_dt datetime
)

服务器B:

create table tbl_transaction_test (
    tabid int identity,
    first_name nvarchar(255),
    last_name nvarchar(255),
    [address] nvarchar(255),
    update_dt datetime
)

begin transaction transaction1
truncate table A
Insert into A.tbl_transaction_test 
     select * from B.tbl_transaction_test 
commit transaction transaction1

同时我想从服务器A上的表中选择。

如何才能获得服务器A中表中的数据只有在提交事务时才会更改的行为,并且会立即(几乎立即)完成此操作。

3 个答案:

答案 0 :(得分:2)

如果你想要内置的功能,也许你应该从High Availability Solutions Overview文章开始。请注意,对于使用这些功能,您应该在两台服务器上都具有适当的权限。简而言之:

  • Replication - 通过
  • 保持源数据库和目标数据库同步
  • Log shipping - 将事务日志备份从一个数据库/服务器发送到一个或多个数据库/服务器并将其应用于目标数据库
  • Mirroring - 基本上,它将活动事务日志记录流发送到目标服务器并将其应用于目标数据库

不要忘记检查您的SQL Server版本和许可证是否支持复制/镜像/日志传送(或者如果您决定使用它,则在文章中提到的群集故障转移)。

或者您可以使用源表上的触发器创建自定义解决方案(类似复制):

  1. 触发器将在日志表中保留已更改的记录,其中包含时间戳列和状态(已更新,已插入,已删除)。
  2. 将此单独的表复制到目标服务器,其中时间戳> last_timestamp_you_transfered在预定义的时间间隔(使用作业)
  3. 将更改应用于目标服务器(时间戳> last_timestamp_applied的更改)
  4. 注意:

    • 您始终可以将日志表保留为小时删除记录,其中时间戳小于上次处理的
    • 您可以通过编写将在每x秒/分钟进行传输的应用程序来避免工作

    每个提议的解决方案都需要对这些服您需要具有设置复制,镜像,日志传送或创建触发器+作业的权限。

答案 1 :(得分:2)

Andomar已经建议如何通过使用临时表和良好的'sp_rename技巧,使整个新数据集“一次”可见。该主题有各种变体,例如使用分区表并切换现有数据,然后切换登台表,请参阅Transferring Data Efficiently by Using Partition Switching

另一种方法是使用快照隔离。使用快照隔离,您可以删除表中的所有行并在事务中插入新行,它不会阻止任何读者,因为所有读者将继续使用旧行版本。请参阅Understanding Row Versioning-Based Isolation Levels

但人们不得不质疑一项涉及每天转移1亿的计划的合理性。只是不可行。因此,在单个事务中操作100M行的想法是,最可能的结果是您的事务日志文件将增长,直到它们填满整个驱动器,然后服务器将翻转并死亡。

您最需要的是Filip建议的解决方案之一:复制,镜像或日志传送。这些解决方案的良好比较是High Availability with SQL Server 2008白皮书。

答案 2 :(得分:1)

一种方法是使用临时表。将整个源表复制到新表中,复制完成后,删除旧表并重命名登台表。

select  * 
into    A.tbl_transaction_test_staging
from    B.tbl_transaction_test

begin transaction
drop A.tbl_transaction_test
exec sp_rename 'A.tbl_transaction_test_staging', 'A.tbl_transaction_test'
commit transaction

重命名操作相当快。