Каков наилучший способ уменьшить размер ibdata в MySQL?

63

У меня есть несколько производственных серверов, ibdataразмер файлов которых увеличивается с каждым днем.

Уже занято 290 ГБ пространства.

Таблицы на серверах в основном InnoDB, и есть высокие запросы на чтение и запись.

Размер файла журнала также увеличивается. В таблицах огромное количество данных.

Как я могу контролировать растущий размер обоих?

Я не использую innodb_file_per_table.

Абдул Манаф
источник

Ответы:

104

Помните, что самым загруженным файлом в инфраструктуре InnoDB является / var / lib / mysql / ibdata1

Этот файл обычно содержит много классов информации (когда innodb_file_per_table равен 0)

  • Данные таблицы
  • Табличные индексы
  • Данные MVCC (Multiversioning Concurrency Control)
    • Сегменты отката
    • Отменить табличное пространство
  • Метаданные таблицы
  • См. Графическое представление

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

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

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

Вы можете отделить Табличные данные и Табличные индексы от ibdata1 и управлять ими независимо, используя innodb_file_per_table . Чтобы сжать ibdata1 раз и навсегда, вы должны сделать следующее

Шаг 01) MySQLDump все базы данных в текстовый файл SQL (назовите его SQLData.sql) ( подробнее здесь )

Шаг 02) Отбросьте все базы данных ( за исключением mysql, performance_schemaи information_schema)

Шаг 03) Выключение mysql

Шаг 04) Добавьте следующие строки в /etc/my.cnf

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

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

Шаг 05) Удалите ibdata1, ib_logfile0 и ib_logfile1

На этом этапе должна быть только схема mysql в / var / lib / mysql

Шаг 06) Перезапустите mysql

Это восстановит ibdata1 на 10 МБ, ib_logfile0 и ib_logfile1 на 1G каждый

Шаг 07) Перезагрузите SQLData.sql в mysql

ibdata1 будет расти, но будет содержать только метаданные таблицы

Каждая таблица InnoDB будет существовать вне ibdata1

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

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

ibdata1 больше никогда не будет содержать данные InnoDB и индексы.

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

Я делал это много раз за свою карьеру в качестве администратора базы данных MySQL

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

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

Если вы хотите узнать, сколько фактических данных хранится в MyISAM и InnoDB, выполните этот запрос:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;
RolandoMySQLDBA
источник
Даже с предлагаемыми настройками для my.cnf (который у меня уже есть), удаляя ib_logfile0 и 1 и затем запуская mysql, новые файлы создаются, и в течение нескольких секунд они увеличиваются до размера базы данных, как показано в вашем запросе выше. Не уверен, копирует ли mysql все таблицы и индексы в эти файлы, сохраняя при этом каждую таблицу в отдельном файле.
Аллен Кинг