MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Como comparar o desempenho do MySQL e do MariaDB usando o SysBench


O que é SysBench? Se você trabalha com MySQL regularmente, provavelmente já ouviu falar dele. O SysBench está no ecossistema MySQL há muito tempo. Ele foi originalmente escrito por Peter Zaitsev, em 2004. Seu objetivo era fornecer uma ferramenta para executar benchmarks sintéticos do MySQL e do hardware em que ele é executado. Ele foi projetado para executar testes de CPU, memória e E/S. Ele também tinha a opção de executar a carga de trabalho OLTP em um banco de dados MySQL. OLTP significa processamento de transações online, carga de trabalho típica para aplicativos online como comércio eletrônico, entrada de pedidos ou sistemas de transações financeiras.

Nesta postagem de blog, focaremos no recurso de benchmark SQL, mas lembre-se de que os benchmarks de hardware também podem ser muito úteis na identificação de problemas em servidores de banco de dados. Por exemplo, o benchmark de E/S foi projetado para simular a carga de trabalho de E/S do InnoDB, enquanto os testes de CPU envolvem simulação de ambiente multi-treaded altamente simultâneo, juntamente com testes para contenção de mutex - algo que também se assemelha a um tipo de carga de trabalho de banco de dados.

História e arquitetura do SysBench


Como mencionado, SysBench foi originalmente criado em 2004 por Peter Zaitsev. Logo depois, Alexey Kopytov assumiu seu desenvolvimento. Chegou à versão 0.4.12 e o desenvolvimento foi interrompido. Após uma longa pausa, Alexey começou a trabalhar no SysBench novamente em 2016. Em breve, a versão 0.5 foi lançada com o benchmark OLTP reescrito para usar scripts baseados em LUA. Então, em 2017, o SysBench 1.0 foi lançado. Era como dia e noite em comparação com a antiga versão 0.4.12. Em primeiro lugar, em vez de scripts codificados, agora temos a capacidade de personalizar benchmarks usando LUA. Por exemplo, a Percona criou um benchmark semelhante ao TPCC que pode ser executado usando o SysBench. Vamos dar uma olhada rápida na arquitetura SysBench atual.

SysBench é um binário C que usa scripts LUA para executar benchmarks. Esses scripts precisam:
  1. Manipule a entrada de parâmetros de linha de comando
  2. Defina todos os modos que o benchmark deve usar (preparar, executar, limpar)
  3. Prepare todos os dados
  4. Defina como o benchmark será executado (como serão as consultas, etc.)

Os scripts podem utilizar várias conexões com o banco de dados, eles também podem processar resultados caso você queira criar benchmarks complexos onde as consultas dependem do conjunto de resultados de consultas anteriores. Com o SysBench 1.0 é possível criar histogramas de latência. Também é possível que os scripts LUA capturem e manipulem erros por meio de ganchos de erro. Há suporte para paralelização nos scripts LUA, várias consultas podem ser executadas em paralelo, tornando, por exemplo, o provisionamento muito mais rápido. Por último, mas não menos importante, vários formatos de saída agora são suportados. Antes, o SysBench gerava apenas saída legível por humanos. Agora é possível gerá-lo como CSV ou JSON, tornando muito mais fácil fazer pós-processamento e gerar gráficos usando, por exemplo, gnuplot ou alimentar os dados em Prometheus, Graphite ou datastore similar.

Por que SysBench?


A principal razão pela qual o SysBench se tornou popular é o fato de ser simples de usar. Alguém sem conhecimento prévio pode começar a usá-lo em poucos minutos. Ele também fornece, por padrão, benchmarks que cobrem a maioria dos casos - cargas de trabalho OLTP, somente leitura ou leitura-gravação, pesquisas de chave primária e atualizações de chave primária. Tudo isso causou a maioria dos problemas para o MySQL, até o MySQL 8.0. Esta também foi a razão pela qual o SysBench foi tão popular em diferentes benchmarks e comparações publicados na Internet. Essas postagens ajudaram a promover essa ferramenta e a tornaram o benchmark sintético para o MySQL.

