MySQL ЗАВАНТАЖЕННЯ ДАНИХ INFILE сповільнюється на 80% після декількох концертних входів за допомогою двигуна InnoDB


14

Я завантажую файл 100 Гб через INFILE ЗАВАНТАЖЕННЯ ДАНИХ. Я мав добрий успіх з MyISAM, кілька годин і зробив.

Я зараз пробую це за допомогою InnoDB. Навантаження починається швидко зі швидкістю понад 10 Мб / сек (спостерігається зростання файлу таблиці, file_per_tableувімкнено).

Але після приблизно 5 ГБ даних він сповільнюється до діапазону 2-4 МБ / сек, оскільки я отримую понад 20 ГБ, він знижувався приблизно в 2 МБ / сек.

Розмір пулів InnoDB - 8G. Перед виконанням команди LOAD DATA INFILE я зробив наступне:

SET @@session.sql_log_bin=0;
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
alter table item_load disable keys;
//Run LOAD DATA INFILE....

Я не бачу причини, чому вона починається добре і з часом сповільнюється.

Також, використовуючи ті самі налаштування, я запустив ту саму команду LOAD DATA INFILE з таблицею за допомогою InnoDB та MyISAM та тестовим набором даних 5 Гб, MyISAM був у 20 разів швидшим:

