Как сжать / очистить файл ibdata1 в MySQL

482

Я использую MySQL в localhost как "инструмент запроса" для выполнения статистики в R, то есть каждый раз, когда я запускаю R script, я создаю новую базу данных (A), создаю новую таблицу (B), импортируйте данные в B, отправьте запрос, чтобы получить то, что мне нужно, а затем я отбрасываю B и отбрасываю A.

Он отлично работает для меня, но я понимаю, что размер файла ibdata быстро растет, я ничего не хранил в MySQL, но файл ibdata1 уже превысил 100 МБ.

Я использую больше или меньше настроек MySQL по умолчанию для установки, есть ли способ, чтобы я мог автоматически сжимать/очищать файл ibdata1 через определенный промежуток времени?

Теги:
database
innodb

7 ответов

650
Лучший ответ

То, что ibdata1 не сокращается, является особенно раздражающей особенностью MySQL. Файл ibdata1 фактически не может быть сокращен, если вы не удалите все базы данных, не удалите файлы и не перезагрузите дамп.

Но вы можете настроить MySQL так, чтобы каждая таблица, включая ее индексы, хранилась как отдельный файл. Таким образом ibdata1 не будет расти столь же большим. Согласно комментарий Билла Карвина, он включен по умолчанию с версии 5.6.6 MySQL.

Недавно я это сделал. Однако, чтобы настроить сервер для использования отдельных файлов для каждой таблицы, вам нужно изменить my.cnf, чтобы включить это:

[mysqld]
innodb_file_per_table=1

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

Как вы хотите вернуть пространство из ibdata1, вам действительно нужно удалить файл:

  • Сделайте mysqldump всех баз данных, процедур, триггеров и т.д. , за исключением mysql и performance_schema баз данных
  • Отбросить все базы данных , кроме указанных выше двух баз данных
  • Остановить mysql
  • Удалить ibdata1 и ib_log файлы
  • Запустить mysql
  • Восстановление из дампа

Когда вы запустите MySQL на шаге 5, файлы ibdata1 и ib_log будут воссозданы.

Теперь ты готов идти. Когда вы создаете новую базу данных для анализа, таблицы будут находиться в отдельных файлах ibd*, а не в ibdata1. Как правило, вы сразу же удаляете базу данных, файлы ibd* будут удалены.

http://dev.mysql.com/doc/refman/5.1/en/drop-database.html

Вы, наверное, видели это:
http://bugs.mysql.com/bug.php?id=1341

Используя команду ALTER TABLE <tablename> ENGINE=innodb или OPTIMIZE TABLE <tablename>, вы можете извлекать данные и индексировать страницы из ibdata1 для разделения файлов. Однако ibdata1 не будет сокращаться, если вы не выполните указанные выше шаги.

Что касается information_schema, это необязательно и невозможно отбросить. На самом деле это всего лишь куча просмотров только для чтения, а не таблиц. И нет файлов, связанных с ними, даже не каталог базы данных. informations_schema использует db-движок памяти, и его отбрасывают и регенерируют после остановки/перезапуска mysqld. См. https://dev.mysql.com/doc/refman/5.7/en/information-schema.html.

  • 0
    Согласно dev.mysql.com/doc/refman/5.1/en/… "= 1" не нужно
  • 15
    А как насчет информации_схемы и производительности_схемы?
Показать ещё 19 комментариев
31

Когда вы удаляете таблицы innodb, MySQL не освобождает пространство внутри файла ibdata, поэтому он продолжает расти. Эти файлы почти никогда не сокращаются.

Как сжать существующий файл ibdata:

http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html

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

Если вы используете опцию конфигурации innodb_file_per_table, вы создаете несколько табличных пространств. То есть MySQL создает отдельные файлы для каждой таблицы вместо одного общего файла. Эти отдельные файлы хранятся в каталоге базы данных и удаляются при удалении этой базы данных. Это должно устранить необходимость сжимать/очищать файлы ibdata в вашем случае.

