我在服务器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中表中的数据只有在提交事务时才会更改的行为,并且会立即(几乎立即)完成此操作。
答案 0 :(得分:2)
如果你想要内置的功能,也许你应该从High Availability Solutions Overview文章开始。请注意,对于使用这些功能,您应该在两台服务器上都具有适当的权限。简而言之:
不要忘记检查您的SQL Server版本和许可证是否支持复制/镜像/日志传送(或者如果您决定使用它,则在文章中提到的群集故障转移)。
或者您可以使用源表上的触发器创建自定义解决方案(类似复制):
注意:
每个提议的解决方案都需要对这些服您需要具有设置复制,镜像,日志传送或创建触发器+作业的权限。
答案 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
重命名操作相当快。