sql >> Database >  >> RDS >> MariaDB

Hoe de prestaties van MySQL en MariaDB te benchmarken met SysBench

Wat is SysBench? Als je regelmatig met MySQL werkt, heb je er vast wel eens van gehoord. SysBench zit al heel lang in het MySQL-ecosysteem. Het werd oorspronkelijk geschreven door Peter Zaitsev, in 2004. Het doel was om een ​​tool te bieden om synthetische benchmarks van MySQL en de hardware waarop het draait uit te voeren. Het is ontworpen om CPU-, geheugen- en I/O-tests uit te voeren. Het had ook een optie om OLTP-werkbelasting uit te voeren op een MySQL-database. OLTP staat voor online transactieverwerking, typische werklast voor online toepassingen zoals e-commerce, orderinvoer of financiële transactiesystemen.

In deze blogpost zullen we ons concentreren op de SQL-benchmarkfunctie, maar houd er rekening mee dat hardwarebenchmarks ook erg handig kunnen zijn bij het identificeren van problemen op databaseservers. De I/O-benchmark was bijvoorbeeld bedoeld om InnoDB I/O-werklast te simuleren, terwijl CPU-tests simulatie van zeer gelijktijdige, multi-treaded omgeving omvatten, samen met tests voor mutex-conflicten - iets dat ook lijkt op een database-type werklast.

SysBench Geschiedenis en Architectuur

Zoals eerder vermeld, werd SysBench oorspronkelijk in 2004 opgericht door Peter Zaitsev. Kort daarna nam Alexey Kopytov de ontwikkeling over. Het bereikte versie 0.4.12 en de ontwikkeling stopte. Na een lange pauze begon Alexey in 2016 weer aan SysBench te werken. Binnenkort is versie 0.5 uitgebracht met de OLTP-benchmark herschreven om op LUA gebaseerde scripts te gebruiken. Toen, in 2017, werd SysBench 1.0 uitgebracht. Dit was dag en nacht vergeleken met de oude versie 0.4.12. Eerst en vooral, in plaats van hardgecodeerde scripts, hebben we nu de mogelijkheid om benchmarks aan te passen met LUA. Percona heeft bijvoorbeeld een TPCC-achtige benchmark gemaakt die kan worden uitgevoerd met SysBench. Laten we eens kijken naar de huidige SysBench-architectuur.

SysBench is een C-binary die LUA-scripts gebruikt om benchmarks uit te voeren. Die scripts moeten:

  1. Invoer van opdrachtregelparameters afhandelen
  2. Definieer alle modi die de benchmark zou moeten gebruiken (voorbereiden, uitvoeren, opschonen)
  3. Bereid alle gegevens voor
  4. Definieer hoe de benchmark zal worden uitgevoerd (hoe zoekopdrachten eruit zullen zien, enz.)

Scripts kunnen meerdere verbindingen met de database gebruiken, ze kunnen ook resultaten verwerken als u complexe benchmarks wilt maken waarbij query's afhankelijk zijn van de resultatenset van eerdere query's. Met SysBench 1.0 is het mogelijk om latency histogrammen te maken. Het is ook mogelijk dat de LUA-scripts fouten opvangen en afhandelen via fouthaken. Er is ondersteuning voor parallellisatie in de LUA-scripts, meerdere query's kunnen parallel worden uitgevoerd, waardoor bijvoorbeeld provisioning veel sneller gaat. Last but not least worden nu meerdere uitvoerformaten ondersteund. Voordat SysBench alleen door mensen leesbare uitvoer genereerde. Het is nu mogelijk om het te genereren als CSV of JSON, waardoor het veel gemakkelijker wordt om nabewerkingen uit te voeren en grafieken te genereren met bijvoorbeeld gnuplot of de gegevens in Prometheus, Graphite of een vergelijkbare datastore te voeren.

Waarom SysBench?

