Pull to refresh

Comments 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, или память закончилась).

При любом отказе flush-а база остановится. Если бы flush был один - то страница с данными могла побиться. Если два - то у нас есть как минимум одна целая копия страницы.

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/ (к ней есть отсылка в начале Вашей статьи. А такие узкотематические материалы мало кто ценит и комментирует)

Sign up to leave a comment.

Articles