適用於:SQL Server
Azure SQL 受控執行個體
本文說明 SQL Server 和 Azure SQL 托管實例的更改資料擷取已知限制、問題和錯誤。
對於 Azure SQL 資料庫,請參閱 Azure SQL 資料庫中的 CDC 的已知問題。
修改中繼資料
若要讓 CDC 正常運作,您不應該手動修改任何 CDC 元數據,例如 CDC schema、變更數據表、CDC 系統預存程式、預設 cdc user 許可權(sys.database_principals)或重新命名 cdc user。
不得修改 sys.objects 中 is_ms_shipped 屬性設為 1 的任何物件。
SELECT name AS object_name
,SCHEMA_NAME(schema_id) AS schema_name
,type_desc
,is_ms_shipped
FROM sys.objects
WHERE is_ms_shipped= 1 AND SCHEMA_NAME(schema_id) = 'cdc'
排序差異
務必要注意,當資料庫與設定為變更資料擷取的資料表欄位之間存在不同定序時的情況。 CDC 會使用臨時存儲來填充側邊資料表。 如果資料表中的 char 或 varchar 欄位的定序與資料庫的定序不同,且這些欄位儲存非 ASCII 字元(例如雙位元組 DBCS 字元),則 CDC 可能無法將變更的資料與基表中的資料一致地持續保留。 原因是臨時存儲變數不能具有相關的定序。
請考慮下列其中一種方法來確保已擷取的異動資料與基底資料表一致:
針對包含非 ASCII 資料的數據行,請使用 nchar 或 nvarchar 資料類型。
或者,對於資料行和資料庫使用相同的定序。
例如,如果您有一個使用 SQL_Latin1_General_CP1_CI_AS 定序的資料庫,請考慮使用下表:
CREATE TABLE T1(
C1 INT PRIMARY KEY,
C2 VARCHAR(10) collate Chinese_PRC_CI_AI)
CDC 可能無法擷取資料行 C2 的二進位資料,因為其定序不同 (Chinese_PRC_CI_AI)。 使用 nvarchar 來避免此問題:
CREATE TABLE T1(
C1 INT PRIMARY KEY,
C2 NVARCHAR(10) collate Chinese_PRC_CI_AI --Unicode data type, CDC works well with this data type
)
加速資料庫復原 (ADR) 和異動資料擷取 (CDC)
SQL Server 2019 (15.x) 不支援為相同資料庫啟用異動數據擷取 (CDC) 和加速資料庫復原 (ADR)。 從 SQL Server 2022 (16.x) 累積更新 18 開始,在更新版本的 SQL Server 版本中支援啟用 CDC 和 ADR。
當您啟用 CDC 時,ADR 的積極日誌截斷功能將會被停用。 這是因為 CDC 掃描會存取資料庫交易記錄。 使用中的交易將繼續保留交易日誌的截斷,直到交易認可且 CDC 掃描趕上,或交易中止。 如果您在已啟用 ADR 的資料庫上啟用 CDC,您可能會觀察到較高的事務歷史記錄使用率。 請確定有足夠的事務歷史記錄空間可供您所有工作負載的需求使用。
如果結構描述或名為 cdc 的使用者已存在,則啟用 CDC 會失敗
當您在資料庫上啟用 CDC 時,它會建立一個名為 cdc 的新結構描述和使用者。 因此,不建議手動建立名為 cdc 的自定義架構或使用者,因為它保留供系統使用。
如果您已手動在資料庫中定義與 CDC 無關的自定義架構或名為 cdc 的使用者,系統預存程式 sys.sp_cdc_enable_db 將無法在資料庫上啟用 CDC,並出現下列錯誤訊息。
The database <database_name> cannot be enabled for change data capture because a database user named 'cdc' or a schema named 'cdc' already exists in the current database. These objects are required exclusively by CDC. Drop or rename the user or schema and retry the operation.
若要解決此問題:
- 手動移除空的
cdc結構描述和cdc使用者。 然後,就可以在資料庫上成功啟用 CDC。
在執行 ALTER COLUMN 之後,CDC 發生失敗。
當已啟用 CDC 的資料表上資料行的資料類型變更為不支援的轉換時,CDC 掃描可能會在更新後導致錯誤。
以下是在資料表上啟用 CDC 時不支援的資料類型變更範例 ALTER COLUMN :
- bigint 轉換為 int
- char(x)、 nvarchar(x) 或 nvarchar(x) 轉換為 uniqueidentifier、 DATE 或 INT
變更已啟用 CDC 的資料表中資料行的資料類型可能會導致下列錯誤:
使用 DDL 陳述式變更已啟用 CDC 的資料表資料行大小可能會造成後續 CDC 擷取程序出現問題,並導致下列錯誤:
請記住,CDC 變更資料表中的資料會根據使用者設定的設定保留。 因此,在對資料行大小進行任何變更之前,您必須評定變更是否與 CDC 變更資料表中的現有資料相容。
如果 sys.dm_cdc_errors 表示掃描因 錯誤 2628 或 錯誤 8115 而失敗,您應該先取用受影響變更資料表中的變更數據。 之後,您需要停用再重新啟用資料表上的 CDC,以有效地解決問題。
當 CREATE OBJECT 觸發程式存在時,啟用 CDC 會失敗
當您啟用 CDC 時,會建立 cdc user 來管理 CDC 創建過程。
cdc user 會執行數個預存程式來啟用 CDC,而其中一些預存程式會建立會引發現有 CREATE OBJECT 觸發程序的物件。 由於 cdc user 沒有寫入 master 資料庫的許可權,因此這些 CDC 預存程式失敗,錯誤 22830。
在資料庫上啟用 CDC 之前,請先禁用任何 CREATE OBJECT 觸發器。 設定 CDC 之後,可重新啟用這些觸發程式。
使用資料層匯入/匯出和擷取/發佈作業匯入資料庫
在已啟用 CDC 的 SQL 資料庫上,當您使用 SqlPackage、SSDT 或其他 SQL 工具來匯入/匯出或擷取/發佈時,cdc 結構描述和使用者會在新的資料庫中遭到排除。 「匯入/匯出」和「擷取/部署」作業中未包含的其他 CDC 物件包括標示為 is_ms_shipped=1sys.objects中的表格。
即使未啟用 CDC,而且您已在資料庫中定義名為 cdc 的自訂結構描述或使用者,也會在匯入/設定新資料庫的匯入/匯出和擷取/部署作業中排除該結構描述或使用者。
使用變數進行資料分割切換
針對 ALTER TABLE ... SWITCH TO ... PARTITION ... 陳述式,不支援在具有異動資料擷取 (CDC) 的資料庫或資料表上使用變數進行資料分割切換。 請參閱分割區切換限制以深入了解。
線上操作
不支援線上 DDL 語句
在 Azure SQL Managed Instance 及 SQL Server 2025(17.x)之前的版本中,當資料庫啟用變更資料擷取時, ALTER TABLE 線上 DDL 語句 不被支援。
不支援線上索引作業
在資料庫上啟用變更資料擷取時,不支援線上索引作業。 您可能會遇到錯誤 18773,「在命令建構期間找不到資料行 “%.*ls”、ID %d 的文字資訊記錄。
新增資料行的預設約束
在資料表上啟用 CDC 並新增具有預設條件約束的不可為 Null 資料行時,現有資料列資料將具有預設條件約束的值。 不過,CDC 會在NULL資料列中使用,而不是使用預設值。 這僅適用於套用 DDL 之前存在的資料。 因應措施是對現有資料列發出不更改UPDATE的陳述式,或者對資料表的叢集索引執行ALTER INDEX ... REBUILD。 如果沒有叢集索引存在,則在資料堆上使用 ALTER TABLE ... REBUILD 。
故障排除
本節會逐步針對與 SQL Server 上的 CDC 和 Azure SQL 受控執行個體關聯的錯誤進行疑難排解。 CDC 相關錯誤可能會阻礙擷取程式正常運作,並導致資料庫事務歷史記錄的擴充。
若要檢查這些錯誤,您可以查詢動態管理檢視 sys.dm_cdc_errors。 如果動態管理檢視傳回任何錯誤 sys.dm_cdc_errors 請檢閱下列疑難排解資訊。
注意
如需有關特定錯誤碼的詳細資訊,請參閱資料庫引擎事件和錯誤。
以下是本節中包含的不同疑難排解類別:
| 類別 | 描述 |
|---|---|
| 已修改的中繼資料 | 包含有關如何在追蹤資料表被修改或刪除時緩解與 CDC 相關問題的資訊。 |
| 資料庫空間管理 | 包括有關在資料庫空間用盡時如何緩解問題的資訊。 |
| CDC 限制 | 包含有關如何緩解 CDC 限制所造成問題的資訊。 |
中繼資料已修改
錯誤 200/208 – 無效的物件名稱
原因:丟失 CDC 中繼資料時,可能會發生錯誤。 若要讓 CDC 正常運作,您不應該手動修改任何 CDC 元數據,例如
CDC schema、變更數據表、CDC 系統預存程式、預設cdc user許可權(sys.database_principals)或重新命名cdc user。建議:若要解決此問題,您需要為資料庫停用並重新啟用 CDC。 在為資料庫啟用異動資料擷取時,也會為資料庫建立 cdc 結構描述、cdc 使用者、中繼資料表及其他系統物件。
注意
在 sys.objects 系統型錄視圖 is_ms_shipped=1 and schema_name='cdc' 中找到的物件不應變更或捨棄。
錯誤 1202 - 資料庫主體不存在,或者使用者不是成員
原因:當
cdc user被棄用時,可能會發生錯誤。 若要讓 CDC 正常運作,您不應該手動修改任何 CDC 中繼資料,例如CDC schema、變更資料表、CDC 系統預存程序、預設cdc user許可權,或將 .cdc user建議:請確保
cdc使用者存在於您的資料庫中,並已指派db_owner角色。 若要建立cdc使用者,請參閱建立 cdc 使用者和指派角色範例。
錯誤 15517 - 無法以資料庫主體的形式執行,因為主體不存在
原因:可能因為無法冒充這種類型的主體,或您沒有權限。 CDC 中繼資料已刪除或不再是
db_owner角色的一部分時,可能會發生錯誤。 若要讓 CDC 正常運作,您不應該手動修改任何 CDC 中繼資料,例如CDC schema、變更資料表、CDC 系統預存程序、預設cdc user許可權,或將 .cdc user建議:請確保
cdc使用者存在於您的資料庫中,並已指派db_owner角色。 若要建立cdc使用者,請參閱建立 cdc 使用者和指派角色範例。
錯誤 18807 – 找不到複寫系統資料表的物件識別碼
原因:在 SQL Server 找不到或存取複寫系統資料表 '%s' 時,會發生此錯誤。 這可能是因為資料表遺失或無法連線。 若要讓 CDC 正常運作,您不應該手動修改任何 CDC 中繼資料,例如
CDC schema、變更資料表、CDC 系統預存程序、預設cdc user許可權,或將 .cdc user建議:請確認該系統資料表已存在,而且可直接透過查詢資料表存取。 查詢 sys.objects 系統目錄,設定述詞子句
is_ms_shipped=1 and schema_name='cdc'with 以列出所有與 CDC 相關的物件。 如果查詢未傳回任何物件,則您應停用並重新啟用資料庫的 CDC。 為資料庫啟用異動資料擷取會針對資料庫建立 cdc 結構描述、cdc 使用者、中繼資料表及其他系統物件。
錯誤 21050 – 只有 sysadmin 或 db_owner 固定伺服器角色的成員才能執行此作業
原因:
cdc user已從db_owner資料庫角色或sysadmin伺服器角色中移除。建議:確認
cdc user已被指派為db_owner角色。 若要建立cdc使用者,請參閱建立 cdc 使用者和指派角色範例。
錯誤 22830 - 無法更新指出資料庫 <database name> 已啟用異動數據擷取的元數據。 執行 命令 <CDC stored procedure name>時發生失敗。
原因:當觸發程式存在於資料庫或伺服器上時
CREATE OBJECT,會發生此錯誤。 當您啟用 CDC 時,會建立cdc user來管理 CDC 創建過程。cdc user會執行數個預存程式來啟用 CDC,而其中一些預存程式會建立會引發現有CREATE OBJECT觸發程序的物件。 由於cdc user沒有寫入master資料庫的許可權,因此這些 CDC 預存程式失敗,錯誤 22830。建議:在資料庫上啟用 CDC 之前,請停用任何
CREATE OBJECT觸發程式。 設定 CDC 之後,請重新啟用這些觸發程式。
資料庫空間管理
錯誤 1105 – 檔案群組已滿,無法在資料庫中為物件配置空間
原因:在資料庫的主要檔案群組空間不足,且 SQL Server 無法為該檔案群組內的物件 (例如資料表或索引) 配置更多空間時,會發生此錯誤。
建議:若要解決此問題,請刪除資料庫內任何不必要的資料以釋放空間。 識別可以安全地移除的檔案群組中未使用的資料表、索引或其他物件。 密切監視空間利用率,如需詳細資訊,請參閱管理 Azure SQL 資料庫中的資料庫檔案空間
如果無法卸除不必要的資料/物件,則請考慮為資料庫交易記錄配置更多空間。 如需有關交易記錄管理的詳細資訊,請參閱 SQL Server 交易記錄架構和管理指南
CDC 限制
錯誤 241 - 從字元字串轉換日期和時間時轉換失敗
原因:當對日期資料類型執行 ALTER COLUMN 且資料表已啟用 CDC 時,會發生此錯誤。 例如,如果資料表有 nvarchar 資料行,而您將資料類型變更為 date (例如
ALTER TABLE table_name ALTER COLUMN [column_name] DATE NULL),您可能會在 sys.dm_cdc_errors DMV 中看到此錯誤。 錯誤 241 是由於變更資料表中不支援的資料轉換,即使來源資料表上的命令成功也一樣ALTER。建議:若要解決此問題,請在變更數據行之後,停用並重新啟用數據表的 CDC。 或者,在變更資料行之前停用 CDC,然後在變更之後
ALTER COLUMN重新啟用 CDC。
錯誤 245 - 將值從字串轉換為 int 時轉換失敗
原因:當數據表已啟用 CDC 時, 發出 ALTER COLUMN 命令以變更數據行的數據類型時,就會發生此錯誤。 例如,如果資料表有 nvarchar 資料行,而您將資料類型變更為 int (例如
ALTER TABLE table_name ALTER COLUMN [column_name] INT NULL),您可能會在 sys.dm_cdc_errors DMV 中看到此錯誤。 錯誤 245 是由於變更資料表中不支援的資料轉換,即使來源資料表上的命令成功也一樣ALTER。建議:若要解決此問題,請在變更數據行之後,停用並重新啟用數據表的 CDC。 或者,在變更資料行之前停用 CDC,然後在變更之後
ALTER COLUMN重新啟用 CDC。
錯誤 913 - 處理具有系統 CLR 資料類型的資料表變更時,CDC 擷取作業會失敗
原因:在具有系統 CLR 資料類型的資料表上啟用 CDC、進行 DML 變更,然後在 CDC 擷取作業處理與其他資料表相關的變更時,會在相同的資料表上進行 DDL 變更時發生此錯誤。
建議:建議的步驟是停止對資料表的 DML,執行擷取作業來處理變更,為資料表執行 DDL,執行擷取作業來處理 DDL 變更,然後重新啟用 DML 處理。 如需詳細資訊,請參閱 處理具有系統 CLR 資料類型 (幾何、地理或階層) 的資料表變更時,CDC 擷取工作會失敗。
錯誤 2628 – 字串或二進位資料在資料表中會被截斷
原因:使用 DDL 陳述式變更啟用 CDC 的資料表的資料行大小可能會導致後續 CDC 擷取程序發生問題。 sys.dm_cdc_errors動態管理檢視(DMV)是檢查任何疾病管制中心(CDC)是否有報告問題(如錯誤編號2628和8115)非常有用的。
建議:在對資料行大小進行任何變更之前,您必須評定變更是否與 CDC 變更資料表中的現有資料相容。 若要解決此問題,您需要為資料庫停用並重新啟用 CDC。 如需為資料庫或資料表啟用 CDC 的詳細資訊,請參閱 為資料庫啟用 CDC 和 為資料表啟用 CDC。
錯誤 8115 - 算術溢位錯誤,將數據類型從 bigint 轉換成 int
原因:當啟用 CDC 的數據表上執行 ALTER COLUMN DDL 時,就會發生此錯誤,導致數據行的有效位數降低(例如將數據行的數據類型從 bigint 變更為 int)。 減少精度的欄位無法容納變更表中的值。
建議:若要解決此問題,請在變更數據行之後,停用並重新啟用數據表的 CDC。 或者,在執行
ALTER COLUMN命令之前停用 CDC,然後在進行ALTER COLUMN變更之後重新啟用 CDC。
錯誤 8169 - 從字串轉換為 uniqueidentifier 時轉換失敗
原因: 當表格已啟用 CDC 時,發出 ALTER COLUMN 指令以變更直欄的資料類型時,會發生此錯誤。 例如,如果資料表具有 char(x)、 nvarchar(x)、 nvarchar(x) 資料行,而且您將資料類型變更為 uniqueidentifier (例如:
ALTER TABLE table_name ALTER COLUMN [column_name] uniqueidentifier),您可能會在 sys.dm_cdc_errors 動態管理檢視 (DMV) 中看到此錯誤。 錯誤 8169 表示變更資料表中不支援的資料轉換,即使來源資料表上的 ALTER 命令成功也一樣。建議:若要解決此問題,請在變更數據行之後,停用並重新啟用數據表的 CDC。 或者,在執行
ALTER COLUMN命令之前停用 CDC,然後在進行ALTER COLUMN變更之後重新啟用 CDC。
建立使用者和指派角色
如果已移除 cdc user,您可以手動新增回此使用者。
使用下列 T-SQL 腳本來建立使用者 (cdc) ,並為相同 (db_owner) 指派適當的角色。
IF NOT EXISTS
(
SELECT *
FROM sys.database_principals
WHERE NAME = 'cdc'
)
BEGIN
CREATE USER [cdc]
WITHOUT LOGIN WITH DEFAULT_SCHEMA = [cdc];
END
EXEC sp_addrolemember 'db_owner', 'cdc';
檢查並新增角色成員資格
若要確認 cdc 使用者是否屬於 sysadmin 或 db_owner 角色,請執行下列 T-SQL 查詢:
EXECUTE AS USER = 'cdc';
SELECT is_srvrolemember('sysadmin'), is_member('db_owner');
如果 cdc 使用者不屬於任一角色,請執行下列 T-SQL 查詢,以將 db_owner 角色新增至 cdc 使用者。
EXEC sp_addrolemember 'db_owner' , 'cdc';