Ето по-пълен отговор по отношение на InnoDB. Това е малко дълъг процес, но може да си струва усилията.
Имайте предвид, че /var/lib/mysql/ibdata1
е най-натовареният файл в инфраструктурата на InnoDB. Обикновено съдържа шест типа информация:
- Данни от таблицата
- Индекси на таблици
- MVCC (Multiversioning Concurrency Control)
Данни
- Сегменти за връщане назад
- Отмяна на интервал
- Метаданни на таблицата (речник на данните)
- Буфер за двойно записване (запис на фон, за да се предотврати разчитането на кеширане на ОС)
- Вмъкване на буфер (управление на промените в неуникални вторични индекси)
- Вижте
Изобразително представяне на ibdata1
Архитектура на InnoDB
Много хора създават множество ibdata
файлове с надежда за по-добро управление на дисковото пространство и производителност, но това убеждение е погрешно.
Мога ли да стартирам OPTIMIZE ТАБЛИЦА
?
За съжаление се изпълнява OPTIMIZE TABLEкод>
срещу InnoDB таблица, съхранена в споделеното пространство за таблици файл ibdata1
прави две неща:
- Прави данните и индексите на таблицата последователни вътре в
ibdata1
- Прави
ibdata1
расте, тъй като последователните страници с данни и индекс са добавени къмibdata1
Можете обаче да отделите таблични данни и индекси на таблици от ibdata1
и ги управлявайте независимо.
Мога ли да стартирам OPTIMIZE ТАБЛИЦА
с innodb_file_per_table
?
Да предположим, че трябва да добавите innodb_file_per_tableкод>
към /etc/my.cnf (my.ini)
. Можете ли след това просто да стартирате OPTIMIZE TABLE
на всички таблици InnoDB?
Добра новина :Когато стартирате OPTIMIZE TABLEкод>
с innodb_file_per_table
активирано, това ще създаде .ibd
файл за тази таблица. Например, ако имате таблица mydb.mytable
с директория с данни на /var/lib/mysql
, той ще произведе следното:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
ще съдържа страниците с данни и индексните страници за тази таблица. Страхотно.
Лоши новини :Всичко, което сте направили, е да извлечете страниците с данни и индексните страници на mydb.mytable
от живеене в ibdata
. Записът в речника с данни за всяка таблица, включително mydb.mytable
, все още остава в речника на данните (Вижте Изобразителното представяне на ibdata1
). НЕ МОЖЕТЕ ПРОСТО ИЗТРИВАНЕ ibdata1
В ТОЗИ МОМЕНТ !!! Моля, имайте предвид, че ibdata1
изобщо не се е свил.
Почистване на инфраструктурата на InnoDB
За свиване на ibdata1
веднъж завинаги трябва да направите следното:
-
Dump (напр. с
mysqldump
) всички бази данни в.sql
текстов файл (SQLData.sql
се използва по-долу) -
Изхвърлете всички бази данни (с изключение на
mysql
иинформационна_схема
) ПРЕДУПРЕЖДЕНИЕ :Като предпазна мярка, моля, стартирайте този скрипт, за да сте сигурни, че имате всички потребителски разрешения:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Влезте в mysql и стартирайте
SET GLOBAL innodb_fast_shutdown =0;
(Това напълно ще изчисти всички останали транзакционни промени отib_logfile0
иib_logfile1
) -
Изключете MySQL
-
Добавете следните редове към
/etc/my.cnf
(илиmy.ini
на Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Странична бележка:Каквото и да сте задали за
innodb_buffer_pool_size
, уверете се, чеinnodb_log_file_size
е 25% отinnodb_buffer_pool_size
.Също така:
innodb_flush_method=O_DIRECT
не е наличен в Windows) -
Изтрийте
ibdata*
иib_logfile*
, По желание можете да премахнете всички папки в/var/lib/mysql
, с изключение на/var/lib/mysql/mysql
. -
Стартирайте MySQL (Това ще създаде отново
ibdata1
[10MB по подразбиране] иib_logfile0
иib_logfile1
по 1G всеки). -
Импортирайте
SQLData.sql
Сега, ibdata1
ще продължи да расте, но ще съдържа само метаданни на таблицата, защото всяка таблица InnoDB ще съществува извън ibdata1
. ibdata1
вече няма да съдържа InnoDB данни и индекси за други таблици.
Например, да предположим, че имате таблица на InnoDB с име mydb.mytable
. Ако погледнете в /var/lib/mysql/mydb
, ще видите два файла, представляващи таблицата:
mytable.frm
(Заглавка на системата за съхранение)mytable.ibd
(Таблица с данни и индекси)
С innodb_file_per_table
опция в /etc/my.cnf
, можете да стартирате OPTIMIZE TABLE mydb.mytable
и файла /var/lib/mysql/mydb/mytable.ibd
всъщност ще се свие.
Правил съм това много пъти в кариерата си като MySQL DBA. Всъщност първият път, когато направих това, свих 50GB ibdata1
файл до само 500 MB!
Пробвам. Ако имате допълнителни въпроси по този въпрос, просто попитайте. Вярвай ми; това ще работи в краткосрочен план, както и в дългосрочен план.
ПРЕДУПРЕЖДЕНИЕ
На стъпка 6, ако mysql не може да се рестартира поради mysql
схемата започва да отпадне, погледнете назад към стъпка 2. Направихте физическото копие на mysql
схема. Можете да го възстановите по следния начин:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Върнете се към Стъпка 6 и продължете
АКТУАЛИЗИРАНЕ 2013-06-04 11:13 EDT
По отношение на настройката innodb_log_file_size до 25% от innodb_buffer_pool_size в Стъпка 5, това общо правило е доста старо училище.
Обратно на 3 юли 2006 г.
, Percona имаше хубава статия защо да изберете подходящ innodb_log_file_s a> . По-късно, на 21 ноември 2008 г.
, Percona последва друга статия за как да изчислим правилния размер въз основа на пиковото работно натоварване, запазвайки стойността на промените за един час
.
Оттогава написах публикации в DBA StackExchange относно изчисляването на размера на журнала и къде се позовавах на тези две статии в Percona.
27 август 2012 г.
:Правилна настройка за 30GB InnoDB таблица на сървър с 48GB RAM17 януари 2013 г.
:MySQL 5.5 - Innodb - innodb_log_file_size по-голям от 4GB заедно?
Лично аз все пак бих спазвал правилото за 25% за първоначална настройка. След това, тъй като работното натоварване може да се определи по-точно с течение на времето в производството, можете да преоразмерите трупитете по време на цикъл на поддръжка само за минути.