描述:目前有两台主机A和B。在主机A上创建了数据库DB(记为A.DB),并开启了CDC。现将A.DB拷贝至主机B上,搭建为数据库B.DB,并开启了SQL代理。(数据库均为SQL Server 2008r2)
现针对B.DB执行如下SQL:
EXEC sys.sp_changedbowner 'sa'; -- 改变用户权限 exec sys.sp_cdc_enable_db; -- 开启数据库 CDC。如果报错,则需要改变用户权限
则出现如下报错:
消息 22906,级别 16,状态 1,过程 sp_cdc_enable_db_internal,第 49 行 因为当前数据库中已存在名为 'cdc' 的数据库用户或名为 'cdc' 的架构,所以无法为变更数据捕获启用数据库 'DB'。变更数据捕获需要独占使用这些对象。请删除或重命名该用户或架构,然后重试相应操作。
而实际上B.DB并未开启CDC。按照提示删除数据库下的cdc架构(删除cdc角色时提示需要先删除架构)
则会出现如下报错:
详细信息如下:
无法对 'cdc' 执行 drop schema,因为对象 'fn_cdc_get_all_changes_ ... ' 正引用它。 (.Net SqlClient Data Provider) ------------------------------ 有关帮助信息,请单击: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500&EvtSrc=MSSQLServer&EvtID=3729&LinkId=20476 ------------------------------ 服务器名称: (local) 错误号: 3729 严重性: 16 状态: 1 行号: 2 ------------------------------ 程序位置: 在 Microsoft.SqlServer.Management.Common.ConnectionManager.ExecuteTSql(ExecuteTSqlAction action, Object execObject, DataSet fillDataSet, Boolean catchException) 在 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
本人依据相关线索,在网上搜到如下SQL以查询与架构相关的对象:
use DB go select obj.type, obj.name from sys.objects obj join sys.schemas s on(s.schema_id = obj.schema_id) where s.name = 'cdc' go
得到部分查询结果如下:
于是想尝试删除sys.objects表中的相关记录:
delete from sys.objects where name = 'fn_cdc_get_all_changes_...' go
又出现如下报错信息:
消息 259,级别 16,状态 1,第 1 行 不允许对系统目录进行即席更新。
(注:以上SQL操作均位于B.DB)
本人最终目的是想开启B.DB的CDC,忘高手解惑。不胜感激~
你是怎么拷贝的呢?
在主机A停止SQL server 的服务,然后将A.DB的数据库文件 A.DB.ldf 及 A.DB.mdf 拷贝至主机B。然后利用主机B的 SQL Server Management Studio 附加数据库A.DB为B.DB。
@之由: 附加这种方式,带上了原本数据库的很多信息。考虑下使用备份为bak的方式拷贝呢。
@幻天芒: 我附加数据库用的是如下SQL
CREATE DATABASE [DB] ON (FILENAME = 'D:\A.DB.mdf'), (FILENAME = 'D:\A.DB.LDF') FOR ATTACH;
这样就会和你说的一样,附加原数据库的很多信息。我先按照你说的试试,虽然还没用过备份为bak的方式。
@幻天芒: 我以备份类型为【完整】的方式进行备份,然后再还原数据库,情况依旧,发现和附加数据库似乎没什么区别。cdc架构依然存在,如果手动去删除它,会出现和问题描述中同样情况。
@之由: 在完整备份的设置中,去掉备份数据库架构之类的试试吧。只需要表结构和数据。
@之由: 实在不行,还可以先关了cdc,复制到新库之后在启用。
@幻天芒: 好,我再试试。
@幻天芒: 你好,我在备份数据库窗口中,似乎并未找到可以去掉备份数据库架构的选项。
@之由: 用数据库导出工具。可以导出一个带数据的sql文件。
@幻天芒: 但是这样导出的sql文件会异常庞大,DB备份的.bak文件就有1.5GB
@幻天芒: 或者对于
消息 259,级别 16,状态 1,第 1 行 不允许对系统目录进行即席更新。
这种情况,有没有办法可以做到即席更新,比如对 sys.databases 表。
@之由: 新建一个DB库,然后直接两个库直接导入导出数据。
对于消息259这种情况,我没遇到过,不知道如何处理。
@幻天芒: 虽然没能直接解决问题(开启B.DB的CDC),但通过VS的数据/架构比较复制了去除CDC后同样的数据库(表、函数、存储过程等),只是数据需要另外导入。感谢你提供思路。
@之由: 搞定就好,这个功能应该不常用,网上都没啥资料。
@幻天芒: 是的,搜国外的也搜不到,唯一搜到相关的就是07年MSDN有人所问删除架构的问题。
使用drop function和drop procedure删除相关对象
drop function cdc.[fn_cdc_get_all_changes_ ... ]
drop function cdc.[fn_cdc_get_net_changes_ ... ]
drop procedure cdc.sp_ins_lsn_time_mapping