Подтвердить что ты не робот

Howto: Очистить механизм хранения mysql InnoDB?

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

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

4b9b3361

Ответ 1

Вот более полный ответ в отношении 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 с datadir /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 раз и навсегда, вы должны сделать следующее:

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

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

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

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

  • Добавьте следующие строки в /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)

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

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

  • Импорт 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 будет фактически уменьшаться.

Я делал это много раз в своей карьере в качестве DBA 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, у Percona была хорошая статья почему выбрать правильный innodb_log_file_size. Позже, на Nov 21, 2008, Percona продолжил работу над еще одной статьей как рассчитать правильный размер, основанный на максимальной рабочей нагрузке, сохраняя изменения в один час.

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

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

Ответ 2

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

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

Ответ 3

Вы можете периодически использовать запрос OPTIMIZE TABLE, чтобы оптимизировать ваше хранилище и немного ускорить запросы SELECT. Ссылка на руководство MySQL: OPTIMIZE TABLE Синтаксис