Sql server 来自Oracle的SQLServer发布
我们的一位客户拥有一台Oracle 10.2.0.5RAC(HPUX)和两台SQL Server 2012(Sql server 来自Oracle的SQLServer发布,sql-server,oracle,Sql Server,Oracle,我们的一位客户拥有一台Oracle 10.2.0.5RAC(HPUX)和两台SQL Server 2012(Windows Server 2008R2)。我们正在帮助他们将数据从Oracle发布到SQL Server。他们还需要知道哪些行被添加、更新和删除,但他们不想修改自己的应用程序 整个过程是这样的: Oracle作为发布服务器->SQL Server A作为分发服务器->SQL Server B作为分发服务器 订户 我们的DBA已经通过SSMS(SQLServerManagementStu
Windows Server 2008R2
)。我们正在帮助他们将数据从Oracle发布到SQL Server。他们还需要知道哪些行被添加、更新和删除,但他们不想修改自己的应用程序
整个过程是这样的:
Oracle作为发布服务器->SQL Server A作为分发服务器->SQL Server B作为分发服务器
订户
我们的DBA已经通过SSMS(SQLServerManagementStudio)像这样配置了所有的数据库。这几天效果很好。但是Oracle的性能越来越差。最后,我们必须停止Oracle的数据发布
事实证明,SSMS将在Oracle中创建一个名为“HREPL”的包,其中包含一个名为“PollEnd
”的过程。“PollEnd
”将以非常高的频率执行,以删除表“HREPL\u ARTICLE1LOG\u 1
”中的数据。但是“PollEnd
”的执行时间会随着时间的推移而增加。最后,执行时间超过了执行的时间跨度,并且表被锁定,Oracle的性能将非常差
我们被困在这里
有人知道怎么解决这个问题吗?请帮忙
“PollEnd”程序:
-----------------------------------------------------------------------------------
--
-- Name: PollEnd
-- Purpose: PollEnd request signifies that the change entries identified with the current
-- interval have been successfully entered into the store and forward database
-- and can be deleted from the article log tables.
-- Input:
-- argLSN IN RAW(10) LSN from distributor that was associated
-- with this poll interval
-- Output:
-- Notes: This request causes those entries of the article log tables represented in the
-- Poll Table and having the current pollid to be deleted from both their article log
-- tables and from the Poll Table. The last request value is updated to reflect a
-- PollEnd request.
--
-----------------------------------------------------------------------------------
PROCEDURE PollEnd
(
argLSN IN RAW
)
AS
SQLCommand VARCHAR2(500);
LogTable VARCHAR2(255);
CurrentPollID NUMBER;
TableIDs number_tab;
InstanceIDs number_tab;
IDCount BINARY_INTEGER;
PublisherLSN RAW(10);
BEGIN
-- Put the published tableIDs in a PL/SQL table of IDs
HREPL.GetTableIDs(TableIDs, InstanceIDs);
-- Get the current Poll ID
SELECT Publisher_CurrentPollid INTO CurrentPollID FROM HREPL_Publisher;
IDCount := TableIDs.COUNT;
-- For each table represented in the ID list
FOR id_ind IN 1 .. IDCount
LOOP
LogTable := REPLACE( REPLACE(ArticleLogTemplate, MatchString, TO_CHAR(TableIDs(id_ind))),
MatchStringY, TO_CHAR(InstanceIDs(id_ind)));
BEGIN
-- Generate command to delete from the article log those entries appearing in the
-- Poll Table with the current PollID
SQLCommand := 'DELETE FROM ' || LogTable || ' l ' ||
'WHERE EXISTS (SELECT p.POLL_POLLID FROM HREPL_POLL p ' ||
' WHERE CHARTOROWID(l.ROWID) = p.Poll_ROWID ' ||
' AND p.Poll_PollID = :Pollid)';
HREPL.ExecuteCommandForPollID(SQLCommand, CurrentPollID);
EXCEPTION
WHEN OTHERS THEN NULL;
END;
END LOOP;
FOR POLLID IN (SELECT CurrentPollid FROM DUAL)
LOOP
-- Delete from HREPL_Event those entries appearing in the Poll Table
-- with the current PollID.
DELETE FROM HREPL_Event e
WHERE EXISTS (SELECT p.POLL_POLLID FROM HREPL_POLL p
WHERE CHARTOROWID(e.ROWID) = p.Poll_ROWID
AND p.Poll_PollID = POLLID.CurrentPollID);
-- Delete entries from the Poll Table having the current Pollid
DELETE FROM HREPL_Poll
WHERE Poll_PollID = POLLID.CurrentPollID;
END LOOP;
-- Drop all views associated with articles that are marked as UnPublishPending.
-- Note: We cannot perform these drops in UnPublish table, since UnPublish
-- table can execute concurrently with PollBegin and the querying
-- of published tables by the log reader. PollEnd, however, executes
-- synchronously with respect to these activities, so can be used
-- to cleanup log tables and views that are no longer needed.
HREPL.CleanupLogsandViews;
-- Mark the last request as PollEnd, and update the Publisher LSN
-- to reflect the LSN committed at the publisher.
UPDATE HREPL_Publisher
SET Publisher_PollInProcess = NoPollInProcess,
Publisher_LSN = argLSN;
-- Commit transaction
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END PollEnd;
编辑01:
全套资料如下:
编辑02:
最后我们放弃了。微软和甲骨文互相指责
我们尝试使用ogg将数据从oracle复制到sql server,这也很混乱
现在我们正在尝试使用ogg将数据从oracle复制到oracle
谢谢您的帮助。转换您的
删除。。。WHERE EXISTS(…)
使用多表删除语法的查询
SQLCommand := 'DELETE l' ||
' FROM HREPL_POLL, ' || LogTable ||
' l WHERE CHARTOROWID(l.ROWID) = p.Poll_ROWID ' ||
' AND p.Poll_PollID = :Pollid)';
在涉及的每个表上创建函数索引:
CREATE INDEX MYTABLE_CHARTOROWID ON MYTABLE(CHARTOROWID(ROWID));
然后再往下走:
DELETE e
FROM HREPL_POLL p, HREPL_Event e
WHERE CHARTOROWID(e.ROWID) = p.Poll_ROWID
AND p.Poll_PollID = POLLID.CurrentPollID;
最后,完全删除dual上的
循环
——它完全不做任何事情;只需直接使用CurrentPollid
执行其中的代码。某些连接条件似乎不合理,使用此版本您可能会更幸运-如果您在生产环境中尝试,您将自行承担风险
-----------------------------------------------------------------------------------
--
-- Name: PollEnd
-- Purpose: PollEnd request signifies that the change entries identified with the current
-- interval have been successfully entered into the store and forward database
-- and can be deleted from the article log tables.
-- Input:
-- argLSN IN RAW(10) LSN from distributor that was associated
-- with this poll interval
-- Output:
-- Notes: This request causes those entries of the article log tables represented in the
-- Poll Table and having the current pollid to be deleted from both their article log
-- tables and from the Poll Table. The last request value is updated to reflect a
-- PollEnd request.
--
-----------------------------------------------------------------------------------
PROCEDURE PollEnd
(
argLSN IN RAW
)
AS
SQLCommand VARCHAR2(500);
LogTable VARCHAR2(255);
CurrentPollID NUMBER;
TableIDs number_tab;
InstanceIDs number_tab;
IDCount BINARY_INTEGER;
PublisherLSN RAW(10);
BEGIN
-- Put the published tableIDs in a PL/SQL table of IDs
HREPL.GetTableIDs(TableIDs, InstanceIDs);
-- Get the current Poll ID
SELECT Publisher_CurrentPollid INTO CurrentPollID FROM HREPL_Publisher;
IDCount := TableIDs.COUNT;
-- For each table represented in the ID list
FOR id_ind IN 1 .. IDCount
LOOP
LogTable := REPLACE( REPLACE(ArticleLogTemplate, MatchString, TO_CHAR(TableIDs(id_ind))),
MatchStringY, TO_CHAR(InstanceIDs(id_ind)));
BEGIN
-- Generate command to delete from the article log those entries appearing in the
-- Poll Table with the current PollID
SQLCommand := 'DELETE FROM ' || LogTable || ' l ' ||
'WHERE l.ROWID IN (SELECT chartorowid(p.Poll_ROWID) FROM HREPL_POLL p ' ||
' WHERE p.Poll_PollID = :Pollid)';
HREPL.ExecuteCommandForPollID(SQLCommand, CurrentPollID);
EXCEPTION
WHEN OTHERS THEN NULL;
END;
END LOOP;
-- Delete from HREPL_Event those entries appearing in the Poll Table
-- with the current PollID.
DELETE FROM HREPL_Event e
WHERE ROWID in (SELECT chartorowid(p.Poll_ROWID) FROM HREPL_POLL p
WHERE p.Poll_PollID = CurrentPollID);
-- Delete entries from the Poll Table having the current Pollid
DELETE FROM HREPL_Poll
WHERE Poll_PollID = CurrentPollID;
-- Drop all views associated with articles that are marked as UnPublishPending.
-- Note: We cannot perform these drops in UnPublish table, since UnPublish
-- table can execute concurrently with PollBegin and the querying
-- of published tables by the log reader. PollEnd, however, executes
-- synchronously with respect to these activities, so can be used
-- to cleanup log tables and views that are no longer needed.
HREPL.CleanupLogsandViews;
-- Mark the last request as PollEnd, and update the Publisher LSN
-- to reflect the LSN committed at the publisher.
UPDATE HREPL_Publisher
SET Publisher_PollInProcess = NoPollInProcess,
Publisher_LSN = argLSN;
-- Commit transaction
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END PollEnd;
像这样的问题很难仅通过一个过程来诊断。您是否知道您的
PollEnd
过程中增加的执行时间与哪个部分有关?那么,IDCount
有多大?随着时间的推移,这个数字会急剧增加吗?另外(可能不相关),为什么要循环使用双表?该表不应该有多行。下游服务器上的数据需要是最新的吗?@MJH我上传了完整的数据包,我会向我们的dba询问您需要的参数。@Bohemian他们希望数据是“实时的”。我认为这不到15秒。这个问题应该继续问。如果你摆脱了无意义的循环,你必须删除循环中的POLLID.
引用。无论如何,循环不太可能对整体性能产生明显的影响。@ammoQ我对代码的厌恶影响了我的rational方面。我修改了我的评论,直接使用CurrentPollid
。干杯。你可能已经注意到我已经多次删除和取消删除了这个答案,但现在我相信它可能会起作用。。。当然,它首先应该在安全的环境中进行彻底的测试。