Point in Time Recovery (PiTR) — это восстановление базы данных на какой‑то конкретный момент времени (с точностью до секунд или до конкретной транзакции).
PiTR невероятно полезен для восстановления базы данных после того, как «случилось непоправимое». Если достаточно точно выбрать точку на которую восстанавливать базу, то можно восстановить базу данных практически без потери данных.
В этой статье мы рассмотрим классический PiTR и еще два способа путешествовать во времени быстрее, и уменьшить количество операций, которые надо выполнять руками.
Это вторая часть моих копаний во внутренностях MySQL. В первой части [habr] были затронуты запись страниц данных на диск (с промежуточной записью в DoubleWrite buffer) и запись бинлогов (с батчингом в виде group commit). В этой части я расскажу про redo log и как все части MySQL координируются для достижения надежной работы.
Разработчики предъявляют высокие требования к базам данных: максимальная надежность (ничего из того, что было записано не должно быть утеряно ни при каких обстоятельствах), и, одновременно, максимальная производительность при различных видах нагрузки (Запись/Чтение или OLTP/OLAP). Достичь этих требований может быть не просто. Давайте попробуем разобраться, как это делает MySQL.
Размышляя о базе данных, легко представить таблицу базы данных как HashMap/BinaryTree, отображающие первичный ключ (primary key) в структурированные записи с данными. Такое хранилище может работать in memory. Но, как только мы захотим записать данные на диск, придется использовать какие-то алгоритмы во внешней памяти. Просто положить наш HashMap на диск не получится, потому что память и диски слишком разные: чтение/запись диска производится блоками, latency диска больше чем у RAM, а еще нельзя будет воспользоваться обычными указателями и аллокаторами памяти - все это придется заменить самостоятельно.
MySQL предоставляет широкий набор встроенных функций, которые покрывают значительную часть ежедневных задач. В ситуациях, когда необходимо реализовать что-то специфичное для вашего проекта - можно создать Хранимую Функцию (Stored Function). Однако, при всей своей гибкости, не все задачи можно легко написать на SQL. В таких ситуациях на помощь приходят User Defined Functions - компилируемые в нативный код функций загружаемых из shared library.
Создать свою UDF, в целом, не сложно надо реализовать несколько методов си-API.
Для самой простой UDF достаточно реализовать всего лишь одну функцию.