简体   繁体   English

SQL Server Transaction Replication error Online index operations can only be performed in Enterprise edition of SQL 服务器从Ent到Standard

[英]SQL Server Transaction Replication error Online index operations can only be performed in Enterprise edition of SQL Server from Ent to Standard

I'm setting up transactional replication for multiple databases in SQL Server where the publisher is on SQL Server 2014 Enterprise Edition and the target is SQL Server 2017 Standard.我正在为 SQL 服务器中的多个数据库设置事务复制,其中发布者位于 SQL Server 2014 Enterprise Edition 上,目标是 SQL Server 2017 Standard。 All but 2 of the databases work great, and the error I'm running into is right at the end of applying the snapshot to the subscriber for those 2.除了 2 个数据库外,所有数据库都运行良好,我遇到的错误就在将快照应用到这 2 个数据库的订阅者的最后。

"Online index operations can only be performed in Enterprise edition of SQL Server"

I'm assuming this means that those 2 databases have at one point applied indexing or changes with ONLINE=ON?我假设这意味着这两个数据库在某一时刻应用了索引或更改了 ONLINE=ON? I have attempted to create the snapshot without the clustered and nonclustered indexes and keep hitting the error as well.我试图在没有聚簇索引和非聚簇索引的情况下创建快照,并且也不断遇到错误。

If this is true, Is there a way to tell which articles in the database have been scripted with ONLINE=ON to cause this error to pop up?如果这是真的,有没有办法告诉数据库中的哪些文章已经编写了 ONLINE=ON 的脚本来导致弹出这个错误?

I'm planning a full index rebuild with ONLINE=OFF on the smaller of the source databases hoping that is the workaround but am curious if anyone out there knows the solution.我计划在较小的源数据库上使用 ONLINE=OFF 重建完整索引,希望这是解决方法,但我很好奇是否有人知道解决方案。 Would hate to have to be forced to get Enterprise Edition just because of this error!不想因为这个错误而被迫获得企业版!

UPDATE: The index rebuild did not get me away from the error.更新:索引重建并没有让我摆脱错误。 Is there a method by chance to do transactional replication without the primary key indexing being applied?有没有一种方法可以在不应用主键索引的情况下进行事务复制?

UPDATE #2: So reporting back, I switched the database type and truncated the logs, then recreated the publication and it would not take the snapshot without the same error.更新#2:所以报告回来,我切换了数据库类型并截断了日志,然后重新创建了发布并且它不会在没有相同错误的情况下拍摄快照。 Then, I identified the offending article removed it from the publication to create a new snapshot and the error still exists.然后,我确定了有问题的文章将其从出版物中删除以创建新快照,但错误仍然存在。 After that, I had a log truncation and index rebuild and created a brand new publication along with subscriber and target database and the error still hits for that database when delivering the snapshot to the subscriber.之后,我进行了日志截断和索引重建,并创建了一个全新的发布以及订阅者和目标数据库,但在将快照传递给订阅者时,该数据库仍然出现错误。 (with or without the article) (有或没有文章)

So in the end, it appears that once you utilize the ONLINE=ON feature on a schema change, index, etc on your database, you are then stuck with transactional replication only going from Enterprise Edition to Enterprise Edition unless you begin editing the binary file of the transaction log which is not recommended, supported and can essentially cause more harm than good when dealing with a high volume transactional production environment.所以最后,看起来一旦您在数据库的架构更改、索引等上使用 ONLINE=ON 功能,您就会陷入只能从企业版到企业版的事务复制,除非您开始编辑二进制文件在处理大量事务性生产环境时,不推荐、不支持事务日志,实际上弊大于利。

Awesome!惊人的! I LOVE THIS QUESTION我喜欢这个问题

Finally we have excuse to dig to the internals我们终于有理由深入挖掘内部结构

I'm assuming this means that those 2 databases have at one point applied indexing or changes with ONLINE=ON?我假设这意味着这两个数据库在某一时刻应用了索引或更改了 ONLINE=ON?

This make sense...这有道理...

But remember that "Online index operations" can include multiple tasks like CREATE/ALTER/DROP INDEX;但请记住,“在线索引操作”可以包括多个任务,如 CREATE/ALTER/DROP INDEX; ALTER TABLE (add or drop UNIQUE or PRIMARY KEY constraints with CLUSTERED index option and alter columns). ALTER TABLE(使用 CLUSTERED 索引选项和更改列添加或删除 UNIQUE 或 PRIMARY KEY 约束)。