Дополнительная информация о нескольких табличных пространствах:

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

27

Добавление в John P answer,

Для системы linux шаги 1-6 могут быть выполнены с помощью следующих команд:

  • mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
  • DROP DATABASE database_name
  • sudo /etc/init.d/mysqld stop
  • sudo rm /var/lib/mysql/ibdata1
    sudo rm /var/lib/mysql/ib_logfile (и удалите любой другой ib_logfile, который может быть назван ib_logfile0, ib_logfile1 и т.д.)
  • sudo /etc/init.d/mysqld start
  • create database [database_name]
  • mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

Предупреждение: эти инструкции приведут к потере других баз данных, если у вас есть другие базы данных в этом экземпляре mysql. Убедитесь, что шаги 1,2 и 6,7 изменены для охвата всех баз данных, которые вы хотите сохранить.

  • 6
    Вам нужно повторить 1,2 и 6 для каждой базы данных, в которой есть таблицы InnoDB.
  • 4
    Вам нужно еще пару шагов между № 5 и № 6. Вы должны воссоздать базу данных и переназначить разрешения. Так из командной строки клиента mysql create database database_name; и затем grant all privileges on database_name.* to 'username'@'localhost' identified by 'password';
Показать ещё 4 комментария
13

Если вы используете механизм хранения InnoDB для (некоторых) ваших таблиц MySQL, вероятно, вы уже столкнулись с проблемой с настройкой по умолчанию. Как вы, возможно, заметили в своем каталоге данных MySQLs (в Debian/Ubuntu -/var/lib/mysql) находится файл с именем ibdata1. Он содержит почти все данные InnoDB (это не журнал транзакций) экземпляра MySQL и может стать довольно большим. По умолчанию этот файл имеет начальный размер 10 Мб, и он автоматически расширяется. К сожалению, по дизайну файлы данных InnoDB нельзя сжимать. Вот почему DELETE, TRUNCATE, DROP и т.д. Не будут возвращать пространство, используемое файлом.

Я думаю, вы можете найти там хорошее объяснение и решение:

http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/

5

Если ваша цель - контролировать свободное пространство MySQL, и вы не можете остановить MySQL для сжатия вашего файла ibdata, а затем получить его через команды состояния таблицы. Пример:

MySQL > 5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'

MySQL < 5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'

Затем сравните это значение с вашим файлом ibdata:

du -b ibdata1

Источник: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html

1

В новой версии рецептов mysql-сервера выше будет раздавлена ​​база данных "mysql". В старой версии он работает. В новых таблицах переключается на тип таблицы INNODB, и при этом вы будете наносить им ущерб. Самый простой способ - сбросить все базы данных, удалить mysql-сервер, add in остался my.cnf:

[mysqld]
innodb_file_per_table=1


erase all in /var/lib/mysql
install mysql-server
restore users and databases
-3

Как уже отмечалось, вы не можете сжимать ibdata1 (для этого вам нужно сбрасывать и перестраивать), но также часто нет реальной необходимости.

Использование autoextend (возможно, наиболее распространенного размера) ibdata1 предопределяет хранение, увеличиваясь каждый раз, когда он почти заполнен. Это делает записи быстрее, поскольку пространство уже выделено.

Когда вы удаляете данные, он не сжимается, но пространство внутри файла помечено как неиспользуемое. Теперь, когда вы вставляете новые данные, он будет повторно использовать пустое пространство в файле, прежде чем расширять файл.

Таким образом, он будет продолжать расти только в том случае, если вам действительно нужны эти данные. Если вам действительно не нужно место для другого приложения, вероятно, нет причин для его сжатия.

  • 65
    Я думаю, что вы слишком пренебрежительно относитесь к необходимости освободить пространство.
  • 2
    У меня есть твердотельный раздел 60Gig. У меня быстро заканчивается свободное место, так как я работаю с базами данных 4+ гигов. Я надеюсь перенести MySQL в другой раздел в ближайшее время, но этот вопрос и ответы на него помогут мне в то же время
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню