Инвалидация кэша PostgreSQL с учётом транзакций

Это руководство объясняет, как триггеры подключённых таблиц не дают чтению через RESP вернуть устаревшее значение после фиксации записи в PostgreSQL.

Инвалидация при записи: зафиксированные обновления публикуют барьер; откат до публикации барьера сохраняет запись действительной.

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

Полное описание согласованности пути чтения см. в техническом справочнике.

Проверка инвалидации между SQL и RESP

Запустите локальную демонстрацию, затем прочитайте один и тот же ключ через RESP и PostgreSQL:

MGET CRUD:pglc_demo.public.items:{"id":42}

В отдельном SQL-сеансе обновите строку и зафиксируйте транзакцию:

BEGIN;
UPDATE public.items SET revision = revision + 1 WHERE id = 42;
COMMIT;

Следующая команда RESP вернёт зафиксированную версию. Если вместо этого отменить транзакцию записи, RESP продолжит возвращать последнюю зафиксированную версию.

RESP использует настроенную роль PostgreSQL в отдельной короткой транзакции. Оно не использует роль, транзакцию или снимок приложения. Для чтения собственных изменений в транзакции приложения и SELECT ... FOR UPDATE используйте SQL.

Случаи, намеренно обходящие кэш

Когда pg_local_cache.enabled выключен, RESP MGET пропускает поиск и заполнение кэша и читает исходную таблицу. Активный барьер записи для ключа, отношения или глобально также блокирует чтение из кэша и сохранение новых записей, поэтому чтение идёт из исходной таблицы. RESP-воркеры запускаются после завершения восстановления, поэтому восстановление не является отдельным условием обхода кэша. Строка, слишком большая для записи кэша, всё же может быть возвращена из PostgreSQL, если её JSON укладывается в лимит RESP, но не сохраняется.

Изучите причину промаха

Сравните local_cache.stats() и local_cache.health() до и после контролируемой нагрузки. Проверьте счётчики обхода кэша, промахов, инвалидации и перезагрузки сопоставлений. Список метрик приведён в техническом справочнике.

Обновлено .