МОСТ. Справка

Миграция данных старого трекера: ключи, время и потерянные связи

Опубликовано 9 окт. 2026 г.12 мин чтенияДля продвинутых
Старый ящик сыплет карточки на ленту через сито, и к новому фиду доходят сохранившие ключ
What you'll learn
  • Три ревизии, из которых состоит переносимость: ключи, временные базы, разорванные связи
  • Почему строка конверсии может хранить дату приёма постбека под видом даты визита
  • Какие записи источник размещает по кампании, и связи в них уже нет
  • Повторяемое сравнение двух лент по вашим же колонкам с разбором каждой корзины расхождений
  • Письменный критерий перехода и четыре вывода, которые он не подтверждает
Advanced
1views

Миграция данных старого трекера начинается с проверки конкретной выгрузки. Определите, какие её поля связывают конверсию с кликом и какие связи сохранились в строках. При переносе нельзя считать отсутствующее значение восстановленным без отдельного источника. Проверку разделите на три части: ключи связи, смысл временных полей и записи с неполными связями.

Отдельная задача - не оборвать приём постбеков при смене системы, она разобрана в материале переход между трекерами без потери конверсий. Здесь переключать ещё нечего. Миграция данных старого трекера касается меньшего, и вопрос её старше: что уезжает из старой системы как доказательство и когда этого доказательства достаточно, чтобы объявить переход.

Миграция данных старого трекера: ревизия по строкам и ключам

Формулировка «история у нас полная» не сводится к проверяемому признаку на уровне кампании. Есть набор полей у каждой записи, и каждое поле попадает в один из трёх классов: уезжает (лежит в выгрузке под документированным именем), выводимо (восстанавливается из других сохранённых колонок, и способ восстановления записан), потеряно (не хранилось вовсе или хранится там, куда выгрузка не дотянется).

Поле строки конверсииГде держится ключЧто даёт документированная выгрузкаКласс
Идентификатор кликасобственный click id трекера, приходит в постбеке параметром subidзначение плюс имя параметра, под которым оно пришлоуезжает
Тот же идентификатор под чужим именемтаблица алиасов в настройках постбекасама таблица алиасов, иначе смысл значения неизвестенвыводимо, если настройки вывезли
Идентификатор транзакциипараметр tid, отделяющий повторную конверсию от перезаписипо строке на каждое уникальное tidуезжает
Выплата и её валютапараметры постбека, иногда отсутствуютсумма, возможно без валютывыводимо или потеряно
Контекст визита для конверсиизапись клика, с которой сработало сопоставлениетолько если ключ клика разрешилсячасто потерян

Документация Keitaro описывает требование к связи прямым текстом: «Without subid and status , the tracker cannot correctly process the postback.» (Postback, документация Keitaro) На этом вся ревизия ключей и держится: строка переносима ровно в той мере, в какой в ней жив ключ клика. Там же предупреждение о перезаписи: параметры вида cost, external_id, creative_id приезжают поверх сохранённых ранее значений клика - «will overwrite data previously recorded with the click from the traffic source».

Вместе с выгрузкой сохраните правила сопоставления полей. Если clickid настроен как алиас ключа клика, это соответствие нужно перенести в описание схемы. В примере связь проверяют через идентификатор клика; для другого источника сначала определите его документированные ключи. В отчёте укажите долю строк, где проверяемая связь сохранилась, и отдельно перечислите строки, для которых её подтвердить не удалось.

Какое время лежит в строке на самом деле

Колонки времени переносят чаще всего неправильно, потому что имя поля обещает больше, чем сохранённое значение. В старой строке конверсии может стоять момент клика, момент исхода у рекламодателя, момент, когда трекер принял постбек, и момент, когда сводка собралась в отчёте.

Расхождение описано документами, это не гипотеза:

В трекере конверсии записываются по дате клика, но журнал конверсий строится по дате конверсии: дате получения постбека трекером.

- Документация Keitaro, журнал конверсий (перевод), docs.keitaro.io

Правило выгрузки Keitaro уточняет: «Конверсии записываются по дате первого постбека, полученного для subid с каждым уникальным значением tid» (перевод). Поэтому дату в CSV журнала конверсий нужно описать как дату приёма постбека и учитывать этот смысл при построении сводки. Для проверки доступности идентификаторов используйте справочник идентификаторов клика.

