Filas de clave duplicadas de la tabla sys.syscommittab en SQL Server
Artículo
En este artículo se proporciona información sobre cómo resolver un problema de Seguimiento de cambios de SQL Server que puede dar lugar a filas duplicadas en sys.syscommittab el archivo.
Versión original del producto: SQL Server 2008 y las versiones posteriores Número de KB original: 3083381
Síntomas
Al comparar el archivo en memoria SYSCOMMITTABLE y el archivo en disco sys.syscommittab en Microsoft SQL Server, es posible que vea filas de clave duplicadas. Estos valores duplicados pueden provocar un error en las operaciones de copia de seguridad y punto de comprobación.
"No se puede insertar una fila de clave duplicada en el objeto "sys.syscommittab" con el índice único "si_xdes_id". El valor de clave duplicado es (KeyValue).
Error: 3999, Gravedad: 17, Estado: 1.
No se pudo vaciar la tabla de confirmación en el disco en dbidDatabaseID debido al error 2601. Compruebe el registro de errores para obtener más información".
Causa
Este problema se produce debido a un problema conocido en el seguimiento de cambios de SQL Server.
Resolución de factores que provocan las claves duplicadas
Para resolver los factores que provocan las claves duplicadas, aplique una de las siguientes correcciones, según corresponda para su situación:
Aunque estas correcciones impiden que las filas de clave duplicadas sigan apareciendo, no quitan automáticamente las filas duplicadas. Sin quitar las filas duplicadas, la base de datos afectada no puede completar los puntos de comprobación de la base de datos y es posible que se produzca un error en las copias de seguridad.
Deshabilitar y habilitar el seguimiento de cambios para quitar filas duplicadas
Deshabilite el seguimiento de cambios en las tablas y bases de datos afectadas.
Emita un punto de control de base de datos manual.
Habilite el seguimiento de cambios en la base de datos y tablas afectadas.
Copie el script de Transact-SQL de la sección script de Transact-SQL en un editor de texto.
Busque el <AFFECTED_DB> marcador de posición en el script y reemplácelo por el nombre de la base de datos afectada.
Guarde el script modificado en el disco duro como un archivo .sql. Por ejemplo, C:\temp\remove_duplicates.sql.
Si usa SQL Server 2014 y versiones posteriores, debe conceder el control total del SID por servicio a los mssqlsystemresource.ldf archivos y mssqlsystemresource.mdf . Para ello, siga estos pasos:
Vaya al directorio Bin que corresponde al identificador de instancia. Por ejemplo: C:\Program Files\Microsoft SQL Server\<Instance ID>\MSSQL\Binn
Abra las propiedades de mssqlsystemresource.ldf y y mssqlsystemresource.mdf, a continuación, seleccione la pestaña Seguridad .
Busque el SID de servicio por servicio de SQL Server y anote los permisos predeterminados:
*Read & execute
*Read
Conceda el servicio SQL Server por sid de servicio control total y, a continuación, cierre los cuadros de diálogo de permisos.
Inicie SQL Server en modo de usuario único. Para obtener más información, vea Iniciar SQL Server en modo de usuario único.
Nota
Cuando SQL Server se inicia en modo de usuario único, omite el proceso de inicio de las bases de datos que forman parte de un grupo de disponibilidad AlwaysOn (AG). Si necesita solucionar un problema con el seguimiento de cambios que requiere iniciar SQL Server en modo de usuario único y la base de datos con el seguimiento de cambios habilitado también forma parte de un grupo de disponibilidad, debe quitar la base de datos del grupo de disponibilidad antes de iniciar SQL Server en modo de usuario único para que la base de datos se conecte.
Use una sqlcmd línea de comandos para conectarse a SQL Server en la conexión de administrador dedicada (DAC) y ejecute el script transact-SQL modificado. Por ejemplo:
Consola
sqlcmd -S PRODSERV1\MSSQLSERVER -A -E -i c:\temp\remove_duplicates.sql
Reinicie SQL Server en modo multiusuario y compruebe que las operaciones de copia de seguridad y CHECKPOINT en la base de datos afectada se completen correctamente. Si se usó el paso 4, revierta los permisos a los valores predeterminados.
Script de Transact-SQL
SQL
--Create a temporary database to store the necessary rows required to remove the duplicate data USEmasterGOIFEXISTS(SELECT1FROM sys.databases WHEREname = 'dbChangeTrackingMetadata')
BEGINDROPDATABASE dbChangeTrackingMetadata
ENDGOCREATEDATABASE dbChangeTrackingMetadata
GO--Table to store the contents of the SYSCOMMITTABLEUSE dbChangeTrackingMetadata
GOCREATETABLE dbo.t_SYSCOMMITTABLE (
commit_ts BIGINT
,xdes_id BIGINT
,commit_lbn BIGINT
,commit_csn BIGINT
,commit_time DATETIME
)
GO--Table to store the duplicate rows to be removed from the sys.syscommittab tableCREATETABLE dbo.t_syscommittab (
commit_ts BIGINT
,xdes_id BIGINT
,commit_lbn BIGINT
,commit_csn BIGINT
,commit_time DATETIME
,dbfragid INT
)
GO--Enable the usage of OPENROWSET
EXEC sys.sp_setbuildresource 1GO--Change <AFFECTED_DB> to the database that contains the duplicate valuesUSE <AFFECTED DB>
GODECLARE @rowcount BIGINTSET @rowcount = 0--Copy all rows from the SYSCOMMITTABLE INTo the temporary databaseINSERTINTO dbChangeTrackingMetadata.dbo.t_SYSCOMMITTABLE
SELECT commit_ts, xdes_id, commit_lbn, commit_csn, commit_time
FROM OPENROWSET (table SYSCOMMITTABLE, db_id (), 0, 0)
--Save the duplicate values INTo the temporary databaseINSERTINTO dbChangeTrackingMetadata.dbo.t_syscommittab
SELECT ondisk_ct.*
FROM sys.syscommittab as ondisk_ct
JOIN dbChangeTrackingMetadata.dbo.t_SYSCOMMITTABLE as inmem_ct
ON ondisk_ct.xdes_id = inmem_ct.xdes_id
--Delete the duplicate valuesDELETEFROM sys.syscommittab
WHERE xdes_id in ( SELECT xdes_id from dbChangeTrackingMetadata.dbo.t_syscommittab )
SET @rowcount = @@rowcount
IF (@rowcount > 0)
BEGIN
PRINT ''
PRINT 'DELETED '+CAST(@rowcount asNVARCHAR(10))+' rows from sys.syscommittab that were also stored in SYSCOMMITTABLE'
PRINT ''ENDELSEBEGIN
PRINT ''
PRINT 'Failed to DELETE DUP rows from sys.syscommittab'
PRINT ''END
EXEC sys.sp_setbuildresource 0GO
Módulo de seguimiento de datos Azure SQL que cubre el seguimiento de los cambios de datos. El módulo explora herramientas como la captura de datos de cambios (CDC) y el seguimiento de cambios.