Код импорта переписан, обмен стал в восемь раз быстрее. Остаётся вопрос, на который «проверил глазами» не отвечает: пишет ли новая версия в базу ровно то же, что старая? Код, который каждые несколько секунд обновляет сотни записей, ошибётся тихо и сразу везде. Вот схема, которой мы это доказываем.

Это четвёртая часть цикла «Массовый импорт в WordPress».

Схема на тестовой копии

  1. Держать рядом точную копию старой реализации — под другим именем, без единой правки.
  2. Снимок всей меты, которую код может изменить (у нас — списки совместимости у всех товаров).
  3. Прогон старой → снимок А → откат к исходному снимку.
  4. Прогон новой → снимок Б → откат.
  5. Сверка А и Б побайтово — сравнивать сериализованные значения, а не «на глаз».
  6. В конце убедиться, что база вернулась в исходное состояние. Иначе проверка сама стала поломкой.
function snapshot(array $ids): array {
    $s = [];
    foreach ($ids as $id) {
        $s[$id] = get_post_meta($id, 'fitsProductUnique', true);
    }
    return array_map('serialize', $s);
}
function restore(array $snap): void {
    foreach ($snap as $id => $v) {
        update_post_meta($id, 'fitsProductUnique', unserialize($v));
    }
}

$before = snapshot($ids);
old_fits_product($target);  $a = snapshot($ids);  restore($before);
new_fits_product($target);  $b = snapshot($ids);  restore($before);

$diff = array_keys(array_diff_assoc($a, $b));
echo count($diff) ? 'РАЗНИЦА: ' . implode(',', $diff) : 'совпадает', "\n";
echo snapshot($ids) === $before ? "база восстановлена\n" : "БАЗА НЕ ВОССТАНОВЛЕНА\n";

На ком гонять

  • самые тяжёлые объекты — где код делает больше всего работы (у нас товар со 101 связью);
  • случайная выборка — чтобы не подбирать удобные случаи;
  • краевые — объекты, на которых код почти ничего не делает: товар, на который никто не ссылается, товар без поля сортировки;
  • запасной путь отдельно. Если в коде есть ветка «при ничьей — по-старому» (третья часть), её условие надо создать искусственно, иначе она так и останется непроверенной.

Ловушка: две версии в одном процессе

Обе реализации мы гоняли в одном PHP-процессе — и старая выглядела втрое быстрее, чем есть: 7,86 секунды в первой итерации и 1,6 во всех следующих. Новая версия заполняла общую памятку, а старая ею пользовалась. Чуть не сделали вывод «выигрыша нет».

Перед каждым прогоном сбрасывайте общее состояние: статические переменные, wp_cache_flush(), свои памятки. И смотрите на первую итерацию отдельно: пока не доказано обратное, она единственная честная.

На рабочем сайте — без записи

На живых данных откатывать нельзя: между снимком и откатом может прийти настоящий обмен. Там та же идея без записи: вместо update_post_meta обе реализации считают в память то, что записали бы, и это сравнивается.

$writes = [];
$write  = function (int $id, $value) use (&$writes) { $writes[$id] = serialize($value); };

old_fits_product($target, $write);  $a = $writes;  $writes = [];
new_fits_product($target, $write);  $b = $writes;

Например, запись в обеих версиях выносится в параметр-функцию: в бою она пишет в базу, в проверке — в массив. Результаты:

  • первый сайт: снимок меты сняли до выката, после выката прогнали новую реализацию и сверили с ним — 9 самых связных товаров, около 900 адресатов, расхождений ноль;
  • второй сайт: 303 адресата — разница в составе групп ноль. Отличался только взаимный порядок пары с одинаковым order, и это ровно то изменение, которое мы внесли сознательно.

Страница работает — это ещё не данные на месте

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

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

Переписываете импорт и боитесь сломать данные?

Пришлите код — соберу проверку, которая сравнивает старую и новую версию на ваших данных без записи в рабочую базу.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.