Временная базаКто её записываетЕсть ли в старой выгрузкеКак её подписать
Клик в момент редиректатрекерда, если запись клика уцелелаvisit_time
Исход у рекламодателяпартнёрская сеть или ваш сайттолько если приехало параметромadvertiser_time, часто пусто
Приём постбекатрекер, когда обработал запросименно по нему сортируется журналreceipt_time
Сборка отчётаваш дашбордтолько в таблицах самого дашбордаэто не поле строки
Визит для разорванной связиниктоподменено временем приёмане восстанавливается, требует пометки

Доступность выгрузки и удаление данных ограничивают разные части проверки. Voluum Traffic Log позволяет получить данные давностью до четырёх месяцев, но выбранный интервал одного отчёта не может превышать семь дней. Это глубина доступной истории и размер интервала запроса, а не срок хранения данных (Traffic log, документация Voluum). В Keitaro настройка Stats store term управляет автоматической очисткой статистики; удалённую статистику восстановить нельзя (Cleaning statistics, документация Keitaro). Архив Keitaro отдельно хранит удалённые ресурсы, например кампании и потоки. Его срок настраивается и по умолчанию составляет 60 дней, после чего эти ресурсы удаляются без возможности восстановления (Archive, документация Keitaro).

До отключения источника запишите ограничения отдельно: какие даты доступны в выгрузке, какой интервал охватывает запрос, когда удаляется статистика и какие ресурсы ещё можно восстановить из архива.

Что источник терял до всякой миграции

Voluum описывает запасной способ регистрации конверсии без click ID. Конверсия связывается с кампанией, а не с визитом; временем визита становится время постбека. Каждый постбек считается уникальным, фильтрации дублей нет, а валюта по умолчанию USD, если её не передали отдельно. В базовом варианте часть контекста визита отсутствует. Дополнительные идентификаторы оффера, лендинга, пути или потока позволяют связать конверсию с отдельными элементами воронки; пользовательские переменные тоже нужно передавать явно. Полный визит эти дополнения не восстанавливают (Registering Conversions Without Click IDs, документация Voluum).

Запрос, который строкой так и не стал, оставляет другой след. Keitaro пишет в журнал отброшенное: «If the status parameter is missing, the tracker ignores the postback and logs the event.» Этот журнал отброшенных запросов и есть доказательство разрыва между тем, что отправил партнёр, и тем, что записал источник, а в выгрузку конверсий он не входит вообще (чек-лист диагностики постбеков разбирает границу в живой работе, задача переноса там не рассматривается).

Миграция данных старого трекера требует отдельного подсчёта записей с неполными связями. Разделите опись на три группы.

  1. Строки без ключа - конверсии, у которых идентификатора клика нет, привязка обычно к кампании или офферу. При переносе сохраняйте доступный контекст кампании или отдельных элементов воронки, не выдавая его за восстановленный визит.
  2. Строки с удалённой второй стороной - ключ был, а записи клика уже нет: срок хранения истёк, дамп выгрузили без таблицы кликов, таблица кликов не сохранилась. Сумма осталась, связь исчезла.
  3. Незаписанные исходы - запросы, которые источник проигнорировал или не получил. В выгрузке их не представляет ничего, остаются только журнал отброшенных и отчётность партнёра (двойные конверсии между трекером, сетью и платформой ведёт механику повторов, здесь tid всего лишь колонка для классификации).

Две ленты событий: повторяемое сравнение

Для повторяемого сравнения двух лент зафиксируйте один интервал, ключ сопоставления и временную базу. Каждое расхождение отнесите к названной группе. До сравнения согласуйте смысл колонок.

csv
click_key,tid,time_base,time_value,offer_id,lander_id,payout,currency,link_class

Поле time_base не украшение: оно указывает, клик или приём записан в time_value, и миграция данных старого трекера без него молча склеивает два журнала, расходящихся по построению. Колонка link_class несёт корзину из предыдущего раздела, тогда разорванная запись остаётся разорванной в новой ленте и не получает правдоподобный визит.