De belangrijkste reden waarom SysBench populair werd, is het feit dat het eenvoudig te gebruiken is. Iemand zonder voorkennis kan het binnen enkele minuten gaan gebruiken. Het biedt ook standaard benchmarks die de meeste gevallen dekken - OLTP-workloads, alleen-lezen of lezen-schrijven, primaire sleutelzoekopdrachten en primaire sleutelupdates. Dit alles veroorzaakte de meeste problemen voor MySQL, tot aan MySQL 8.0. Dit was ook een reden waarom SysBench zo populair was in verschillende benchmarks en vergelijkingen die op internet werden gepubliceerd. Die berichten hielpen deze tool te promoten en maakten het tot de synthetische benchmark voor MySQL.

Een ander voordeel van SysBench is dat, sinds versie 0.5 en integratie van LUA, iedereen elke vorm van benchmark kan voorbereiden. We noemden al een TPCC-achtige benchmark, maar iedereen kan iets maken dat lijkt op haar productiewerklast. We zeggen niet dat het eenvoudig is, het zal hoogstwaarschijnlijk een tijdrovend proces zijn, maar deze mogelijkheid is handig als u een aangepaste benchmark moet voorbereiden.

Omdat het een synthetische benchmark is, is SysBench geen tool die u kunt gebruiken om configuraties van uw MySQL-servers af te stemmen (tenzij u LUA-scripts met aangepaste werkbelasting hebt voorbereid of uw werkbelasting erg lijkt op de benchmark-werkbelastingen waarmee SysBench wordt geleverd). Het is geweldig om de prestaties van verschillende hardware te vergelijken. U kunt eenvoudig de prestaties vergelijken van, laten we zeggen, verschillende soorten nodes die worden aangeboden door uw cloudprovider en de maximale QPS (query's per seconde) die ze bieden. Als u die statistiek kent en weet wat u betaalt voor een bepaald knooppunt, kunt u een nog belangrijker statistiek berekenen:QP$ (query's per dollar). Hiermee kunt u bepalen welk knooppunttype u moet gebruiken bij het bouwen van een kostenefficiënte omgeving. Natuurlijk kan SysBench ook worden gebruikt voor de eerste afstemming en beoordeling van de haalbaarheid van een bepaald ontwerp. Laten we zeggen dat we een Galera-cluster bouwen over de hele wereld - Noord-Amerika, EU, Azië. Hoeveel inserts per seconde kan zo'n setup aan? Wat zou de commit latency zijn? Heeft het zelfs zin om een ​​proof of concept te doen of is de netwerklatentie misschien zo hoog dat zelfs een simpele workload niet werkt zoals je zou verwachten?

Hoe zit het met stresstesten? Niet iedereen is overgestapt naar de cloud, er zijn nog steeds bedrijven die liever hun eigen infrastructuur bouwen. Elke nieuwe server die wordt aangeschaft, moet een opwarmperiode doormaken waarin u de nadruk legt op mogelijke hardwaredefecten. In dit geval kan SysBench ook helpen. Ofwel door OLTP-werkbelasting uit te voeren die de server overbelast, of u kunt ook speciale benchmarks gebruiken voor CPU, schijf en geheugen.

Zoals u kunt zien, zijn er veel gevallen waarin zelfs een eenvoudige, synthetische benchmark erg nuttig kan zijn. In de volgende paragraaf zullen we kijken naar wat we kunnen doen met SysBench.

Wat kan SysBench voor u doen?

Welke tests kunt u uitvoeren?

Zoals aan het begin vermeld, zullen we ons concentreren op OLTP-benchmarks en ter herinnering herhalen we dat SysBench ook kan worden gebruikt om I/O-, CPU- en geheugentests uit te voeren. Laten we eens kijken naar de benchmarks waarmee SysBench 1.0 wordt geleverd (we hebben enkele helper-LUA-bestanden en niet-database-LUA-scripts uit deze lijst verwijderd).

