awesome-everything EN
↑ Обратно к восхождению

Базы данных

MVCC и изоляция: тест с выбором ответа

Суть Тест с выбором на синтез по всему юниту MVCC — видимость снимков, компромиссы isolation level, write skew против lost update, пиннинг bloat и XID wraparound.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Шесть вопросов поперёк всего юнита. Каждый отражает решение, которое ты принимаешь в реальном инциденте — какой isolation level, почему autovacuum застрял, что на самом деле означает 40001 — а не определение для заучивания.

Цель

Убедись, что связываешь видимость снимков, выбор isolation level, аномалии, которые каждый уровень допускает, пиннинг bloat и wraparound — тот синтез, к которому вели семь уроков.

Викторина

Соединение B выполняет это под READ COMMITTED, пока соединение A коммитит UPDATE между двумя операторами: ```sql -- B: BEGIN; SELECT balance FROM accounts WHERE id = 42; -- вернул 100 -- (A коммитит: UPDATE accounts SET balance = 0 WHERE id = 42) SELECT balance FROM accounts WHERE id = 42; -- вернёт ? ``` Что вернёт второй SELECT и почему?

Викторина

Приложение читает строку, вычисляет новое значение в коде и записывает обратно. Два запроса гонятся: ```sql -- оба соединения, конкурентно: BEGIN; SELECT stock FROM items WHERE id = 7; -- оба прочли 10 -- приложение считает 10 - 1 = 9 UPDATE items SET stock = 9 WHERE id = 7; COMMIT; ``` Под уровнем по умолчанию итоговый stock равен 9, а не 8. Что это и каков минимальный фикс?

Викторина

У таблицы doctors есть инвариант «хотя бы один доктор on_call». Две транзакции под REPEATABLE READ: ```sql -- T1: -- T2 (конкурентно): SELECT count(*) FROM doctors SELECT count(*) FROM doctors WHERE on_call; -- 2 WHERE on_call; -- 2 UPDATE doctors SET on_call=false UPDATE doctors SET on_call=false WHERE name='alice'; WHERE name='bob'; COMMIT; COMMIT; ``` Обе коммитят; теперь ноль докторов на дежурстве. Что произошло и какой уровень это предотвращает?

Викторина

Autovacuum проработал 30 минут на таблице orders 200 ГБ и логирует «287 million are dead but not yet removable, oldest xmin: 28391456». n_dead_tup не падает. Какова первопричина и что проверить первым?

Викторина

Перевод между двумя счетами в банке читает оба баланса, дебетует один, кредитует другой. DBA предлагает READ COMMITTED с SELECT ... FOR UPDATE на обеих строках (с блокировкой в согласованном порядке) вместо SERIALIZABLE, который в 5 раз медленнее на пике. Это корректно?

Викторина

Нагрузка делает много SELECT ... FOR KEY SHARE (неявная блокировка от проверок внешних ключей) и натыкается на предупреждение autovacuum о wraparound гораздо раньше, чем предсказывает её пропускная способность транзакций. Какой счётчик является ограничением?

Итог

Сквозная линия юнита — одно правило видимости и решения, надстроенные над ним. Снимки решают, что видит каждая транзакция (на каждый оператор под READ COMMITTED, на транзакцию под REPEATABLE READ). Isolation level решает, какими аномалиями владеешь ты: RC оставляет lost update приложению, REPEATABLE READ бросает 40001 на конкурентных обновлениях строки, но всё ещё допускает write skew, SERIALIZABLE добавляет SSI для ловли циклов write skew. Налог хранения — мёртвые tuples — autovacuum возвращает лишь до глобального oldest xmin, поэтому долгая транзакция или orphan slot — первый подозреваемый при разрастании bloat. А 32-битные счётчики XID и MultiXact оба требуют заморозки до wraparound. Выбирай самый слабый уровень, ещё защищающий твой инвариант, затем оборони границу.

Продолжить восхождение ↑MVCC и изоляция: тест на припоминание
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.