Outra coisa boa do SysBench é que, desde a versão 0.5 e incorporação do LUA, qualquer pessoa pode preparar qualquer tipo de benchmark. Já mencionamos benchmark semelhante ao TPCC, mas qualquer um pode criar algo que se assemelhe à sua carga de trabalho de produção. Não estamos dizendo que é simples, provavelmente será um processo demorado, mas ter essa capacidade é benéfico se você precisar preparar um benchmark personalizado.

Sendo um benchmark sintético, o SysBench não é uma ferramenta que você pode usar para ajustar as configurações de seus servidores MySQL (a menos que você tenha preparado scripts LUA com carga de trabalho personalizada ou sua carga de trabalho seja muito semelhante às cargas de trabalho de benchmark que o SysBench vem com). O que é ótimo é comparar o desempenho de hardware diferente. Você pode comparar facilmente o desempenho de, digamos, diferentes tipos de nós oferecidos pelo seu provedor de nuvem e o máximo de QPS (consultas por segundo) que eles oferecem. Conhecendo essa métrica e sabendo o que você paga por determinado nó, você pode calcular uma métrica ainda mais importante - QP$ (consultas por dólar). Isso permitirá que você identifique qual tipo de nó usar ao criar um ambiente econômico. Obviamente, o SysBench também pode ser usado para ajuste inicial e avaliação da viabilidade de um determinado projeto. Digamos que construímos um cluster Galera abrangendo todo o mundo - América do Norte, UE, Ásia. Quantas inserções por segundo pode lidar com essa configuração? Qual seria a latência do commit? Faz sentido fazer uma prova de conceito ou talvez a latência da rede seja alta o suficiente para que mesmo uma carga de trabalho simples não funcione como você esperaria.

E quanto ao teste de estresse? Nem todo mundo migrou para a nuvem, ainda existem empresas que preferem construir sua própria infraestrutura. Cada novo servidor adquirido deve passar por um período de aquecimento durante o qual você irá estressá-lo para identificar possíveis defeitos de hardware. Neste caso, o SysBench também pode ajudar. Ou executando a carga de trabalho OLTP que sobrecarrega o servidor, ou você também pode usar benchmarks dedicados para CPU, disco e memória.

Como você pode ver, existem muitos casos em que mesmo um benchmark sintético simples pode ser muito útil. No próximo parágrafo veremos o que podemos fazer com o SysBench.

O que o SysBench pode fazer por você?

Quais testes você pode executar?


Como mencionado no início, vamos nos concentrar em benchmarks OLTP e apenas como um lembrete, vamos repetir que o SysBench também pode ser usado para realizar testes de E/S, CPU e memória. Vamos dar uma olhada nos benchmarks que o SysBench 1.0 vem com (removemos alguns arquivos LUA auxiliares e scripts LUA que não são de banco de dados desta lista).
-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

Vamos passar por eles um por um.

Primeiro, bulk_insert.lua. Este teste pode ser usado para avaliar a capacidade do MySQL de realizar inserções de várias linhas. Isso pode ser bastante útil ao verificar, por exemplo, o desempenho da replicação ou do cluster Galera. No primeiro caso, pode ajudá-lo a responder a uma pergunta:“com que rapidez posso inserir antes que o atraso de replicação seja ativado?”. No último caso, ele informará o quão rápido os dados podem ser inseridos em um cluster Galera, dada a latência atual da rede.