-rwxr-xr-x 1 root root 1.5K May 30 07:46 bulk_insert.lua
-rwxr-xr-x 1 root root 1.3K May 30 07:46 oltp_delete.lua
-rwxr-xr-x 1 root root 2.4K May 30 07:46 oltp_insert.lua
-rwxr-xr-x 1 root root 1.3K May 30 07:46 oltp_point_select.lua
-rwxr-xr-x 1 root root 1.7K May 30 07:46 oltp_read_only.lua
-rwxr-xr-x 1 root root 1.8K May 30 07:46 oltp_read_write.lua
-rwxr-xr-x 1 root root 1.1K May 30 07:46 oltp_update_index.lua
-rwxr-xr-x 1 root root 1.2K May 30 07:46 oltp_update_non_index.lua
-rwxr-xr-x 1 root root 1.5K May 30 07:46 oltp_write_only.lua
-rwxr-xr-x 1 root root 1.9K May 30 07:46 select_random_points.lua
-rwxr-xr-x 1 root root 2.1K May 30 07:46 select_random_ranges.lua

Laten we ze een voor een doornemen.

Eerst bulk_insert.lua. Deze test kan worden gebruikt om het vermogen van MySQL om inserts met meerdere rijen uit te voeren, te benchmarken. Dit kan heel handig zijn bij het controleren van bijvoorbeeld de prestaties van replicatie of Galera-cluster. In het eerste geval kan het u helpen een vraag te beantwoorden:"hoe snel kan ik invoegen voordat de replicatievertraging optreedt?". In het laatste geval zal het u vertellen hoe snel gegevens in een Galera-cluster kunnen worden ingevoegd, gegeven de huidige netwerklatentie.

Alle oltp_*-scripts delen een gemeenschappelijke tabelstructuur. De eerste twee (oltp_delete.lua en oltp_insert.lua) voeren enkele DELETE- en INSERT-instructies uit. Nogmaals, dit zou een test kunnen zijn voor replicatie of Galera-cluster - drijf het tot het uiterste en kijk hoeveel insertie of zuivering het aankan. We hebben ook andere benchmarks die zijn gericht op bepaalde functionaliteit - oltp_point_select, oltp_update_index en oltp_update_non_index. Deze zullen een subset van query's uitvoeren - op primaire sleutels gebaseerde selecties, op index gebaseerde updates en niet-index-gebaseerde updates. Als je een aantal van deze functionaliteiten wilt testen, zijn de tests er. We hebben ook complexere benchmarks die zijn gebaseerd op OLTP-workloads:oltp_read_only, oltp_read_write en oltp_write_only. U kunt ofwel een alleen-lezen werklast uitvoeren, die zal bestaan ​​uit verschillende soorten SELECT-query's, u kunt alleen schrijfbewerkingen uitvoeren (een combinatie van DELETE, INSERT en UPDATE) of u kunt een combinatie van die twee uitvoeren. Ten slotte kunt u met select_random_points en select_random_ranges een willekeurige SELECT uitvoeren met behulp van willekeurige punten in de IN()-lijst of willekeurige bereiken met BETWEEN.

Hoe kunt u een benchmark configureren?

Wat ook belangrijk is, benchmarks zijn configureerbaar - u kunt verschillende werkbelastingspatronen uitvoeren met dezelfde benchmark. Laten we eens kijken naar de twee meest voorkomende benchmarks om uit te voeren. We zullen een diepe duik nemen in OLTP read_only en OLTP read_write benchmarks. Allereerst heeft SysBench enkele algemene configuratie-opties. We zullen hier alleen de belangrijkste bespreken, je kunt ze allemaal controleren door het volgende uit te voeren:

sysbench --help

Laten we ze eens bekijken.

  --threads=N                     number of threads to use [1]

U kunt definiëren wat voor soort gelijktijdigheid u wilt dat SysBench genereert. MySQL heeft, zoals elke software, enkele schaalbaarheidsbeperkingen en de prestaties zullen pieken op een bepaald niveau van gelijktijdigheid. Deze instelling helpt bij het simuleren van verschillende gelijktijdigheden voor een bepaalde werklast en om te controleren of deze de goede plek al gepasseerd is.

  --events=N                      limit for total number of events [0]
  --time=N                        limit for total execution time in seconds [10]

