CHECK_DATA
Содержание раздела
Запрос позволяет проверить идентичность данных логической таблицы во всех СУБД хранилища. Данные проверяются по дельтам в обратном порядке: с последней закрытой дельты до указанной в запросе (обе дельты включительно). При первом найденном расхождении система останавливает проверку и возвращает сообщение о расхождении в данных.
В проверке участвуют все СУБД хранилища, в которых есть данные логической таблицы, указанной в запросе. Если такая СУБД одна, проверка все равно проходит и считается успешной.
Порядок проверки зависит от параметров запроса:
- если указаны столбцы к проверке, система сверяет контрольные суммы загруженных записей в каждой дельте;
- иначе — система сверяет количество загруженных записей в каждой дельте.
Подробнее о порядке проверки см. в секции Порядок проверки данных, о расчете контрольной суммы — в секции Порядок расчета контрольной суммы.
В ответе возвращается:
- объект ResultSet с одной записью, содержащей результат проверки, при успешном выполнении запроса. Результат включает список проверенных дельт, где для каждой указано сообщение об успешной проверке или найденном расхождении;
- исключение при неуспешном выполнении запроса.
Значения типа FLOAT и DOUBLE могут приводить к расхождениям при проверке из-за разницы в точности типов. Чтобы избежать таких расхождений, используйте для значений с плавающей точкой только тип DOUBLE (как более распространенный среди СУБД) или не включайте столбцы типа FLOAT и DOUBLE в запросы CHECK_DATA
.
Проверка может давать ложноположительный результат. Этому подвержены оба варианта проверок: как с указанием, так и без указания столбцов. Чтобы снизить частоту ложных срабатываний, рекомендуется включать первичный ключ в список проверяемых столбцов.
Синтаксис
CHECK_DATA([db_name.]table_name, delta_number[, normalization][, square-bracketed_column_list])
Параметры:
db_name
(опциональный) — имя логической базы данных, в которой находится проверяемая логическая таблица. Параметр опционален, если выбрана логическая БД, используемая по умолчанию;table_name
— имя проверяемой логической таблицы;delta_number
— номер дельты, с которой начинается проверка. Должен быть меньше или равен номеру последней закрытой дельты. Номер последней закрытой дельты можно узнать с помощью запроса GET_DELTA_OK;normalization
(опциональный) — коэффициент, который повышает максимально допустимое количество записей в дельте, но снижает уникальность контрольных сумм. Может принимать любое положительное целочисленное значение, начиная с 1. Значение по умолчанию — 1. Если коэффициент не указан или равен 1, каждая из проверяемых дельт может содержать до4'294'967'298
записей; при увеличении коэффициента допустимое количество записей увеличивается пропорционально. Если количество записей в какой-либо из дельт больше допустимого, в ответе возвращается исключение;square_bracketed_column_list
(опциональный) — список проверяемых столбцов таблицы. Элементы списка должны быть указаны в квадратных скобках через запятую, например[id, transaction_date]
. Если столбцы указаны, проверяется контрольная сумма загруженных записей в каждой дельте, иначе — количество таких записей.
Ограничения
- Существует математическая вероятность получения одинаковых контрольных сумм для разных наборов записей, поэтому возможен ложноположительный результат проверки.
- Максимальное количество записей в дельте, для которых контрольная сумма рассчитывается корректно, пропорционально коэффициенту нормализации. Если коэффициент не указан или равен 1, проверяемая дельта может содержать до
4'294'967'298
записей; при увеличении коэффициента допустимое количество записей также увеличивается.
Примеры
Запрос без перечисления столбцов
Проверка целостности данных логической таблицы stores75
в диапазоне [дельта 0, последняя закрытая дельта]:
CHECK_DATA(sales.stores75, 0)
На рисунке ниже показан пример ответа CHECK_DATA
при успешной проверке логической таблицы stores75
, данные которой размещены только в ADB.
Запрос с перечислением столбцов
Проверка целостности данных столбцов id
, transaction_date
и product_code
таблицы sales
:
CHECK_DATA(sales.sales, 10, [id, transaction_date, product_code])
На рисунке ниже показан пример ответа на запрос CHECK_DATA
по столбцам таблицы при наличии расхождений: контрольная сумма дельты 10 в ADB отличается от контрольной суммы в ADG и ADQM.
Запрос с коэффициентом нормализации
Проверка целостности данных некоторых столбцов таблицы sales
с коэффициентом нормализации 100:
CHECK_DATA(sales.sales, 12, 100, [id, transaction_date, product_code])
На рисунке ниже показан пример ответа на такой запрос.
Порядок проверки данных
Идентичность данных проверяется в следующем порядке:
- В каждой из целевых СУБД:
- Выбираются проверяемые дельты: от указанной в запросе до последней закрытой (обе включительно).
- По каждой дельте выбираются все записи, загруженные в логическую таблицу, которая указана в запросе.
- По каждой дельте — в зависимости от наличия/отсутствия столбцов в запросе — рассчитывается контрольная сумма или количество загруженных записей. Порядок расчета контрольной суммы см. ниже.
- Значения по каждой дельте сравниваются в целевых СУБД.
- Если значение по одной из дельт отсутствует или не соответствует другим, для нее в ответе возвращается сообщение о расхождении в данных. Иначе по всем дельтам возвращаются сообщения об успешной проверке.
Порядок расчета контрольной суммы
Контрольная сумма логической таблицы в дельте рассчитывается в следующем порядке:
- По каждой записи, загруженной в логическую таблицу в этой дельте:
- Формируется текстовая строка: значения столбцов конвертируются в зависимости от типа данных (см. таблицу ниже) и записываются через точку с запятой. Значение NULL записывается как пустая строка.
- Для полученной строки вычисляется MD5-хеш в виде байтовой последовательности в шестнадцатеричном формате.
- Хеш интерпретируется как ASCII-строка в нижнем регистре.
- Выбираются первые 4 символа строки, выстраиваются в порядке от младшего к старшему (little endian) и конвертируются в целое 32-битное число.
- Полученное число делится на коэффициент нормализации, дробная часть результата отбрасывается — получается контрольная сумма записи.
- Контрольные суммы всех записей в дельте суммируются — получается 64-битная контрольная сумма таблицы в дельте.
В таблице ниже показано, как значения столбцов (column_value
), указанных в запросе, конвертируются в зависимости от их типа данных.
Тип данных | Порядок конвертации | Пример |
---|---|---|
BOOLEAN | (column_value)::int | true -> 1 |
DATE | column_value - make_date(1970, 01, 01) | 2021-03-15 -> 18701 |
TIME | (extract(epoch from column_value)*1000000)::bigint | 13:01:44 -> 46904000000 |
TIMESTAMP | (extract(epoch from column_value)*1000000)::bigint | 2020-11-17 21:11:12 -> 1605647472000000 |
Другие типы данных | column_value | Иванов -> Иванов |
Пример расчета контрольной суммы
Рассмотрим пример расчета контрольной суммы таблицы sales
в дельте, в которой была загружена одна запись со следующими значениями:
id
= 10021,transaction_date
= 2020-11-17 21:11:12,product_code
= ABC1830.
В качестве коэффициента нормализации возьмем число 10.
Контрольная сумма таблицы рассчитывается в следующем порядке:
- Формируется строка для хеш-функции:
10021;1605647472000000;ABC1830
. - Вычисляется MD5-хеш:
bedbead6aea8ca373d8f0a15713639c1
. - Выбираются первые 4 символа хеша:
bedb
. - Символы интерпретируются как ASCII-строка в нижнем регистре:
98 101 100 98
. - Строка конвертируется в целое 32-битное число: 98*20 + 101*28 + 100*216 + 98*224 = 1650746722.
- Полученное значение делится на коэффициент нормализации, остаток отбрасывается: 1650746722 : 10 = 165074672.
Так как запись в дельте одна, контрольная сумма таблицы в этой дельте равна полученной контрольной сумме записи (165074672
).