Todos os scripts oltp_* compartilham uma estrutura de tabela comum. Os dois primeiros deles (oltp_delete.lua e oltp_insert.lua) executam instruções DELETE e INSERT simples. Novamente, isso pode ser um teste para replicação ou cluster Galera - leve-o ao limite e veja com que quantidade de inserção ou eliminação ele pode lidar. Também temos outros benchmarks focados em funcionalidades específicas - oltp_point_select, oltp_update_index e oltp_update_non_index. Eles executarão um subconjunto de consultas - seleções baseadas em chave primária, atualizações baseadas em índice e atualizações não baseadas em índice. Se você quiser testar algumas dessas funcionalidades, os testes estão aí. Também temos benchmarks mais complexos baseados em cargas de trabalho OLTP:oltp_read_only, oltp_read_write e oltp_write_only. Você pode executar uma carga de trabalho somente leitura, que consistirá em diferentes tipos de consultas SELECT, pode executar somente gravações (uma mistura de DELETE, INSERT e UPDATE) ou pode executar uma combinação desses dois. Finalmente, usando select_random_points e select_random_ranges, você pode executar algum SELECT aleatório usando pontos aleatórios na lista IN() ou intervalos aleatórios usando BETWEEN.

Como você pode configurar um comparativo de mercado?


O que também é importante, os benchmarks são configuráveis ​​- você pode executar diferentes padrões de carga de trabalho usando o mesmo benchmark. Vamos dar uma olhada nos dois benchmarks mais comuns para executar. Vamos nos aprofundar nos benchmarks OLTP read_only e OLTP read_write. Em primeiro lugar, o SysBench possui algumas opções gerais de configuração. Vamos discutir aqui apenas os mais importantes, você pode conferir todos eles executando:
sysbench --help

Vamos dar uma olhada neles.
  --threads=N                     number of threads to use [1]

Você pode definir que tipo de simultaneidade você gostaria que o SysBench gerasse. O MySQL, como todo software, tem algumas limitações de escalabilidade e seu desempenho atingirá o pico em algum nível de simultaneidade. Essa configuração ajuda a simular diferentes simultaneidades para uma determinada carga de trabalho e verificar se ela já passou do ponto ideal.
  --events=N                      limit for total number of events [0]
  --time=N                        limit for total execution time in seconds [10]

Essas duas configurações controlam por quanto tempo o SysBench deve continuar funcionando. Ele pode executar um certo número de consultas ou pode continuar em execução por um tempo predefinido.
  --warmup-time=N                 execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled [0]

Isso é autoexplicativo. O SysBench gera resultados estatísticos dos testes e esses resultados podem ser afetados se o MySQL estiver em um estado frio. O Warmup ajuda a identificar a taxa de transferência “regular” executando o benchmark por um tempo predefinido, permitindo aquecer o cache, pools de buffer etc.
  --rate=N                        average transactions rate. 0 for unlimited rate [0]

Por padrão, o SysBench tentará executar consultas o mais rápido possível. Para simular um tráfego mais lento, esta opção pode ser usada. Você pode definir aqui quantas transações devem ser executadas por segundo.
  --report-interval=N             periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]

Por padrão, o SysBench gera um relatório após concluir sua execução e nenhum progresso é relatado enquanto o benchmark está em execução. Usando esta opção, você pode tornar o SysBench mais detalhado enquanto o benchmark ainda é executado.
  --rand-type=STRING   random numbers distribution {uniform, gaussian, special, pareto, zipfian} to use by default [special]

O SysBench oferece a capacidade de gerar diferentes tipos de distribuição de dados. Todos eles podem ter seus próprios propósitos. A opção padrão, ‘especial’, define vários hot-spots (é configurável) nos dados, algo bastante comum em aplicações web. Você também pode usar outras distribuições se seus dados se comportarem de maneira diferente. Ao fazer uma escolha diferente aqui, você também pode alterar a maneira como seu banco de dados é estressado. Por exemplo, distribuição uniforme, onde todas as linhas têm a mesma probabilidade de serem acessadas, é uma operação que consome muito mais memória. Ele usará mais buffer pool para armazenar todos os dados e consumirá muito mais disco se seu conjunto de dados não couber na memória. Por outro lado, a distribuição especial com alguns hot-spots colocará menos estresse no disco, pois as linhas quentes são mais propensas a serem mantidas no pool de buffers e o acesso às linhas armazenadas no disco é muito menos provável. Para alguns dos tipos de distribuição de dados, o SysBench oferece mais ajustes. Você pode encontrar essa informação na saída 'sysbench --help'.
  --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]