Die twee instellingen bepalen hoe lang SysBench moet blijven draaien. Het kan een aantal zoekopdrachten uitvoeren of het kan een vooraf bepaalde tijd blijven draaien.

  --warmup-time=N                 execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled [0]

Dit is duidelijk. SysBench genereert statistische resultaten van de tests en die resultaten kunnen worden beïnvloed als MySQL zich in een koude toestand bevindt. Warmup helpt bij het identificeren van "gewone" doorvoer door benchmark uit te voeren gedurende een vooraf gedefinieerde tijd, waardoor de cache, bufferpools enz. kunnen worden opgewarmd.

  --rate=N                        average transactions rate. 0 for unlimited rate [0]

SysBench probeert standaard query's zo snel mogelijk uit te voeren. Om langzamer verkeer te simuleren kan deze optie worden gebruikt. U kunt hier definiëren hoeveel transacties er per seconde moeten worden uitgevoerd.

  --report-interval=N             periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]

SysBench genereert standaard een rapport nadat het de run heeft voltooid en er wordt geen voortgang gerapporteerd terwijl de benchmark wordt uitgevoerd. Met deze optie kunt u SysBench uitgebreider maken terwijl de benchmark nog draait.

  --rand-type=STRING   random numbers distribution {uniform, gaussian, special, pareto, zipfian} to use by default [special]

SysBench geeft u de mogelijkheid om verschillende soorten gegevensdistributie te genereren. Ze kunnen allemaal hun eigen doeleinden hebben. Standaardoptie, 'speciaal', definieert verschillende (het is configureerbare) hotspots in de gegevens, iets wat vrij gebruikelijk is in webapplicaties. U kunt ook andere distributies gebruiken als uw gegevens zich op een andere manier gedragen. Door hier een andere keuze te maken, kunt u ook de manier waarop uw database wordt belast, wijzigen. Uniforme distributie, waarbij alle rijen dezelfde kans hebben om te worden benaderd, is bijvoorbeeld veel meer geheugenintensieve bewerking. Het zal meer bufferpool gebruiken om alle gegevens op te slaan en het zal veel schijfintensiever zijn als uw gegevensset niet in het geheugen past. Aan de andere kant zal een speciale distributie met een paar hotspots minder stress op de schijf leggen, omdat het waarschijnlijker is dat hete rijen in de bufferpool worden bewaard en toegang tot rijen die op de schijf zijn opgeslagen veel minder waarschijnlijk is. Voor sommige typen gegevensdistributie biedt SysBench u meer tweaks. U kunt deze informatie vinden in de uitvoer van 'sysbench --help'.

  --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]

Met deze instelling kunt u beslissen of SysBench voorbereide instructies moet gebruiken (zolang deze beschikbaar zijn in de gegeven datastore - voor MySQL betekent dit dat PS standaard is ingeschakeld) of niet. Dit kan een verschil maken bij het werken met proxy's zoals ProxySQL of MaxScale - ze moeten voorbereide instructies op een speciale manier behandelen en ze moeten allemaal naar één host worden gerouteerd, waardoor het onmogelijk is om de schaalbaarheid van de proxy te testen.

Naast de algemene configuratie-opties kan elk van de tests zijn eigen configuratie hebben. U kunt controleren wat mogelijk is door het volgende uit te voeren:

[email protected]:~# sysbench ./sysbench/src/lua/oltp_read_write.lua  help
sysbench 1.1.0-2e6b7d5 (using bundled LuaJIT 2.1.0-beta3)

