MySQL 8.0 medførte enorme ændringer og modifikationer, som blev skubbet af Oracle MySQL-teamet. Fysiske filer er blevet ændret. For eksempel eksisterer *.frm, *.TRG, *.TRN og *.par ikke længere. Masser af nye funktioner er blevet tilføjet såsom CTE (Common Table Expressions), Window Functions, Invisible Indexes, regexp (eller Regular Expression) - sidstnævnte er blevet ændret og giver nu fuld Unicode-understøttelse og er multibytesikker. Dataordbogen har også ændret sig. Det er nu indarbejdet med en transaktionsdataordbog, der gemmer information om databaseobjekter. I modsætning til tidligere versioner blev ordbogsdata gemt i metadatafiler og ikke-transaktionelle tabeller. Sikkerheden er blevet forbedret med den nye tilføjelse af caching_sha2_password, som nu er standardgodkendelsen, der erstatter mysql_native_password og tilbyder mere fleksibilitet, men skærpet sikkerhed, som enten skal bruge en sikker forbindelse eller en ukrypteret forbindelse, der understøtter adgangskodeudveksling ved hjælp af et RSA-nøglepar.
Med alle disse fede funktioner, forbedringer, forbedringer, som MySQL 8.0 tilbyder, var vores team interesseret i at bestemme, hvor godt den nuværende version MySQL 8.0 fungerer, især i betragtning af, at vores support til MySQL 8.0.x-versioner i ClusterControl er på vej (så følg med på dette). Dette blogindlæg vil ikke diskutere funktionerne i MySQL 8.0, men har til hensigt at benchmarke dets ydeevne i forhold til MySQL 5.7 og se, hvordan det er blevet forbedret derefter.
Serveropsætning og -miljø
Til dette benchmark har jeg til hensigt at bruge en minimal opsætning til produktion ved hjælp af følgende AWS EC2-miljø:
Instans-type:t2.xlarge instans
Lagring:gp2 (SSD-lager med minimum 100 og maksimum 16000 IOPS)
vCPUS:4
Hukommelse:16GiB
MySQL 5.7 version:MySQL Community Server (GPL) 5.7.24
MySQL 8.0 version:MySQL Community Server - GPL 8.0.14
Der er få bemærkelsesværdige variabler, som jeg også har sat for dette benchmark, som er:
- innodb_max_dirty_pages_pct =90 ## Dette er standardværdien i MySQL 8.0. Se her for detaljer.
- innodb_max_dirty_pages_pct_lwm=10 ## Dette er standardværdien i MySQL 8.0
- innodb_flush_neighbors=0
- innodb_buffer_pool_instances=8
- innodb_buffer_pool_size=8GiB
Resten af variablerne, der indstilles her for begge versioner (MySQL 5.7 og MySQL 8.0), er allerede tunet op af ClusterControl til dens my.cnf-skabelon.
Den bruger, jeg brugte her, overholder heller ikke den nye godkendelse af MySQL 8.0, som bruger caching_sha2_password. I stedet bruger begge serverversioner mysql_native_password plus at variabelen innodb_dedicated_server er FRA (standard), hvilket er en ny funktion i MySQL 8.0.
For at gøre livet lettere konfigurerede jeg MySQL 5.7 Community-versionsknudepunktet med ClusterControl fra en separat vært og fjernede derefter noden i en klynge og lukkede ClusterControl-værten for at gøre MySQL 5.7-knuden i dvale (ingen overvågningstrafik). Teknisk set er begge noder MySQL 5.7 og MySQL 8.0 i dvale, og der går ingen aktive forbindelser gennem noderne, så det er i bund og grund en ren benchmarking-test.
Anvendte kommandoer og scripts
Til denne opgave bruges sysbench til test og belastningssimulering for de to miljøer. Her er følgende kommandoer eller script, der bruges på denne test:
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
Så scriptet forbereder simpelthen sbtest-skemaet og udfylder tabeller og poster. Derefter udfører den læse/skrive-belastningstest ved hjælp af /usr/share/sysbench/oltp_read_write.lua script. Scriptet dumper globale status- og MySQL-variabler, indsamler CPU-udnyttelse og parser InnoDB-rækkeoperationer, der håndteres af scriptet innodb-ops-parser.py. Scriptet genererer derefter *.csv-filer baseret på de dumpede logfiler, der blev indsamlet under benchmark, derefter brugte jeg et Excel-regneark her til at generere grafen fra *.csv-filer. Tjek venligst koden her i dette github-lager.
Lad os nu fortsætte med grafresultaterne!
InnoDB Row Operations
Grundlæggende her udpakkede jeg kun InnoDB-rækkeoperationerne, som vælger (læser), sletter, indsætter og opdaterer. Når antallet af tråde stiger, overgår MySQL 8.0 markant MySQL 5.7! Begge versioner har ingen specifikke konfigurationsændringer, men kun de bemærkelsesværdige variabler, jeg har indstillet. Så begge versioner bruger stort set standardværdier.
Interessant nok, med hensyn til påstandene fra MySQL Server-teamet om ydeevnen for læsning og skrivning i den nye version, peger graferne på en væsentlig forbedring af ydeevnen, især i en server med høj belastning. Forestil dig forskellen mellem MySQL 5.7 versus MySQL 8.0 for alle dets InnoDB-rækkeoperationer, der er stor forskel, især når antallet af tråde stiger. MySQL 8.0 afslører, at den kan fungere effektivt uanset dens arbejdsbyrde.
Transaktioner behandlet
Som vist i grafen ovenfor viser MySQL 8.0 ydeevne igen en enorm forskel i den tid, det tager at behandle transaktioner. Jo lavere, jo bedre yder den, hvilket betyder, at det er hurtigere at behandle transaktioner. De behandlede transaktioner (den anden graf) afslører også, at begge antal transaktioner ikke adskiller sig fra hinanden. Det betyder, at begge versioner udfører næsten det samme antal transaktioner, men adskiller sig i, hvor hurtigt det kan afsluttes. Selvom jeg kunne sige, kan MySQL 5.7 stadig klare meget ved lavere belastning, men den realistiske belastning, især i produktionen, kunne forventes at være højere - især den travleste periode.
Grafen ovenfor viser stadig de transaktioner, den var i stand til at behandle, men adskiller læsning fra skrivning. Men der er faktisk afvigelser i graferne, som jeg ikke inkluderede, da de er små godbidder af resultatet, som ville skævvride grafen.
MySQL 8.0 afslører store forbedringer, især til at læse. Det viser sin effektivitet i skrivninger, især for servere med en høj arbejdsbyrde. Noget fantastisk ekstra understøttelse, der påvirker MySQL-ydeevnen for læsninger i version 8.0, er evnen til at oprette et indeks i faldende rækkefølge (eller fremadgående indeksscanninger). Tidligere versioner havde kun stigende eller baglæns indeksscanning, og MySQL var nødt til at udføre filsortering, hvis den havde brug for en faldende rækkefølge (hvis der er behov for filsortering, kan du overveje at tjekke værdien af max_length_for_sort_data). Faldende indekser gør det også muligt for optimeringsværktøjet at bruge indekser med flere kolonner, når den mest effektive scanningsrækkefølge blander stigende rækkefølge for nogle kolonner og faldende rækkefølge for andre. Se her for flere detaljer.
CPU-ressourcer
Under denne benchmarking besluttede jeg at tage nogle hardwareressourcer, især CPU-udnyttelsen.
Lad mig først forklare, hvordan jeg tager CPU-ressourcen her under benchmarking. sysbench inkluderer ikke samlet statistik for hardwareressourcer, der bruges eller bruges under processen, når du benchmarker en database. På grund af det, det, jeg gjorde, var at oprette et flag ved at oprette en fil, oprette forbindelse til målværten gennem SSH og derefter høste data fra Linux-kommandoen "top" og analysere det, mens jeg sov i et sekund, før det indsamles igen. Tag derefter den mest fremragende stigning i CPU-brug for mysqld-processen og fjern derefter flagfilen. Du kan gennemgå koden der, jeg har i github.
Så lad os diskutere igen om grafresultatet, det ser ud til at afsløre, at MySQL 8.0 bruger meget CPU. Mere end MySQL 5.7. Det kan dog være nødvendigt at håndtere nye variabler tilføjet i MySQL 8.0. For eksempel kan disse variabler påvirke din MySQL 8.0-server:
- 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
Variablerne med dens værdier efterlades af deres standardværdier for dette benchmark. De første tre variabler håndterer CPU til redo-logning, hvilket i MySQL 8.0 har været en forbedring på grund af re-design af, hvordan InnoDB skriver til REDO-loggen. Variablen innodb_log_spin_cpu_pct_hwm har CPU-affinitet, hvilket betyder, at den vil ignorere andre CPU-kerner, hvis mysqld for eksempel kun er fastgjort til 4 kerner. For parallelt læste tråde, i MySQL 8.0, tilføjer den en ny variabel, som du kan indstille, hvor mange tråde der skal bruges.
Jeg har dog ikke gravet nærmere i emnet. Der kan være måder, hvorpå ydeevnen kan forbedres ved at drage fordel af de funktioner, som MySQL 8.0 har at tilbyde.
Konklusion
Der er tonsvis af forbedringer, der er til stede i MySQL 8.0. Benchmark-resultaterne afslører, at der er sket en imponerende forbedring, ikke kun med hensyn til håndtering af læse-arbejdsbelastninger, men også på en høj læse-/skrive-arbejdsbelastning sammenlignet med MySQL 5.7.
Går vi over til de nye funktioner, som MySQL 8.0, ser det ud til, at den har udnyttet de mest opdaterede teknologier, ikke kun på software (som stor forbedring for Memcached, Remote Management for bedre DevOps-arbejde osv.), men også i hardware. Taget for eksempel udskiftningen af latin1 med UTF8MB4 som standard tegnkodning. Dette ville betyde, at det ville kræve mere diskplads, da UTF8 har brug for 2-bytes på ikke-US-ASCII-tegnene. Selvom dette benchmark ikke udnyttede at bruge den nye godkendelsesmetode med caching_sha2_password, vil det ikke påvirke ydeevnen, om det bruger kryptering. Når det er godkendt, gemmes det i cache, hvilket betyder, at godkendelse kun udføres én gang. Så hvis du bruger én bruger til din klient, vil det ikke være et problem og er mere sikkert end de tidligere versioner.
Da MySQL udnytter den mest opdaterede hardware og software, ændrer den sine standardvariabler. Du kan læse her for flere detaljer.
Samlet set har MySQL 8.0 domineret MySQL 5.7 effektivt.