在批量数据复制期间确定最有效和最安全的表锁

发布于 2024-12-28 09:38:08 字数 1789 浏览 6 评论 0原文

这将是最糟糕的情况之一,你会想要提出完全不同的建议。别担心,我知道,不幸的是我对此无能为力,所以请尽量将您的答案限制在那些能够解释可能产生最大影响的最小变化的答案上。

话虽如此,我的情况是这样的:有一个进程在工作时间内每 30 分钟将数据从 Sybase 服务器 (15.5) 复制到 SQL Server (2008 R2)。在 SQL 服务器上,有一个链接到 Sybase 数据库的服务器,我们从中复制表。这是可怕的部分:复制是通过删除所有现有行并从 Sybase 插入新行来完成的,以这种方式(在 SQL Server 上的存储过程中,由企业调度软件触发):

-- 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

所以我的问题是:

  • 修改存储过程以合并事务并锁定是否允许对即将要执行的表的请求修改为继续执行而不返回空值和/或导致死锁?
  • 如果不能,并且如果您可以更改某些内容(在 SQL 服务器上),那会是什么?

Sybase 和 Microsoft SQL服务器处于可以进行正常数据库复制的位置,并且已经考虑过,但这项任务对于我们的集团和我们的预算来说太繁琐了。

This is going to be one of those worst-of-the-worst situations where you're going to want to suggest something entirely different. Don't worry, I know, and unfortunately there's nothing I can do about it, so please try to limit your answers to ones that explain the smallest change possible that will make the biggest impact.

With that said, here's my situation: there is a process that replicates data from a Sybase server (15.5) to a SQL Server (2008 R2) every 30 minutes during business hours. On the SQL server, there is a linked server to the Sybase database from which we are copying tables. Here's the scary part: the copying is done by DELETING all of the existing rows and INSERTING the new ones from Sybase, in this fashion (within a stored procedure on the SQL server, triggered by enterprise scheduling software):

-- 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

There are no indices, primary keys, foreign keys, or data integrity whatsoever on the SQL server copy, but we can control the table schemas; we cannot, however, touch the Sybase server. The MSSQL database is basically a read-only environment for reporting and lookups. Performance isn't critical. It's been this way for years and so it lives on...

If you haven't vomited yet, you might have already thought of the problem: every once in a while, for a couple of seconds, our applications and reports cannot find (and sometimes cannot access) the data in the tables while they are being deleted from and inserted to.

I'm no DBA, so things like table locks, hold locks, exclusive locks, etc. are foreign to me, but I gather that perhaps they could be of some help in this situation. After reading through MSDN's article on table hints, my brain is telling me that I should do something with transactions and table locks. I have no idea what, say, the following would do, because I am also unsure how to test it:

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

So my questions are:

  • Would modifying the stored procedure to incorporate transactions and locking allow requests to tables that are about to be modified to carry on without coming back empty and/or causing deadlocks?
  • If not, and if you could change something (on the SQL server), what would it be?

Sybase and Microsoft SQL Server are at the point where normal database replication is possible, and it has been considered, but the task is too unwieldy for our group and our budget.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寻找一个思念的角度 2025-01-04 09:38:08

一个想法......洗牌表,这样被查询的表就不是被加载的表。

您可以使用更改表..开关。使用 SWITCH,您可以在文件组中的相同表之间移动数据。请注意,目标表必须为空,因此它可能不适合您的设置。

在这种情况下,请考虑隐藏带有同义词的表

An idea... shuffle tables so the one being queried isn't the one being loaded.

You can use ALTER TABLE .. SWITCH. With SWITCH you can move data between identical tables in the filegroup. Note, the target table must be empty so it may not suit your setup.

In that case, consider hiding the tables with synonyms instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文