oltp_read_only.lua options:
  --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
  --secondary[=on|off]          Use a secondary index in place of the PRIMARY KEY [off]
  --create_secondary[=on|off]   Create a secondary index in addition to the PRIMARY KEY [on]
  --index_updates=N             Number of UPDATE index queries per transaction [1]
  --range_size=N                Range size for range SELECT queries [100]
  --auto_inc[=on|off]           Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]
  --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]
  --tables=N                    Number of tables [1]
  --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]
  --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  --table_size=N                Number of rows per table [10000]
  --pgsql_variant=STRING        Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0
  --simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  --range_selects[=on|off]      Enable/disable all range SELECT queries [on]
  --point_selects=N             Number of point SELECT queries per transaction [10]

Ook hier bespreken we nogmaals de belangrijkste opties. Allereerst heb je controle over hoe een transactie er precies uit zal zien. Over het algemeen bestaat het uit verschillende soorten zoekopdrachten - INSERT, DELETE, ander type SELECT (puntopzoeking, bereik, aggregatie) en UPDATE (geïndexeerd, niet-geïndexeerd). Variabelen gebruiken zoals:

  --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]
  --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]
  --index_updates=N             Number of UPDATE index queries per transaction [1]
  --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]
  --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]
  --simple_ranges=N             Number of simple range SELECT queries per transaction [1]
  --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]
  --point_selects=N             Number of point SELECT queries per transaction [10]
  --range_selects[=on|off]      Enable/disable all range SELECT queries [on]

U kunt definiëren hoe een transactie eruit moet zien. Zoals je kunt zien door naar de standaardwaarden te kijken, zijn de meeste zoekopdrachten SELECT's - voornamelijk puntselecties, maar ook verschillende soorten bereik-SELECT's (je kunt ze allemaal uitschakelen door range_selects uit te zetten). U kunt de werklast aanpassen aan een meer schrijfzware werklast door het aantal updates of INSERT/DELETE-query's te verhogen. Het is ook mogelijk om instellingen aan te passen met betrekking tot secundaire indexen, automatisch verhogen, maar ook de grootte van de gegevensset (aantal tabellen en hoeveel rijen elk ervan moet bevatten). Hiermee kun je je werklast heel mooi aanpassen.

  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]

Dit is een andere instelling die erg belangrijk is bij het werken met proxy's. Standaard probeert SysBench query's uit te voeren in een expliciete transactie. Op deze manier blijft de dataset consistent en wordt het niet beïnvloed:SysBench zal bijvoorbeeld INSERT en DELETE op dezelfde rij uitvoeren, om ervoor te zorgen dat de dataset niet groeit (wat invloed heeft op uw vermogen om resultaten te reproduceren). Proxy's zullen expliciete transacties echter anders behandelen - alle query's die binnen een transactie worden uitgevoerd, moeten op dezelfde host worden uitgevoerd, waardoor de mogelijkheid om de werklast te schalen wordt weggenomen. Houd er rekening mee dat het uitschakelen van transacties ertoe leidt dat de gegevensset afwijkt van het oorspronkelijke punt. Het kan ook enkele problemen veroorzaken, zoals dubbele sleutelfouten of iets dergelijks. Om transacties uit te schakelen, kunt u ook kijken naar:

  --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]

Met deze instelling kunt u foutcodes van MySQL specificeren die SysBench moet negeren (en de verbinding niet beëindigen). Als u bijvoorbeeld fouten wilt negeren zoals:error 1062 (Dubbele invoer '6' voor sleutel 'PRIMARY'), moet u deze foutcode doorgeven:--mysql-ignore-errors=1062

Wat ook belangrijk is, is dat elke benchmark een manier moet bieden om een ​​dataset voor tests te voorzien, deze uit te voeren en deze vervolgens op te schonen nadat de tests zijn voltooid. Dit wordt gedaan met behulp van de opdrachten ‘prepare’, ‘run’ en ‘cleanup’. We zullen in het volgende gedeelte laten zien hoe dit wordt gedaan.

Voorbeelden

