У меня есть база данных с количеством таблиц.
Я хочу удалить некоторые записи из таблиц, например, нет записей больше 20К или 50К.
Все таблицы являются InnoDB. И file_per_table
это прочь .
Когда я буду удалять записи из ряда таблиц, в таблицах будет фрагментация.
Есть ли способ убрать фрагментацию.?
Обновление 17 апреля
mysql> select TABLE_NAME, TABLE_SCHEMA, Data_free from information_schema.TABLES where TABLE_SCHEMA NOT IN ('information_schema', 'mysql') and Data_Free >0;
+-----------------+--------------+-----------+
| TABLE_NAME | TABLE_SCHEMA | Data_free |
+-----------------+--------------+-----------+
| City | world_innodb | 5242880 |
| City_Copy | world_innodb | 5242880 |
| Country | world_innodb | 5242880 |
| CountryLanguage | world_innodb | 5242880 |
| a | world_innodb | 5242880 |
| t1 | world_innodb | 5242880 |
| t2 | world_innodb | 5242880 |
+-----------------+--------------+-----------+
7 rows in set (0.00 sec)
Итак, теперь мой вопрос заключается в том, как я буду решать, фрагментированы ли мои таблицы или нет.
Ответы:
Я обратился к этому в StackOverflow еще в октябре 2010 года .
Помните о самом загруженном файле в инфраструктуре InnoDB: / var / lib / mysql / ibdata1
Этот файл обычно содержит четыре типа информации
Запуск
OPTIMIZE TABLE
таблицы InnoDB, хранящейся в ibdata1, делает две вещи:Хотя вы можете отделить Табличные данные и Табличные индексы от ibdata1 и управлять ими независимо, используя innodb_file_per_table , большое свободное пространство на диске в ibdata1 просто не исчезнет и не может быть восстановлено. Вы должны сделать больше.
Чтобы сжать ibdata1 раз и навсегда, вы должны сделать следующее:
1) MySQLDump все базы данных в текстовый файл SQL (назовите его /root/SQLData.sql)
2) Удалить все базы данных (кроме схемы mysql).
3) Отключение mysql
4) Добавьте следующие строки в /etc/my.cnf
Примечание: каким бы ни был ваш набор для innodb_buffer_pool_size, убедитесь, что innodb_log_file_size составляет 25% от innodb_buffer_pool_size.
5) Удалить ibdata1, ib_logfile0 и ib_logfile1
На этом этапе должна быть только схема mysql в / var / lib / mysql
6) Перезапустите MySQL
Это воссоздает ibdata1 на 10 или 18 МБ (в зависимости от версии MySQL), ib_logfile0 и ib_logfile1 на 1G каждый
7) Перезагрузите /root/SQLData.sql в mysql
ibdata1 будет расти, но будет содержать только метаданные таблицы. На самом деле, он будет расти очень медленно с годами. Единственный способ быстрого роста ibdata1 - это если у вас есть одно или несколько из следующих:
CREATE TABLE
,DROP TABLE
,ALTER TABLE
)Каждая таблица InnoDB будет существовать вне ibdata1
Предположим, у вас есть таблица InnoDB с именем mydb.mytable. Если вы войдете в / var / lib / mysql / mydb, вы увидите два файла, представляющих таблицу
ibdata1 больше никогда не будет содержать данные InnoDB и индексы.
С параметром innodb_file_per_table в /etc/my.cnf вы можете запустить,
OPTIMIZE TABLE mydb.mytable;
и файл /var/lib/mysql/mydb/mytable.ibd будет фактически уменьшен.Я делал это много раз за свою карьеру в качестве администратора базы данных MySQL
Фактически, в первый раз, когда я сделал это, я свернул файл ibdata1 размером 50 ГБ в 500 МБ.
Попробуйте. Если у вас есть дополнительные вопросы по этому поводу, напишите мне. Доверьтесь мне. Это будет работать в краткосрочной и долгосрочной перспективе !!!
ОБНОВЛЕНИЕ 2012-04-19 09:23 ПО ВОСТОЧНОМУ ВРЕМЕНИ
После выполнения описанных выше шагов, как вы можете определить, какие таблицы необходимо дефрагментировать? Это можно выяснить, но у вас будет скрипт.
Вот пример: Предположим, у вас есть таблица
mydb.mytable
. С включенной innodb_file_per_table у вас есть файл /var/lib/mysql/mydb/mytable.ibdВам нужно будет получить два номера
ФАЙЛИЗАЦИЯ ИЗ ОС: Вы можете определить размер файла из ОС, как это
FILESIZE FROM INFORMATION_SCHEMA: Вы можете определить размер файла из файла information_schema.tables следующим образом:
Просто вычтите значение INFORMATION_SCHEMA из значения ОС и разделите разницу на значение INFORMATION_SCHEMA.
Оттуда вы решите, какой процент считает необходимым дефрагментировать эту таблицу. Конечно, вы дефрагментируете его с помощью одной из следующих команд:
или
источник
Если вы часто удаляете строки (или обновляете строки с типами данных переменной длины), в ваших файлах данных может оказаться много потерянного пространства, аналогично фрагментации файловой системы.
Если вы не используете эту
innodb_file_per_table
опцию, единственное, что вы можете с ней сделать, это экспортировать и импортировать базу данных, процедура, требующая много времени и места.Но если вы используете
innodb_file_per_table
, вы можете идентифицировать и восстановить это пространство!До 5.1.21 счетчик свободного пространства доступен из столбца table_comment в information_schema.tables. Вот некоторый SQL для идентификации таблиц с не менее 100 МБ (фактически 97,65 МБ) свободного пространства:
Начиная с 5.1.21, это было перемещено в столбец data_free (гораздо более подходящее место):
Вы можете восстановить потерянное пространство, восстановив таблицу. Лучший способ сделать это - использовать 'alter table', фактически ничего не меняя:
Это то, что MySQL делает негласно, если вы запускаете «оптимизацию таблицы» для таблицы InnoDB. Это приведет к блокировке чтения, но не полной блокировке таблицы. Сколько времени это займет, полностью зависит от объема данных в таблице (но не от размера файла данных). Если у вас есть таблица с большим количеством удалений или обновлений, вы можете запускать ее ежемесячно или даже еженедельно.
источник