这将是一个最糟糕的情况之一,你会想要提出完全不同的建议。别担心,我知道,不幸的是我无能为力,所以请尽量将你的答案限制在可以解释可能产生最大影响的最小变化的答案上。
说到这里,我的情况是:有一个进程在工作时间每30分钟将数据从Sybase服务器(15.5)复制到SQL Server(2008 R2)。在SQL服务器上,有一个到Sybase数据库的链接服务器,我们从中复制表。这是可怕的部分:复制是通过删除所有现有行并以这种方式从Sybase插入新行来完成的(在SQL服务器上的存储过程中,由企业调度软件触发):
-- Table 1
DELETE FROM abc1;
INSERT INTO abc1 (col1, col2, col3)
SELECT col1, col2, col3 FROM LINKED.SERVER.dbo.abc1;
GO
-- Table 2
DELETE FROM abc2;
INSERT INTO abc2 (col1, col2, col3)
SELECT col1, col2, col3 FROM LINKED.SERVER.dbo.abc2;
GO
-- ... and so on for hundreds of tables
SQL Server副本上没有索引,主键,外键或数据完整性,但我们可以控制表模式;但是,我们无法触及Sybase服务器。 MSSQL数据库基本上是用于报告和查找的只读环境。表现并不重要。这种方式已经存在多年了,所以它继续存在......
如果你还没有呕吐,你可能已经想到了这个问题:每隔一段时间,几秒钟,我们的应用程序和报告就无法找到(有时无法访问)数据表格从中删除并插入。
我不是DBA,所以表锁,保持锁,独占锁等都是我的陌生,但我认为,或许他们可以在这种情况下提供一些帮助。在阅读了MSDN关于表提示的文章后,我的大脑告诉我,我应该对事务和表锁做些什么。我不知道下面会做什么,因为我也不确定如何测试它:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
-- Table 1
BEGIN TRANSACTION UpdateAbc1
DELETE FROM abc1 WITH (TABLOCK, HOLDLOCK);
INSERT INTO abc1 WITH (TABLOCK, HOLDLOCK) (col1, col2, col3)
SELECT col1, col2, col3 FROM LINKED.SERVER.dbo.abc1;
COMMIT TRANSACTION UpdateAbc1
-- Table 2
BEGIN TRANSACTION UpdateAbc2
DELETE FROM abc2 WITH (TABLOCK, HOLDLOCK);
INSERT INTO abc2 WITH (TABLOCK, HOLDLOCK) (col1, col2, col3)
SELECT col1, col2, col3 FROM LINKED.SERVER.dbo.abc2;
COMMIT TRANSACTION UpdateAbc2
所以我的问题是:
Sybase和Microsoft SQL Server正处于可以进行正常数据库复制的阶段,并且已经考虑过了,但是对于我们的团队和我们的预算来说,这项任务过于笨拙。
答案 0 :(得分:0)
一个想法......随机播放表格,以便被查询的人不是正在加载的人。
您可以使用ALTER TABLE .. SWITCH。使用SWITCH,您可以在文件组中的相同表之间移动数据。请注意,目标表必须为空,因此可能不适合您的设置。
在这种情况下,请考虑使用hiding the tables with synonyms。