In deze sectie zullen we enkele voorbeelden doornemen van waar SysBench voor kan worden gebruikt. Zoals eerder vermeld, zullen we ons concentreren op de twee meest populaire benchmarks:OLTP alleen-lezen en OLTP lezen/schrijven. Soms kan het zinvol zijn om andere benchmarks te gebruiken, maar we kunnen u in ieder geval laten zien hoe die twee kunnen worden aangepast.

Opzoeken van primaire sleutel

Allereerst moeten we beslissen welke benchmark we gaan draaien, alleen-lezen of lezen-schrijven. Technisch gezien maakt het geen verschil, aangezien we schrijfbewerkingen uit de R/W-benchmark kunnen verwijderen. Laten we ons concentreren op de alleen-lezen versie.

Als eerste stap moeten we een dataset voorbereiden. We moeten beslissen hoe groot het moet zijn. Voor deze specifieke benchmark zal, met behulp van standaardinstellingen (er worden dus secundaire indexen gemaakt), 1 miljoen rijen resulteren in ~ 240 MB aan gegevens. Tien tabellen, 1000000 rijen elk gelijk aan 2,4 GB:

[email protected]:~# du -sh /var/lib/mysql/sbtest/
2.4G    /var/lib/mysql/sbtest/
[email protected]:~# ls -alh /var/lib/mysql/sbtest/
total 2.4G
drwxr-x--- 2 mysql mysql 4.0K Jun  1 12:12 .
drwxr-xr-x 6 mysql mysql 4.0K Jun  1 12:10 ..
-rw-r----- 1 mysql mysql   65 Jun  1 12:08 db.opt
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:12 sbtest10.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:12 sbtest10.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest1.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest1.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest2.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest2.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest3.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest3.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:10 sbtest4.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:10 sbtest4.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest5.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest5.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest6.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest6.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest7.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest7.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:11 sbtest8.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:11 sbtest8.ibd
-rw-r----- 1 mysql mysql 8.5K Jun  1 12:12 sbtest9.frm
-rw-r----- 1 mysql mysql 240M Jun  1 12:12 sbtest9.ibd

Dit zou u een idee moeten geven hoeveel tafels u wilt en hoe groot ze moeten zijn. Laten we zeggen dat we de werkbelasting in het geheugen willen testen, dus we willen tabellen maken die in de InnoDB-bufferpool passen. Aan de andere kant willen we er ook voor zorgen dat er genoeg tafels zijn om geen bottleneck te worden (of dat het aantal tafels overeenkomt met wat je zou verwachten in je productieopstelling). Laten we onze dataset voorbereiden. Houd er rekening mee dat SysBench standaard zoekt naar het 'sbtest'-schema dat moet bestaan ​​voordat u de dataset voorbereidt. Mogelijk moet u deze handmatig maken.

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=4 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 prepare
sysbench 1.1.0-2e6b7d5 (using bundled LuaJIT 2.1.0-beta3)

Initializing worker threads...

Creating table 'sbtest2'...
Creating table 'sbtest3'...
Creating table 'sbtest4'...
Creating table 'sbtest1'...
Inserting 1000000 records into 'sbtest2'
Inserting 1000000 records into 'sbtest4'
Inserting 1000000 records into 'sbtest3'
Inserting 1000000 records into 'sbtest1'
Creating a secondary index on 'sbtest2'...
Creating a secondary index on 'sbtest3'...
Creating a secondary index on 'sbtest1'...
Creating a secondary index on 'sbtest4'...
Creating table 'sbtest6'...
Inserting 1000000 records into 'sbtest6'
Creating table 'sbtest7'...
Inserting 1000000 records into 'sbtest7'
Creating table 'sbtest5'...
Inserting 1000000 records into 'sbtest5'
Creating table 'sbtest8'...
Inserting 1000000 records into 'sbtest8'
Creating a secondary index on 'sbtest6'...
Creating a secondary index on 'sbtest7'...
Creating a secondary index on 'sbtest5'...
Creating a secondary index on 'sbtest8'...
Creating table 'sbtest10'...
Inserting 1000000 records into 'sbtest10'
Creating table 'sbtest9'...
Inserting 1000000 records into 'sbtest9'
Creating a secondary index on 'sbtest10'...
Creating a secondary index on 'sbtest9'...

