Почему MySQL занимает больше места, чем нужно данным

Из таблицы удалили старые записи, а свободного места на диске не прибавилось - знакомая картина? В InnoDB после удалений и обновлений страницы могут оставаться частично заполненными. Освободившееся место внутри файла можно использовать повторно, но сам файл от этого не уменьшается.

В PostgreSQL это различие также есть и его видно даже по командам - обычный VACUUM, который запускает autovacuum, освобождает место для повторного использования внутри таблицы. Чтобы переписать таблицу и вернуть место файловой системе, есть отдельный VACUUM FULL.

В InnoDB старые версии строк убирает фоновый purge, а для перестройки таблицы можно запустить OPTIMIZE TABLE. По цели эта команда ближе к VACUUM FULL. Если таблица хранится в отдельном файле .ibd, после перестройки файл может стать меньше.

Сколько места вернется, проще всего проверить на нескольких крупных таблицах. На одной тестовой базе DATA_FREE показывал около 3%, а после перестройки файлы заняли на 26% меньше. Свободное место было разбросано по страницам, в которых еще оставались данные.

Реплики надо также учитывать и выбирать темп оптимизации, чтобы не накапливать отставания. Например, если мастер перестроил таблицы одной базы за ~10 минут, то на самой медленной реплике может потрабоваться до 30~40 минут, если база была большая. Если сразу брать следуюцую базу, реплика будет разгребать очередь, когда с нее уже пора снимать бэкап. Поэтому после каждой оптимизированной базы желательно взять паузу, пока реплики догонят мастер, а на время бэкапов и миграций вообще поставить работу на паузу.

На одном SaaS-проекте оптимизация уже вернула 400ГБ на мастерах. Файлы обработанных таблиц стали меньше на 21-28%, как и ожидалось. По окончанию процеса должно освододиться до 800 ГиБ на мастерах и примерно столько же на репликах в VK Cloud. Это позволит не наращивать экстренно объем дискового пространства под базы данных и получить необходимый запас перед праздничными пиками. Экономия в деньгах не очень впечатляющая, до 200 тыс. руб. в год, в данном кейсе ценнее запас по диску и отсутствие нобходимости в его экстренном наращивании.

На этом пока всё. Живите долго, деплойте спокойно.

#mysql #innodb #postgresql #базыданных #оптимизация