Как активировать отслеживание измененных данных (CDC) для вновь добавленных столбцов базовой таблицы, не отключая CDC

У меня есть требование, когда я хочу включить CDC для новых добавленных столбцов таблицы, но я не могу отключить CDC и снова включить его. Есть ли способ добиться этого?

Я нашел решение, в котором я могу скопировать старые значения таблицы CDC во временную таблицу, затем отключить CDC, а затем включить CDC с новой схемой таблицы. Позднее копирование значений временной таблицы в новую таблицу CDC и обновление значения LSN.

Вместо вышеперечисленного мне нужно решение, в котором я могу включить новый столбец в таблицу CDC, когда CDC включен.


person Mohan    schedule 26.07.2016    source источник
comment
comment
@ M.Hassan Я ни в коем случае не хочу отключать CDC при добавлении нового столбца.   -  person Mohan    schedule 26.07.2016


Ответы (2)


CDC поддерживает два экземпляра таблиц захвата. Итак, вы можете сделать следующие шаги:

  1. Добавить новый столбец
  2. Добавить новый экземпляр cdc-capture
  3. Переместить данные из старой таблицы в новую
  4. Отключить старый экземпляр CDC

Это решение не позволит вам прекратить сбор изменений, и вы не потеряете данные.

EXEC sp_cdc_enable_table
    @source_schema = N'common',
    @source_name = N'EntityTypes',
    @role_name = NULL,
    @filegroup_name = N'CDC',
    @capture_instance = 'common_EntityTypes'


ALTER TABLE common.EntityTypes
    ADD TestColumn int

EXEC sp_cdc_enable_table
    @source_schema = N'common',
    @source_name = N'EntityTypes',
    @role_name = NULL,
    @filegroup_name = N'CDC',
    @capture_instance = 'common_EntityTypes2'

INSERT INTO cdc.common_EntityTypes2_CT
(__$start_lsn, __$end_lsn,__$seqval,__$operation,__$update_mask,Id,Name)
SELECT
    __$start_lsn, 
    __$end_lsn,
    __$seqval,
    __$operation,
    __$update_mask,
    Id,
    Name
FROM cdc.common_EntityTypes_CT

EXEC sp_cdc_disable_table
    @source_schema = N'common',
    @source_name = N'EntityTypes',
    @capture_instance = 'common_EntityTypes'
person Backs    schedule 26.07.2016
comment
но когда я выполнил операцию DDL для вновь добавленного столбца, изменения TestColumn не фиксируются во вновь созданном экземпляре cdc.common_EntityTypes2_CT - person Mohan; 26.07.2016
comment
Переместить данные из старой таблицы в новую. Было бы точнее сказать, что нужно переместить процесс ETL для использования нового экземпляра CDC? То есть вы можете соединить два экземпляра, используя минимальный номер LSN для второго экземпляра в качестве конечной точки для первого экземпляра захвата. После того, как вы обработали все записи до этой конечной точки включительно из первой, вы переключаете свой ETL на использование второй и продолжаете обработку оттуда. Лично мне нравится использовать абстракцию (то есть синонимы или представление), чтобы скрыть тот факт, что я переключаю экземпляры CDC. - person Ben Thul; 26.07.2016
comment
@Mohan, вы должны создать новый экземпляр cdc после добавления нового столбца - person Backs; 26.07.2016
comment
@BenThul да, это одно из возможных решений. В нашем проекте мы используем представление, но я не знаю всех требований в этом случае. - person Backs; 27.07.2016
comment
Я знаю, что речь идет о добавлении новых столбцов, но следует быть осторожным и с удалением столбцов, потому что они могут повлиять на точное вычисление того, какие столбцы изменились на основе исторических масок. Очень легко забыть, что один столбец иногда удалялся в прошлом перед добавлением нового. Как только вы отключите и снова включите cdc, ваши исторические маски испортятся, потому что они отражают структуры, которые действовали в то время. Решением будет сохранение списков столбцов вместе с каждой вставкой/обновлением. Или как-то сделать снимок структуры таблицы где-нибудь и сослаться на это. - person costa; 24.07.2020

Приведенное выше решение хорошо работает, когда у вас есть один экземпляр в целевой таблице, но если у вас уже есть два экземпляра, вам, возможно, придется подумать немного дальше и использовать некоторое планирование.

Вопрос потери данных актуален, но вы можете рассмотреть этот вопрос при первоначальной разработке процесса CDC, один из очень важных моментов: какова конечная точка для данных? Например, если вы используете решение BI, возможно, используя хранилище, или простую базу данных OLAP, такую ​​как витрина данных, для решения по отчетности, вы можете рассмотреть возможность введения окон обслуживания или использования текущего окна обслуживания. Процесс прост и мало чем отличается от ответа Бэкса:

  1. Передайте все текущие данные _CT в конечную точку.

  2. Отключить текущий экземпляр в таблице (sp_cdc_disable_table)

  3. Снова включите экземпляр с обновленным списком столбцов (sp_cdc_enable_table).

Это позволяет вносить изменения, даже если два экземпляра уже нацелены на одну и ту же таблицу, без потери клиентских данных.

Примечание: использование параметра списка столбцов не столько обязательно (если вы хотите захватить все столбцы), но может быть предпочтительнее для согласованности, когда другим разработчикам может потребоваться просмотреть код. Однако так же легко получить эти данные через системные таблицы cdc.X.

person LogicalMan    schedule 16.09.2016