Комментарии 8
Большое спасибо за гайд, но с двойной записью все ещё непонятно: в 2 разных файла данные записываются, или как-то переносятся из одного файла в другой?
"сам doublewrite buffer не удваивает количество IO операций - страницы в doublewrite buffer пишутся большими блоками"
с двойной записью все ещё непонятно: в 2 разных файла данные записываются, или как-то переносятся из одного файла в другой?
Страницы с данными пишутся дважды. Сначала пачкой в double write buffer, потом уже в положенное место (каждая страничка в своё место - здесь получается рандомная запись). Переноса данных между файлами нет - это привело бы к лишним операциям чтения.
"сам doublewrite buffer не удваивает количество IO операций - страницы в doublewrite buffer пишутся большими блоками"
Это почти прямая цитата из документации :)
Теоретически - запись данных два раза должна приводить к двукратному замедлению работы базы. Но на моих замерах производительность с double write и без него - отличалась в пределах погрешности. Справедливости ради, авторы MySQL ожидают 5% замедления от double write, а разработчики из Facebook добавили innodb_doublewrite=DETECT_ONLY
- который пишет только метаданные о страницах (Восстановить страницу из такого doublewrite невозможно, но понять что данные могли быть побиты - можно).
вопрос был исключительно про IO операции, не про замедление работы (конкретно меня больше волнует ресурс диска). Получается, что число операций все же удваивается? Зачем создавать 2 точки отказа вместо одной (если данные побились при первой записи - они невалидные, если только при второй - тоже невалидные, вероятность побиться или при первой, или при второй записи выше, чем только при первой)?
Когда данные пишутся два раза в разные места, и между записью(write) делается flush - у нас всегда есть цельная копия странички. Страничка может быть оказаться неактуальной версии, но к странице можно применить изменения из redo log-а (во второй части статьи), и получить нужную версию.
flush может теперь отказать целых два раза (например, электричество выключили, или контроллер сдох, или kernel panic, или память закончилась).
MySQL может писать в binlog как SQL Statements (Statement-based replication), так и просто измененные данные (row-based replication). Для Statment-based replication сложнее гарантировать детерминированность транзакций и совпадение данных, хранящихся на разных хостах.
Кроме того, существует еще один репликации, а именно mixed, это когда по умолчанию репликация работает в statement, но в случае обнаружения опасных операторов, например, NOW, RANDOM и других, mysql переключится для этих запросов в row based.
Спасибо, за статью, буду ждать вторую часть.
В коллекцию - https://habr.com/ru/articles/820591/ (к ней есть отсылка в начале Вашей статьи. А такие узкотематические материалы мало кто ценит и комментирует)
Разбираемся что MySQL пишет на диск и зачем [часть 1]