Sysbench

Sysbench e' un tool Open Source per effettuare benchmark.
Consente di eseguire diverse tipologie di test ed in particolare test sui DB relazionali. Grazie alla sua completezza e semplicita' d'uso e' diventato uno standard di fatto per i benchmark su MySQL.

Era molto tempo che volevo pubblicare una paginetta su sysbench... finalmente con l'uscita della versione 1.0 ho trovato l'occasione per aggiornare questo documento e sottometterlo!
Nel seguito sono riportate alcune informazioni di interesse organizzate in paragrafi specifici: Installazione, Varie ed Eventuali, ...

Per meglio comprendere gli argomenti e' utile una discreta conoscenza di MySQL e dei principali Benchmark sui DB relazionali.

Ho fretta

Anche se sono un fautore dello Slow Hacking ecco un breve esempio per chi ha fretta:

# yum install sysbench $ sysbench --table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=test --mysql-password=xxx oltp_read_write prepare sysbench --table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=luca55 oltp_read_write prepare $ sysbench --table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=test --mysql-password=xxx oltp_read_write run ... SQL statistics: transactions: 4306 (430.04 per sec.) queries: 86120 (8600.74 per sec.) ...

Nel resto del documento cercheremo di vedere tutte le variazioni possibili a questo primo esempio!

Installazione

sysbench e' disponibile sulla maggioranza delle distribuzioni Unix. L'installazione e' quindi banale:

## Red Hat/CentOS/Oracle Linux/Fedora/... # yum install sysbench ## Debian/Ubuntu/... # apt-get install sysbench

Si tratta di meno di 100KB: l'installazione e' molto veloce.

La versione piu' aggiornata ed i sorgenti sono mantenuti su GitHub [NdE in precedenza era su launchpad] ed e' recentemente approdata alla 1.0 (ma sysbench funzionava perfettamente da anni anche se le precedenti release erano 0.x).

Sintassi 1.0

Con la versione 1.0 sono cambiate un po' di cosette: sysbench e' molto piu' scalabile (ora sistemi con centinaia di core sono piuttosto normali), gli script sono programmabili in Lua (rendendendo possibili innumerevoli tipi di test), si possono gestire gli errori, si puo' personalizzare l'output, ... Un riassunto delle novita' si puo' trovare su questa paginetta.

Cambia un poco anche la sintassi del comando ed in questa paginetta utilizzeremo la nuova sintassi. Quali sono le differenze rispetto a prima? Basta un esempio!

## Vecchia sintassi $ sysbench --test=cpu run ## Nuova sintassi $ sysbench cpu run

Inoltre in precedenza gli unici comandi per ogni test erano: prepare, run, cleanup, help dal significato piuttosto ovvio... Ora gli script Lua possono prevedere ulteriori comandi da utilizzare in linea.

L'elenco completo delle opzioni si ottiene con sysbench --help.

Ovviamente molte cose non sono cambiate. Le opzioni piu' significative sono: --threads=N number of threads to use [1] --events=N limit for total number of events [0] --time=N

Naturalmente per effettuare test su MySQL servono le relative opzioni:

  --mysql-host=[LIST,...]          MySQL server host [localhost]
  --mysql-port=[LIST,...]          MySQL server port [3306]
  --mysql-socket=[LIST,...]        MySQL socket
  --mysql-user=STRING              MySQL user [sbtest]
  --mysql-password=STRING          MySQL password []
  --mysql-db=STRING                MySQL database name [sbtest]
  --mysql-ssl[=on|off]             use SSL connections, if available in the client library [off]
  --mysql-ssl-cipher=STRING        use specific cipher for SSL connections []
  --mysql-compression[=on|off]     use compression, if available in the client library [off]
  --mysql-debug[=on|off]           trace all client library calls [off]
  --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]
  --mysql-dry-run[=on|off]         Dry run, pretend that all MySQL client API calls are successful without executing them [off]

Poiche' i test sono scritti in linguaggio Lua e' possibile programmarli a piacere partendo dai molti esempi disponibili [NdA tipicamente nella directory: /usr/share/sysbench].

E' anche possibile utilizzare uno dei test gia' predisposti. I test piu' usati per MySQL sono oltp_read_only, oltp_read_write; con prepare viene creata la tabella sbtest1 e con run viene eseguito il benchmark.

