Помните, что самым загруженным файлом в инфраструктуре 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;