将数据库附加到SQL Server 2008 R2实例后,CDC失败

时间:2013-02-16 22:50:50

标签: sql-server sql-server-2008 sql-server-2008-r2

我们在SQL Server 2008 R2(SP 1)上托管了一个SQL Server数据库,并启用了CDC(更改数据捕获)。

由于许可证到期而重新安装SQL Server实例(部署团队忘记安装正确的许可证:())我们将数据库附加到新安装的实例。

但是,并未为所有表启用CDC 当我们尝试通过执行

启用它时
sys.sp_cdc_enable_table
我们得到了

  

未对变更数据捕获启用数据库“DBName”。确保   设置了正确的数据库上下文并重试该操作。至   报告有关为变更数据捕获启用的数据库,查询   sys.databases目录视图中的is_cdc_enabled列。

建议未启用CDC。

因此,我们尝试通过执行

来启用它
sys.sp_cdc_enable_db

我们收到以下错误:

  

消息22906,级别16,状态1,过程sp_cdc_enable_db_internal,   49号线   无法为更改数据启用数据库“DBName”   捕获因为名为“cdc”的数据库用户或名为“cdc”的模式   已存在于当前数据库中。这些对象是必需的   完全由变更数据捕获。删除或重命名用户或架构   并重试该操作。

尝试通过执行

禁用CDC
sys.sp_cdc_disable_db

我们再次收到错误相同的错误:

  

未对变更数据捕获启用数据库“DBName”。确保   设置了正确的数据库上下文并重试该操作。至   报告有关为变更数据捕获启用的数据库,查询   sys.databases目录视图中的is_cdc_enabled列。

我的猜测是,db系统表与导致CDC状态无效的SQL Server系统表之间存在一些不一致。

有没有办法解决这个问题?

任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:4)

<强>您好 用于修复Db(删除cdc架构中的所有内容和架构本身) 使用这个:

DECLARE @tableName NVARCHAR(100);
DECLARE myCursor CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
    SELECT  QUOTENAME(t.name) AS name
    FROM    sys.tables t
            JOIN sys.schemas s ON t.schema_id = s.schema_id
    WHERE   s.name = 'cdc'
OPEN myCursor 
FETCH FROM myCursor INTO @TableName 
WHILE ( @@Fetch_Status = 0 ) 
    BEGIN 

        EXEC ( 'drop table cdc.' + @TableName + '; ' );
        FETCH NEXT FROM myCursor INTO @TableName 
    END  
CLOSE myCursor 
DEALLOCATE myCursor;
go

DECLARE @prName NVARCHAR(100);
DECLARE myCursor2 CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
    SELECT  QUOTENAME(pr.name) AS name
    FROM    sys.procedures pr
            JOIN sys.schemas s ON pr.schema_id = s.schema_id
    WHERE   s.name = 'cdc'
OPEN myCursor2 
FETCH FROM myCursor2 INTO @prName 
WHILE ( @@Fetch_Status = 0 ) 
    BEGIN 
        EXEC ( 'drop procedure cdc.' + @prName + '; ' );
        FETCH NEXT FROM myCursor2 INTO @prName 
    END  
CLOSE myCursor2
DEALLOCATE myCursor2 

GO

DECLARE @fnName NVARCHAR(100);
DECLARE myCursor3 CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
    SELECT  QUOTENAME(fn.name) AS name
    FROM    sys.objects fn
            JOIN sys.schemas s ON fn.schema_id = s.schema_id
    WHERE   fn.type IN ( 'FN', 'IF', 'TF' )
            AND s.name = 'cdc'
OPEN myCursor3 
FETCH FROM myCursor3 INTO @fnName 
WHILE ( @@Fetch_Status = 0 ) 
    BEGIN 
        EXEC ( 'drop function cdc.' + @fnName + '; ' );
        FETCH NEXT FROM myCursor3 INTO @fnName 
    END  
CLOSE myCursor3
DEALLOCATE myCursor3 
go
DECLARE @ruleName NVARCHAR(100);
SELECT  @ruleName = DP1.name
FROM    sys.database_principals AS DP1
        JOIN sys.database_principals AS DP2 ON DP1.owning_principal_id = DP2.principal_id
WHERE   DP1.type = 'R'
        AND DP2.name = 'cdc';
EXEC ('ALTER AUTHORIZATION ON ROLE::'+@ruleName+' TO dbo; ')
go 
DROP SCHEMA [cdc]
GO
DROP USER [cdc]
GO

答案 1 :(得分:0)

我也遇到了处理CDC en / disabling的坏方法。如果我是你,我会尝试删除cdc架构和架构本身的所有内容,并尝试再次在数据库中启用CDC。或者,如果您正在恢复(而不是附加),则有一个KEEP_CDC选项。