Одного click_key для связи мало. Журнал конверсий описан документированно и содержит записи «for one subid with different tid»: повторные конверсии одного клика различаются ровно полем tid. Сравнение по одному только click_key схлопнет такие строки в одну и покажет это как совпадение. Ниже ключ собирается из пары click_key + tid, и именно эту пару лестница наблюдений дальше называет принятой записью. Пара склеивается литеральным #, и ключ остаётся однозначным, пока этого символа нет ни в одной из колонок; строку с # внутри click_key или tid охранное условие ниже отсекает, иначе одна склейка начала бы означать две разные пары.

bash
# сохраняем как compare_feeds.sh и запускаем bash'ом; один закрытый интервал с двух сторон
set -euo pipefail
TB=receipt_time                       # то значение time_base, на котором договорились обе ленты
printf 'click_key,tid,time_base,time_value,link_class\nsubid-1,t-1,receipt_time,2026-08-03T11:20:05Z,carried\nsubid-2,t-1,receipt_time,2026-08-04T09:10:00Z,carried\nsubid-3,t-2,receipt_time,2026-08-05T18:42:11Z,purged_key\nsubid-4,,receipt_time,2026-08-05T19:00:00Z,unkeyed\n' > old_export.csv
printf 'click_key,tid,time_base,time_value,link_class\nsubid-1,t-1,receipt_time,2026-08-03T11:20:05Z,carried\nsubid-2,t-1,receipt_time,2026-08-04T09:15:00Z,carried\nsubid-9,t-7,receipt_time,2026-08-06T07:00:00Z,carried\n' > new_feed.csv
: > excluded_rows.csv                 # строки, которые охранное условие не пустило в join, остаются видны
keyed() {                             # одна лента -> строки "click_key#tid,time_value"
  tail -n +2 "$1" | awk -F, -v tb="$TB" -v bad=excluded_rows.csv '
    BEGIN { OFS = "," }
    $3 == tb && $1 != "" && $2 != "" && $1 !~ /#/ && $2 !~ /#/ { print $1 "#" $2, $4; next }
    { print >> bad }'
}
join -t, -a1 -a2 -e MISSING -o 1.1,2.1,1.2,2.2 \
  <(keyed old_export.csv | LC_ALL=C sort -t, -k1,1) \
  <(keyed new_feed.csv  | LC_ALL=C sort -t, -k1,1) > joined_rows.csv
awk -F, '{ if ($1 == $2 && $3 == $4) same++
           else if ($2 == "MISSING") only_old++
           else if ($1 == "MISSING") only_new++
           else time_diff++ }
     END { printf "joined_rows %d\nsame_key_same_time %d\nonly_in_old_export %d\nonly_in_new_feed %d\nkey_matched_time_differs %d\n",
           NR, same+0, only_old+0, only_new+0, time_diff+0 }' joined_rows.csv > bucket_counts.txt
printf 'excluded_unkeyable_rows %d\n' "$(awk 'END { print NR+0 }' excluded_rows.csv)" >> bucket_counts.txt
cat bucket_counts.txt

Перечень полей выше задаёт авторский формат сравнения. Сопоставьте его с документированной схемой своего источника. В скрипте заголовок удаляется до сортировки, а строки, не прошедшие проверку ключа, сохраняются в excluded_rows.csv. Просматривайте этот файл вместе с результатом сопоставления. Перед миграцией адаптируйте разбор строк и правила ключа к реальной выгрузке.

Ожидаемый вывод для встроенного примера, шесть строк:

joined_rows 4
same_key_same_time 1
only_in_old_export 1
only_in_new_feed 1
key_matched_time_differs 1
excluded_unkeyable_rows 1

В CSV-контракте выше девять колонок. Bash-фикстура использует пять из них: click_key, tid, time_base, time_value, link_class. Поля offer_id, lander_id, payout, currency в неё не включены и в сравнении не участвуют. Последняя старая строка показывает работу охранного условия: у subid-4 пустой tid, поэтому в сопоставление она не попадает, и joined_rows 4 считает только строки с ключом. Отказ тоже остаётся видимым: такая строка дописывается в excluded_rows.csv, а шестой счётчик печатает число строк, до которых сравнение не дошло, то есть шагу 4 есть что объяснять числом. Значения unkeyed и purged_key лежат в колонке link_class, поэтому строка без ключа принадлежит той же описи, что и четыре корзины. Молча её потерять значит получить честное сравнение по подмножеству, которое никто не называл.

