Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд,
когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет,
что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Короче, вопрос про пайплайн добавления данных в базу:
1) Сначала фиксируем факт добавления данных в лог (durability). Как минимум это так при WAL.
Как без WAL я, кстати, с ходу не скажу.
2) Далее я должен эти данные валидировать на предмет всяческих ограничений и уникальности (в таблице).
3) Добавление данных в файл бд (commit), перестройка индексов и соотв. машинерия при необходимости.
Кажется, после шага 2 уже можно вернуть в запрос, что ок или не ок. Ждать шаг 3 уже не обязательно,
тут все можно сделать асинхронно.
Хоть это все сильно упрощенно, но отдаленно на реальность похоже? Или все не так, и я все перепутал.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте.
S>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
S>Короче, вопрос про пайплайн добавления данных в базу: S>1) Сначала фиксируем факт добавления данных в лог (durability). Как минимум это так при WAL. S>Как без WAL я, кстати, с ходу не скажу. S>2) Далее я должен эти данные валидировать на предмет всяческих ограничений и уникальности (в таблице). S>3) Добавление данных в файл бд (commit), перестройка индексов и соотв. машинерия при необходимости.
S>Кажется, после шага 2 уже можно вернуть в запрос, что ок или не ок. Ждать шаг 3 уже не обязательно, S>тут все можно сделать асинхронно. S>Хоть это все сильно упрощенно, но отдаленно на реальность похоже? Или все не так, и я все перепутал.
S>Заранее благодарю.
S>Упд: 1 и 2 прекрасно параллелятся.
Тут ответ зависит от того, что предпримет база при перезапуске в случае сбоя между записью в лог и записью в файл, например при отключении питания. Если посмотрит лог, а потом добавит не записанные записи в файл, то запись в лог = записи в файл, а так помимо просто записи есть еще и транзакции.
S>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Кем считается? Клиентом — когда получил ответ от сервера, что транзакция успешно завершена. На сервере — если он упадёт после записи в лог, но до записи в дату, то при перезапуске должно произойти какое-то recovery, с переходом в 1 из согласованных состояний (транзакцию либо дозавершить либо откатить).
Друга ищи не того, кто любезен с тобой, кто с тобой соглашается, а крепкого советника, кто полезного для тебя ищет и противится твоим необдуманным словам.
Re: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте.
S>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Возможно вопрос с подвохом?
По сути, данные добавлены в БД тогда, когда мы их можем получить обратно.
Например, в BASE базах, удачная вставка данных, не гарантирует что мы можем вычитать их сразу же.
- Слава России!
— Героям СВО Слава!
Re[2]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Qulac, Вы писали:
S>>Заранее благодарю. S>>Упд: 1 и 2 прекрасно параллелятся. Q>Тут ответ зависит от того, что предпримет база при перезапуске в случае сбоя между записью в лог и записью в файл, например при отключении питания. Если посмотрит лог, а потом добавит не записанные записи в файл, то запись в лог = записи в файл, а так помимо просто записи есть еще и транзакции.
По классике так. Но тут речь скорее всего идет о том, что вернется клиенту. И возвращать ок клиенту после
добавления в лог как-то странно, а если данные не пройдут валидацию? Кажется, что можно 1 и 2 шаг выполнять
одновременно и по результатам обоих выдавать ответ. Иначе получится, что данные записали в лог, но они
не пройдут валидацию. И что тогда?
Кодом людям нужно помогать!
Re[2]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Osaka, Вы писали:
S>>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит? O>Кем считается? Клиентом — когда получил ответ от сервера, что транзакция успешно завершена. На сервере — если он упадёт после записи в лог, но до записи в дату, то при перезапуске должно произойти какое-то recovery, с переходом в 1 из согласованных состояний (транзакцию либо дозавершить либо откатить).
Ответ от сервера когда приходит, очевидно, что не сразу после записи в лог, а если данные не валидны?
Кодом людям нужно помогать!
Re[3]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, Qulac, Вы писали:
S>>>Заранее благодарю. S>>>Упд: 1 и 2 прекрасно параллелятся. Q>>Тут ответ зависит от того, что предпримет база при перезапуске в случае сбоя между записью в лог и записью в файл, например при отключении питания. Если посмотрит лог, а потом добавит не записанные записи в файл, то запись в лог = записи в файл, а так помимо просто записи есть еще и транзакции.
S>По классике так. Но тут речь скорее всего идет о том, что вернется клиенту. И возвращать ок клиенту после S>добавления в лог как-то странно, а если данные не пройдут валидацию? Кажется, что можно 1 и 2 шаг выполнять S>одновременно и по результатам обоих выдавать ответ. Иначе получится, что данные записали в лог, но они S>не пройдут валидацию. И что тогда?
Насколько мне известно при запуске после сбоя все действия которые не были зафиксированы транзакциями — отменяются, если эти данные еще были записаны в журнал, то запись в журнал не означает что данные в бд сохранены.
Программа – это мысли спрессованные в код
Re: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте.
S>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Ответьте им, что вопрос малость идиотский, особенно учитывая наличие транзакций и возможную вложенность транзакций.
Данные в базу добавлены, когда все транзакции в активном соединении с базой завершены успешно. Куда база их записывает — это её, базы, дело. И в логе они будут, и в файле данных они будут.
Re: Базовый вопрос про добавление(вставку) данных в бд.
мдя, неужели в эпоху чатгпт такие вопросы еще могут возникать.
в полноценных базах с логом транзакций только запись в лог транзакций считается коммитом. записалось ли файлы данных или нет, не важно. если записались гигабайты в файлы данных но сервер рестартанул, рестарт откатит транзакцию и зачистит файлы. то же самое в обратной ситуации, если в лог коммит записался, а в файлы не успел (данных кеш не сбросился). при рестарте из лога, данные на в файлы данных накатятся.
Здравствуйте, Sharov, Вы писали:
S>Тут на собеседовании спросили на тему когда считается, что данные добавлены в бд, S>когда мы записали их в лог или непосредственно в файл данных? Ну типа когда бд вернет, S>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Это зависит от БД и вообще много от чего.
БД может в кластере быть и тогда вопрос насколько надо нод записать чтоб вернуть ок.
WBR, Igor Evgrafov
Re[2]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Gt_, Вы писали:
Gt_>мдя, неужели в эпоху чатгпт такие вопросы еще могут возникать.
Выбирал, или-или. Решил здесь, расчитывая на некую дискуссию. А всяческая нежить может и наглючить.
Gt_>в полноценных базах с логом транзакций только запись в лог транзакций считается коммитом. записалось ли файлы данных или нет, не важно. если записались гигабайты в файлы данных но сервер рестартанул, рестарт откатит транзакцию и зачистит файлы. то же самое в обратной ситуации, если в лог коммит записался, а в файлы не успел (данных кеш не сбросился). при рестарте из лога, данные на в файлы данных накатятся.
Похоже на правду, благодарю.
Кодом людям нужно помогать!
Re: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sharov, Вы писали:
S>Короче, вопрос про пайплайн добавления данных в базу: S>1) Сначала фиксируем факт добавления данных в лог (durability). Как минимум это так при WAL. S>Как без WAL я, кстати, с ходу не скажу. S>2) Далее я должен эти данные валидировать на предмет всяческих ограничений и уникальности (в таблице). S>3) Добавление данных в файл бд (commit), перестройка индексов и соотв. машинерия при необходимости.
S>Кажется, после шага 2 уже можно вернуть в запрос, что ок или не ок. Ждать шаг 3 уже не обязательно, S>тут все можно сделать асинхронно. S>Хоть это все сильно упрощенно, но отдаленно на реальность похоже? Или все не так, и я все перепутал.
Нет.
1. Все валидации делаются до того, как будет принято решение о внесении изменений.
2. Когда решение принято, дальнейшие шаги теоретически зависят от того, как в СУБД реализована crash recovery. В учебниках пишут про Undo Logging, Redo Logging, и Undo/Redo Logging.
На практике все (кроме студенческих поделок) реализуют последний вариант, он же WAL, он же ARIES. Ну, либо совсем ничего не реализуют, и тогда пайплайн может быть устроен более-менее произвольным образом — либо мы сначала выполняем все модификации синхронно, и только потом подтверждаем коммит, либо мы бодренько подтверждаем коммит, не дожидаясь сброса кэшей на диск. Последний вариант особенно популярен у всяких мамкиных инженеров, которые любят кричать "смотрите, мы делаем в тысячу раз больше коммитов в секунду, чем оракл", пока их не ткнут носом в потери после сбоя.
3. Правила WAL требуют выполнения ровно одной гарантии: для любого изменения запись о нём в лог должна доехать до диска раньше, чем само изменение. Теоретически, это можно реализовать при помощи разворота порядка операций — то есть сначала мы добавляем лог-запись, и только потом вносим изменения в "основные" данные. Но нам всё равно нужно следить за тем, чтобы случайно не записать изменения до сброса журнала на диск.
Наивная реализация (зато очень простая — можно вообще не управлять буферами, а просто отобразить файл данных в память) вынуждена обеспечивать это при помощи сброса журнала на каждое изменение.
Это настолько чудовищно неэффективно при мало-мальской нагрузке, что обычно всё же делают более сложную схему с менеджером буферов. Менеджер перед записью грязной страницы на диск делает flush журнала, что позволяет сбрасывать записи журнала "пачками".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sinclair, Вы писали:
S>3. Правила WAL требуют выполнения ровно одной гарантии: для любого изменения запись о нём в лог должна доехать до диска раньше, чем само изменение. Теоретически, это можно реализовать при помощи разворота порядка операций — то есть сначала мы добавляем лог-запись, и только потом вносим изменения в "основные" данные.
Что значит любого изменения? Если оно нарушает какое-нибудь ограничение? Или речь все же про валидные изменения?
Кодом людям нужно помогать!
Re[2]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sinclair, Вы писали:
S>3. Правила WAL требуют выполнения ровно одной гарантии: для любого изменения запись о нём в лог должна доехать до диска раньше, чем само изменение. Теоретически, это можно реализовать при помощи разворота порядка операций — то есть сначала мы добавляем лог-запись, и только потом вносим изменения в "основные" данные. Но нам всё равно нужно следить за тем, чтобы случайно не записать изменения до сброса журнала на диск.
Возращаясь ко второй части вопроса ТС, когда клиент получает подтверждение, что данные/изменения записаны?
Если память не изменяет, в любой момент после записи лога, не обязательно дожидаясь записи самих данных на диск, или нет?
S>Ну типа когда бд вернет,
что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Re[3]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, Sharov, Вы писали:
S>Что значит любого изменения? Если оно нарушает какое-нибудь ограничение? Или речь все же про валидные изменения?
Про любые. Если мы вообще собрались вносить в базу изменение, то в RAM можно резвиться как угодно, но на диск это изменение не должно попасть до того, как в WAL уедет соответствующая запись.
Потому что иначе после сбоя у нас не будет способа восстановить предыдущее значение.
А если вас беспокоят deferred constraints, то они проверяются между получением от пользователя команды commit transaction и внесением в WAL записи commit(TID). Если какие-то из констреинтов окажутся нарушенными, то информация из журнала будет использована для отката этой транзакции.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, paucity, Вы писали:
P>Если память не изменяет, в любой момент после записи лога, не обязательно дожидаясь записи самих данных на диск, или нет?
После того, как будет выполнен flush log после добавления в журнал записи commit(TID).
Запись "самих данных" на диск тут полностью асинхронна — она может завершиться ещё до этого момента; может даже и не начаться к этому моменту; может быть частично выполнена к этому моменту.
P>что данные добавлены, после добавления данных в лог или когда в сам файл данных будет комит?
Современные СУБД не делают "коммит в файл данных". Это слишком дорого. Файл данных лениво синхронизуется с памятью более-менее независимо от коммитов транзакций. То есть в каждый момент в "файле данных" на диске находится каша из изменений, которые внесены незавершёнными транзакциями; устаревших копий страниц, изменённых завершенными транзакциями, но ещё не сброшенных на диск, и прочего мусора.
Но при этом в каждый момент у нас есть на руках фрагмент журнала, который позволяет нам гарантированно навести в этом мусоре порядок.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Базовый вопрос про добавление(вставку) данных в бд.
Здравствуйте, paucity, Вы писали:
S>>1. Все валидации делаются до того, как будет принято решение о внесении изменений.
Ну, это я немножко погорячился. Некоторые СУБД поддерживать deferred constraints. Это позволяет нам решать всякие проблемы типа кольцевых ссылок между таблицами — как нам вставить отдел, если у него обязательный FK на начальника отдела, и как нам вставить начальника отдела, если у него обязательный FK на отдел, в котором тот работает?
Но достигается это ценой ведения отдельного журнала нарушений с перепроверкой этих нарушений при commit. То есть нагрузка на СУБД увеличивается.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.