MySQL 8.0 přineslo obrovské změny a úpravy, které prosadil tým Oracle MySQL. Fyzické soubory byly změněny. Například *.frm, *.TRG, *.TRN a *.par již neexistují. Byly přidány tuny nových funkcí, jako je CTE (Common Table Expressions), funkce oken, neviditelné indexy, regexp (nebo regulární výraz) – ten byl změněn a nyní poskytuje plnou podporu Unicode a je bezpečný pro více bajtů. Změnil se také datový slovník. Nyní je součástí transakčního datového slovníku, který ukládá informace o databázových objektech. Na rozdíl od předchozích verzí byla data slovníku uložena v souborech metadat a netransakčních tabulkách. Zabezpečení bylo vylepšeno novým přidáním caching_sha2_password, což je nyní výchozí autentizace nahrazující mysql_native_password a nabízí větší flexibilitu, ale zpřísněné zabezpečení, které musí používat buď zabezpečené připojení, nebo nešifrované připojení, které podporuje výměnu hesel pomocí páru klíčů RSA.
Se všemi těmito skvělými funkcemi, vylepšeními a vylepšeními, které MySQL 8.0 nabízí, měl náš tým zájem zjistit, jak dobře si současná verze MySQL 8.0 vede, zejména vzhledem k tomu, že naše podpora verzí MySQL 8.0.x v ClusterControl je na cestě (takže zůstaňte naladěni Na toto). Tento blogový příspěvek nebude diskutovat o funkcích MySQL 8.0, ale má v úmyslu porovnat jeho výkon s MySQL 5.7 a zjistit, jak se poté zlepšil.
Nastavení serveru a prostředí
Pro tento benchmark hodlám použít minimální nastavení pro produkci pomocí následujícího prostředí AWS EC2:
Typ instance:t2.xlarge instance
Úložiště:gp2 (úložiště SSD s minimem 100 a maximem 16000 IOPS)
vCPUS:4
Paměť:16GiB
Verze MySQL 5.7:MySQL Community Server (GPL) 5.7.24
Verze MySQL 8.0:MySQL Community Server – GPL 8.0.14
Existuje několik pozoruhodných proměnných, které jsem nastavil i pro tento benchmark, kterými jsou:
- innodb_max_dirty_pages_pct =90 ## Toto je výchozí hodnota v MySQL 8.0. Podrobnosti naleznete zde.
- innodb_max_dirty_pages_pct_lwm=10 ## Toto je výchozí hodnota v MySQL 8.0
- innodb_flush_neighbors=0
- innodb_buffer_pool_instances=8
- innodb_buffer_pool_size=8GiB
Zbytek proměnných, které se zde nastavují pro obě verze (MySQL 5.7 a MySQL 8.0), jsou již vyladěny ClusterControl pro svou šablonu my.cnf.
Také uživatel, kterého jsem zde použil, nevyhovuje novému ověřování MySQL 8.0, které používá caching_sha2_password. Místo toho obě verze serveru používají mysql_native_password plus proměnná innodb_dedicated_server je vypnutá (výchozí), což je nová funkce MySQL 8.0.
Abych si usnadnil život, nastavil jsem uzel verze MySQL 5.7 Community s ClusterControl ze samostatného hostitele, poté jsem odstranil uzel v clusteru a vypnul hostitele ClusterControl, aby byl uzel MySQL 5.7 nečinný (žádné monitorování provozu). Technicky jsou oba uzly MySQL 5.7 a MySQL 8.0 nečinné a přes uzly neprocházejí žádná aktivní připojení, takže jde v podstatě o čistý srovnávací test.
Používané příkazy a skripty
Pro tento úkol se sysbench používá pro testování a simulaci zatížení pro dvě prostředí. V tomto testu se používají následující příkazy nebo skripty:
sb-prepare.sh
#!/bin/bash
host=$1
#host192.168.10.110
port=3306
user='sysbench'
password='[email protected]'
table_size=500000
rate=20
ps_mode='disable'
sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --threads=1 --max-requests=0 --time=3600 --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --tables=10 --report-interval=1 --skip-trx=on --table-size=$table_size --rate=$rate --db-ps-mode=$ps_mode prepare
sb-run.sh
#!/usr/bin/env bash
host=$1
port=3306
user="sysbench"
password="[email protected]"
table_size=100000
tables=10
rate=20
ps_mode='disable'
threads=1
events=0
time=5
trx=100
path=$PWD
counter=1
echo "thread,cpu" > ${host}-cpu.csv
for i in 16 32 64 128 256 512 1024 2048;
do
threads=$i
mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
tmpfile=$path/${host}-tmp${threads}
touch $tmpfile
/bin/bash cpu-checker.sh $tmpfile $host $threads &
/usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --events=$events --threads=$threads --time=$time --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --report-interval=1 --skip-trx=on --tables=$tables --table-size=$table_size --rate=$rate --delete_inserts=$trx --order_ranges=$trx --range_selects=on --range-size=$trx --simple_ranges=$trx --db-ps-mode=$ps_mode --mysql-ignore-errors=all run | tee -a $host-sysbench.log
echo "${i},"`cat ${tmpfile} | sort -nr | head -1` >> ${host}-cpu.csv
unlink ${tmpfile}
mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
done
python $path/innodb-ops-parser.py $host
mysql -h $host -e "SHOW GLOBAL VARIABLES" >> $host-global-vars.log
Skript tedy jednoduše připraví schéma sbtest a naplní tabulky a záznamy. Poté provede zátěžové testy čtení/zápisu pomocí skriptu /usr/share/sysbench/oltp_read_write.lua. Skript vypíše globální stav a proměnné MySQL, shromažďuje využití CPU a analyzuje operace řádků InnoDB zpracovávané skriptem innodb-ops-parser.py. Skripty pak generují *.csv soubory na základě výpisů logů, které byly shromážděny během benchmarku, pak jsem zde použil excelovou tabulku pro vygenerování grafu ze souborů *.csv. Zkontrolujte prosím kód zde v tomto úložišti github.
Nyní pokračujme s výsledky grafu!
Operace řádků InnoDB
V podstatě jsem zde pouze extrahoval operace řádků InnoDB, které provádějí výběr (čtení), mazání, vkládání a aktualizace. Když se počet vláken zvýší, MySQL 8.0 výrazně překonává MySQL 5.7! Obě verze nemají žádné konkrétní změny konfigurace, ale pouze významné proměnné, které jsem nastavil. Obě verze tedy do značné míry používají výchozí hodnoty.
Zajímavé je, že pokud jde o tvrzení týmu MySQL Server Team o výkonu čtení a zápisu v nové verzi, grafy ukazují na výrazné zlepšení výkonu, zejména na vysoce vytížených serverech. Představte si rozdíl mezi MySQL 5.7 a MySQL 8.0 pro všechny její řádkové operace InnoDB, je zde velký rozdíl, zvláště když se zvýší počet vláken. MySQL 8.0 odhaluje, že může fungovat efektivně bez ohledu na pracovní zátěž.
Zpracované transakce
Jak je znázorněno v grafu výše, výkon MySQL 8.0 opět ukazuje obrovský rozdíl v době, kterou trvá zpracování transakcí. Čím nižší, tím lepší výkon, což znamená rychlejší zpracování transakcí. Zpracované transakce (druhý graf) také ukazují, že oba počty transakcí se od sebe neliší. To znamená, že obě verze provádějí téměř stejný počet transakcí, ale liší se v rychlosti dokončení. I když bych mohl říci, že MySQL 5.7 stále zvládá hodně při nižší zátěži, ale realistická zátěž, zejména ve výrobě, by se dala očekávat vyšší - zejména v nejrušnějším období.
Výše uvedený graf stále zobrazuje transakce, které dokázal zpracovat, ale odděluje čtení od zápisu. V grafech jsou však ve skutečnosti odlehlé hodnoty, které jsem nezahrnul, protože jsou to malé kousky výsledku, které by graf zkreslily.
MySQL 8.0 odhaluje skvělá vylepšení zejména pro čtení. Projevuje svou efektivitu v zápisech zejména pro servery s vysokou zátěží. Velkou přidanou podporou, která ovlivňuje výkon MySQL pro čtení ve verzi 8.0, je schopnost vytvářet index v sestupném pořadí (nebo dopředné skenování indexu). Předchozí verze měly pouze vzestupné nebo zpětné skenování indexu a MySQL muselo provádět řazení souborů, pokud potřebovalo sestupné pořadí (pokud je potřeba řazení souborů, můžete zvážit kontrolu hodnoty max_length_for_sort_data). Sestupné indexy také umožňují optimalizátoru používat indexy s více sloupci, když nejúčinnější pořadí skenování míchá vzestupné pořadí pro některé sloupce a sestupné pořadí pro jiné. Další podrobnosti naleznete zde.
Prostředky CPU
Během tohoto benchmarkingu jsem se rozhodl vzít nějaké hardwarové prostředky, zejména využití CPU.
Dovolte mi nejprve vysvětlit, jak zde beru prostředky CPU během benchmarkingu. sysbench nezahrnuje kolektivní statistiky pro hardwarové prostředky využívané nebo používané během procesu, když srovnáváte databázi. Z tohoto důvodu jsem vytvořil příznak vytvořením souboru, připojil se k cílovému hostiteli přes SSH a poté sklidil data z linuxového příkazu „top“ a analyzoval je ve spánku na sekundu, než je znovu shromáždím. Poté proveďte nejvýraznější zvýšení využití CPU pro proces mysqld a poté odstraňte soubor vlajky. Můžete si prohlédnout kód, který mám v githubu.
Pojďme tedy znovu diskutovat o výsledku grafu, zdá se, že odhaluje, že MySQL 8.0 spotřebovává hodně CPU. Více než MySQL 5.7. Možná se však bude muset vypořádat s novými proměnnými přidanými do MySQL 8.0. Tyto proměnné mohou například ovlivnit váš server MySQL 8.0:
- innodb_log_spin_cpu_abs_lwm =80
- innodb_log_spin_cpu_pct_hwm =50
- innodb_log_wait_for_flush_spin_hwm =400
- innodb_parallel_read_threads =4
Proměnné s jejich hodnotami jsou ponechány ve výchozích hodnotách pro tento benchmark. První tři proměnné se starají o CPU pro opakované protokolování, což v MySQL 8.0 bylo vylepšením díky přepracování způsobu, jakým InnoDB zapisuje do protokolu REDO. Proměnná innodb_log_spin_cpu_pct_hwm má CPU afinitu, což znamená, že by ignorovala ostatní jádra CPU, pokud je například mysqld připojeno pouze ke 4 jádrům. Pro paralelní čtení vláken v MySQL 8.0 přidává novou proměnnou, pro kterou můžete ladit, kolik vláken se má použít.
Dále jsem se však k tématu nehrabal. Mohou existovat způsoby, jak zlepšit výkon využitím funkcí, které MySQL 8.0 nabízí.
Závěr
MySQL 8.0 obsahuje spoustu vylepšení. Výsledky benchmarku odhalují, že došlo k působivému zlepšení nejen ve správě zátěže čtení, ale také ve vysoké zátěži čtení/zápis ve srovnání s MySQL 5.7.
Když přejdeme k novým funkcím MySQL 8.0, zdá se, že využila nejmodernější technologie nejen v oblasti softwaru (jako skvělé vylepšení pro Memcached, vzdálenou správu pro lepší práci DevOps atd.), ale také i v hardwaru. Vezměme si například nahrazení latin1 za UTF8MB4 jako výchozí kódování znaků. To by znamenalo, že by to vyžadovalo více místa na disku, protože UTF8 potřebuje 2 bajty na znaky jiné než US-ASCII. Ačkoli tento benchmark nevyužil použití nové metody ověřování s caching_sha2_password, neovlivní výkon, pokud používá šifrování. Jakmile je ověřeno, je uloženo v mezipaměti, což znamená, že ověření je provedeno pouze jednou. Pokud tedy pro svého klienta používáte jednoho uživatele, nebude to problém a je bezpečnější než předchozí verze.
Protože MySQL využívá nejaktuálnější hardware a software, mění své výchozí proměnné. Více podrobností si můžete přečíst zde.
Celkově MySQL 8.0 efektivně dominuje MySQL 5.7.