== Базы данных. Лаборатория Tarantool. Современные алгоритмы для двухуровневой памяти
https://youtu.be/0A4_SdNEH8c
- диск-память-кэш-процессор
- стоимостная модель
- проблема memory-layout матрицы
- транспонирование матриц
- log-structured-merge дерево
- bloom фильтр
- двойная буфиризация (пишем в один, сбрасываем на диск второй, чередуем)
LSM БД юзаются для частого обновлеющихся данных
- Fractional Cascading - способ уменьшить затраты для упорядоченных структур
- bit-cask. Append only file (AOF) - нет спаек при записи как у LSM. Надо переписывать индекс каждый раз в конец вместе с изменениями
- page-index сохраняет мин-макс в ячейке, что бы сократить время поиска
https://youtu.be/0A4_SdNEH8c
- диск-память-кэш-процессор
- стоимостная модель
- проблема memory-layout матрицы
- транспонирование матриц
- log-structured-merge дерево
- bloom фильтр
- двойная буфиризация (пишем в один, сбрасываем на диск второй, чередуем)
LSM БД юзаются для частого обновлеющихся данных
- Fractional Cascading - способ уменьшить затраты для упорядоченных структур
- bit-cask. Append only file (AOF) - нет спаек при записи как у LSM. Надо переписывать индекс каждый раз в конец вместе с изменениями
- page-index сохраняет мин-макс в ячейке, что бы сократить время поиска
YouTube
2. Базы данных. Лаборатория Tarantool. Современные алгоритмы для двухуровневой памяти | Технострим
Слайды лекции: https://goo.gl/c8jGkC
Подробнее о курсе: https://goo.gl/iPt6an
Лекция читается в рамках образовательного проекта "Техносфера Mail.ru Group" при МГУ им. М.В. Ломоносова.
Цель курса — изучение топологии, многообразия и основных принципов …
Подробнее о курсе: https://goo.gl/iPt6an
Лекция читается в рамках образовательного проекта "Техносфера Mail.ru Group" при МГУ им. М.В. Ломоносова.
Цель курса — изучение топологии, многообразия и основных принципов …
== Базы данных. Лаборатория Tarantool. Кэширование
https://youtu.be/jhAOFFUVSjk
Least Recently Used - вытеснение давноиспользуемых (одновязанный список, например)
- былали изменена страница?
- завершена ли транзакция, кот модифицировала страницу ?
- физический порядок страниц на диске
- вытеснение осуществляется превентивно в другом потоке
для Index Scan лучше MRU
Midpoint insertion strategy
- LRU разбивается на тёплую и горячую зоны
- Граница между зонами плавающая
- index scan более не «вымывает» кэш
Идея
Балансировать между малыми и большими издержками до тех пор пока сумма малых издержек не превысит большие
LFD - longest forward distance (~clairvoyant algorithm, ~Belady's algorithm)
выталкиваем страницу которая будет запрошена позже всего в будущем
Для любого другого алгоритма А, cost(A) не ухудшается если мы, в случаях когда A отличается от LFD, выталкиваем страницу в
соответствии с LFD, а не с A
для онлайн алгоритмов худший случай это загрузить все страницы
алгоритм консервативен если нет чтения когда работаем с элементами которые в памяти. так же увеличение кэша линейно увеличивает производительность (в лучшем случае линейно)
Рандомизированный алгоритм: MARK
- Помечает страницу при использовании (они не выталкиваются)
- Когда все страницы помечены, и нужна страница, все пометки снимаются (кроме пометки на новой странице)
- Для выталкивания выбирается случайная страница из непомеченных
====> const(MARK) = lg(k) * cost(LFD)
LRU таким образом в целом не хуже чем MARK (на случайных данных)
https://youtu.be/jhAOFFUVSjk
Least Recently Used - вытеснение давноиспользуемых (одновязанный список, например)
- былали изменена страница?
- завершена ли транзакция, кот модифицировала страницу ?
- физический порядок страниц на диске
- вытеснение осуществляется превентивно в другом потоке
для Index Scan лучше MRU
Midpoint insertion strategy
- LRU разбивается на тёплую и горячую зоны
- Граница между зонами плавающая
- index scan более не «вымывает» кэш
Идея
Балансировать между малыми и большими издержками до тех пор пока сумма малых издержек не превысит большие
LFD - longest forward distance (~clairvoyant algorithm, ~Belady's algorithm)
выталкиваем страницу которая будет запрошена позже всего в будущем
Для любого другого алгоритма А, cost(A) не ухудшается если мы, в случаях когда A отличается от LFD, выталкиваем страницу в
соответствии с LFD, а не с A
для онлайн алгоритмов худший случай это загрузить все страницы
алгоритм консервативен если нет чтения когда работаем с элементами которые в памяти. так же увеличение кэша линейно увеличивает производительность (в лучшем случае линейно)
Рандомизированный алгоритм: MARK
- Помечает страницу при использовании (они не выталкиваются)
- Когда все страницы помечены, и нужна страница, все пометки снимаются (кроме пометки на новой странице)
- Для выталкивания выбирается случайная страница из непомеченных
====> const(MARK) = lg(k) * cost(LFD)
LRU таким образом в целом не хуже чем MARK (на случайных данных)
YouTube
3. Базы данных. Лаборатория Tarantool. Кэширование | Технострим
Слайды лекции: https://goo.gl/XjmeYN
Подробнее о курсе: https://goo.gl/iPt6an
Лекция читается в рамках образовательного проекта "Техносфера Mail.ru Group" при МГУ им. М.В. Ломоносова.
Цель курса — изучение топологии, многообразия и основных принципов …
Подробнее о курсе: https://goo.gl/iPt6an
Лекция читается в рамках образовательного проекта "Техносфера Mail.ru Group" при МГУ им. М.В. Ломоносова.
Цель курса — изучение топологии, многообразия и основных принципов …
== Caching and Cache-Efficient Algorithms
https://youtu.be/xDKnMXtZKq8
Fully Associative Cache
Direct-Mapped Cache
Set-Associative Cache
Taxonomy of Cache Misses
- cold miss
- capacity miss
- conflict miss
- sharing miss
Conflict Misses for Submatrices
Ideal-Cache Model
How Reasonable Are Ideal Caches?
Cache-Miss Lemma
Tall Caches
What's Wrong with Short Caches?
Submatrix Caching Lemma
Multiply Square Matrices
Analysis of Cache Misses
Swapping Inner Loop Order
Tiled Matrix Multiplication
Two-Level Cache
https://youtu.be/xDKnMXtZKq8
Fully Associative Cache
Direct-Mapped Cache
Set-Associative Cache
Taxonomy of Cache Misses
- cold miss
- capacity miss
- conflict miss
- sharing miss
Conflict Misses for Submatrices
Ideal-Cache Model
How Reasonable Are Ideal Caches?
Cache-Miss Lemma
Tall Caches
What's Wrong with Short Caches?
Submatrix Caching Lemma
Multiply Square Matrices
Analysis of Cache Misses
Swapping Inner Loop Order
Tiled Matrix Multiplication
Two-Level Cache
YouTube
14. Caching and Cache-Efficient Algorithms
MIT 6.172 Performance Engineering of Software Systems, Fall 2018
Instructor: Julian Shun
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Shun discusses…
Instructor: Julian Shun
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Shun discusses…
тот момент когда лекции MIT оч хорошо рассказывают то где ты уже сьел целый выводок собак, но блять где вы были раньше ? )))
но насколько же круто они преподают... захотелось быть студентом у них на курсе
== Bit Hacks
https://youtu.be/ZusiKXcz_ac
unsigned int 150 = 2 + 4 + 16 + 128
- clear
- flip
- extract
- set x to y
- swap without temp var
- branchless merging sorted arrays
- power of 2
- kog base 2 of power of 2
но насколько же круто они преподают... захотелось быть студентом у них на курсе
== Bit Hacks
https://youtu.be/ZusiKXcz_ac
0b10010110
signed int -106 = 2 + 4 + 16 - 128unsigned int 150 = 2 + 4 + 16 + 128
0b11111111 => -1x + ~x = -1
-x = ~x + 1
A = 0b10110011- set
B = 0b01101001
A&B = 0b00100001
A^B = 0b11011010
A|B = 0b11111011
A >> 3 = 0b00010110
A << 2 = 0b11001100
- clear
- flip
- extract
- set x to y
- swap without temp var
(x ^ y) ^ y
- min x and ym = y ^ ((x ^ y) & -(x < y))
NO BRANCHES -> no performance leaks!- branchless merging sorted arrays
- power of 2
- kog base 2 of power of 2
YouTube
3. Bit Hacks
MIT 6.172 Performance Engineering of Software Systems, Fall 2018
Instructor: Julian Shun
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Shun discusses…
Instructor: Julian Shun
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Shun discusses…
ну просто шикарные преподы в MIT. даже то что знаешь хорошо просто приятно послушать
== Assembly Language & Computer Architecture
https://youtu.be/L1ung0wil9Y
data movement
- mov, cmov
- sigh or zero extension: movs, movz
- stack: push, pop
arithmetic and logic
- int logic: add, sub, mul, imul, div, idiv, lea, sal, sar, shl, shr, rol, ror, dec, neg
- bin logic: and, or, xor, not
- bool logic: test, cmp
Control transfer
- unconditional jump: jmp
- conditional jumps: j<condition>
- subroutines: call, ret
for fetching something from memory - x*100 тактов
compiler generates NOP lines for optimize instruction memory (code, size, alignment....)
SSE and AVX supports x64 fpu
sufixies: ss, sd, ps, pd
pipelininig improves processor throughput !
but
- structural hazard (one instruction for one tact)
- data hazard (depends from result):
- i writes a location that j reads
- j reads location that j writes
- i and j write to the same location
- control hazard (fetching/loading/storing etc operators)
== Assembly Language & Computer Architecture
https://youtu.be/L1ung0wil9Y
data movement
- mov, cmov
- sigh or zero extension: movs, movz
- stack: push, pop
arithmetic and logic
- int logic: add, sub, mul, imul, div, idiv, lea, sal, sar, shl, shr, rol, ror, dec, neg
- bin logic: and, or, xor, not
- bool logic: test, cmp
Control transfer
- unconditional jump: jmp
- conditional jumps: j<condition>
- subroutines: call, ret
for fetching something from memory - x*100 тактов
compiler generates NOP lines for optimize instruction memory (code, size, alignment....)
SSE and AVX supports x64 fpu
sufixies: ss, sd, ps, pd
pipelininig improves processor throughput !
but
- structural hazard (one instruction for one tact)
- data hazard (depends from result):
- i writes a location that j reads
- j reads location that j writes
- i and j write to the same location
- control hazard (fetching/loading/storing etc operators)
YouTube
4. Assembly Language & Computer Architecture
MIT 6.172 Performance Engineering of Software Systems, Fall 2018
Instructor: Charles Leiserson
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Leiserson…
Instructor: Charles Leiserson
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
Prof. Leiserson…
👍1
== Seaborn - лучшая data science библиотека для визуализации на Python
https://youtu.be/gMSQMLeQ4UI
https://youtu.be/gMSQMLeQ4UI
YouTube
Seaborn - лучшая data science библиотека для визуализации на Python?
🔥 Telegram https://news.1rj.ru/str/ershov_diary
🔥 Индивидуальная программа по обучению data science под вашу цель с моей менторской поддержкой до результата:
https://bit.ly/3uRvTz3
Тут я рассказываю почему я создал эту программу, для кого она подходит и в чем ее…
🔥 Индивидуальная программа по обучению data science под вашу цель с моей менторской поддержкой до результата:
https://bit.ly/3uRvTz3
Тут я рассказываю почему я создал эту программу, для кого она подходит и в чем ее…
Forwarded from Записки админа
🆖 Nginx common useful configuration - вдруг кто-то найдёт для себя что-то полезное для работы с Nginx. Там ещё и ссылок приличное количество имеется, по ним тоже имеет смысл пройти.
#nginx #будничное
#nginx #будничное
Forwarded from Записки админа
🆖 Comparing NGINX Performance in Bare Metal and Virtual Environments - сравнение производительности Nginx на голом железе и в виртуальном окружении.
#nginx #kubernetes #baremetal
#nginx #kubernetes #baremetal
у меня очередной небольшой виток в схемотехнику )
== Намотка импульсного трансформатора
https://youtu.be/gIacydXiF0o
нюансы импульсных блоков питания. особенности намотки трансформаторов для импульсников. разбор резонансов и параметров
== A power supply with voltage regulation
https://youtu.be/Wq0JFW2KhUo
== STM32 - программирование для начинающих. Пошагово. CubeMX CubeIDE
https://youtu.be/fxAsY0S2Xa0
== Намотка импульсного трансформатора
https://youtu.be/gIacydXiF0o
нюансы импульсных блоков питания. особенности намотки трансформаторов для импульсников. разбор резонансов и параметров
== A power supply with voltage regulation
https://youtu.be/Wq0JFW2KhUo
== STM32 - программирование для начинающих. Пошагово. CubeMX CubeIDE
https://youtu.be/fxAsY0S2Xa0
YouTube
Намотка импульсного трансформатора
Свою первую печатную плату можете заказать на сайте:
https://www.pcbway.com
Интересные сайты: Паяльник https://cxem.net
Поговорю я о такой вещи как намотка импульсных трансформаторов.
Импульсная преобразовательная техника сейчас находиться в подавляющем…
https://www.pcbway.com
Интересные сайты: Паяльник https://cxem.net
Поговорю я о такой вещи как намотка импульсных трансформаторов.
Импульсная преобразовательная техника сейчас находиться в подавляющем…
если чтото идет не так с маунтом то
оч помог в дебаге того что намутил в fstab
sudo mount -a оч помог в дебаге того что намутил в fstab
Forwarded from Пристанище Дата Сайентиста
Сбор и хранение данных
SQL
- «SQL Problems and solutionsS», I. Moiseenko Интерактивный учебник по SQL
- ByteScout SQL Trainer Быстрый и приятный тренажер, усложняющийся по мере вашего продвижения.
- Simple SQL Queries Упражнения для Постгреса
- SQL Tutorial for Beginners: Database, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIKE, IN, BETWEEN
- Тренажер по SQL
- Как посчитать всё на свете одним SQL-запросом. Оконные функции PostgreSQL https://habr.com/ru/post/268983/
- Простенький тренажер с теорией https://sqlzoo.net/wiki/SQL_Tutorial
- Мануал по установке PostgreSQL в MacOS https://www.robinwieruch.de/postgres-sql-macos-setup
- Пример обращения к MySQL с помощью Python, используя библиотеку sqlalchemy https://pythondata.com/quick-tip-sqlalchemy-for-mysql-and-pandas/
- Пример обращения к PostgreSQL с помощью Python: https://khashtamov.com/ru/postgresql-python-psycopg2/
- window function - https://learnsql.com/course/window-functions
- window function - https://campus.datacamp.com/courses/intermediate-t-sql/window-functions?ex=4
- Хорошая статья об оконных функций SQL - https://khashtamov.com/ru/window-functions-sql/
Парсинг
- Русский перевод документации к BeautifulSoup Beautiful Soup — это библиотека Python для извлечения данных из файлов HTML и XML. Она работает с вашим любимым парсером, чтобы дать вам естественные способы навигации, поиска и изменения дерева разбора. Она обычно экономит программистам часы и дни работы.
- Статья с примером парсинга данных с веб-сайтов с применением BeautifulSoup Освещены все основные этапы: формирование запроса и получение странички с помощью requests, поиск нужного элемента в HTML через инспектор, выделение данных из элемента через методы BeautifulSoup.
API
Работа с первичной аналитикой: выгружаем сырые данные из Метрики с помощью скрипта
SQL
- «SQL Problems and solutionsS», I. Moiseenko Интерактивный учебник по SQL
- ByteScout SQL Trainer Быстрый и приятный тренажер, усложняющийся по мере вашего продвижения.
- Simple SQL Queries Упражнения для Постгреса
- SQL Tutorial for Beginners: Database, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIKE, IN, BETWEEN
- Тренажер по SQL
- Как посчитать всё на свете одним SQL-запросом. Оконные функции PostgreSQL https://habr.com/ru/post/268983/
- Простенький тренажер с теорией https://sqlzoo.net/wiki/SQL_Tutorial
- Мануал по установке PostgreSQL в MacOS https://www.robinwieruch.de/postgres-sql-macos-setup
- Пример обращения к MySQL с помощью Python, используя библиотеку sqlalchemy https://pythondata.com/quick-tip-sqlalchemy-for-mysql-and-pandas/
- Пример обращения к PostgreSQL с помощью Python: https://khashtamov.com/ru/postgresql-python-psycopg2/
- window function - https://learnsql.com/course/window-functions
- window function - https://campus.datacamp.com/courses/intermediate-t-sql/window-functions?ex=4
- Хорошая статья об оконных функций SQL - https://khashtamov.com/ru/window-functions-sql/
Парсинг
- Русский перевод документации к BeautifulSoup Beautiful Soup — это библиотека Python для извлечения данных из файлов HTML и XML. Она работает с вашим любимым парсером, чтобы дать вам естественные способы навигации, поиска и изменения дерева разбора. Она обычно экономит программистам часы и дни работы.
- Статья с примером парсинга данных с веб-сайтов с применением BeautifulSoup Освещены все основные этапы: формирование запроса и получение странички с помощью requests, поиск нужного элемента в HTML через инспектор, выделение данных из элемента через методы BeautifulSoup.
API
Работа с первичной аналитикой: выгружаем сырые данные из Метрики с помощью скрипта
Forwarded from Сингулярити 🎉
То чувство, когда Telegram начинает тестировать рекламные сообщения... но не на твоем канале. Потому что и Дурову ты не нужен.
забавный редактор для 3D
https://www.tinkercad.com
забавно что построено это немного по другому принципу, нежели в солидворкс. очень напомнило флэш в логике создания обьектов
сложных инженерных штук мне кажется сделать будет нереально но для 3д принтера накидать побыстрому чтото простое очень даже в тему. онлайн это плюс
https://www.tinkercad.com
забавно что построено это немного по другому принципу, нежели в солидворкс. очень напомнило флэш в логике создания обьектов
сложных инженерных штук мне кажется сделать будет нереально но для 3д принтера накидать побыстрому чтото простое очень даже в тему. онлайн это плюс
Tinkercad
Tinkercad is a free, easy-to-use app for 3D design, electronics, and coding.
Forwarded from Технотренды
Юлий Цезарь в мире ИИ: Google разрабатывает многозадачную ИИ-модель Pathways
Корпорация Google заявила о начале работы над проектом из сферы ИИ, в рамках которого корпорация планирует создавать комплексные нейросети. Они, по словам разработчиков, смогут одновременно работать над решением тысяч или даже миллионов разных тасков одновременно. Проект получил название Pathways.
#ai #google
Корпорация Google заявила о начале работы над проектом из сферы ИИ, в рамках которого корпорация планирует создавать комплексные нейросети. Они, по словам разработчиков, смогут одновременно работать над решением тысяч или даже миллионов разных тасков одновременно. Проект получил название Pathways.
#ai #google
Forwarded from Акула (в) IT
ARIES (1/8)
Введение.
ARIES — алгоритм записи и восстановления данных в транзакционных системах, основанный на write-ahead logging (WAL). Он поддерживает как полный, так и частичный роллбек транзакций, подходит для разных политик buffer manager (часть БД, отвечающая за запись данных с памяти в диск и обратно. Подробнее — ниже), а также позволяет использовать гранулярные блокировки вплоть до блокировки отдельных строк. ARIES основан на полном повторе истории при восстановлении. Другими словами, он не делает разницы между транзакциям, которые успели сделать коммит до начала рестарта, и теми что не успели. ARIES сначала всегда восстанавливает состояние базы до того, каким оно было перед рестартом, а лишь затем откатывает неуспешные транзакции. Такой подход позволяет значительно упростить алгоритм восстановления, особенно если первый его запуск завершился неуспешно. ARIES работает даже при множественных рестартах.
Довольно сложно найти 100% подтверждения, какие базы и когда использовали ARIES. В разных источниках к ним добавляют и Oracle DBMS, и Microsoft SQL server, и IBM DB2. Часто в документациях не пишут, что БД использует ARIES напрямую, но похожие идеи всё равно просачиваются.
ACID и ARIES.
ARIES частично связан с понятием ACID — четырьмя важными свойствами любой транзакционной системы. Поскольку ARIES отвечает за запись и восстановление, он является частью A — Atomicity и D — Durability из ACID. Опосредованно ARIES позволяет делать гранулярные локи, т.е. влияет и на I — Isolation.
Если на чистоту, акроним ACID не особо-то и удачный, в основном из-за путаницы в определениях, которую он создает. К примеру, atomicity здесь не имеет отношение к атомарным операциям в языках программирования и ОС. В ACID, A — это возможность прервать транзакции в любой момент до её полного окончания. Consistency часто не относится к самой БД, а скорее к тому, как данные внутри неё используются приложением. И уж точно consistency в БД и consistency в CAP к примеру — совершенно разные вещи. С Isolation ещё сложнее. Изоляция говорит о том, как БД работает с конкурентными операциями. Фактически, уровень изоляции задаёт, какие ошибки и ситуации можно, а какие нельзя считать корректными. Это определение очень похоже на модели консистентности, но C в ACID уже есть... Хоть c durability вроде как проблем не возникает.
Ещё одна причина, почему ACID несёт больше семантики, чем настоящего смысла заключается в том, что в БД все эти свойства обеспечиваются одновременно. Нет отдельной подсистемы, отвечающий только за durability или только за atomicity, это всё алгоритмы и структуры данных.
ARIES (Algorithm for Recovery and Isolation Exploiting Semantics) — один из самых влиятельных и дремучих алгоритмов записи и восстановления данных. Работа (пдф) датируется 1992 годом, но похожие алгоритмы существуют примерно с 60-70-ых, когда первые базы данных только появились. Идеи из ARIES всё ещё используются повсеместно, а сама работа уже цитировалась более 1500 раз (по google scholar)! Практически любой другой труд про транзакционность или восстановление упоминает ARIES.
Авторы рассказывают не только о проблемах восстановления данных, но также о том, какое влияние алгоритм записи оказывает на возможность БД обеспечивать гранулярность локов (чем меньше данных закрывает один лок, тем больше данных можно менять параллельно), как реализовывать лишь частичный роллбек данных, что делать если процесс восстановления прервётся, и как одновременно принимать новые транзакции, пока старые ещё не восстановились. Здесь же приводится сравнение с существующими на тот момент решениями, и показывается чем они хуже. Последнюю часть я опущу, но это тоже очень любопытное чтиво. Кстати, из-за постоянных сравнений с другими базами и алгоритмами, эту работу читать очень тяжело, хотя сам алгоритм довольно простой.
Вторая-третья часть поста посвящена работе памяти и дисков в БД и подходу write-ahead logging. Само описание ARIES начинается с четвёртого поста и продолжается до конца.
Введение.
ARIES — алгоритм записи и восстановления данных в транзакционных системах, основанный на write-ahead logging (WAL). Он поддерживает как полный, так и частичный роллбек транзакций, подходит для разных политик buffer manager (часть БД, отвечающая за запись данных с памяти в диск и обратно. Подробнее — ниже), а также позволяет использовать гранулярные блокировки вплоть до блокировки отдельных строк. ARIES основан на полном повторе истории при восстановлении. Другими словами, он не делает разницы между транзакциям, которые успели сделать коммит до начала рестарта, и теми что не успели. ARIES сначала всегда восстанавливает состояние базы до того, каким оно было перед рестартом, а лишь затем откатывает неуспешные транзакции. Такой подход позволяет значительно упростить алгоритм восстановления, особенно если первый его запуск завершился неуспешно. ARIES работает даже при множественных рестартах.
Довольно сложно найти 100% подтверждения, какие базы и когда использовали ARIES. В разных источниках к ним добавляют и Oracle DBMS, и Microsoft SQL server, и IBM DB2. Часто в документациях не пишут, что БД использует ARIES напрямую, но похожие идеи всё равно просачиваются.
ACID и ARIES.
ARIES частично связан с понятием ACID — четырьмя важными свойствами любой транзакционной системы. Поскольку ARIES отвечает за запись и восстановление, он является частью A — Atomicity и D — Durability из ACID. Опосредованно ARIES позволяет делать гранулярные локи, т.е. влияет и на I — Isolation.
Если на чистоту, акроним ACID не особо-то и удачный, в основном из-за путаницы в определениях, которую он создает. К примеру, atomicity здесь не имеет отношение к атомарным операциям в языках программирования и ОС. В ACID, A — это возможность прервать транзакции в любой момент до её полного окончания. Consistency часто не относится к самой БД, а скорее к тому, как данные внутри неё используются приложением. И уж точно consistency в БД и consistency в CAP к примеру — совершенно разные вещи. С Isolation ещё сложнее. Изоляция говорит о том, как БД работает с конкурентными операциями. Фактически, уровень изоляции задаёт, какие ошибки и ситуации можно, а какие нельзя считать корректными. Это определение очень похоже на модели консистентности, но C в ACID уже есть... Хоть c durability вроде как проблем не возникает.
Ещё одна причина, почему ACID несёт больше семантики, чем настоящего смысла заключается в том, что в БД все эти свойства обеспечиваются одновременно. Нет отдельной подсистемы, отвечающий только за durability или только за atomicity, это всё алгоритмы и структуры данных.
ARIES (Algorithm for Recovery and Isolation Exploiting Semantics) — один из самых влиятельных и дремучих алгоритмов записи и восстановления данных. Работа (пдф) датируется 1992 годом, но похожие алгоритмы существуют примерно с 60-70-ых, когда первые базы данных только появились. Идеи из ARIES всё ещё используются повсеместно, а сама работа уже цитировалась более 1500 раз (по google scholar)! Практически любой другой труд про транзакционность или восстановление упоминает ARIES.
Авторы рассказывают не только о проблемах восстановления данных, но также о том, какое влияние алгоритм записи оказывает на возможность БД обеспечивать гранулярность локов (чем меньше данных закрывает один лок, тем больше данных можно менять параллельно), как реализовывать лишь частичный роллбек данных, что делать если процесс восстановления прервётся, и как одновременно принимать новые транзакции, пока старые ещё не восстановились. Здесь же приводится сравнение с существующими на тот момент решениями, и показывается чем они хуже. Последнюю часть я опущу, но это тоже очень любопытное чтиво. Кстати, из-за постоянных сравнений с другими базами и алгоритмами, эту работу читать очень тяжело, хотя сам алгоритм довольно простой.
Вторая-третья часть поста посвящена работе памяти и дисков в БД и подходу write-ahead logging. Само описание ARIES начинается с четвёртого поста и продолжается до конца.
Forwarded from Акула (в) IT
ARIES (2/8)
БД с высоты птичьего полёта. Работа с памятью и диском.
Для начала несколько параграфов о том, как БД работают, если смотреть очень издалека, но чуть ближе, чем при работа с клиентами БД в языках программирования. Фундаментально БД — это точно такой же процесс или группа процессов, запущенных на операционной системе, как наши с вами любимые веб-серверы или приложения на телефоне. Распределённые БД опустим, там всё тоже самое, только в миллиард раз сложнее. Для начала про память и диск в БД, а затем как БД предотвращают потерю данных за счёт логирования.
Как и в любом другом процесс, часть данных БД находится в энергозависимой памяти, она же RAM, она же просто «память». При этом основная задача базы данных — сохранять данные в энергонезависимую память: на HDD, SDD, ленточные накопители (tape drive) в зависимости от того, что у вас там есть под рукой и какой сейчас год. Энергонезависимые устройства обычно сильно медленнее читают, и уж тем более записывают данные, чем память. Настолько медленно, что у БД нет совершенно никакой возможности транслировать запросы на чтения и записи напрямую в диск. Получается дилемма. С одной стороны, БД должна всё сохранять в диск, чтобы данные не терялись. С другой, часть данных нужно хранить в памяти, потому что диски слишком медленные. А информация из памяти пропадает сразу, как только выключается свет или умирает процесс с БД.
Самый прямолинейный выход из такой ситуации: хранить в БД буфер памяти (memory buffer), отображаемый периодически один-к-одному на диск. Решение не идеальное, поскольку объём дисков обычно многократно больше объёма памяти, всё хранить не получится. К тому же записывать и читать прямо весь буфер сразу — затратно. Не синхронизировать же в самом деле по 32+ ГБ RAM за раз. Но выход есть: хранить только какое-то количество страниц (page) в памяти. Страницы обычно делают одинакового размера — так с ними проще работать. Здесь мы исходит из предложения, что все данные разом скорее всего не нужны, поэтому можно хранить только ту часть, с которой сейчас идёт работа.
Выходит, в БД хранится некий набор страниц, отображаемых 1-к-1 на участки диска. А теперь финт ушами. Вот мы вытащили страницу из диска и храним её в памяти. Поскольку единственный способ поменять содержимое диска — записать страницу, пока этого не произошло, наша страница — это точное отображение данных на диске. И она хранится в памяти. Значит любой запрос к данным на диске можно адресовать к этой самой странице в памяти. Это от нескольких раз до нескольких порядков быстрее!
Теперь про запись. Пока данные на странице не поменялись, т.е. пока страница остаётся «чистой» — можно даже не ходить в диск, так как данные есть в памяти. Как только данные на странице поменялись, она становится «грязной» (dirty page). Такую страницу нужно запись на жёсткий диск, чтобы она снова стала чистой. Записью и чтением страниц из памяти и наоборот в БД занимается компонент под названием buffer manager (Далее — BM). Кстати, если вам кажется, что вы что-то такое про страницы и синхронизации уже слышали, то как оно и есть! Виртуальная память в ОС работает довольно похожим образом, правда у ОС не стоит задачи все данные впихнуть в диск, а ещё есть аппаратная поддержка. Тем не менее, подходы и даже терминология очень схожи.
БД с высоты птичьего полёта. Работа с памятью и диском.
Для начала несколько параграфов о том, как БД работают, если смотреть очень издалека, но чуть ближе, чем при работа с клиентами БД в языках программирования. Фундаментально БД — это точно такой же процесс или группа процессов, запущенных на операционной системе, как наши с вами любимые веб-серверы или приложения на телефоне. Распределённые БД опустим, там всё тоже самое, только в миллиард раз сложнее. Для начала про память и диск в БД, а затем как БД предотвращают потерю данных за счёт логирования.
Как и в любом другом процесс, часть данных БД находится в энергозависимой памяти, она же RAM, она же просто «память». При этом основная задача базы данных — сохранять данные в энергонезависимую память: на HDD, SDD, ленточные накопители (tape drive) в зависимости от того, что у вас там есть под рукой и какой сейчас год. Энергонезависимые устройства обычно сильно медленнее читают, и уж тем более записывают данные, чем память. Настолько медленно, что у БД нет совершенно никакой возможности транслировать запросы на чтения и записи напрямую в диск. Получается дилемма. С одной стороны, БД должна всё сохранять в диск, чтобы данные не терялись. С другой, часть данных нужно хранить в памяти, потому что диски слишком медленные. А информация из памяти пропадает сразу, как только выключается свет или умирает процесс с БД.
Самый прямолинейный выход из такой ситуации: хранить в БД буфер памяти (memory buffer), отображаемый периодически один-к-одному на диск. Решение не идеальное, поскольку объём дисков обычно многократно больше объёма памяти, всё хранить не получится. К тому же записывать и читать прямо весь буфер сразу — затратно. Не синхронизировать же в самом деле по 32+ ГБ RAM за раз. Но выход есть: хранить только какое-то количество страниц (page) в памяти. Страницы обычно делают одинакового размера — так с ними проще работать. Здесь мы исходит из предложения, что все данные разом скорее всего не нужны, поэтому можно хранить только ту часть, с которой сейчас идёт работа.
Выходит, в БД хранится некий набор страниц, отображаемых 1-к-1 на участки диска. А теперь финт ушами. Вот мы вытащили страницу из диска и храним её в памяти. Поскольку единственный способ поменять содержимое диска — записать страницу, пока этого не произошло, наша страница — это точное отображение данных на диске. И она хранится в памяти. Значит любой запрос к данным на диске можно адресовать к этой самой странице в памяти. Это от нескольких раз до нескольких порядков быстрее!
Теперь про запись. Пока данные на странице не поменялись, т.е. пока страница остаётся «чистой» — можно даже не ходить в диск, так как данные есть в памяти. Как только данные на странице поменялись, она становится «грязной» (dirty page). Такую страницу нужно запись на жёсткий диск, чтобы она снова стала чистой. Записью и чтением страниц из памяти и наоборот в БД занимается компонент под названием buffer manager (Далее — BM). Кстати, если вам кажется, что вы что-то такое про страницы и синхронизации уже слышали, то как оно и есть! Виртуальная память в ОС работает довольно похожим образом, правда у ОС не стоит задачи все данные впихнуть в диск, а ещё есть аппаратная поддержка. Тем не менее, подходы и даже терминология очень схожи.
Forwarded from Акула (в) IT
ARIES (3/8)
БД с высоты птичьего полёта. Политики buffer manager и write-ahead logging.
Buffer manager в транзакционной системе может работать в разных режимах, которые иногда называют политиками. Одна из таких политик — steal / no steal. Суть такая: внутри транзакционной системы исполняются... транзакции. Они меняют содержимое чистых страниц из-за чего те становятся грязными. Одна транзакция может одновременно менять содержимое нескольких страниц. Протекать транзакция тоже может относительно долго, вплоть до коммита или полного роллбека. Здесь встаёт вопрос — а можно ли записать грязную страницу на диск, сделав её чистой, до того, как все транзакции, использующие эту страницу, завершатся. Если так можно делать, BM придерживается steal политики. Если нельзя, т.е. записать можно только страницы, над которыми сейчас не происходит изменения, используется no steal политика.
Steal политика позволяет выкинуть кучу примитивов синхронизации и увеличить конкурентность доступа, но с другой стороны, при steal политике нужно контроллировать, какая часть обновлений каждой транзакции уже записана на диск, а какая находится в грязных страницах.
Другая важная политика BM — force / no-force. При force политике транзакция не может завершиться коммитом, пока все её изменения не будут записаны на энергонезависимое хранилище. Другими словами, каждая транзакция всегда синхронизирует свои изменения на диск. Force политика очень упрощает процесс восстановления, потому что если транзакция успела сделать коммит до отказа БД, данные точно есть в хранилище. С другой стороны, при force политике про производительность можно забыть. Синзронизировать вообще каждое изменение в диск — супер затратно.
ARIES позволяет работать с самым мягким набором политик — steal + no-force, и всё ещё обеспечивать «гарантированное» сохранение данных. В кавычках, потому что нельзя взять и отбросить все мириады особенностей OS, дисков, SSD и их драйверов из-за которых вроде запись гарантируется, но не всегда. Прежде чем перейти к ARIES, осталось сказать про алгоритм/протокол write-ahead logging. Протоколом он называется в самой работе.
Write-ahead logging использует в системах, в которых страницы с изменениями перезаписываются. Другими словами, существует одна копия страницы на диске и её клон в памяти в виде чистой или грязной страницы. Никаких вторых версий в другом месте, только одна копия. Такой подход накладывает некоторые ограничения, а именно: при использовании WAL, перед тем как грязная страница в памяти получит право перезаписать страницу на диске, сначала на диск обязательно должен быть сохранён лог, содержащий изменения. Сначала лог с информации об обновлении, потом само обновление. Поэтому подход и называется write-ahead logging.
WAL в общем случае — это привычный всем лог. Как и любой лог, пишется он только вперёд. Синхронизация такого лога также происходит достаточно быстро, поскольку старые данные не могут меняться. Слово «синхронизация» здесь используется не случайно, потому что WAL это очередной буфер, который живет в памяти БД и гипотетически может не дожить до записи на диск. Чтобы этого не происходило, как правило БД синхронизирует WAL при коммитах/прерываниях транзакций. Ещё одна причина для синхронизации WAL — превышение размер буфера или просто по времени. В постгресе к примеру размер буфера и время после которого произойдёт запись можно даже настроить.
Замечу ещё, что протокол write-ahead logging и сам журнал с логами часто в литературе называется одним словом — WAL. Обычно это не приводит к путанице, так как по контексту понятно, идёт ли речь о протоколе или о файле. В общем случае, протокол WAL — это правило, из-за которого обновление страницы в диск может попасть только после того, как в этот же диск попадёт обновление журнала. А лог WAL — это файл с записями о транзакциях.
БД с высоты птичьего полёта. Политики buffer manager и write-ahead logging.
Buffer manager в транзакционной системе может работать в разных режимах, которые иногда называют политиками. Одна из таких политик — steal / no steal. Суть такая: внутри транзакционной системы исполняются... транзакции. Они меняют содержимое чистых страниц из-за чего те становятся грязными. Одна транзакция может одновременно менять содержимое нескольких страниц. Протекать транзакция тоже может относительно долго, вплоть до коммита или полного роллбека. Здесь встаёт вопрос — а можно ли записать грязную страницу на диск, сделав её чистой, до того, как все транзакции, использующие эту страницу, завершатся. Если так можно делать, BM придерживается steal политики. Если нельзя, т.е. записать можно только страницы, над которыми сейчас не происходит изменения, используется no steal политика.
Steal политика позволяет выкинуть кучу примитивов синхронизации и увеличить конкурентность доступа, но с другой стороны, при steal политике нужно контроллировать, какая часть обновлений каждой транзакции уже записана на диск, а какая находится в грязных страницах.
Другая важная политика BM — force / no-force. При force политике транзакция не может завершиться коммитом, пока все её изменения не будут записаны на энергонезависимое хранилище. Другими словами, каждая транзакция всегда синхронизирует свои изменения на диск. Force политика очень упрощает процесс восстановления, потому что если транзакция успела сделать коммит до отказа БД, данные точно есть в хранилище. С другой стороны, при force политике про производительность можно забыть. Синзронизировать вообще каждое изменение в диск — супер затратно.
ARIES позволяет работать с самым мягким набором политик — steal + no-force, и всё ещё обеспечивать «гарантированное» сохранение данных. В кавычках, потому что нельзя взять и отбросить все мириады особенностей OS, дисков, SSD и их драйверов из-за которых вроде запись гарантируется, но не всегда. Прежде чем перейти к ARIES, осталось сказать про алгоритм/протокол write-ahead logging. Протоколом он называется в самой работе.
Write-ahead logging использует в системах, в которых страницы с изменениями перезаписываются. Другими словами, существует одна копия страницы на диске и её клон в памяти в виде чистой или грязной страницы. Никаких вторых версий в другом месте, только одна копия. Такой подход накладывает некоторые ограничения, а именно: при использовании WAL, перед тем как грязная страница в памяти получит право перезаписать страницу на диске, сначала на диск обязательно должен быть сохранён лог, содержащий изменения. Сначала лог с информации об обновлении, потом само обновление. Поэтому подход и называется write-ahead logging.
WAL в общем случае — это привычный всем лог. Как и любой лог, пишется он только вперёд. Синхронизация такого лога также происходит достаточно быстро, поскольку старые данные не могут меняться. Слово «синхронизация» здесь используется не случайно, потому что WAL это очередной буфер, который живет в памяти БД и гипотетически может не дожить до записи на диск. Чтобы этого не происходило, как правило БД синхронизирует WAL при коммитах/прерываниях транзакций. Ещё одна причина для синхронизации WAL — превышение размер буфера или просто по времени. В постгресе к примеру размер буфера и время после которого произойдёт запись можно даже настроить.
Замечу ещё, что протокол write-ahead logging и сам журнал с логами часто в литературе называется одним словом — WAL. Обычно это не приводит к путанице, так как по контексту понятно, идёт ли речь о протоколе или о файле. В общем случае, протокол WAL — это правило, из-за которого обновление страницы в диск может попасть только после того, как в этот же диск попадёт обновление журнала. А лог WAL — это файл с записями о транзакциях.
Forwarded from Акула (в) IT
ARIES (4/8)
Содержание WAL в ARIES.
Наконец-то подошли к самому интересному, как собственно ARIES работает. Он работает через повторение истории. Это значит, что в WAL должно содержаться достаточно информации, чтобы эту самую историю повторить, а значит надо сначала поговорить о кусочках, из которых состоит WAL и вспомогательных структурах в БД. Сейчас будет много наименований и терминов, но ниже пример, так что держитесь. В крайнем случае в конце последнего поста есть ссылка на youtube лекцию — очень советую, если останутся вопросы.
Поскольку запись в WAL идёт последовательно, каждой записи в нём можно присвоить некий монотонно возрастающий номер. Он называется log sequence number или LSN. В некоторых ситуациях LSN даже не нужно присваивать, так как запись идёт последовательно, т.е. в качестве LSN подойдет адрес на диске. Это работает до тех пор, пока лог не перестанет помещаться на диске. Чтобы избежать уже этой проблемы, если свои хаки, например диск можно рассматривать как циклический буфер, а LSN будет записываться как адрес + количество циклов, но это детали реализации. Важно одно — каждая запись в WAL содержит LSN, по которому можно построить историю обновлений БД.
Помимо LSN каждая запись также содержит 3 другие поля: prevLSN, TrId и type. PrevLSN указывает на предыдущую запись в лог, созданную транзакцией под номером TrId. Другими словами, набор записей с одинаковым TrId образуют связный список, где предыдущую запись всегда можно найти по prevLSN.
Type указывает на тип записи. Типов в разных источниках выделяют разное количество, но нам хватит трёх. От типа зависит, какие ещё поля содержатся в одной записи в WAL.
Самый простой тип записи это "commit". Он не содержит других полей и всего лишь говорит о том, что транзакция завершилась успешно.
Далее идёт запись, отвечающая за изменения или создание новых данных, а именно "update". Каждое обновление содержит помимо prevLSN, TrId и type="update" ещё 3 новых поля. Первое pageId — страница, на которой происходит обновление, а второе и третье — redoData и undoData. Redo — это непосредственно те изменения, которые вносятся в рамках транзакции. Там может быть какой-нибудь инкремент значения или новое значение для колонки. Undo — обратная операция. Если Redo — инкремент, Redo — декремент. Если Redo — новое значение, в Undo будет содержаться старое. Не так важно, лежит ли в undo/redo изменение в логическом виде или результат после его применения — оба подхода работают, важно что в одной update записи в WAL написано и как применить изменение, и как его откатить.
Последний интересный вид лога — это компенсирующие логи, они же compensation log records они же CLR. Такие логи записываются базой при роллбеках. На каждую запись с типом update при полном роллбеке будет по одной записи с типом CLR, только применяться они будут в обратно порядке. Сначала откатиться самый старый апдейт, потом тот что был перед ним и так далее. Каждый CLR Помимо prevLSN, TrId и type="compensations" содержит pageId, который как и в update логах обозначает номер страницы, а ещё два поля, которые я назвал особым образом, чтобы стало понятнее, но не уверен что получилось.
Первое поле: redoTheUndoData. CRL используется при роллбеках, т.е. он откатывает транзакцию. Информация об откатывании находится в связанном "update" логе в поле undoData. CRL как раз таки и содержит эту undoData в поле redoTheUndoData. Иными словами, CRL говорит о том, какую операцию нужно исполнить, чтобы откатить связанную запись.
Второе поле: undoNextLSN. В нём хранится информация о записи в WAL, которую нужно откатить после того, как откатится текущая. Если откатить нужно только одну запись, здесь может содержаться null или другой аналог пустого значения. Таким образом несколько CRL логов не связаны между собой напрямую, но опосредованно связаны через undoNextLSN.
Содержание WAL в ARIES.
Наконец-то подошли к самому интересному, как собственно ARIES работает. Он работает через повторение истории. Это значит, что в WAL должно содержаться достаточно информации, чтобы эту самую историю повторить, а значит надо сначала поговорить о кусочках, из которых состоит WAL и вспомогательных структурах в БД. Сейчас будет много наименований и терминов, но ниже пример, так что держитесь. В крайнем случае в конце последнего поста есть ссылка на youtube лекцию — очень советую, если останутся вопросы.
Поскольку запись в WAL идёт последовательно, каждой записи в нём можно присвоить некий монотонно возрастающий номер. Он называется log sequence number или LSN. В некоторых ситуациях LSN даже не нужно присваивать, так как запись идёт последовательно, т.е. в качестве LSN подойдет адрес на диске. Это работает до тех пор, пока лог не перестанет помещаться на диске. Чтобы избежать уже этой проблемы, если свои хаки, например диск можно рассматривать как циклический буфер, а LSN будет записываться как адрес + количество циклов, но это детали реализации. Важно одно — каждая запись в WAL содержит LSN, по которому можно построить историю обновлений БД.
Помимо LSN каждая запись также содержит 3 другие поля: prevLSN, TrId и type. PrevLSN указывает на предыдущую запись в лог, созданную транзакцией под номером TrId. Другими словами, набор записей с одинаковым TrId образуют связный список, где предыдущую запись всегда можно найти по prevLSN.
Type указывает на тип записи. Типов в разных источниках выделяют разное количество, но нам хватит трёх. От типа зависит, какие ещё поля содержатся в одной записи в WAL.
Самый простой тип записи это "commit". Он не содержит других полей и всего лишь говорит о том, что транзакция завершилась успешно.
Далее идёт запись, отвечающая за изменения или создание новых данных, а именно "update". Каждое обновление содержит помимо prevLSN, TrId и type="update" ещё 3 новых поля. Первое pageId — страница, на которой происходит обновление, а второе и третье — redoData и undoData. Redo — это непосредственно те изменения, которые вносятся в рамках транзакции. Там может быть какой-нибудь инкремент значения или новое значение для колонки. Undo — обратная операция. Если Redo — инкремент, Redo — декремент. Если Redo — новое значение, в Undo будет содержаться старое. Не так важно, лежит ли в undo/redo изменение в логическом виде или результат после его применения — оба подхода работают, важно что в одной update записи в WAL написано и как применить изменение, и как его откатить.
Последний интересный вид лога — это компенсирующие логи, они же compensation log records они же CLR. Такие логи записываются базой при роллбеках. На каждую запись с типом update при полном роллбеке будет по одной записи с типом CLR, только применяться они будут в обратно порядке. Сначала откатиться самый старый апдейт, потом тот что был перед ним и так далее. Каждый CLR Помимо prevLSN, TrId и type="compensations" содержит pageId, который как и в update логах обозначает номер страницы, а ещё два поля, которые я назвал особым образом, чтобы стало понятнее, но не уверен что получилось.
Первое поле: redoTheUndoData. CRL используется при роллбеках, т.е. он откатывает транзакцию. Информация об откатывании находится в связанном "update" логе в поле undoData. CRL как раз таки и содержит эту undoData в поле redoTheUndoData. Иными словами, CRL говорит о том, какую операцию нужно исполнить, чтобы откатить связанную запись.
Второе поле: undoNextLSN. В нём хранится информация о записи в WAL, которую нужно откатить после того, как откатится текущая. Если откатить нужно только одну запись, здесь может содержаться null или другой аналог пустого значения. Таким образом несколько CRL логов не связаны между собой напрямую, но опосредованно связаны через undoNextLSN.
Forwarded from Акула (в) IT
ARIES (5/8)
Пример WAL, прочие структуры данных.
Настало время привести пример. Для упрощения я опущу работу со страницами, полями pageId и покажу как связаны все записи в WAL.
Пусть есть некая страница X с двумя поля
Напомню, что запись с типом update содержит поля prevLSN, TrId, pageId (опустим), redoData и undoData:
Первые две записи содержат "-" вместо поля prevLSN, поскольку они являются первыми изменениями в своих транзакциях. Запись 3 (LSN = 79) в поле prevLSN содержит 77 — это указание на LSN предыдущей записи, сделанной этой транзакцией, т.е. записи с LSN = 77.
Теперь пусть транзакция 2 сделать коммит, а транзакция 1 сделает полный роллбек предыдущих обновлений, затем увеличивать k на 13, а затем сделает коммит. Получится следующая ситуация:
Для начала посмотрим на запись 89. В поле redoTheUndoData содержится
Если бы в undoNextLSN не было бы данных, это означало бы, что роллбек частичный, т.е. откатывается только одна запись из двух. Другими словами, наличие записи в undoNextLSN означает, что роллбек ещё не завершён. Когда роллбек откатит последнюю запись в CRL в undoNextLSN не будет ссылки. Именно этот случай показан в записи под номером 90. Здесь тоже CLR запись, но следующий за ней записи нет, поэтому в поле undoNextLSN стоит "-".
Помимо особого способа заполнения WAL, ARIES ещё нужно поддерживать рядом с журналом две таблицы. Их можно собрать по WAL, поэтому достаточно держать их в памяти.
Первая — это таблица грязных страниц dirty pages table (DPT). В ней содержится всего два поля: pageId для номера страницы и указатель на первую запись в WAL, после которой страница стала грязной. Это поле называется recoveryLSN и оно используется для поиска той записи, с которой нужно начинать восстановление. Таблица меняется в двух случаях. Если очередная запись в WAL изменила страницу, которая была чистой — сюда добавляется номер этой страницы и номер LSN записи. Если же страница синхронизируется на диск, запись из DPT удаляется.
Вторая нужная для работы ARIES структура — это таблица транзакций transactions table (TT). В ней находятся все незавершённые транзакции с указанием их идентификатора TrID, а также последнего изменения, произошедшего в рамках этой транзакции lastLSN. У каждой записи в WAL есть указатель на предыдущую запись в поле prevLSN, т.е. все записи объединены в связный список. В TT указывается транзакция и её последнее изменение, т.е. фактически запись здесь — это указатель на голову связного списка. Записи в TT обновляются всякий раз когда в рамках транзакции происходит изменение. Запись удаляется при коммите или полном роллбеке.
Пример WAL, прочие структуры данных.
Настало время привести пример. Для упрощения я опущу работу со страницами, полями pageId и покажу как связаны все записи в WAL.
Пусть есть некая страница X с двумя поля
k и n. Есть также две параллельные транзакции, одна увеличивает k на 2, а вторая уменьшает n на 3. Затем первая транзакция снова увеличивает k на 9. Пока ни одна не успела сделать коммит. Каждая запись в WAL я обозначу числом, которое равно LSN, но как вы помните, писать LSN не обязательно — для этого подойдёт и адрес лога. Начну писать лог с середине, чтобы тоже лишний раз не путаться. Вместо "update" будет просто "u", "commit" — "c", а "compensation" заменю на "clr"Напомню, что запись с типом update содержит поля prevLSN, TrId, pageId (опустим), redoData и undoData:
77. [-, 1, "u", k+=2, k-=2]
78. [-, 2, "u", n-=3, n+=3]
79. [77, 1, "u", k+=9, k-=9]
Первые две записи содержат "-" вместо поля prevLSN, поскольку они являются первыми изменениями в своих транзакциях. Запись 3 (LSN = 79) в поле prevLSN содержит 77 — это указание на LSN предыдущей записи, сделанной этой транзакцией, т.е. записи с LSN = 77.
Теперь пусть транзакция 2 сделать коммит, а транзакция 1 сделает полный роллбек предыдущих обновлений, затем увеличивать k на 13, а затем сделает коммит. Получится следующая ситуация:
77. [-, 1, "u", k+=2, k-=2]
78. [-, 2, "u", n-=3, n+=3]
79. [77, 1, "u", k+=9, k-=9]
...
88. [78, 2, "c"]
89. [79, 1, "clr", k-=9, 77]
90. [89, 1, "clr", k-=2, -]
91. [90, 1, "u", k+=13, k-=13]
92. [91, 1, "c"]
Для начала посмотрим на запись 89. В поле redoTheUndoData содержится
k-=9 — ровно тоже самое, что содержалось в предыдущей записи 79 с типом update в поле undoData. Фактически здесь при создании CLR записи происходит копирование данных. В поле undoNextLSN содержится 77, т.е. указатель на следующая запись, которую нужно откатить во время этого роллбека. Оно скопировано из prevLSN той записи, которая откатывается. У записи с LSN 79 в поле prevLSN записано 77. Если бы в undoNextLSN не было бы данных, это означало бы, что роллбек частичный, т.е. откатывается только одна запись из двух. Другими словами, наличие записи в undoNextLSN означает, что роллбек ещё не завершён. Когда роллбек откатит последнюю запись в CRL в undoNextLSN не будет ссылки. Именно этот случай показан в записи под номером 90. Здесь тоже CLR запись, но следующий за ней записи нет, поэтому в поле undoNextLSN стоит "-".
Помимо особого способа заполнения WAL, ARIES ещё нужно поддерживать рядом с журналом две таблицы. Их можно собрать по WAL, поэтому достаточно держать их в памяти.
Первая — это таблица грязных страниц dirty pages table (DPT). В ней содержится всего два поля: pageId для номера страницы и указатель на первую запись в WAL, после которой страница стала грязной. Это поле называется recoveryLSN и оно используется для поиска той записи, с которой нужно начинать восстановление. Таблица меняется в двух случаях. Если очередная запись в WAL изменила страницу, которая была чистой — сюда добавляется номер этой страницы и номер LSN записи. Если же страница синхронизируется на диск, запись из DPT удаляется.
Вторая нужная для работы ARIES структура — это таблица транзакций transactions table (TT). В ней находятся все незавершённые транзакции с указанием их идентификатора TrID, а также последнего изменения, произошедшего в рамках этой транзакции lastLSN. У каждой записи в WAL есть указатель на предыдущую запись в поле prevLSN, т.е. все записи объединены в связный список. В TT указывается транзакция и её последнее изменение, т.е. фактически запись здесь — это указатель на голову связного списка. Записи в TT обновляются всякий раз когда в рамках транзакции происходит изменение. Запись удаляется при коммите или полном роллбеке.