Видалення та відновлення місця з таблиці InnoDB


14

У мене є таблиця InnoDB 700 Гб, до якої я більше не пишу даних (лише для читання). Я хотів би видалити старіші дані, які він містить, і повернути цей диск на дисках (оскільки у мене його не вистачає). Видалити частину досить просто, оскільки у мене є первинний індекс з автоматичним включенням, тому я можу просто повторювати їх за допомогою і видаляти рядки, але це не поверне мені простір. Я припускаю, що це OPTIMIZE TABLEбуде, але це може зайняти вічно на столі в 700 Гб, тож чи є інший варіант, який я оглядаю?

Редагувати RolandoMySQLDBA

Припустимо, що ваша таблиця є mydb.mytable, запустіть наступний запит і опублікуйте його тут, щоб ви могли визначити дисковий простір, необхідний для усадки таблиці:

SELECT
    FORMAT(dat/POWER(1024,3),2) datsize,
    FORMAT(ndx/POWER(1024,3),2) ndxsize,
    FORMAT((dat+ndx)/POWER(1024,3),2) tblsize
FROM (SELECT data_length dat,index_length ndx
FROM information_schema.tables WHERE
table_schema='mydb' AND table_name='mytable') A;

Нам також потрібно побачити структуру таблиці, якщо це дозволено.

Редагувати Ноам

Це вихід запиту:

datsize ndxsize tblsize
682.51 47.57 730.08

Це структура таблиці ( SHOW CREATE TABLE)

`CREATE TABLE `mybigtable` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL,  
  `created_at` datetime NOT NULL,  
  `tid` bigint(20) NOT NULL,  
  `text` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
  `ft` tinyint(1) NOT NULL,  
  `irtsd` bigint(20) NOT NULL,  
  `irtuid` int(11) NOT NULL,  
  `rc` int(11) NOT NULL,  
  `r` tinyint(1) NOT NULL,  
  `e` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,  `timezone` varchar(5) NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `uid_tid` (`uid`,`tid`)) ENGINE=InnoDB AUTO_INCREMENT=2006963844 DEFAULT CHARSET=utf8`

Чи є у вас інший об'єм диска, щоб тільки вибирати дані ???
RolandoMySQLDBA

@RolandoMySQLDBA У мене є зовнішній жорсткий диск, який я можу встановити. Це враховує?
Ноам

@RolandoMySQLDBA але буде через звичайно , як варіант , щоб видалити деякий простір без необхідності мати інший 700GB
Ноам

@RolandoMySQLDBA чи викликає зайвий розмір диска проблеми з продуктивністю?
Аріс

@Aris це може залежати від диска та часу пошуку. У наші дні більшість дисків спрацьовують краще зараз, але яка користь - це витрачатися на цикли (навіть дуже швидко), якщо у вас в таблиці великі рідкі кишені дискового простору ???. Особливо це стосується InnoDB, який зазвичай фіксується на 16К блоках. Завдяки внутрішній фрагментації 16К блоків, ви можете дефрагментувати таблицю, використовуючи ALTER TABLE ... ENGINE=InnoDB;(якщо у вас є кімната для цього). Більшість просто задоволені своїми дуже швидкими SSD-дисками і більше не хвилюються.
RolandoMySQLDBA

Відповіді:


21

Це гарне запитання. У вас є кілька рішень, але ваш стіл досить великий, тому жоден не буде без болю :)

У вас є три рішення "зменшити" таблиці InnoDB:

1. ОПТИМІЗУЙТЕ ТАБЛИЦЮ

Ви можете використовувати, OPTIMIZE TABLEяк ви згадували, але вам слід подбати про innodb_file_per_tableзмінну:

mysql> show variables like "innodb_file_per_table";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.00 sec)

Дозволь пояснити:

OPTIMIZE TABLEТі таблиць InnoDB, блокує таблицю, скопіювати дані в нову чисту таблицю (то чому результат вмощується), видалення вихідної таблиці і перейменуйте нову таблицю з оригінальною назвою. Ось чому вам слід подбати про те, щоб подвійний об'єм вашого столу був доступний на вашому диску (під час роботи вам знадобиться 2x700GB).

Коли ви перебуваєте в innodb_file_per_table = УВІМКНЕНО. Усі таблиці мають відповідний файл даних. Тож OPTIMIZEоператор створить новий файл даних (~ 700 ГБ), коли операція закінчиться, MySQL видалить оригінальний і перейменує новий (тож наприкінці 700 ГБ - можливо менше, тому що буде скорочено - даних) генерований під час операції буде випущено)

