InnoDB je jedním z nejpoužívanějších úložišť v MySQL. Tento úložný modul je známý jako vysoce spolehlivý a vysoce výkonný úložný modul a mezi jeho klíčové výhody patří podpora zamykání na úrovni řádků, cizí klíče a následování modelu ACID. InnoDB nahrazuje MyISAM jako výchozí modul úložiště od verze MySQL 5.5, která byla vydána v roce 2010.
Tento úložný modul může být neuvěřitelně výkonný a výkonný, pokud je správně optimalizován – dnes se podíváme na to, co můžeme udělat, aby fungoval co nejlépe, ale než se ponoříme do InnoDB bychom však měli pochopit, co je výše zmíněný ACID model.
Co je ACID a proč je důležitá?
ACID je sada vlastností databázových transakcí. Zkratka se překládá do čtyř slov:Atomicita, Konzistence, Izolace a Trvanlivost. Stručně řečeno, tyto vlastnosti zajišťují, že databázové transakce jsou zpracovávány spolehlivě a zaručují platnost dat navzdory chybám, výpadkům napájení nebo podobným problémům. Systém správy databází, který dodržuje tyto principy, je označován jako DBMS kompatibilní s ACID. Zde je návod, jak vše funguje v InnoDB:
- Atomičnost zajišťuje, že příkazy v transakci fungují jako nedělitelná jednotka a že jejich účinky jsou vnímány společně nebo vůbec;
- Konzistenci zajišťují protokolovací mechanismy MySQL, které zaznamenávají všechny změny v databázi;
- Izolace se týká zamykání InnoDB na úrovni řádků;
- Životnost je také zachována, protože InnoDB spravuje soubor protokolu, který sleduje všechny změny v systému.
Porozumění InnoDB
Nyní, když jsme probrali ACID, bychom se pravděpodobně měli podívat na to, jak InnoDB vypadá pod pokličkou. Zde je návod, jak InnoDB vypadá zevnitř (obrázek s laskavým svolením Percona):
InnoDB InternalsZ obrázku výše jasně vidíme, že InnoDB má několik parametry rozhodující pro jeho výkon a ty jsou následující:
- Parametr innodb_data_file_path popisuje systémový tabulkový prostor (systémový tabulkový prostor je úložná oblast pro datový slovník InnoDB, vyrovnávací paměti pro dvojitý zápis a změny a protokoly zpět). Parametr znázorňuje soubor, do kterého budou uložena data odvozená z tabulek InnoDB;
- Parametr innodb_buffer_pool_size je vyrovnávací paměť, kterou InnoDB používá k ukládání dat a indexů svých tabulek do mezipaměti;
- Parametr innodb_log_file_size znázorňuje velikost souborů protokolu InnoDB;
- Parametr innodb_log_buffer_size se používá k zápisu do souborů protokolu na disku;
- Parametr innodb_flush_log_at_trx_commit řídí rovnováhu mezi přísným dodržováním ACID a vyšším výkonem;
- Parametr innodb_lock_wait_timeout je doba v sekundách, po kterou transakce InnoDB čeká na uzamčení řádku, než se vzdá;
- Parametr innodb_flush_method definuje metodu použitou k vyprázdnění dat do datových souborů InnoDB a souborů protokolu, což může ovlivnit I/O propustnost.
InnoDB také ukládá data ze svých tabulek do souboru nazvaného ibdata1 – protokoly jsou však uloženy ve dvou samostatných souborech s názvem ib_logfile0 a ib_logfile1:všechny tyto tři soubory jsou umístěny v /var/lib/mysql adresář.
Aby byl InnoDB co nejvýkonnější, musíme tyto parametry doladit a co nejvíce je optimalizovat s ohledem na naše dostupné hardwarové zdroje.
Ladění InnoDB pro vysoký výkon
Chcete-li upravit výkon InnoDB na vašem hardwaru, postupujte takto:
-
Chcete-li automaticky rozšířit cestu k souboru innodb_data_file_path, zadejte v nastavení atribut autoextend a restartujte server. Například:
innodb_data_file_path=ibdata1:10M:autoextend
Při použití parametru autoextend se velikost datového souboru automaticky zvětší o 8 MB pokaždé, když je potřeba místo. Nový automaticky rozšiřující datový soubor lze také specifikovat takto (v tomto případě se nový datový soubor nazývá ibdata2):
innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
-
Při použití InnoDB je hlavním použitým mechanismem zásobník vyrovnávacích pamětí. InnoDB silně spoléhá na zásobník vyrovnávacích pamětí a jako orientační pravidlo by měl parametr innodb_buffer_pool_size tvořit přibližně 60 % až 80 % celkové dostupné paměti RAM na serveru. Mějte na paměti, že byste měli ponechat určitou RAM také pro procesy běžící v OS;
-
Velikost innodb_log_file_size InnoDB by měla být nastavena co největší, ale ne větší, než je nutné. V tomto případě mějte na paměti, že větší velikost souboru protokolu je lepší pro výkon, ale čím větší je, tím delší je doba obnovy po havárii. Jako takové neexistuje žádné řešení „jedna velikost pro všechny“, ale říká se, že kombinovaná velikost souborů protokolu by měla být dostatečně velká. To pomáhá serveru MySQL pravidelně pracovat na činnosti kontrolních bodů a vyplachování disku. To šetří příliš mnoho CPU a diskových IO a může běžet hladce během špičky nebo vysoké pracovní zátěže. Ačkoli doporučený přístup je otestovat a experimentovat sami a sami najít optimální hodnotu;
-
Hodnota innodb_log_buffer_size by měla být nastavena alespoň na 16 milionů. Velká vyrovnávací paměť protokolu umožňuje spouštět velké transakce bez nutnosti zapisovat protokol na disk předtím, než se transakce potvrdí, čímž se ušetří část I/O disku;
-
Při ladění innodb_flush_log_at_trx_commit mějte na paměti, že tento parametr přijímá tři hodnoty – 0, 1 a 2. S hodnotou 1 získáte shodu s ACID a s hodnotami 0 nebo 2 získáte vyšší výkon, ale menší spolehlivost, protože v takovém případě mohou být transakce, jejichž protokoly ještě nebyly vyprázdněny na disk, ztraceny při selhání;
-
Aby bylo možné nastavit innodb_lock_wait_timeout na správnou hodnotu, mějte na paměti, že tento parametr definuje čas v sekundách (výchozí hodnota je 50) před vydání následující chyby a vrácení aktuálního příkazu:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
-
V InnoDB je k dispozici několik metod vyprázdnění. Ve výchozím nastavení je toto nastavení nastaveno na „async_unbuffered“ na počítačích se systémem Windows, pokud je hodnota nastavena na NULL a na „fsync“ na počítačích se systémem Linux. Zde jsou uvedeny metody a k čemu slouží:
Metoda InnoDB Flush | Účel |
normální | InnoDB bude používat simulované asynchronní I/O a vyrovnávací I/O. |
bez vyrovnávací paměti | InnoDB bude používat simulované asynchronní I/O a non-buffered I/O. |
async_unbuffered | InnoDB bude používat asynchronní I/O Windows a I/O bez vyrovnávací paměti. Výchozí nastavení na počítačích se systémem Windows. |
fsync | InnoDB použije funkci fsync() k vyprázdnění dat a souborů protokolu. Výchozí nastavení na počítačích se systémem Linux. |
O_DSYNC | InnoDB použije O_SYNC k otevření a vyprázdnění souborů protokolu a funkci fsync() k vyprázdnění datových souborů. O_DSYNC je rychlejší než O_DIRECT, ale data mohou, ale nemusí být konzistentní kvůli latenci nebo přímému selhání. |
nosync | Používá se pro interní testování výkonu – nepodporováno. |
littlesync | Používá se pro interní testování výkonu – nepodporováno. |
O_DIRECT | InnoDB použije O_DIRECT k otevření datových souborů a funkci fsync() k vyprázdnění dat i souborů protokolu. Ve srovnání s O_DSYNC je O_DIRECT stabilnější a datově konzistentnější, ale pomalejší. Tímto nastavením se vyhnete vyrovnávací paměti OS – toto nastavení je doporučené nastavení na počítačích se systémem Linux. |
O_DIRECT_NO_FSYNC | InnoDB použije O_DIRECT během proplachování I/O – část „NO_FSYNC“ definuje, že funkce fsync() bude přeskočena. |
- Měli byste také zvážit povolení nastavení innodb_file_per_table. Tento parametr je ve výchozím nastavení zapnutý v MySQL 5.6 a vyšší. Tento parametr vás zbaví problémů se správou tabulek InnoDB tím, že je uloží do samostatných souborů a vyvaruje se přebujelých hlavních slovníků a systémových tabulek. Povolením této proměnné se také vyhnete složitosti obnovy dat v případě poškození určité tabulky
- Teď, když jste tato nastavení upravili podle výše uvedených pokynů, měli byste být téměř připraveni začít! Než se však pustíte do provozu, měli byste pravděpodobně sledovat nejvytíženější soubor v celé infrastruktuře InnoDB – ibdata1.
Zacházení s ibdata1
V ibdata1 je uloženo několik tříd informací:
- Data tabulek InnoDB;
- Indexy tabulek InnoDB;
- Metadata tabulky InnoDB;
- Údaje o řízení víceverzí souběžnosti (MVCC);
- Vyrovnávací paměť pro dvojitý zápis – taková vyrovnávací paměť umožňuje InnoDB obnovit se z napůl zapsaných stránek. Účelem takové vyrovnávací paměti je zabránit poškození dat;
- Vkládací vyrovnávací paměť – takovou vyrovnávací paměť používá InnoDB k ukládání aktualizací na stejnou stránku, takže je lze provádět najednou a ne jednu po druhé.
Při práci s velkými soubory dat může být soubor ibdata1 extrémně velký a to může být jádro velmi frustrujícího problému - soubor může pouze růst a ve výchozím nastavení se nemůže zmenšovat. Můžete vypnout MySQL a smazat tento soubor, ale toto se nedoporučuje, pokud nevíte, co děláte. Po odstranění nebude MySQL správně fungovat, protože slovník a systémové tabulky jsou pryč, takže hlavní systémová tabulka je poškozena.
Chcete-li ibdata1 jednou provždy zmenšit, postupujte takto:
- Vypište všechna data z databází InnoDB. Pro tuto akci můžete použít mysqldump nebo mysqlpump;
- Zrušte všechny databáze kromě databází mysql, performance_schema a information_schema;
- Zastavit MySQL;
- Přidejte do svého souboru my.cnf následující položky:
[mysqld] innodb_file_per_table = 1 innodb_flush_method = O_DIRECT innodb_log_file_size = 25% of innodb_buffer_pool_size innodb_buffer_pool_size = up to 60-80% of available RAM.
- Smažte soubory ibdata1 a ib_logfile* (ty budou znovu vytvořeny při příštím restartu MySQL);
- Spusťte MySQL a obnovte data z výpisu, který jste předtím vytvořili. Po provedení výše uvedených kroků bude soubor ibdata1 stále růst, ale již nebude obsahovat data z tabulek InnoDB – soubor bude obsahovat pouze metadata a každá tabulka InnoDB bude existovat mimo ibdata1. Pokud nyní přejdete do adresáře /var/lib/mysql, uvidíte dva soubory představující každou tabulku, kterou máte s enginem InnoDB. Soubory budou vypadat takto:
- demotable.frm
- demotable.ibd
Soubor .frm obsahuje záhlaví úložiště a soubor .ibd obsahuje data tabulky a indexy vaší tabulky.
Před zavedením změn se však ujistěte, že jste doladili parametry podle vaší infrastruktury. Tyto parametry mohou snížit nebo snížit výkon InnoDB, takže je vždy sledujte. Nyní byste měli jít!
Shrnutí
Abych to shrnul, optimalizace výkonu InnoDB může být velkým přínosem, pokud vyvíjíte aplikace, které vyžadují integritu dat a zároveň vysoký výkon – InnoDB vám umožňuje změnit, kolik paměti smí engine ukládat spotřebovat, změnit velikost souboru protokolu, vyrovnávací metodu, kterou engine používá a tak dále - tyto změny mohou způsobit, že InnoDB bude fungovat extrémně dobře, pokud jsou správně vyladěny. Před provedením jakýchkoli vylepšení si však dejte pozor na důsledky vašich akcí pro váš server i MySQL.
Jako vždy, před optimalizací čehokoli pro výkon vždy udělejte (a otestujte!) zálohy, abyste mohli v případě potřeby obnovit svá data a před zavedením změn do produkce vždy otestujte jakékoli změny na místním serveru.