Назад | Перейти на главную страницу

Как MyISAM и InnoDB используют пространство HD?

На моем сервере MySQL быстро заканчивается место на жестком диске. В большинстве моих больших таблиц используется движок InnoDB (без критических причин). В попытке избежать ужасного 'удалить базу данных для восстановления дискового пространства innodb' ответ, я хотел бы лучше понять, как два движка хранят данные на диске.

  1. Если бы я использовал MyISAM, смог бы я легче восстанавливать дисковое пространство, удаляя строки? Есть ли команда, которую мне нужно было бы запустить в дополнение к запросу на удаление / усечение / пустой?
  2. Предполагая, что № 1 был правдой: возможно ли преобразовать существующие таблицы InnoDB в MyISAM и таким образом освободить место?

Использование MySQL DiskSpace вполне предсказуемо.

Information_schema может быстро определить, сколько места используется обоими механизмами хранения. Однако это гораздо лучше настроить InnoDB с помощью innodb_file_per_table. Таким образом, вы можете контролировать дисковое пространство отдельных таблиц InnoDB. Если у вас нет innodb_file_per_table, ibdata1 будет расти и НИКОГДА, НИКОГДА НЕ УДАР.

Я написал хорошие статьи об очистке InnoDB раз и навсегда.

Что касается MyISAM, вам необходимо периодически запускать одно из следующих:

  • OPTIMIZE TABLE myisam-tablename;
  • ALTER TABLE myisam-tablename ENGINE=MyISAM; ANALYZE TABLE myisam-tablename;

Они сжимают MyISAM, чтобы в компонентах таблицы MyISAM (.MYD и .MYI) не осталось неиспользуемых страниц данных и индекса.

Вы можете вручную отслеживать использование дискового пространства с помощью этого запроса:

SELECT IFNULL(B.engine,'Total') "Storage Engine", CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Table Size" FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,SUM(data_length+index_length) TSize FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema') AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,(SELECT 3 pw) A ORDER BY TSize;

Это покажет, сколько места занято данными и индексом для механизма хранения. Обратите внимание на предложение в конце запроса: (SELECT 3 pw). Измените номер для создания отчета в разных единицах

(SELECT 0 pw) for Bytes
(SELECT 1 pw) for KiloBytes
(SELECT 2 pw) for MegaBytes
(SELECT 3 pw) for GigaBytes
(SELECT 4 pw) for TeraBytes
(SELECT 5 pw) for PetaBytes (Write me if you every get numbers this high)

ОБНОВЛЕНИЕ 2012-05-26 22:29 EDT

Когда дело доходит до InnoDB, если вы используете innodb_file_per_table, вы можете обнаружить разницу между размером файла .ibd файл и сумма data_length + index_length.

Для таблицы InnoDB mydb.mytable, вот сравнение, которое вам следует провести:

  • Получите размер файла, запустив ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print %5}'
  • Получим размер таблицы с точки зрения информационной схемы: SELECT data_length+index_length FROM information_schema.tables WHERE table_schema='mydb' AND table_name='mytable';
  • Если filesize > (data_length+index_length) * 1.1, то вы должны перетащить таблицу следующим образом: ALTER TABLE mydb.mytable ENGINE=InnoDB;

Это создаст временную таблицу, скопирует только реальные страницы данных и индексные страницы во временную таблицу, удалит оригинал и переименует временную таблицу обратно в mydb.mytable. Мгновенное сжатие таблицы одной командой. Планируйте все сжатия стола в нерабочее время.

MyISAM выделяет на диск, отражая фактически используемое пространство. Если вы не используете внешние ключи, транзакции или любую другую особенность, уникальную для InnoDB, вы можете легко преобразовать в MyISAM. InnoDB быстрее пишет, а MyISAM быстрее читает. В конце концов, я бы рекомендовал подробно изучить различия между движками, прежде чем произвольно менять механизмы хранения.

Вот процедура, которую я использовал для освобождения табличного пространства InnoDB в прошлом:

Удаление огромных блоков данных из mysql innodb