Шесть шагов, у каждого свой артефакт:

  1. Зафиксируйте снимок данных за выбранный исторический интервал и сравнивайте его неизменяемые копии. Поздно поступившие записи учитывайте отдельно; приём рабочих постбеков продолжайте.
  2. Повторите выгрузку из того же снимка и сравните файлы. Если они различаются, проверьте фильтры, настройки экспорта и выбранный снимок до дальнейшего сравнения.
  3. Запустите блок выше как скрипт и сохраните bucket_counts.txt: шесть счётчиков на шести строках, рядом excluded_rows.csv. Миграция данных старого трекера требует сохранённых файлов для повторной проверки.
  4. Объясните каждую корзину классом: удалённый ключ, разорванная связь, поздний приём, фильтр в новой ленте, строки, которые отсечало условие пустого tid или символа #. Необъяснённый остаток это находка, погрешность тут ни при чём.
  5. Пересоберите с обеих сторон метрику, по которой вы отчитываетесь (выплаты по офферу, число по статусу), и сверяйте её; построчного сопоставления тут недостаточно.
  6. Отдельно выпишите, чего ревизия не достала: строки, чей клик давно вышел за документированное окно выгрузки.

Критерий перехода и его пределы

Критерий держится на трёх условиях, каждое проверяемо другим человеком:

  • у каждой корзины сравнения названа причина, остаток либо ноль строк, либо явно перечисленное исключение;
  • миграция данных старого трекера даёт покрытие по интервалам и по офферам, потому что сквозная цифра прячет кампании, где из источника нечего было выгрузить;
  • то же сравнение после остановки старого приёма воспроизводит счётчики, значит, доверять можно самой ленте событий, а не скрипту разовой выгрузки.

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

УровеньЧем доказанЧем он не доказан
Отправленоисходящий журнал партнёра или сетичто трекер понял запрос
Полученострока в собственном журнале запросов трекера, каким бы ни было его решениечто вызов стал строкой конверсии, потому что журнал из цитаты выше пишет отказ так же аккуратно, как и приём
Принятострока конверсии с ключом click_key и tidчто строка доедет до отчёта и что выгрузка до неё ещё дотянется
Вывезеновоспроизводимый файл внутри документированного окна, где эта строка лежитчто новая лента посчитала запись
Посчитанострока в новой ленте или в отчёте по нейатрибуцию и результаты торгов внутри рекламной платформы

Последняя строка и есть настоящая граница, и продуктовая страница формулирует её прямо: записи об интеграции «do not promise attribution or bidding outcomes inside an ad platform» (Way2 Telegram tracking, доказательства и границы). Принимает ли приёмник историю задним числом и в каком окне, отдельная проверка; для Telegram-контура она разобрана в статье восстановимость истории в Telegram, здесь сознательно не решается.

Отдельно держатся два предела. При переносе различайте полный визит и доступный контекст кампании или отдельных элементов воронки для конверсии без ключа. Дамп это ещё не ревизия: полный перенос сервера автоматически увозит статистику и настройки вместе с postback-ключом (Transfer Tracker to Another Server, документация Keitaro), а новую систему всё равно кто-то должен спросить, какая временная база лежит в каждой колонке.

Нужно разобрать перенос данных?

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

Не отправляйте токены и пароли.

Источники

Sources

Was this guide helpful?
Author
Most Team
Справочная служба

Официальные руководства и глоссарий для платформы Most и Активатора пикселей.

Похожие руководства

Модель эксплуатации интеграции: четыре вопроса, на которые отвечает договор

Сравнивать управляемый тариф и развёртывание на своём сервере значит читать обязательства: в каком хранилище лежат записи о клике и об отправленном событии, кто ставит обновления, какой текст о поддержке существует и почему одну цену нельзя поделить на другую.

8 мин

Приёмочный тест конверсий: отправлено, принято и учтено

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

7 мин

Входные данные конверсионного пути: что подрядчик получает до начала работ

Входные данные конверсионного пути - то, что заказчик передаёт подрядчику до старта работ: пять обязательных наборов значений, ни одного секрета в тексте и четыре отдельные строки приёмки, чтобы отправленное, принятое, учтённое и приписанное не подписывались одной фразой.

11 мин

Как проверить read-only доступ Google Ads для аудита

Для аудита нужен список ресурсов и разрешённых проверок. Название роли в одном сервисе не открывает другой сервис и не подтверждает видимость всех экранов.

5 мин