Usando esta configuração, você pode decidir se o SysBench deve usar instruções preparadas (desde que estejam disponíveis no armazenamento de dados fornecido - para MySQL significa que o PS será ativado por padrão) ou não. Isso pode fazer a diferença ao trabalhar com proxies como ProxySQL ou MaxScale - eles devem tratar instruções preparadas de maneira especial e todas elas devem ser roteadas para um host, impossibilitando testar a escalabilidade do proxy.

Além das opções gerais de configuração, cada um dos testes pode ter sua própria configuração. Você pode verificar o que é possível executando:
[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]

Novamente, discutiremos as opções mais importantes a partir daqui. Em primeiro lugar, você tem um controle de como exatamente uma transação será. De um modo geral, consiste em diferentes tipos de consultas - INSERT, DELETE, diferentes tipos de SELECT (pesquisa de ponto, intervalo, agregação) e UPDATE (indexado, não indexado). Usando variáveis ​​como:
  --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]

Você pode definir como uma transação deve ser. Como você pode ver observando os valores padrão, a maioria das consultas são SELECTs - principalmente seleções de ponto, mas também diferentes tipos de SELECTs de intervalo (você pode desabilitar todas elas definindo range_selects como off). Você pode ajustar a carga de trabalho para uma carga de trabalho mais pesada de gravação aumentando o número de atualizações ou consultas INSERT/DELETE. Também é possível ajustar as configurações relacionadas a índices secundários, incremento automático, mas também tamanho do conjunto de dados (número de tabelas e quantas linhas cada uma delas deve conter). Isso permite que você personalize sua carga de trabalho muito bem.
  --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]

Esta é outra configuração, bastante importante ao trabalhar com proxies. Por padrão, o SysBench tentará executar consultas em transações explícitas. Dessa forma, o conjunto de dados permanecerá consistente e não será afetado:o SysBench, por exemplo, executará INSERT e DELETE na mesma linha, garantindo que o conjunto de dados não cresça (impactando sua capacidade de reproduzir resultados). No entanto, os proxies tratarão transações explícitas de maneira diferente - todas as consultas executadas em uma transação devem ser executadas no mesmo host, removendo assim a capacidade de dimensionar a carga de trabalho. Lembre-se de que desabilitar transações resultará em um conjunto de dados divergindo do ponto inicial. Também pode desencadear alguns problemas, como erros de chave duplicada ou outros. Para poder desabilitar as transações, você também pode pesquisar:
  --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]

Esta configuração permite que você especifique códigos de erro do MySQL que o SysBench deve ignorar (e não matar a conexão). Por exemplo, para ignorar erros como:erro 1062 (Entrada duplicada '6' para chave 'PRIMARY') você deve passar este código de erro:--mysql-ignore-errors=1062

O que também é importante, cada benchmark deve apresentar uma maneira de provisionar um conjunto de dados para testes, executá-los e limpá-los após a conclusão dos testes. Isso é feito usando os comandos 'prepare', 'run' e 'cleanup'. Mostraremos como isso é feito na próxima seção.

Exemplos


Nesta seção, veremos alguns exemplos de como o SysBench pode ser usado. Como mencionado anteriormente, vamos nos concentrar nos dois benchmarks mais populares - OLTP somente leitura e OLTP leitura/gravação. Às vezes, pode fazer sentido usar outros benchmarks, mas pelo menos poderemos mostrar como esses dois podem ser personalizados.

Pesquisas de chave primária


Antes de tudo, temos que decidir qual benchmark vamos rodar, somente leitura ou leitura-escrita. Tecnicamente falando, não faz diferença, pois podemos remover gravações do benchmark R/W. Vamos nos concentrar no somente leitura.