am curious if anyone out there knows the solution很好奇是否有人知道解决方案

For first step, we need to find who/how/which task was executed and used ONLINE which lead to this issue.第一步,我们需要找到导致此问题的在线执行和使用任务的人员/方式/任务 Meaning we need to find the task which was used ONLINE and block you from using none-Enterprise edition.这意味着我们需要找到在线使用的任务并阻止您使用非企业版。

Note!笔记! For the sake of the discussion I will speak about CREATE INDEX but the same procedure can be applied to other ONLINE tasks, which are logged in the transaction log.为了便于讨论,我将讨论CREATE INDEX ,但同样的过程可以应用于记录在事务日志中的其他 ONLINE 任务。

This might be a bit complex and advance, since the information about how we created the index, is not stored in the database tables (metadata) as much as remember since once it was created it has no value/uses (usually, since as we found now it might have a value in this question).这可能有点复杂和先进,因为关于我们如何创建索引的信息并没有像我们记得的那样存储在数据库表(元数据)中,因为一旦创建它就没有价值/用途(通常,因为我们现在发现它可能在这个问题中有价值)。

Therefore, we need to pull the information from the transaction log exactly from the same place that the transaction replication takes it from.因此,我们需要从事务复制从中提取信息的相同位置,从事务日志中提取信息

For this task we will use the undocumented function fn_dblog对于此任务,我们将使用未记录的 function fn_dblog

Q: Is there a way to tell which articles in the database have been scripted with ONLINE=ON问:有没有办法判断数据库中的哪些文章已使用 ONLINE=ON 编写脚本

The answer is yes:-)答案是肯定的:-)

Lets demonstrate it from start to end让我们从头到尾演示一下

CREATE DATABASE Test
GO
USE Test
GO

DROP TABLE IF EXISTS fyi_links_indexed
GO

Create table fyi_links_indexed(url char(100))
GO -- No index yet

-- Let's find the last LSN from the log file. 
-- This will help us to filter the log file in our sample instead of read the entire log file each time.
SELECT TOP 1 [Current LSN] 
FROM fn_dblog(null,null)
ORDER BY [Current LSN] DESC
GO -- remember this value for next step. In my test Db I got 00000025:00000a18:0024

-- For each query now we will use: where [Current LSN] > '00000025:00000a18:0024'

-- Let's CREATE INDEX ONLINE and check what was added in the transaction log

CREATE INDEX fyi_links_url ON fyi_links_indexed (url)
   WITH (ONLINE = ON);
GO

-- just for understanding let's see waht added to the transaction log:
SELECT * FROM fn_dblog(null,null)
where [Current LSN] > '00000025:00000a18:0024'
GO
-- Notice that creating the index online writes multiple rows in the transaction log


-- just for understanding let's confirm that this index was created ONLINe,
-- which is what the replication see as well
-- and what failed in the standards edidion
SELECT [Current LSN], [Transaction ID], [Transaction Name] FROM fn_dblog(null,null)
where [Current LSN] > '00000025:00000a18:0024' and [Transaction Name] in('CREATE INDEX','ONLINE_INDEX_DDL')
GO


-- our next task is to find the transaction ID
-- search for Transaction name "CREATE INDEX"
SELECT [Transaction ID], [Transaction Name] FROM fn_dblog(null,null)
where [Current LSN] > '00000025:00000a18:0024' and Operation = 'LOP_BEGIN_XACT' and [Transaction Name] = 'CREATE INDEX'
GO -- 0000:0000042d



-- Now we have the transaction ID so we can get the object ID if the entitiy which was used ONLINE (in our case the INDEX)
select [Lock Information]
FROM fn_dblog(null,null) where [Transaction ID] = '0000:0000042d' and [Lock Information] like '%object_id = %'
GO 
-- result should be like:
-- HoBt 0:ACQUIRE_LOCK_SCH_M METADATA: database_id = 9 INDEXSTATS(object_id = 901578250, index_id or stats_id = 2), lockPartitionId = 0
-- Notice the object Id (in my case 901578250)

That is all!就这些!

We found the id of the problematic entity which was created using ONLINE我们找到了使用 ONLINE 创建的有问题实体的 ID


What next?接下来是什么?

The problem is that cleaning the information from the transaction log in ordefr to continue the replication as it is, might be very advance and complexs (can be done in theory)问题是从事务日志中清除信息以便继续复制,这可能是非常先进和复杂的(理论上可以完成)