Коли ви перебуваєте в innodb_file_per_table = ВИКЛ. Усі дані надходять до одного файлу даних: ibdata . Цей файл має сумну особливість, його неможливо скоротити. Таким чином, під час OPTIMIZEпроцесу буде створено вашу нову таблицю (близько 700 ГБ), але навіть після операції падіння та перейменування (та закінчення OPTIMIZEфази) ваші ібдати не випустять ~ 700 ГБ, тому ви захотіли звільнити деякі дані, але у вас є 700 ГБ більше, класно чи не так?

2. АЛЬТЕР ТАБЛИЦЯ

Ви також можете використовувати ALTER TABLEзаяву, ALTER TABLEволя працюватиме так само, як і OPTIMIZE TABLE. Ви можете просто використовувати:

ALTER TABLE myTable EGINE=InnoDB;

3. АЛЬТЕР ТАБЛИЦЯ (ОНЛАЙН)

Проблема OPTIMIZEі в ALTER TABLEтому, що вона блокує таблицю під час роботи. Ви можете скористатися інструментом Percona: pt-online-schema-change (від Percona Toolkit: посилання ). pt-online-схема ... побудує меканізм із тригерами та таблицею temp, що дозволяє дозволити оригінальній таблиці бути доступною для читання та запису під час операції. Я використовую цей інструмент у виробництві для великих, ALTERце досить круто.

Зауважте, що ви повинні мати FOREIGN KEYпосилання на свою таблицю, FK і спрацьовує ризик створити безлад. Щоб перевірити цей попередній запит, запитайте:

mysql> SELECT COUNT(*) FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE REFERENCED_TABLE_NAME = "myTable";
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+
1 row in set (0.04 sec)

Ось як я використовую pt-online-schema-change:

pt-online-schema-change --alter "ENGINE=InnoDB" D=myBase,t=myTable --user --ask-pass

Зауважте, що моя примітка до innodb_file_per_table стосується і цього рішення.

4. mysqldump

Останнє рішення - відтворити всі бази даних з дампа. Страшенно довго, але страшенно ефективно. Зауважте, що це єдине рішення "зменшити" файл ibdata.

Макс.


Крім того, в Інтернеті для інструмента «Percona» в Інтернеті варіант зміни інтернету мені буде потрібно 700 Гб вільного місця на диску?
Ноам

Так, pt-он-лайн просто використовують деякий механізм, щоб зробити АЛЬТЕР в Інтернеті, але це все-таки робить АЛЬТЕР.
Максим Фульє

@MaximeFouilleul чи викликає додатковий розмір диска проблеми з продуктивністю?
Аріс

1

Якщо вам не вистачає розміру диска, я б запропонував вам зробити так, як Макс запропонував за допомогою зміни pt-online-schema (ONLINE). Я опинився в тій же ситуації зі значно меншим столом (200 ГБ) і вирішив зробити деякий компресій одночасно. Щось у цьому напрямку має спрацювати:

pt-online-schema-change --alter="ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4" D=myBase,t=myTable --user --ask-pass

Це працюватиме лише у тому випадку, якщо ви знаходитесь у форматі файлу barracuda та у форматі КОМПАКТУ таблиці. Також у вас повинен бути включений innodb_file_per_table. Це може дивуватись розміру вашої таблиці, особливо якщо багато тексту та якщо ви використовуєте менший KEY_BLOCK_SIZE, наприклад 8K або навіть 4K (за замовчуванням - 16K). Ви також можете перевірити, скільки місця ви можете отримати за допомогою декількох орієнтирів щодо цієї проблеми в інших блогах, але документація на MySQL рекламує від 25% до 50% (для мене це було майже 90%).

Зауважте, що це також може вплинути на продуктивність при виконанні SELECT (з документації на MySQL):

Таким чином, в будь-який момент часу буферний пул може містити як стиснуті, так і нестиснені форми сторінки, або лише стиснуту форму сторінки, або жодну.

MySQL також повинен видаляти дані, коли вони не знаходяться в буферному пулі. Тож будьте попереджені.

У моєму випадку це справді добре спрацювало. У мене був довгий текст. 200 ГБ стало 26 ГБ. Виступи не були змінені.

Для отримання більш детальної інформації перевірте ці посилання:

https://dev.mysql.com/doc/refman/5.5/uk/innodb-compression-usage.html

https://dev.mysql.com/doc/refman/5.5/uk/innodb-compression-internals.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.