InnoDB:

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (21 min 25.38 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

MyISAM:

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (1 min 2.52 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

Що б я ще не міг спробувати? Двигун MyISAM здатний набагато краще підтримувати швидкість навантаження.


Додаткові дані:

  • Я намагався завантажувати файли окремо, різниці немає.

  • До речі, у мене 150 файлів по 500 МБ кожен, в кожному файлі клавіші сортуються.

  • Після отримання 40 Гб за ніч, через 12 годин, швидкість навантаження знизилася до 0,5 МБ / сек, тобто операція, практично кажучи, неможлива.

  • Я не знайшов жодних інших відповідей на подібні запитання на інших форумах, мені здається, що InnoDB не підтримує завантаження великої кількості даних у таблиці розміром декілька ГБ.

Відповіді:


7

ЗАБЕЗПЕЧЕННЯ №1

Я помітив, що ви вимкнули autocommit. Це дозволить накопичити стільки даних в ibdata1. Чому?

Існує сім (7) класів інформації, яка зберігається в ibdata1:

  • Сторінки даних для таблиць InnoDB
  • Індексні сторінки для таблиць InnoDB
  • Словник даних
  • Подвійний буфер запису
    • Мережа безпеки для запобігання корупції даних
    • Допомагає обійти ОС для кешування
  • Вставити буфер (упорядкування змін до вторинних індексів)
  • Відхилення сегментів
  • Скасувати журнали
  • Натисніть тут, щоб побачити живописне представлення ibdata1

Частина цієї інформації стає видимою для певних транзакцій залежно від рівня ізоляції. Такі дії можуть створити ненавмисні блокування первинного ключа та безліч фантомних даних . Коли ці дві речі збільшуються, ви повинні очікувати, що це сповільниться.

Рекомендація: Залиште автокомісію увімкнено

ОБМЕЖЕННЯ №2

Я бачу, у вас це є:

alter table item_load disable keys;

ОСНОВНІ КЛЮЧІ не працює з InnoDB . Ось чому:

  • MyISAM: DISABLE KEYSпросто вимикає оновлення вторинного індексу для таблиці MyISAM. Коли ви збираєте INSERT в таблицю MyISAM з відключеними клавішами, ви отримуєте швидке завантаження таблиці разом із будівлею ПЕРВИЧНОГО КЛЮЧА та всіх унікальних індексів. Під час запуску ENABLE KEYSвсі вторинні індекси будуються лінійно на таблиці та додаються до .MYD.
  • InnoDB: Як показано на внутрішній фотографії InnoDB, системний ibdata1набір таблиць має структуру, присвячену Вкладам вторинних індексів. Наразі не існує положення для обробки індексів, таких як MyISAM.

Щоб проілюструвати це, зверніть увагу на мою спробу запустити DISABLE KEYS на таблиці InnoDB в MySQL

mysql> show create table webform\G
*************************** 1. row ***************************
       Table: webform
Create Table: CREATE TABLE `webform` (
  `nid` int(10) unsigned NOT NULL,
  `confirmation` text NOT NULL,
  `confirmation_format` tinyint(4) NOT NULL DEFAULT '0',
  `redirect_url` varchar(255) DEFAULT '<confirmation>',
  `status` tinyint(4) NOT NULL DEFAULT '1',
  `block` tinyint(4) NOT NULL DEFAULT '0',
  `teaser` tinyint(4) NOT NULL DEFAULT '0',
  `allow_draft` tinyint(4) NOT NULL DEFAULT '0',
  `submit_notice` tinyint(4) NOT NULL DEFAULT '1',
  `submit_text` varchar(255) DEFAULT NULL,
  `submit_limit` tinyint(4) NOT NULL DEFAULT '-1',
  `submit_interval` int(11) NOT NULL DEFAULT '-1',
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> alter table webform disable keys;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'webform' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select version();
+------------+
| version()  |
+------------+
| 5.5.27-log |
+------------+
1 row in set (0.00 sec)

mysql>

ЗАБЕЗПЕЧЕННЯ №3

Ви помітили, що MyISAM завантажується в 20 разів швидше, ніж InnoDB. Ви хочете, щоб це було схоже на 24-25 разів швидше? Потім запустіть наступне:

ALTER TABLE item_load ROW_FORMAT=Fixed;

Це пришвидшить INSERT в 20-25% разів без будь-яких інших змін DDL . Побічний ефект: Таблиця MyISAM може вирости на 80% -100%, можливо, і більше.

Ви можете це запустити і на таблиці InnoDB, але поведінка, сумісна з ACID, і MVCC InnoDB все одно будуть вузьким місцем її продуктивності, особливо якщо записуються поля VARCHAR значно збільшуються ibdata1.


Перші два спостереження - це те, що я намагався додати, щоб виправити проблему після того, як я її вперше помітив. Першою моєю спробою було, звичайно, залишити innodb у спокої (просто вимкнути ведення журналу). На третьому спостереженні розмір моїх даних сильно змінюється по довжині, я припускаю, що це буде проблемою? Я відчуваю, що мені просто потрібно зберегти цей стіл мійсам.
Девід Паркс

6

Остаточною відповіддю на це питання було не використовувати InnoDB для масивної довідкової таблиці. MyISAM швидко кричить, майже повну пропускну здатність швидкості диска протягом усього навантаження, InnoDB виходить з ладу. MyISAM простий, але в цьому випадку такі вимоги є і в цій таблиці. Для простої довідкової таблиці з об’ємними навантаженнями через INFILE ЗАВАНТАЖЕННЯ ДАНИХ, MyISAM - це шлях, поки що хороший.

Але зауважте, що якщо ви запускаєте таблиці MyISAM та InnoDB, вам потрібно буде розглянути розподіл пам’яті для двох механізмів кешування, кожен двигун має власне унікальне кешування, яке потребує окремого розподілу пам’яті.


5

Ви можете спробувати розділити вхідні файли на менші шматки.

Я особисто використовую для цього http://www.percona.com/doc/percona-toolkit/2.1/pt-fifo-split.html .

Що станеться, якщо під час імпорту ви отримаєте блокування таблиці для таблиці? Можливо, блокування рівнів InnoDB уповільнює його (MyISAM використовує блокування таблиці).

Ви також можете прочитати тут, щоб отримати додаткові ідеї: http://derwiki.tumblr.com/post/24490758395/loading-half-a-billion-rows-into-mysql


Мої файли вже розміщені в 500 МБ, я перекладав їх через одну названу трубу, щоб полегшити завантаження, але я зараз спробую такий підхід.
Девід Паркс

Не бачачи тут ніякої різниці, досить швидко я бачу зниження швидкості від 11 МБ / сек розширення файлу БД до 6 Мб (приблизно 2 ГБ) даних, і він продовжує падати. Я завантажую всі файли в циклі for, окремі дзвінки mysql.
Девід Паркс

Перший файл завантажений у 54-х, 2-й у 3м39, 3-й у 3м9с, 4м7с, 5м21с тощо. всі файли приблизно однакового розміру.
Девід Паркс

2

Якщо ваш ПК не є AUTO_INCREMENT або дані у файлі csv не відсортовані за ПК, це може вплинути на ефективність завантаження даних. Оскільки таблиця в MySQL є індексом, отже всі дані зберігаються у відсортованому порядку, якщо значення ПК не є AUTO_INCREMENT, ніж MySQL повинен зробити багато зрушення даних, щоб отримати дані, що зберігаються у відсортованому порядку. Це є причиною уповільнення завантаження даних, коли розмір таблиці починає зростати.

Я завантажую файл csv 91 ГБ в ПК на AUTO_INCREMENT, використовуючи ЗАВАНТАЖЕННЯ ДАНИХ INFILE, і я не бачу жодного падіння моєї пропускної здатності. Я отримую 140K до 145K вставок за секунду. Використання Percona MySQL 5.6.38

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