Mysql
 sql >> база данни >  >> RDS >> Mysql

Защо InnoDB дава очевидно фалшива информация за свободното пространство

(Това отговаря на някои от въпросите, заровени в коментарите.)

Погрешно обозначение „Свободното“ пространство включва само цели блокове, а не свободно място в блоковете и много други детайли.

Случай 1:Всички таблици са в ibdata1 -- SHOW TABLE STATUS (или еквивалентната заявка в information_schema ще покаже същото Data_free стойност, а именно колко е безплатно в ibdata1 . Това пространство може да се използва повторно от всяка маса. Трудно е да се върне мястото на ОС.

Случай 2:Всички таблици са file_per_table -- Сега всеки Data_free се отнася до мястото за масата. И SUM() е смислено. (ibdata1 все още съществува, но не съдържа реални таблици; има много други неща, от които InnoDB се нуждае.)

Случай 3:Смес -- Ако включите/изключите file_per_table в различни моменти, някои таблици ще бъдат в ibdata1, други ще имат свои собствени пространства за таблици.

Случай 4:СЪЗДАВАНЕ НА ПРОСТРАНСТВО ЗА ТАБЛИЦА в 5.7 -- Например, можете да имате пространство за таблици за всяка база данни.

Случай 5:Разпределени таблици -- Всеки дял действа като таблица.

Случай 6:8.0 -- Предстоят още повече промени.

База данни ==Директория В дървото на директориите на MySQL всяка база данни може да се разглежда като директория на файлова система. В тази директория може да се види някакъв набор от файлове за всяка таблица. .frm файл съдържа дефиницията на таблицата. Ако .ibd файл съществува, таблицата е създадена с file_per_table. Това може да е най-надеждният начин да разберете дали таблицата е file_per_table. (8.0 ще има значителни промени тук.)

Колко място мога да използвам повторно ? Няма добър отговор. Обикновено вмъкването на ред ще намери място в блока, където му е мястото, и Data_free няма да се свие. Но, ако имаше разделяне(я) на блок(и), Data_free може да спадне с някакво кратно на 16KB (размерът на блока) или 4MB („размерът на екстента“ - или може би е 8MB?). Освен това произволните вмъквания водят до това, че BTree блоковете са средно пълни с около 69%.

Промяна на innodb_file_per_table няма ефект до следващия CREATE TABLE или ALTER TABLE . И тогава има ефект само върху това къде да се поставят новосъздадените/копирани данни+индекси (ibdata1 или .ibd). Няма да унищожи данни.

Големи маси обикновено имат 4MB до 7MB Data_free. Когато изчислявате колко реда можете да добавите, не планирайте Data_free да пада под този диапазон.

Avg_row_size трябва да е полезно. Но понякога той (и редовете) са лошо приблизителни. Продуктът им (дължина_на_данни) винаги е правилен. И така, това може би да бъде добра оценка на "редове, които трябва да преминат, преди да вземете повече място от ОС:

(Data_free - 7M) / Avg_row_size

Препоръки за пространство за таблици :Поставете 'големи' таблици във file_per_table. Поставете „малки“ таблици в ibdata1 или специфични за база данни пространства за таблици (5.7). За съжаление няма проста препоръка за разделителната линия между „голям“ и „малък“. И е тромаво да мигрирате таблица:SET global innodb_file_per_table = ...;; излез от профила си; вход (за да вземете глобалния); ALTER TABLE tbl ENGINE=InnoDB; . И задължително е пълно копие на таблицата.

(Предупреждение :Пропуснах много подробности.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySql Count не може да показва 0 стойности

  2. Система за уведомяване, използваща php и mysql

  3. Изпълнение на множество заявки в codeigniter, които не могат да бъдат изпълнени една по една

  4. Въвеждане на променливо количество данни в база данни с възможно най-добро нормализиране

  5. Как да върна различни стойности и техния брой?