Ecco un esempio, volutamente un poco semplificato, di programma di test scritto in LUA [NdA vi ho gia' risparmiato l'Hello World..., ora non potete sfuggire all'EMP7]:

function prepare()
   db_query("CREATE TABLE emp7 (EMPNO integer not null,ENAME VARCHAR(10),DEPTNO integer,SAL float)")
   db_query("ALTER TABLE emp7 ADD PRIMARY KEY(EMPNO)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7369, 'SMITH', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7499, 'ALLEN', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7521, 'WARD',  10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7566, 'JONES', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7654, 'MARTIN',10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7698, 'BLAKE', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7782, 'CLARK', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7788, 'SCOTT', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7839, 'KING',  10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7844, 'TURNER',10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7876, 'ADAMS', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7900, 'JAMES', 10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7902, 'FORD',  10, 100)")
   db_query("insert into emp7(empno, ename, deptno, sal) values(7934, 'MILLER',10, 100)")
end

function event()
   db_query("select count(*) from emp7 emp1, emp7 emp2, emp7 emp3, emp7 emp4, emp7 emp5, emp7 emp6, emp7 emp_7 where emp_7.deptno=10")
end

function event_upd()
   db_query("UPDATE emp7 SET sal = sal + " .. sb_rand(1, 100) .. " ORDER BY RAND() LIMIT 1")
end

function cleanup()
   db_query("DROP TABLE emp7")
end


sysbench.cmdline.options = {
   table_size =
      {"Number of rows per table", 14}
   }

sysbench.cmdline.commands = {
   update_test = {event_upd}
}

Ulteriori esempi:

sysbench --test=cpu --cpu-max-prime=20000 run

sysbench emp7.lua --mysql-user=sbtest --mysql-password=xxx --events=10 --time=0 run

sysbench cpu run
...
    execution time (avg/stddev):   22.2060/0.00 (prod-dbfarmXX)
    execution time (avg/stddev):   22.3790/0.00 (prod-dbfarmXX)
    execution time (avg/stddev):   9.9967/0.00 (meosMac)

sysbench --test=cpu  run
    execution time (avg/stddev):   8.7966/0.00 (prod-dbfarmXX)


sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/oltp_read_write.lua --table-size=1000000 --mysql-user=root --mysql-password=xxx prepare
sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/oltp_read_write.lua --table-size=1000000 --mysql-user=root --mysql-password=xxx prepare

sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp-table-size=1000000 --mysql-user=root --mysql-password=xxx --mysql-db=sbtest --oltp-test-mode=complex --oltp-read-only=off --oltp-reconnect=on --max-requests=10000 --num-threads=64 prepare


sysbench --test=/var/tmp/testIO --file-total-size=150G prepare
sysbench --test=/var/tmp/testIO --file-total-size=150G --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run
...

sysbench --test=fileio --file-total-size=150G cleanup

sysbench --test=tests/db/oltp.lua --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=xxx --oltp-test-mode=complex --oltp-read-only=off --oltp-reconnect=on --max-requests=10000 --num-threads=64 run

sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=xxx --oltp-test-mode=complex --oltp-read-only=off --oltp-reconnect=on --max-requests=10000 --num-threads=64 run

--mysql_dry_run

sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=sysbench --mysql-user=root --mysql-password=xxx --mysql-host=localhost --mysql-port=3306 prepare

Creating table 'sbtest'...
Creating 1000000 records in table 'sbtest'...

sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=xxx --mysql-host=prod-dbfarmxx --mysql-port=3306 --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run
...
    transactions:                        446577 (7442.80 per sec.) (prod-dbfarmxx)
    transactions:                        275341 (4588.90 per sec.) (prod-dbfarmxx)

sysbench --test=oltp --mysql-db=sysbench --mysql-user=root --mysql-password=xxx cleanup 

  --pgsql-host=STRING     PostgreSQL server host [localhost]
  --pgsql-port=N          PostgreSQL server port [5432]
  --pgsql-user=STRING     PostgreSQL user [sbtest]
  --pgsql-password=STRING PostgreSQL password []
  --pgsql-db=STRING       PostgreSQL database name [sbtest]

sysbench --test=oltp help

Compiled-in tests:
  fileio - File I/O test
  cpu - CPU performance test
  memory - Memory functions speed test
  threads - Threads subsystem performance test
  mutex - Mutex performance test
  oltp - OLTP test

Con sysbench sono disponibili una serie di test (eg. /usr/local/Cellar/sysbench/1.0.x/share/sysbench). Tra questi i piu' comunemente usati sono: oltp_read_only, oltp_read_write, select_random_points, oltp_update_non_index, ...

Varie ed eventuali

Gli aggiornamenti di sysbench sono riportati nella pagina Il tuo server puzza!

Puo' essere utile la pagina: Benchmark sui DB relazionali.


Titolo: Sysbench
Livello: Avanzato (3/5)
Data: 14 Febbraio 2014
Versione: 1.0.2 - 14 Febbraio 2020
Autore: mail [AT] meo.bogliolo.name