Есть только один способ это осуществить. Вам нужно будет экспортировать данные с помощью mysqldumps, удалить все базы данных, завершить работу mysqld, удалить ib_logfile0, удалить ib_logfile1, удалить ibdata1, добавить innodb_file_per_table
под [mysqld]
заголовком, запустить mysql.
Я опубликовал этот ответ в StackOverflow еще в октябре 2010 года.
Вот шаги, перечисленные по вертикали:
Шаг 01) MySQLDump все базы данных в текстовый файл SQL (назовите его SQLData.sql)
Шаг 02) Удалите все базы данных (кроме схемы mysql)
Шаг 03) Выключение mysql
CAVEAT : чтобы полностью очистить незафиксированные транзакции из файлов InnoDB, запустите
mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop
Шаг 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 МБ.
Попробуйте. Если у вас есть дополнительные вопросы по этому поводу, напишите мне. Доверьтесь мне. Это будет работать в краткосрочной и долгосрочной перспективе. !!!
Существует альтернатива, которая извлекает таблицу InnoDB без сокращения ibdata1.
Шаг 01) Добавьте следующие строки в /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
Шаг 02) service mysql restart
Шаг 03) Чтобы извлечь одну таблицу InnoDB с именем mydb.mytable, сделайте это:
ALTER TABLE mydb.mytable ENGINE=InnoDB;
Это создаст один файл, сохраняющий исходную структуру файла.
- /var/lib/mysql/mydb/mytable.frm
- /var/lib/mysql/mydb/mytable.ibd
Вы можете сделать это для каждой таблицы InnoDB. К сожалению, ibdata1 останется 150 ГБ.
ERROR 1071 (42000) at line 25: Specified key was too long; max key length is 1000 bytes
какие-либо идеи?innodb_file_per_table
и затем выполнитеALTER TABLE
каждую таблицу, можете ли вы удалить файл ibdata1, чтобы освободить место без необходимости восстановления?Если вы хотите освободить пространство ibdata, дамп / восстановление является вашим единственным выбором, как отмечает Роландо . Это также, вероятно, лучше для производительности, чтобы сделать это.
Однако, если вы просто хотите сократить свои потери и «потерять» эти 150 ГБ на жестком диске, вы можете просто включить их
innodb_file_per_table
в my.cnf и перезапустить сервер.Затем для каждой таблицы выполните:
Проблема здесь в том, что для больших табличных пространств потребуется некоторое время.
Я бы посоветовал установить подчиненное устройство вашей живой базы данных, запустить преобразование на ведомом устройстве, затем либо отключить мастер / подчиненное устройство и скопировать новое пространство данных на ведущее устройство, либо назначить подчиненное устройство ведущим, как только оно догонит его. ,
Вам будет трудно сделать это изменение без простоев вообще.
источник