SO at this point we know what to fix but the next question is how to fix...所以在这一点上我们知道要修复什么但下一个问题是如何修复......

The simples way is to start the replication from this point after the problematic entity was already created since if we use the current transaction log then the issue will appear even if we drop the the index now since the replication is done log by log and once we will use the log that include the CREATE INDEX ONLINE then the issue will appear again.最简单的方法是在已经创建有问题的实体之后从这一点开始复制,因为如果我们使用当前的事务日志,那么即使我们现在删除索引,问题也会出现,因为复制是逐个日志完成的,一旦我们将使用包含CREATE INDEX ONLINE的日志,然后问题将再次出现。

After you create the replication then we need to avoid related issue in the future创建复制后,我们需要避免将来出现相关问题

In production the execution of index rebuild (which can use ONLINE) for example, is usually done by manual exaction or maintenance tasks which executed in Jobs (Unfortunately it can come from other triggers which are more difficult to find if you are not familiar with the system).例如,在生产中,索引重建(可以使用 ONLINE)的执行通常是通过在 Jobs 中执行的手动执行或维护任务来完成的(不幸的是,它可能来自其他触发器,如果您不熟悉系统)。

At this point you must confirm that if you duplicated the same jobs from the source server then you should fix all these jobs and other task which use ONLINE.此时您必须确认,如果您从源服务器复制了相同的作业,那么您应该修复所有这些作业和其他使用 ONLINE 的任务。

This is a separate task这是一个单独的任务

find jobs which include the world ONLINE找到包括世界在线的工作

SELECT 
    s.step_id as 'Step ID',
    j.[name] as 'SQL Agent Job Name',
    s.database_name as 'DB Name',
    s.command as 'Command'
FROM   msdb.dbo.sysjobsteps AS s
INNER JOIN msdb.dbo.sysjobs AS j ON  s.job_id = j.job_id
WHERE  s.command LIKE '%ONLINE%'

Last question we had here我们在这里遇到的最后一个问题

Is there a method by chance to do transactional replication without the primary key indexing being applied?有没有一种方法可以在不应用主键索引的情况下进行事务复制?

No. Transactional replication requires a primary key constraint on each published table.否。事务复制需要对每个已发布的表进行主键约束。

https://learn.microsoft.com/en-us/sql/relational-databases/replication/administration/frequently-asked-questions-for-replication-administrators?view=sql-server-ver15#how-do-i-manage-constraints-on-published-tables--- https://learn.microsoft.com/en-us/sql/relational-databases/replication/administration/frequently-asked-questions-for-replication-administrators?view=sql-server-ver15#how-do-i-管理对已发布表的约束---


Credit信用

the answer was first published here (copied here by the original author): https://ariely.info/Blog/tabid/83/EntryId/302/SQL-Server-Transaction-Replication-from-Enterprise-to-Standard-error-Online-index-operations-can-only-be-performed-in-Enterprise-edition.aspx答案首发于此(原作者复制于此): https://ariely.info/Blog/tabid/83/EntryId/302/SQL-Server-Transaction-Replication-from-Enterprise-to-Standard-error -在线索引操作只能在企业版中执行.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL Server 2008中的BIDS,标准版和企业版 - BIDS, Standard and Enterprise Edition in SQL Server 2008 我可以从SQL Server 2016 13.0.5026.0(X64)标准版升级到Microsoft SQL Server 2014-12.0.4100.1(X64)企业版吗? - Can I upgrade from SQL Server 2016 13.0.5026.0 (X64) Standard Edition to Microsoft SQL Server 2014 - 12.0.4100.1 (X64) Enterprise Edition? SQL Server Standard和Enterprise Edition 2005之间的性能差异 - Performance difference between SQL Server Standard & Enterprise Edition 2005 我可以将SQL Server企业镜像到标准吗? - Can I mirror SQL server enterprise to standard? SQL Server Standard Edition 2014中的群集列存储索引? - Clustered Columnstore Index in SQL Server Standard Edition 2014? SQL Server 2017 标准版中的数据压缩 - Data Compression in SQL Server 2017 Standard Edition SQL Server Web与标准版 - SQL Server Web vs Standard edition Sql Server 2008 事务复制和事务日志 - Sql Server 2008 Transactional Replication and the Transaction Log SQL复制错误(在服务器代理上) - SQL Replication Error (On Server Agent) 可以使用SQL Server Express来有效地管理SQL Server Standard / Enterprise安装吗? - Can SQL Server Express be used to effectively administrate a SQL Server Standard/Enterprise installation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM