Предположим , что вы должны были добавить innodb_file_per_tableк /etc/my.cnf (my.ini). Можете ли вы тогда просто запустить OPTIMIZE TABLEвсе таблицы InnoDB?
Хорошие новости : когда вы запускаете OPTIMIZE TABLEс innodb_file_per_tableвключенным, это создаст .ibdфайл для этой таблицы. Например, если у вас есть таблица mydb.mytableс datadir of /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) ПРЕДОСТЕРЕЖЕНИЕ : В качестве меры предосторожности запустите этот сценарий, чтобы убедиться, что у вас есть все пользовательские гранты:
Войдите в mysql и запустите SET GLOBAL innodb_fast_shutdown = 0;(это полностью очистит все оставшиеся транзакционные изменения из ib_logfile0и ib_logfile1)
Отключение MySQL
Добавьте следующие строки в /etc/my.cnf(или my.iniв Windows)
(Примечание: какой бы ни был ваш набор 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действительно сократится.
Я делал это много раз за свою карьеру администратора баз данных MySQL. Фактически, в первый раз, когда я сделал это, я сжал 50 ГБibdata1 файл до 500 МБ!
Попробуйте. Если у вас есть дополнительные вопросы по этому поводу, просто задавайте их. Доверьтесь мне; это будет работать как в краткосрочной, так и в долгосрочной перспективе.
ПРЕДОСТЕРЕЖЕНИЕ
На шаге 6, если mysql не может перезапуститься из-за того, что mysqlсхема begin отброшена, вернитесь к шагу 2. Вы сделали физическую копию mysqlсхемы. Вы можете восстановить его следующим образом:
Лично я по-прежнему придерживаюсь правила 25% для начальной настройки. Затем, поскольку рабочая нагрузка может быть более точно определена с течением времени в процессе производства, вы можете изменить размеры журналов во время цикла обслуживания за считанные минуты.
Я также с большим эффектом использовал опцию innodb_file_per_table, имея 200 баз данных по 200 таблиц в каждой на одном сервере, я смог символьно связать базы данных различий на разные разделы, поэтому использовал больше буферов ввода-вывода и шпинделей, которые в противном случае были бы доступны :)
Дэйв Рикс,
2
@SeanDowney Кстати не забывайте поднять в innodb_open_tablesслучае необходимости. Значение по умолчанию - 300.
RolandoMySQLDBA
2
@ giorgio79, вам нужно установить большую массовую вставку. Это хороший момент. К своему ответу добавлю суть вашего вопроса.
RolandoMySQLDBA
3
В 32-битных системах значение в 4 Гб для innodb_buffer_pool_size не допускается. Mysql автоматически запустится с отключенным innodb, а восстановленные таблицы будут изменены на myisam. Используйте немного меньшее значение, чтобы исправить это.
Дэвид
5
Боже. Я просто хочу сказать, что это, пожалуй, один из лучших ответов, которые я когда-либо видел на ТАК чертовски хорошая работа, сэр. Помог мне найти решение моей проблемы, когда я получал ОШИБКУ 2013 (HY000) при импорте 154 г дБ. Спасибо за отличный ответ!
Джош Браун
4
Движок InnoDB не хранит удаленные данные. Когда вы вставляете и удаляете строки, неиспользуемое пространство остается выделенным в файлах хранилища InnoDB. Со временем общее пространство не уменьшится, но со временем «удаленное и освобожденное» пространство будет автоматически повторно использовано сервером БД.
Вы можете дополнительно настраивать и управлять пространством, используемым движком, путем ручной реорганизации таблиц. Для этого выполните дамп данных в затронутых таблицах с помощью mysqldump, отбросьте таблицы, перезапустите службу mysql и затем заново создайте таблицы из файлов дампа.
Ответы:
Вот более полный ответ относительно InnoDB. Это немного длительный процесс, но может стоить усилий.
Имейте в виду, что
/var/lib/mysql/ibdata1
это самый загруженный файл в инфраструктуре InnoDB. Обычно он содержит шесть типов информации:Pictorial Representation of ibdata1
InnoDB Архитектура
Многие люди создают несколько
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 of/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
) ПРЕДОСТЕРЕЖЕНИЕ : В качестве меры предосторожности запустите этот сценарий, чтобы убедиться, что у вас есть все пользовательские гранты:Войдите в mysql и запустите
SET GLOBAL innodb_fast_shutdown = 0;
(это полностью очистит все оставшиеся транзакционные изменения изib_logfile0
иib_logfile1
)Отключение MySQL
Добавьте следующие строки в
/etc/my.cnf
(илиmy.ini
в Windows)(Примечание: какой бы ни был ваш набор
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
действительно сократится.Я делал это много раз за свою карьеру администратора баз данных MySQL. Фактически, в первый раз, когда я сделал это, я сжал 50 ГБ
ibdata1
файл до 500 МБ!Попробуйте. Если у вас есть дополнительные вопросы по этому поводу, просто задавайте их. Доверьтесь мне; это будет работать как в краткосрочной, так и в долгосрочной перспективе.
ПРЕДОСТЕРЕЖЕНИЕ
На шаге 6, если mysql не может перезапуститься из-за того, что
mysql
схема begin отброшена, вернитесь к шагу 2. Вы сделали физическую копию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.
Aug 27, 2012
: Правильная настройка для таблицы InnoDB 30 ГБ на сервере с 48 ГБ RAMJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size выше 4 ГБ вместе взятых?Лично я по-прежнему придерживаюсь правила 25% для начальной настройки. Затем, поскольку рабочая нагрузка может быть более точно определена с течением времени в процессе производства, вы можете изменить размеры журналов во время цикла обслуживания за считанные минуты.
источник
innodb_open_tables
случае необходимости. Значение по умолчанию - 300.Движок InnoDB не хранит удаленные данные. Когда вы вставляете и удаляете строки, неиспользуемое пространство остается выделенным в файлах хранилища InnoDB. Со временем общее пространство не уменьшится, но со временем «удаленное и освобожденное» пространство будет автоматически повторно использовано сервером БД.
Вы можете дополнительно настраивать и управлять пространством, используемым движком, путем ручной реорганизации таблиц. Для этого выполните дамп данных в затронутых таблицах с помощью mysqldump, отбросьте таблицы, перезапустите службу mysql и затем заново создайте таблицы из файлов дампа.
источник