Что под капотом Insert, Commit tran?

Я изучаю механизм транзакций в ms sql. В документации к журналу транзакций сказано: "Исходный образ записи - это копия данных до выполнения операции". Как эти данные из журнала используются при фиксации транзакции?

Например, есть такой код:

begin tran
insert to ...
commit tran

Что происходит с данными под капотом, когда выполняется "insert", кроме записи в журнал транзакций?

Что происходит, когда вы выполняете "commit"? Данные каким-то образом перемещаются из журнала в таблицу или они уже находятся в таблице и просто помечаются как зафиксированные?

Где можно прочитать об этой механике? В том числе об откатах транзакций и т.д.

upd: вопрос исключительно про то как меняются данные


Ответы (1 шт):

Автор решения: Roman-Stop RU aggression in UA

По ссылке из комментариев есть хорошее описание процесса. Тут я опишу самое главное и, надеюсь, более удобоваримо:

  1. Данные хранятся постранично. Сначала страница, в которую будет произведена запись, загружается в память с диска. Хранятся такие страницы в так называемом Buffer pool - это по сути кеш данных с диска. Кеш в том смысле, что он хранит данные временно, чтоб не нужно было каждое изменение записывать на диск или читать с диска сразу же (но дальше об этом подробнее).

  2. Оператор изменения (в нашем случае insert) получает эксклюзивную блокировку на изменяемую страницу. Это означает, что ни один другой параллельный запрос не сможет считать изменяемую страницу.

  3. Оператор изменения добавляет в лог транзакций запись, в точности описывающую, что и как оператор собирается изменить на этой странице. В нашем случае, он добит информацию, что собираюсь вставить запись с такими-то значениями колонок. При этом генерируется LSN (Log sequence number) – номер операции внутри лога транзакций.

  4. После этого оператор изменяет страницу в памяти (т.е. Buffer pool). Страница на диске в этот момент не меняется!

  5. LSN записывается в заголовок изменяемой страницы в поле «LSN последнего изменения» (last modified LSN)

  6. Снимается эксклюзивная блокировка на страницу. Теперь страница может быть прочитана другими транзакциями (например, в режиме Read Uncommitted). Важно понимать, что до сих пор ни одного байта не было записано на диск – все изменения происходили в памяти.

  7. Перед тем, как изменяющая транзакция будет завершена, она должна создать новую запись лога, фиксирующую факт, что транзакция зафиксирована (committed). Эта запись добавляется в лог транзакций и после этого она и все предшествующие записи лога (в рамках транзакции) записываются на диск – в файл лога транзакций. Изменяемая страница в этот момент всё еще не записана на диск, её изменения остаются только в памяти. Но сама транзакция с этого момента становится надёжной (durable): даже если служба SQL Server упадёт, информация об изменениях на странице хранятся в логе транзакций, процесс запуска БД прочитает её и повторит нужные действия.

  8. Периодически (но не сразу по окончании транзакции) изменения в страницах из Buffer pool записываются на диск, в файл данных. Эта операция называется CHECKPOINT.

Фактически состояние БД в любой момент, это страницы, хранящиеся на диске + содержимое лога транзакций (опять же на диске). То что находится в памяти (т.е. Buffer pool) сервера, содержит незафиксированные транзакции и его можно терять без ущерба для durability.

→ Ссылка