Как: Очистить движок хранения MySQL InnoDB? - PullRequest
128 голосов
/ 14 октября 2010

Можно ли очистить механизм хранения mysql innodb, чтобы он не сохранял данные из удаленных таблиц?

Или мне нужно каждый раз перестраивать новую базу данных?

Ответы [ 2 ]

341 голосов
/ 30 октября 2010

Вот более полный ответ относительно InnoDB. Это немного длительный процесс, но он может стоить усилий.

Имейте в виду, что /var/lib/mysql/ibdata1 является самым загруженным файлом в инфраструктуре InnoDB. Обычно в нем хранится шесть типов информации:

  • Таблица данных
  • Таблица индексов
  • MVCC (Multiversioning Concurrency Control) Данные
    • Сегменты отката
    • Отменить пробел
  • Метаданные таблицы (словарь данных)
  • Двойной буфер записи (фоновая запись для предотвращения зависимости от кэширования ОС)
  • Вставить буфер (управление изменениями в неуникальных вторичных индексах)
  • См. Pictorial Representation of ibdata1

Архитектура InnoDB

InnoDB Architecture

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

Могу я запустить OPTIMIZE TABLE?

К сожалению, выполнение OPTIMIZE TABLE для таблицы InnoDB, хранящейся в файле общего табличного пространства ibdata1, делает две вещи:

  • Делает данные таблицы и индексы смежными внутри ibdata1
  • Увеличивает ibdata1, потому что смежные страницы данных и индексов добавляются к ibdata1

Однако вы можете отделить Табличные данные и Табличные индексы от ibdata1 и управлять ими независимо.

Можно ли запустить OPTIMIZE TABLE с innodb_file_per_table?

Предположим, вам нужно было добавить innodb_file_per_table к /etc/my.cnf (my.ini). Можете ли вы просто запустить OPTIMIZE TABLE на всех таблицах InnoDB?

Хорошие новости : Когда вы запускаете OPTIMIZE TABLE с innodb_file_per_table, это будет создайте файл .ibd для этой таблицы. Например, если у вас есть таблица mydb.mytable с датадиром /var/lib/mysql, она выдаст следующее:

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

.ibd будет содержать страницы данных и индексные страницы для этой таблицы. Отлично.

Плохие новости : Все, что вы сделали, это извлекли страницы данных и индексные страницы mydb.mytable из жизни в ibdata. Запись словаря данных для каждой таблицы, включая mydb.mytable, все еще остается в словаре данных (см. Графическое представление ibdata1 ). ВЫ НЕ МОЖЕТЕ ПРОСТО УДАЛИТЬ ibdata1 В ЭТОЙ ТОЧКЕ !!! Обратите внимание, что ibdata1 совсем не сократился.

Очистка инфраструктуры InnoDB

Чтобы сжать ibdata1 раз и навсегда, вы должны сделать следующее:

  1. Дамп (например, с mysqldump) всех баз данных в текстовый файл .sql (ниже используется SQLData.sql)

  2. Удалите все базы данных (кроме mysql и information_schema) CAVEAT : В качестве меры предосторожности, пожалуйста, запустите этот скрипт, чтобы убедиться, что у вас есть все пользовательские права на месте:

    mkdir /var/lib/mysql_grants
    cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
    chown -R mysql:mysql /var/lib/mysql_grants
    
  3. Войдите в MySQL и запустите SET GLOBAL innodb_fast_shutdown = 0; (Это полностью сбросит все оставшиеся транзакционные изменения с ib_logfile0 и ib_logfile1)

  4. Завершение работы MySQL

  5. Добавьте следующие строки в /etc/my.cnf (или my.ini в Windows)

    [mysqld]
    innodb_file_per_table
    innodb_flush_method=O_DIRECT
    innodb_log_file_size=1G
    innodb_buffer_pool_size=4G
    

    (Sidenote: Каким бы ни был ваш набор для innodb_buffer_pool_size, убедитесь, что innodb_log_file_size составляет 25% от innodb_buffer_pool_size.

    Также: innodb_flush_method=O_DIRECT недоступно в Windows)

  6. Удалить ibdata* и ib_logfile*, При желании вы можете удалить все папки в /var/lib/mysql, кроме /var/lib/mysql/mysql.

  7. Запустите MySQL (при этом воссоздаются ibdata1 [10 МБ по умолчанию] и ib_logfile0 и ib_logfile1 по 1 ГБ каждый).

  8. Импорт SQLData.sql

Теперь ibdata1 будет по-прежнему расти, но будет содержать только метаданные таблицы, поскольку каждая таблица InnoDB будет существовать вне ibdata1. ibdata1 больше не будет содержать данные InnoDB и индексы для других таблиц.

Например, предположим, что у вас есть таблица InnoDB с именем mydb.mytable. Если вы посмотрите в /var/lib/mysql/mydb, вы увидите два файла, представляющих таблицу:

  • mytable.frm (заголовок ядра хранилища)
  • mytable.ibd (данные таблицы и индексы)

С параметром innodb_file_per_table в /etc/my.cnf вы можете запустить OPTIMIZE TABLE mydb.mytable и файл /var/lib/mysql/mydb/mytable.ibd на самом деле уменьшится.

Я делал это много раз за свою карьеру в качестве администратора базы данных MySQL.Фактически, в первый раз, когда я сделал это, я сократил размер файла 50 ГБ ibdata1 до 500 МБ!

Попробуйте.Если у вас есть дополнительные вопросы по этому поводу, просто спросите.Доверьтесь мне;это будет работать как в краткосрочной, так и в долгосрочной перспективе.

CAVEAT

На шаге 6, если mysql не может перезапуститься из-за сброса схемы mysql, оглянемся на шаг2. Вы сделали физическую копию схемы mysql.Вы можете восстановить его следующим образом:

mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql

Вернитесь к шагу 6 и продолжайте

ОБНОВЛЕНИЕ 2013-06-04 11:13 EDT

Что касается настройки innodb_log_file_size до 25% innodb_buffer_pool_size на шаге 5 это общее правило - довольно старая школа.

Вернемся к July 03, 2006, у Перконы была хорошая статья почемувыбрать правильный innodb_log_file_size .Позже, Nov 21, 2008, Percona опубликовала еще одну статью о о том, как рассчитать правильный размер на основе пиковой рабочей нагрузки, сохраняя стоимость изменений за один час .

.DBA StackExchange о расчете размера журнала и о том, где я ссылался на эти две статьи о Percona.

Лично я бы все равно использовал правило 25% для начальной настройки.Затем, поскольку рабочая нагрузка может быть более точно определена с течением времени при производстве, вы можете изменить размеры журналов во время цикла обслуживания за считанные минуты.

4 голосов
/ 14 октября 2010

Движок InnoDB не сохраняет удаленные данные. Когда вы вставляете и удаляете строки, неиспользуемое пространство остается выделенным в файлах хранения InnoDB. Со временем общее пространство не уменьшится, но со временем «удаленное и освобожденное» пространство будет автоматически повторно использовано сервером БД.

Вы можете дополнительно настроить и управлять пространством, используемым двигателем, с помощью ручного изменения таблиц. Для этого выведите данные в соответствующие таблицы с помощью mysqldump, удалите таблицы, перезапустите службу mysql, а затем заново создайте таблицы из файлов дампа.

...