C, PHP, VB, .NET

Дневникът на Филип Петров


* innodb_file_per_table – необходимото зло

Публикувано на 24 март 2013 в раздел Бази от Данни.

По подразбиране MySQL използва един общ системен файл за запазване на цялата информация свързана с InnoDB таблиците. Файлът се казва ibdata1 и съдържа цялата информация записана във всички InnoDB таблици, всички индекси, както и различни буфери. Един основен недостатък при използването на общо запазване е… че ibdata1 никога не намалява размера си. Дори да изтривате информация от таблиците си, даже и да изтриете цели таблици, файлът няма да намали своята големина. В него остават „дупки“. Така в зависимост от системата, която работи, е съвсем възможно иначе малка база от данни да заема все повече и повече дисково пространство, докато в един момент не запълни целия хард диск.

Алтернативата е да се добави опцията innodb_file_per_table в my.cnf конфигурационния файл. По този начин всяка таблица ще използва свое собствено хранилище (един .frm файл с метаданни и .ibd файл с информацията). Подобна конфигурация има няколко основни предимства:

  • Вече команди като OPTIMIZE ще освобождават дисковото пространство, което не се използва;
  • Можете да разположите различни таблици на различни дискове и така да увеличите бързодействието на системата;
  • Когато правите backup/restore на дадени таблици, вие засягате само тях, а не всички действащи в системата.

За съжаление трябва да се отбележи и един недостатък:

  • Реалните тестове върху система, на която всички таблици са разположени на един твърд диск, обикновено показват намалено бързодействие заради значително повече дискови операции.

При SSD диск това не би било прекалено сериозен проблем разбира се.

В общи линии когато инсталирате нова система е препоръчително да се възползвате от innodb_file_per_table, особено ако тя ще се използва от различни приложения и различни потребители. Администраторите на съществуващи инсталации с MySQL обаче трябва да имат нещо важно предвид – добавянето на innodb_file_per_table в my.cnf няма никакъв ефект върху вече съществуващите таблици в системата. Това означава, че само и единствено новосъздадени таблици ще използват събствен файл – старите ще продължат да работят с общия ibdata1. Ако желаете да преместите съществуваща таблица в свой отделен файл, ще се наложи да изпълните команда:

ALTER TABLE <таблица> ENGINE=InnoDB;

Така таблицата ще се премести в нов самостоятелен файл, но забележете – пространството, което е заемала в ibdata1 няма да се освободи! Тоест ibdata1 наистина е един безкрайно растящ файл. Един от начините да го „смалите“ до стандартните си 10MB е:

  • Да направите пълно резервно копие на всички бази данни (mysqldump с –all-databases);
  • Изтривате с DROP всички бази данни (без information schema);
  • Спирате MySQL и изтривате ibdata1, ib_logfile0 и ib_logfile1;
  • Стартирате MySQL (ще създаде отново стандартния ibdata1) и връщате резервното копие.

Можете да си представите как подобна операция би била доста неприятна на един действащ сървър, особено ако базите от данни са огромни. Затова е хубаво кофигурациите да се правят навреме. Виждал съм лично пример, в който една малка 40MB база от данни беше „изяла“ над 2GB дисково пространство на сървър. А по форумите хората дават и много по-драстични примери. В тези случаи дори намаленото бързодействие наистина си заслужава – именно затова в заглавието написах, че innodb_file_per_table е необходимото зло.

 



Добави коментар

Адресът на електронната поща няма да се публикува


*