Задание очистки Change Data Capture (CDC) удаляет только несколько записей за раз

Я новичок в SQL Server. Для проекта мне нужно, чтобы CDC был включен. Копирую данные cdc в другую (архивную) базу и после этого таблицы CDC можно сразу чистить. Таким образом, время хранения не должно быть высоким, я просто поставил его на 1 минуту, и когда задание очистки запускается (после того, как время хранения уже выполнено), кажется, что оно удалило только несколько записей (самые старые). Почему не удалил все? Иногда вообще ничего не удаляет. После запуска задания несколько раз другие записи удаляются. Я нахожу это странным, потому что время хранения давно прошло.

Я установил время удержания на 1 минуту (на самом деле я хотел 0, но это было невозможно) и не изменил порог (= 5000). Я отключил расписание, так как хочу, чтобы задание очистки запускалось сразу после того, как записи CDC будут скопированы в мою архивную базу данных, а не в определенное время.

Моя логика для этой идеи заключалась в том, что, например, днем ​​будут обновления. Задача по копированию записей CDC в архивную базу данных должна запускаться в 2:00, после этого задачи вызывается задание очистки. Таким образом, из-за минимального времени хранения все записи CDC должны быть удалены заданием очистки. Время удержания все-таки прошло?

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

Я сделал обходной путь, создав новое задание с задачей удалить все записи в таблицах CDC (и отключив все задание очистки CDC по умолчанию). Это работает лучше, так как удаляет все, но меня это беспокоит, потому что я хочу работать с исходным заданием очистки, и я думаю, что оно должно работать так, как я хочу.

Спасибо,

Ким


person Kim    schedule 13.08.2014    source источник
comment
Типичный рабочий процесс CDC — это обработка любых данных CDC, которые я не обрабатывал ранее, что влечет за собой отслеживание последнего LSN, который вы обработали для каждой таблицы. Вы также должны установить срок хранения, значительно превышающий частоту обработки (т. Е. Если вы обрабатываете один раз в день, вы должны установить срок хранения 3 дня или что-то в этом роде), чтобы, если что-то пойдет не так, у вас было время отреагировать до того, как данные будут очищены. И тогда вы просто позволяете системе позаботиться об этом. Тем не менее, я не удивлен странным поведением на пределе 1 минуты. Что произойдет, если вы установите его на что-то вроде 1 часа и запланируете его?   -  person Ben Thul    schedule 13.08.2014
comment
Спасибо! Я установил время хранения на 1 час и запланировал его. Я изменил 2 записи и через несколько минут еще одну запись. Когда подходило расписание + время хранения, я увидел, что удалена только 1 запись из 2, которые я изменил сначала. Я снова установил другое расписание, а затем он удалил 2-ю запись из этих 2. Осталась еще одна запись. Таким образом, он по-прежнему удалял одну запись за раз. Это должно быть даже дольше, чем один час? Дело в том, что я хочу удалить записи CDC в ту же ночь. Например, задача SSIS должна скопировать все записи примерно в полночь, и до следующего утра я хочу очистить их.   -  person Kim    schedule 14.08.2014
comment
P.S. Можете ли вы объяснить (может быть, небольшой пример), что вы имеете в виду в своем первом предложении. Я не уверен, правильно ли я это понял. Типичный рабочий процесс CDC — это обработка любых данных CDC, которые я не обрабатывал ранее, что влечет за собой отслеживание последнего LSN, который вы обработали для каждой таблицы.   -  person Kim    schedule 14.08.2014
comment
Вы не должны обращаться к таблицам захвата напрямую, а должны получать данные CDC через функции, созданные при настройке cdc. В частности, cdc.fn_cdc_get_all_changes_‹capture_instance› или cdc.fn_cdc_get_net_changes_‹capture_instance›. Управляя диапазонами LSN, которые вы обрабатываете при каждом запуске, вы можете быть уверены, что каждая строка обрабатывается один и только один раз. С вашей текущей схемой вы рискуете пропустить некоторые из них (если изменения произойдут между запуском ETL и удалением данных CDC). Когда вы используете функции, вам не нужно беспокоиться о том, что и когда удаляется.   -  person Ben Thul    schedule 14.08.2014


Ответы (1)


Вместо того, чтобы беспокоиться о том, что находится в таблице, я бы использовал вспомогательные функции, созданные для каждого экземпляра захвата. В частности, cdc.fn_cdc_get_all_changes_ и cdc.fn_cdc_get_net_changes_. Типичный рабочий процесс, который я использовал, описан ниже (сделайте это для всех экземпляров захвата). Во-первых, вам понадобится таблица для сохранения статуса обработки. Я использую что-то вроде:

create table dbo.ProcessingStatus (
   CaptureInstance sysname,
   LSN numeric(25,0),
   IsProcessed bit
)
create unique index [UQ_ProcessingStatus] 
   on dbo.ProcessingStatus (CaptureInstance) 
   where IsProcessed = 0
  1. Получите текущий максимальный порядковый номер журнала (LSN) с помощью fn_cdc_get_max_lsn.
  2. Получите последний обработанный LSN и увеличьте его с помощью fn_cdc_increment_lsn. Если у вас его нет (т. е. вы обрабатываете его впервые), используйте fn_cdc_get_min_lsn для этого экземпляра и используйте его (но не увеличивайте его!). Запишите любой номер LSN, который вы используете, в таблицу, установите IsProcessed = 0.
  3. Выберите любую из функций cdc.fn_cdc_get…, подходящую для вашего сценария, и обработайте результаты так, как вы собираетесь их обрабатывать.
  4. Обновление IsProcessed = 1 для этого запуска.

Что касается мониторинга исходной проблемы, просто убедитесь, что данные в таблице захвата обычно находятся в пределах срока хранения. То есть, если вы установите его на 2 дня, я бы даже не подумал о том, что это проблема, пока он не превысит 4 дня (при условии, что ваш вызов на задание по очистке запланирован примерно каждый час). И когда вы обрабатываете по приведенной выше схеме, вам не нужно беспокоиться о том, что там «слишком много» данных; вы всегда обрабатываете определенный интервал, а не «все».

person Ben Thul    schedule 14.08.2014
comment
Спасибо за ваше объяснение, теперь я лучше понимаю CDC. Я немного поэкспериментировал со всем этим и использовал его с задачей управления CDC в SSIS, и теперь он работает отлично. Теперь он обрабатывает таблицы CDC только один раз, проблема решена :) - person Kim; 15.08.2014