Como primeiro passo, temos que preparar um conjunto de dados. Precisamos decidir o quão grande deve ser. Para este benchmark específico, usando as configurações padrão (portanto, os índices secundários são criados), 1 milhão de linhas resultarão em aproximadamente 240 MB de dados. Dez tabelas, 1.000.000 linhas, cada uma equivale a 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

Isso deve lhe dar uma ideia de quantas mesas você quer e quão grandes elas devem ser. Digamos que queremos testar a carga de trabalho na memória para criar tabelas que se encaixem no buffer pool do InnoDB. Por outro lado, também queremos garantir que haja tabelas suficientes para não se tornar um gargalo (ou que a quantidade de tabelas corresponda ao que você esperaria em sua configuração de produção). Vamos preparar nosso conjunto de dados. Por favor, tenha em mente que, por padrão, o SysBench procura o esquema ‘sbtest’ que deve existir antes de você preparar o conjunto de dados. Você pode ter que criá-lo manualmente.
[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'...

Assim que tivermos nossos dados, vamos preparar um comando para executar o teste. Queremos testar pesquisas de chave primária, portanto, desativaremos todos os outros tipos de SELECT. Também desabilitaremos as instruções preparadas, pois queremos testar consultas regulares. Vamos testar baixa simultaneidade, digamos 16 threads. Nosso comando pode ficar assim:
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

O que fizemos aqui? Definimos o número de threads para 16. Decidimos que queremos que nosso benchmark seja executado por 300 segundos, sem limite de consultas executadas. Definimos conectividade com o banco de dados, número de tabelas e seu tamanho. Também desabilitamos todos os SELECTs de intervalo, também desabilitamos as instruções preparadas. Por fim, definimos o intervalo de relatório para um segundo. É assim que uma saída de amostra pode se parecer:
[ 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

A cada segundo, vemos um instantâneo das estatísticas da carga de trabalho. Isso é bastante útil para rastrear e plotar - o relatório final fornecerá apenas médias. Os resultados intermediários permitirão acompanhar o desempenho segundo a segundo. O relatório final pode ficar assim:
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

Você encontrará aqui informações sobre consultas executadas e outras instruções (BEGIN/COMMIT). Você aprenderá quantas transações foram executadas, quantos erros aconteceram, qual foi a taxa de transferência e o tempo total decorrido. Você também pode verificar as métricas de latência e a distribuição de consultas entre os encadeamentos.

Se estivéssemos interessados ​​na distribuição de latência, também poderíamos passar o argumento '--histogram' para o SysBench. Isso resulta em uma saída adicional como abaixo:
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

Quando estivermos bem com nossos resultados, podemos limpar os dados:
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

Tráfego intenso de gravação


Vamos imaginar aqui que queremos executar uma carga de trabalho pesada de gravação (mas não somente gravação) e, por exemplo, testar o desempenho do subsistema de E/S. Em primeiro lugar, temos que decidir o tamanho do conjunto de dados. Vamos supor ~48 GB de dados (20 tabelas, 10.000.000 linhas cada). Precisamos prepará-lo. Desta vez, usaremos o benchmark de leitura e gravação.
[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

Feito isso, podemos ajustar os padrões para forçar mais gravações no mix de consultas:
[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

Como você pode ver a partir dos resultados intermediários, as transações estão agora no lado pesado da gravação:
[ 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

Compreendendo os resultados


Como mostramos acima, o SysBench é uma ótima ferramenta que pode ajudar a identificar alguns dos problemas de desempenho do MySQL ou MariaDB. Ele também pode ser usado para o ajuste inicial da configuração do banco de dados. Claro, você deve ter em mente que, para tirar o melhor proveito de seus benchmarks, você precisa entender por que os resultados se parecem. Isso exigiria insights sobre as métricas internas do MySQL usando ferramentas de monitoramento, por exemplo, ClusterControl. Isso é muito importante lembrar - se você não entender por que o desempenho foi como era, você pode tirar conclusões incorretas dos benchmarks. Sempre há um gargalo, e o SysBench pode ajudar a levantar os problemas de desempenho, que você precisa identificar.