Zodra we onze gegevens hebben, laten we een opdracht voorbereiden om de test uit te voeren. We willen het opzoeken van primaire sleutels testen, daarom zullen we alle andere soorten SELECT uitschakelen. We zullen ook voorbereide instructies uitschakelen omdat we reguliere zoekopdrachten willen testen. We zullen een lage gelijktijdigheid testen, laten we zeggen 16 threads. Onze opdracht kan er als volgt uitzien:

sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 --range_selects=off --db-ps-mode=disable --report-interval=1 run

Wat hebben we hier gedaan? We hebben het aantal threads op 16 gezet. We hebben besloten dat we onze benchmark 300 seconden willen laten draaien, zonder een limiet van uitgevoerde queries. We hebben de connectiviteit met de database, het aantal tabellen en hun grootte gedefinieerd. We hebben ook alle bereik-SELECT's uitgeschakeld, we hebben ook voorbereide instructies uitgeschakeld. Ten slotte stellen we het rapportinterval in op één seconde. Zo kan een voorbeelduitvoer eruitzien:

[ 297s ] thds: 16 tps: 97.21 qps: 1127.43 (r/w/o: 935.01/0.00/192.41) lat (ms,95%): 253.35 err/s: 0.00 reconn/s: 0.00
[ 298s ] thds: 16 tps: 195.32 qps: 2378.77 (r/w/o: 1985.13/0.00/393.64) lat (ms,95%): 189.93 err/s: 0.00 reconn/s: 0.00
[ 299s ] thds: 16 tps: 178.02 qps: 2115.22 (r/w/o: 1762.18/0.00/353.04) lat (ms,95%): 155.80 err/s: 0.00 reconn/s: 0.00
[ 300s ] thds: 16 tps: 217.82 qps: 2640.92 (r/w/o: 2202.27/0.00/438.65) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00

Elke seconde zien we een momentopname van de werklaststatistieken. Dit is heel handig om te volgen en te plotten - het eindrapport geeft u alleen gemiddelden. Tussenresultaten zullen het mogelijk maken om de prestaties van seconde tot seconde te volgen. Het eindrapport kan er als volgt uitzien:

