Как сжать / очистить файл ibdata1 в MySQL - PullRequest
536 голосов
/ 11 августа 2010

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

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

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

Ответы [ 8 ]

755 голосов
/ 11 августа 2010

То, что 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, вам действительно нужно удалить файл:

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

Когда вы запустите 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.

42 голосов
/ 31 октября 2014

Добавление к Ответ Джона П ,

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

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

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

34 голосов
/ 11 августа 2010

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

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

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

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

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

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

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

14 голосов
/ 24 апреля 2012

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

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

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

7 голосов
/ 26 июля 2018

Быстрый сценарий принятой процедуры ответа в bash:

#!/usr/bin/env bash
DATABASES="$(mysql -e 'show databases \G' | grep "^Database" | grep -v '^Database: mysql$\|^Database: binlog$\|^Database: performance_schema\|^Database: information_schema' | sed 's/^Database: //g')"
mysqldump --databases $DATABASES -r alldatabases.sql && echo "$DATABASES" | while read -r DB; do
    mysql -e "drop database \`$DB\`"
done && \
    /etc/init.d/mysql stop && \
    find /var/lib/mysql -maxdepth 1 -type f \( -name 'ibdata1' -or -name 'ib_logfile*' \) -delete && \
    /etc/init.d/mysql start && \
    mysql < alldatabases.sql && \
    rm -f alldatabases.sql

Сохранить как purge_binlogs.sh и запустить как root.

Исключает mysql, information_schema, performance_schema (и каталог binlog).

Предполагается, что у вас есть учетные данные администратора в /root/.my.cnf и ваша база данных находится в каталоге /var/lib/mysql по умолчанию.

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

PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;
6 голосов
/ 26 января 2012

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

MySQL> 5.1.24:

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

MySQL <5.1.24: </p>

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

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

du -b ibdata1

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

4 голосов
/ 07 августа 2017

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

[mysqld]
innodb_file_per_table=1


erase all in /var/lib/mysql
install mysql-server
restore users and databases
0 голосов
/ 21 ноября 2011

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

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

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

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

...