SQL statistics:
    queries performed:
        read:                            614660
        write:                           0
        other:                           122932
        total:                           737592
    transactions:                        61466  (204.84 per sec.)
    queries:                             737592 (2458.08 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

Throughput:
    events/s (eps):                      204.8403
    time elapsed:                        300.0679s
    total number of events:              61466

Latency (ms):
         min:                                   24.91
         avg:                                   78.10
         max:                                  331.91
         95th percentile:                      137.35
         sum:                              4800234.60

Threads fairness:
    events (avg/stddev):           3841.6250/20.87
    execution time (avg/stddev):   300.0147/0.02

Hier vindt u informatie over uitgevoerde queries en andere (BEGIN/COMMIT) statements. U leert hoeveel transacties zijn uitgevoerd, hoeveel fouten er zijn opgetreden, wat de doorvoer was en de totale verstreken tijd. U kunt ook latentiestatistieken en de vraagverdeling over threads controleren.

Als we geïnteresseerd waren in latentiedistributie, zouden we ook het '--histogram'-argument kunnen doorgeven aan SysBench. Dit resulteert in een extra output zoals hieronder:

Latency histogram (values are in milliseconds)
       value  ------------- distribution ------------- count
      29.194 |******                                   1
      30.815 |******                                   1
      31.945 |***********                              2
      33.718 |******                                   1
      34.954 |***********                              2
      35.589 |******                                   1
      37.565 |***********************                  4
      38.247 |******                                   1
      38.942 |******                                   1
      39.650 |***********                              2
      40.370 |***********                              2
      41.104 |*****************                        3
      41.851 |*****************************            5
      42.611 |*****************                        3
      43.385 |*****************                        3
      44.173 |***********                              2
      44.976 |**************************************** 7
      45.793 |***********************                  4
      46.625 |***********                              2
      47.472 |*****************************            5
      48.335 |**************************************** 7
      49.213 |***********                              2
      50.107 |**********************************       6
      51.018 |***********************                  4
      51.945 |**************************************** 7
      52.889 |*****************                        3
      53.850 |*****************                        3
      54.828 |***********************                  4
      55.824 |***********                              2
      57.871 |***********                              2
      58.923 |***********                              2
      59.993 |******                                   1
      61.083 |******                                   1
      63.323 |***********                              2
      66.838 |******                                   1
      71.830 |******                                   1

Als we eenmaal goed zijn met onze resultaten, kunnen we de gegevens opschonen:

sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=10 --table-size=1000000 --range_selects=off --db-ps-mode=disable --report-interval=1 cleanup

Veel schrijfverkeer

Laten we ons hier voorstellen dat we een schrijfzware (maar niet alleen-schrijven) werkbelasting willen uitvoeren en bijvoorbeeld de prestaties van het I/O-subsysteem willen testen. Allereerst moeten we beslissen hoe groot de dataset moet zijn. We gaan uit van ~ 48 GB aan gegevens (20 tabellen, elk 10 000 000 rijen). We moeten het voorbereiden. Deze keer gebruiken we de lees-schrijfbenchmark.

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=20 --table-size=10000000 prepare

Zodra dit is gebeurd, kunnen we de standaardinstellingen aanpassen om meer schrijfacties in de querymix te forceren:

[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=16 --events=0 --time=300 --mysql-host=10.0.0.126 --mysql-user=sbtest --mysql-password=pass --mysql-port=3306 --tables=20 --delete_inserts=10 --index_updates=10 --non_index_updates=10 --table-size=10000000 --db-ps-mode=disable --report-interval=1 run

Zoals je kunt zien aan de tussentijdse resultaten, zijn transacties nu aan een schrijfzware kant:

[ 5s ] thds: 16 tps: 16.99 qps: 946.31 (r/w/o: 231.83/680.50/33.98) lat (ms,95%): 1258.08 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 16 tps: 17.01 qps: 955.81 (r/w/o: 223.19/698.59/34.03) lat (ms,95%): 1032.01 err/s: 0.00 reconn/s: 0.00
[ 7s ] thds: 16 tps: 12.00 qps: 698.91 (r/w/o: 191.97/482.93/24.00) lat (ms,95%): 1235.62 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 16 tps: 14.01 qps: 683.43 (r/w/o: 195.12/460.29/28.02) lat (ms,95%): 1533.66 err/s: 0.00 reconn/s: 0.00

De resultaten begrijpen

Zoals we hierboven hebben laten zien, is SysBench een geweldige tool die kan helpen bij het opsporen van enkele prestatieproblemen van MySQL of MariaDB. Het kan ook worden gebruikt voor de eerste afstemming van uw databaseconfiguratie. Natuurlijk moet u er rekening mee houden dat u, om het beste uit uw benchmarks te halen, moet begrijpen waarom de resultaten eruitzien zoals ze zijn. Dit vereist inzicht in de interne MySQL-statistieken met behulp van monitoringtools, bijvoorbeeld ClusterControl. Dit is heel belangrijk om te onthouden - als u niet begrijpt waarom de prestatie was zoals deze was, kunt u onjuiste conclusies trekken uit de benchmarks. Er is altijd een knelpunt en SysBench kan helpen bij het verhogen van de prestatieproblemen, die u vervolgens moet identificeren.


  1. hoe de rijgrootte in de tabel te vinden

  2. 3 manieren om alle tabellen te retourneren ZONDER een primaire sleutel in SQL Server

  3. Oracle Ace-wijzigingen

  4. SQLite JSON_GROUP_OBJECT()