4. Looking for bottlenecks
How the various parts of the system
interact?
– Disk IO, RAM, RBMS, etc
Measure quantities:
– How do they perform?
– Where is the most time spent?
– Which components are busiest?
Finding the causes of bottlenecks: 4
– Why?
5. Measurement is a requirement to
choose the right hardware and the right
software
understand behaviors
understand performance
correctly tune and configure
identify advantages and disadvantages
spot weak points
5
6. Measurement is a requirement to
Plan for growth
Plan for special events
Understand scalability
Your organization may be interested in the above!
6
7. What to benchmark
Full-stack
– Benchmark all the infrastructure, web
servers, applications, caching layers,
databases, network, external resources, etc
– Gives a better overview
– Very difficult to implement
– Results are complex to understand, and may
be misleading
Single-component 7
– Benchmark of only a single component of the
8. Database benchmarks
Single component benchmark
Compare:
different OS configuration
different hardware
different DB systems
different parameters
different schema
different queries
different workload
8
9. Benchmark guidelines
Define pre-benchmark goals
Understand the workload to reproduce
Record everything, even what seems
useless, HW info, configuration, versions,
table size , …
Create baselines
– Every benchmark is a baseline for future
ones
Define post-benchmark targets 9
Change only one thing at the time, and
12. Stress testing
System tested to its limit
– Extreme load is used
– Defines upper boundary
– Defines capacity
12
13. Load testing
System tested against an expected load
– Number of users
– Number of transactions
– Dataset size
13
14. Endurance testing
Similar to load testing
Emulating extended time
Measure stability on long term
14
15. Spike testing
Sudden change in workload
Defines the system's behavior in such
circumstances. Possible cases:
– The spike is handled with no impact
– Performance will degrade
– System will halt/fail/crash
15
16. Performance testing goals
Must be defined before starting any
benchmark
Verify if the system meets defined
criteria
Compare two systems
Isolate the component of the system that
has poor performance
16
17. Performance testing goals
High throughput
Low latency
Stability when faced with scalability
Stability when faced with concurrency
17
18. Throughput
The most widely used measured quantity
Number of successful transactions per
time unit ( usually second or minute )
Normally it focuses only on average result
Widely used in marketing for comparisons
Important for Stress Testing
18
19. Latency
Total execution time for a transaction to
complete
Min / Avg / Max response time
Important in Load Testing
19
20. Stability when faced with scalability
Measures how system performs when
scaling
Finds weak spots before they become a
serious problem
Useful for capacity planning
Endurance Testing
20
21. Stability when faced with concurrency
Measures how system performs when
number of threads/connections changes
Defines if it is useful to impose an upper
limit in number of threads and introduce
queues
Spike Testing
21
23. Test conditions
How to avoid common mistakes
Run benchmarks on a realistic setup
Similar/identical hardware
– CPU, memory, network, IO subsystem
Same software configuration
Similar dataset size
Similar distribution of data
Similar access pattern
– Avoid query and data caching
– Reproduce access distribution 23
24. Record everything
It is better to have useless information
than to miss important ones
Document all the steps to re-run the
benchmark
Configuration : hardware, software version
and parameters, data size, data set
Collect hardware statistics ( CPU , disk ,
network , memory )
Collect software statistics ( GLOBAL
24
STATUS, INNODB STATUS)
25. Isolate the benchmark setup
Run benchmarks on a system that is not
used for other purposes
Avoid shared environment ( Virtualization,
or SAN)
Ensure that no other applications are using
the network
Identical conditions at starting point
(warmup)
(if necessary) Restart the system before 25
each benchmark
26. Automate benchmark
Simplify the recurrent execution
Avoid human mistakes
Improved documentation
Easy to reproduce
Easy to analyze
26
27. Analysis of results
Process all the data collected
Identify which data provide useful
information
Answer the questions defined in your
goals
Document the result
Conclusion
Define targets 27
30. mysqlslap
Load emulator client
It executes in 3 stages:
– It creates the tables structure
and load data
– Run tests
– Cleanup
30
31. mysqlslap (examples)
$ mysqlslap --only-print --auto-generate-sql
DROP SCHEMA IF EXISTS `mysqlslap`;
CREATE SCHEMA `mysqlslap`;
use mysqlslap;
CREATE TABLE `t1` (intcol1 INT(32) ,charcol1 VARCHAR(128));
INSERT INTO t1 VALUES (...);
INSERT INTO t1 VALUES (...);
....
SELECT intcol1,charcol1 FROM t1;
INSERT INTO t1 VALUES (...);
SELECT intcol1,charcol1 FROM t1;
INSERT INTO t1 VALUES (...);
...
DROP SCHEMA IF EXISTS `mysqlslap`;
31
32. mysqlslap (examples)
$ mysqlslap --only-print --auto-generate-sql | awk '{print
$1" "$2}' | sort | uniq -c | sort -n -r
105 INSERT INTO
5 SELECT intcol1,charcol1
2 DROP SCHEMA
1 use mysqlslap;
1 CREATE TABLE
1 CREATE SCHEMA
By default, it creates and drop the database `mysqlslap`
--create-schema=value to specify a different database
name
Each thread performs 100 INSERT during the loads data
stage ( default for --auto-generate-sql-write-number )
Each thread performs as many INSERT and SELECT
during the test stage ( default for --auto-generate-sql-load-
32
type )
35. mysqlslap (examples)
~$ mysqlslap --auto-generate-sql --concurrency=1,2,3 –
iteration=10
--number-of-queries=100 –auto-generate-sql-write-
number=100000
Benchmark
Average number of seconds to run all queries: 4.522 seconds
Minimum number of seconds to run all queries: 4.216 seconds
Maximum number of seconds to run all queries: 4.648 seconds
Number of clients running queries: 1
Average number of queries per client: 100
Benchmark
Average number of seconds to run all queries: 3.025 seconds
Minimum number of seconds to run all queries: 2.737 seconds
Maximum number of seconds to run all queries: 3.227 seconds
Number of clients running queries: 2
Average number of queries per client: 50
35
Benchmark
Average number of seconds to run all queries: 2.618 seconds
36. mysqlslap (examples)
$ mysqlslap --auto-generate-sql –-concurrency=4
--engine=myisam,innodb --number-of-queries=100
--iteration=10 --auto-generate-sql-write-number=100000
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 2.232 seconds
Minimum number of seconds to run all queries: 2.003 seconds
Maximum number of seconds to run all queries: 2.319 seconds
Number of clients running queries: 4
Average number of queries per client: 25
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.332 seconds
Minimum number of seconds to run all queries: 5.314 seconds
Maximum number of seconds to run all queries: 5.370 seconds
Number of clients running queries: 4 36
Average number of queries per client: 25
37. mysqlslap (examples)
$ mysqlslap --auto-generate-sql --concurrency=4
--engine=myisam,innodb --number-of-queries=1000
--iteration=10 --auto-generate-sql-write-number=10000
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 2.059 seconds
Minimum number of seconds to run all queries: 1.937 seconds
Maximum number of seconds to run all queries: 2.169 seconds
Number of clients running queries: 4
Average number of queries per client: 250
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.604 seconds
Minimum number of seconds to run all queries: 5.560 seconds
Maximum number of seconds to run all queries: 5.659 seconds
Number of clients running queries: 4 37
Average number of queries per client: 250
38. mysqlslap (examples)
SET GLOBAL concurrent_insert=0;
$ mysqlslap --auto-generate-sql –-concurrency=4 –
engine=myisam,innodb
--number-of-queries=1000 --iteration=10 --auto-generate-
sql-write-number=10000
Benchmark
Running for engine myisam
Average number of seconds to run all queries: 3.256 seconds
Minimum number of seconds to run all queries: 3.210 seconds
Maximum number of seconds to run all queries: 3.317 seconds
Number of clients running queries: 4
Average number of queries per client: 250
Benchmark
Running for engine innodb
Average number of seconds to run all queries: 5.615 seconds38
Minimum number of seconds to run all queries: 5.585 seconds
Maximum number of seconds to run all queries: 5.699 seconds
39. mysqlslap (examples)
mysqlslap --auto-generate-sql -–concurrency=4
--engine=memory,myisam,innodb --iteration=10
--number-of-queries=1000 –auto-generate-sql-write-
number=10000 --auto-generate-sql-add-autoincrement
CREATE TABLE `t1` (id serial,intcol1 INT(32) ,charcol1
VARCHAR(128));
Running for engine memory
Average number of seconds to run all queries: 0.035 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.038 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.032 seconds
39
100x times faster?
40. mysqlslap (examples)
Increasing the duration of the test
$ mysqlslap --auto-generate-sql --concurrency=4
--engine=memory,myisam,innodb --iteration=10
--number-of-queries=10000 --auto-generate-sql-write-
number=10000 --auto-generate-sql-add-autoincrement
Running for engine memory
Average number of seconds to run all queries: 0.430 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.467 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.327 seconds
InnoDB wins! 40
41. mysqlslap (examples)
Add more fields:
$ mysqlslap mysqlslap -a -c4 -y4 -x4
--engine=memory,myisam,innodb -i10 --number-of-
queries=10000 --auto-generate-sql-write-number=10000
--auto-generate-sql-add-autoincrement
Running for engine memory
Average number of seconds to run all queries: 0.504 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.526 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.468 seconds
InnoDB still wins, but has slow down a lot.
41
42. mysqlslap (examples)
Increase concurrency:
$ mysqlslap mysqlslap -a -c8 -y4 -x4
--engine=memory,myisam,innodb -i10 --number-of-
queries=10000 --auto-generate-sql-write-number=10000
--auto-generate-sql-add-autoincrement
Running for engine memory
Average number of seconds to run all queries: 0.526 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.596 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.657 seconds
InnoDB is the slowest
42
43. mysqlslap (examples)
Workload: read primary key
$ mysqlslap mysqlslap --auto-generate-sql-load-type=key -a
-c8 -y4 -x4 --engine=memory,myisam,innodb -i10 --number-of-
queries=10000 --auto-generate-sql-write-number=10000 –auto-
generate-sql-add-autoincrement
Running for engine memory
Average number of seconds to run all queries: 0.278 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.328 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.324 seconds
43
44. mysqlslap (examples)
Workload: update primary key
$ mysqlslap mysqlslap --auto-generate-sql-load-type=update -a
-c8 -y4 -x4 –engine=blackhole,memory,myisam,innodb -i10
--number-of-queries=10000 --auto-generate-sql-write-
number=10000 –auto-generate-sql-add-autoincrement
Running for engine blackhole
Average number of seconds to run all queries: 0.251 seconds
Running for engine memory
Average number of seconds to run all queries: 0.724 seconds
Running for engine myisam
Average number of seconds to run all queries: 0.939 seconds
Running for engine innodb
Average number of seconds to run all queries: 0.518 seconds44
46. sysbench
Multi-threaded benchmark tool for:
File I/O performance
Scheduler performance
Memory allocation and transfer speed
POSIX threads implementation
performance
46
Database server performance (OLTP)
47. sysbench
Intially developed for MySQL , but then
extended
Available at:
•
https://code.launchpad.net/~sysbenc
h-developers/sysbench/0.5
•
http://sysbench.sourceforge.net/
•
http://dev.mysql.com/downloads/ben
chmarks.html 47
48. Sysbench
installation
$ b zr b ran ch lp :sysb e n ch
$ cd sysb e n ch
$ ./au to ge n .sh
$ ./co n figu re
$ m ake
$ su d o m ake in stall
48
49. sysbench
CPU test
Very simple test to process
prime numbers:
$ sysb e n ch --te st= cp u --cp u -m ax-
p rim e = 20000 ru n
Ru n n in g th e te st with fo llo win g o p tio n s:
N u m b e r o f th re ad s: 1
Prim e r n u m b e rs lim it: 20000 49
50. sysbench
CPU test
Prime numbers, multi-
threads:
$ sysb e n ch --n u m -th re ad s= 4 --te st= cp u
--cp u -m ax-p rim e = 20000 ru n
Ru n n in g th e te st with fo llo win g o p tio n s:
N u m b e r o f th re ad s: 4
50
Prim e r n u m b e rs lim it: 20000
51. sysbench
CPU test
Prime numbers, multi-
threads:
$ sysb e n ch --n u m -th re ad s= 8 --te st= cp u
--cp u -m ax-p rim e = 20000 ru n
Ru n n in g th e te st with fo llo win g o p tio n s:
N u m b e r o f th re ad s: 8
51
Prim e r n u m b e rs lim it: 20000
52. sysbench
threads test (scheduler)
Lock mutex => Yield CPU
=> Run queue =>
Unlock mutex
$ sysb e n ch --n u m -th re ad s= 64
--te st= th re ad s ru n
Ru n n in g th e te st with fo llo win g o p tio n s:
N u m b e r o f th re ad s: 64 52
53. sysbench
mutexs test
Threads trying to acquire
the same set of mutexs
Measure mutexes
implementation.
$ sysb e n ch --n u m -th re ad s= 1 28
--te st= m u te x --m u te x-lo cks= 1 00000 53
--m u te x-lo o p s= 1 00 --m u te x-
54. sysbench
memory test
Sequential read or write
memory
$ sysb e n ch --n u m -th re ad s= 1
--te st= m e m o ry ru n – m e m o ry-b lo ck-
size = 1 6k
--m e m o ry-to tal-size = 4G --m e m o ry-
o p e r= re ad 54
Ru n n in g th e te st with fo llo win g o p tio n s:
56. sysbench
CPU test
Numbers lie!
The previous test reports reads at 1.8TB/
s with 8MB block size.
With 32MB block size, reads go to
7.2TB/s
56
Constant OPS is the real bottleneck.
59. sysbench
fileio test
2 stages test:
prepare
files are created on filesystem
run
test is executed on previously created
files
59
60. sysbench
fileio test
Supported I/O tests: ( --file-test-mode)
seqwr : sequential write
seqrewr : sequential rewrite
seqrd : sequential read
rndrd : random read
rndwr : random write
rndrw : random read/write
60
61. sysbench
fileio test
Other options:
--file-num : number of files
--file-block-size
--file-total-size : all files combined
--file-io-mode : sync , async, mmap
--file-extra-flags (odirect)
--file-fsync-freq : frequency of fsync()
--file-fsync-all
--file-rw-ratio : R/W ratio in rndrw mode
61
62. sysbench
fileio test
Prepare the files:
$ sysbench --test=fileio --file-num=4
--file-total-size=1G prepare
4 files, 262144Kb each, 1024Mb total
Creating files for the test...
Extra file open flags: 0
Creating file test_file.0
Creating file test_file.1 62
Creating file test_file.2
63. Sysbench - fileio test
sysbench --test=fileio --file-
num=1 --file-total-size=2G
--file-fsync-all=on --file-
test-mode=seqrewr --max-
time=100 –file-block-size=4096
--max-requests=0 run
Number of threads: 1
Extra file open flags: 0
1 files, 2Gb each
2Gb total file size
Block size 4Kb 63
Calling fsync() after each write
64. Sysbench - fileio test
sysbench --test=fileio --file-
num=29 --file-total-size=290G
--file-fsync-all=on --file-
test-mode=rndrw --max-time=100
--file-block-size=16384 --max-
requests=0 run
Number of threads: 1
Extra file open flags: 0
29 files, 10Gb each
290Gb total file size
Block size 16Kb 64
Number of random requests for
65. Sysbench - fileio test
sysbench --num-threads=8
--test=fileio --file-num=29 –
file-total-size=290G
--file-fsync-all=on --file-
test-mode=rndrw --max-time=100
–file-rw-ratio=4
--file-block-size=16384 --max-
requests=0 run
Number of threads: 8
Extra file open flags: 0
29 files, 10Gb each 65
290Gb total file size
66. Sysbench - fileio test
sysbench --num-threads=16
--test=fileio --file-num=29 –
file-total-size=290G
--file-fsync-all=on --file-
test-mode=rndrw --max-time=100
–file-rw-ratio=4
--file-block-size=16384 --max-
requests=0 run
Number of threads: 16
Extra file open flags: 0
29 files, 10Gb each 66
290Gb total file size
69. Sysbench - OLTP
Delays
--oltp-reconnect-mode :
– session : never disconnect
– query : after each query
– transaction : after each transaction
– random : randomly
--oltp-connect-delay
--oltp-user-delay-min
--oltp-user-delay-max
69
70. Sysbench - OLTP
$ m ysq l -e "D RO P D ATABASE IF EXISTS sb te st"
$ m ysq l -e "CREATE D ATABASE sb te st"
$ sysb e n ch – te st= te sts/d b /o ltp .lu a
--o ltp -tab le s-co u n t= 4 --o ltp -tab le -size = 500000
--m ysq l-tab le -e n gin e = in n o d b --m ysq l-u se r= ro o t
--m ysq l-p asswo rd = p asswo rd p re p are
Cre atin g tab le 'sb te st1 '...
In se rtin g 500000 re co rd s in to 'sb te st1 '
Cre atin g tab le 'sb te st2'...
In se rtin g 500000 re co rd s in to 'sb te st2'
Cre atin g tab le 'sb te st3'...
In se rtin g 500000 re co rd s in to 'sb te st3' 70
Cre atin g tab le 'sb te st4'...
71. Sysbench - OLTP
$ sysb e n ch --te st= te sts/d b /o ltp .lu a --o ltp -tab le s-
co u n t= 4 --o ltp -tab le -size = 500000 --o ltp -te st-
m o d e = sim p le ru n
N u m b e r o f th re ad s: 1
O LTP te st statistics:
q u e rie s p e rfo rm e d :
re ad : 1 40000
write : 40000
o th e r: 20000
to tal: 200000
tran sactio n s: 1 0000 (21 7.87 p e r se c.)
d e ad lo cks: 0 (0.00 p e r se c.)
re ad /write re q u e sts: 1 80000 (3921 .61 p e r 71
se c.)
72. Sysbench - OLTP
$ sysb e n ch --te st= te sts/d b /o ltp .lu a – oltp-tables-
count=16
--o ltp -tab le -size = 500000 --o ltp -te st-m o d e = sim p le –
num-threads=16 ru n
N u m b e r o f th re ad s: 1 6
O LTP te st statistics:
q u e rie s p e rfo rm e d :
re ad : 1 40000
write : 40000
o th e r: 20000
to tal: 200000
tran sactio n s: 1 0000 (777.78 p e r se c.)
72
d e ad lo cks: 0 (0.00 p e r se c.)
re ad /write re q u e sts: 1 80000 (1 3999.96
73. Sysbench - OLTP
$ sysb e n ch --te st= sysb e n ch /sysb e n ch /sysb e n ch /te sts/
d b /o ltp .lu a --o ltp -tab le s-co u n t= 4 --o ltp -tab le -
size = 500000 --o ltp -te st-m o d e = co m p le x – m ysq l-
u se r= ro o t
--m ysq l-p asswo rd = p asswo rd --n u m -th re ad s= 1 6 –
oltp-point-selects=1000
--oltp-range-size=1000 --oltp-index-updates=1000
--max-time=300 ru n
N u m b e r o f th re ad s: 1 6
O LTP te st statistics:
q u e rie s p e rfo rm e d :
re ad : 58031 20
73
write : 201 5732
o th e r: 7585
74. Sysbench - OLTP
Type of queries:
Point queries:
SELECT c FROM sbtest WHERE id=N
UPDATEs on index column:
UPDATE sbtest SET k=k+1 WHERE id=N
UPDATEs on non-index column:
UPDATE sbtest SET c=N WHERE id=M
Range queries:
SELECT c FROM sbtest WHERE id BETWEEN N
AND M
Range SUM():
SELECT SUM(k) FROM sbtest WHERE id between
N and M
74
Range ORDER BY:
SELECT c FROM sbtest WHERE id between N and M
76. DBT2
is an OLTP transactional performance
test
it simulates a wholesale parts supplier
where several workers access a
database, update customer
information and check on parts
inventories
DBT-2™ is a fair usage
implementation of the TPC's TPC-C™ 76
Benchmark specification
77. DBT2
it is one of the most popular benchmark
tool for MySQL
It seriously lacks of any good
documentation
Website:
http://osdldbt.sourceforge.net
77
79. DBT2 :Download and compile
Download page: http://sourceforge.net/projects/osdldbt/files/dbt2/
$ wget
http://downloads.sourceforge.net/project/osdldbt/dbt2/0.40/dbt2-0.
40.tar.gz
$ tar -zxf dbt2-0.40.tar.gz
$ cd dbt2-0.40
$ ./configure –with-mysql[=/usr/local/mysql]
$ make
Note: If you don't have installed MySQL or any of its variants through package
manager ( rpm/deb ) , you can specify a path for –with-mysql .
Ex: unpack MySQL tarball in /usr/local/mysql
79
80. DBT2 : stages
Generate data
Load data
Run benchmark
80
81. DBT2 :Generate data
Data for the test is generated by datagen
Usage: datagen -w # [-c #] [-i #] [-o #] [-s #] [-n #] [-d <str>]
-w # : warehouse cardinality
-c # : customer cardinality, default 3000
-i # : item cardinality, default 100000
-o # : order cardinality, default 3000
-n # : new-order cardinality, default 900
-d <path> : output path of data files
--sapdb : format data for SAP DB
--pgsql : format data for PostgreSQL
--mysql : format data for MySQL
Ex:
$ mkdir /tmp/dbt2-w10
$ datagen -w 10 -d /tmp/dbt2-w10 –mysql
81
82. DBT2 : Load data
Load data using build_db.sh
options:
-d <database name>
-f <path to dataset files>
-g (generate data files)
-s <database socket>
-h <database host>
-u <database user>
-p <database password> *
-e <storage engine: [MYISAM|INNODB]. (default INNODB)>
-l <to use LOCAL keyword while loading dataset> *
-v <verbose>
-w <scale factor>
build_db.sh -w 3 -d dbt2 -f /tmp/dbt2-w3 -s
/var/run/mysqld/mysqld.sock -h localhost -u root -p password -e 82
INNODB -v -l
83. DBT2 : Load data (cont.)
Series of gotcha :
Documentation say to use scripts/mysql/mysql_load_db.sh : this
script doesn't exist!
Instead, use script/mysql/build_db.sh
Doesn't load the files!
In build_db.sh replace:
> while getopts "d:h:f:gs:e:m:u:p:vw:" opt; do
with:
< while getopts "d:h:f:gs:e:m:u:p:vlw:" opt; do
The database password is not accepted via -p but via -x
83
84. DBT2 : Run the test
Run test using run_workload.sh
usage: run_workload.sh -c <number of database connections> -d
<duration of test> -w <number of warehouses>
other options:
-d <database name. (default dbt2)> *
-h <database host name. (default localhost)> *
-l <database port number>
-o <enable oprofile data collection>
-s <delay of starting of new threads in milliseconds>
-n <no thinking or keying time (default no)>
-u <database user>
-x <database password>
-z <comments for the test>
(*) See next slide
84
85. DBT2 : Run the test (cont.)
Series of gotcha :
Documentation say to use scripts/run_mysql.sh : this script doesn't
exist!
Instead use scripts/run_workload.sh
Options:
-h doesn't specify the database hostname, but prints the help! Use -
H instead
-d is not the database name, but the duration of the test in seconds
It fails to run unless you also run the follow:
$ export USE_PGPOOL=0 85
Socket /tmp/mysql.sock is hardcoded in the script. If your server run
86. DBT2 : Run the test (cont.)
Example:
./run_workload.sh -c 10 -d 900 -n -w 10 -s 60 -u root -x password
Response Time (s)
Transaction % Average : 90th % Total Rollbacks %
------------ ----- --------------------- ----------- --------------- -----
Delivery 3.99 0.313 : 0.493 14301 0 0.00
New Order 45.18 0.074 : 0.102 161981 1635 1.02
Order Status 3.93 0.054 : 0.077 14103 0 0.00
Payment 42.90 0.059 : 0.083 153816 0 0.00
Stock Level 4.00 0.053 : 0.076 14324 0 0.00
------------ ----- --------------------- ----------- --------------- -----
10592.50 new-order transactions per minute (NOTPM)
15.0 minute duration
0 total unknown errors
2 second(s) ramping up
86
88. tpcc-mysql
It s an OLTP transactional
performance test
benchmark tool developed by
Percona
It generates TPC-C workload
88
89. tpcc-mysql
get the software
Hosted on launchpad at:
https://code.launchpad.net/~percona-
dev/perconatools/tpcc-mysql
Get the branch:
$ bzr branch lp:~percona-dev/perconatools/tpcc-mysql
Compile:
$ cd tpcc-mysql/src
$ make
$ cd ..
89
90. tpcc-mysql
prepare the database
mysqladmin create tpcc10
mysql tpcc10 < create_table.sql
mysql tpcc10 < add_fkey_idx.sql
90
91. tpcc-mysql
load the data
./tpcc_load localhost tpcc10 root pass 10
Options are:
- hostname
- dbname
- dbuser
- dbpass
- number of warehouses
91
93. tpcc-mysql
start the benchmark
***************************************
* * * ###e asy### TPC-C Lo ad Ge n e rato r * * *
***************************************
o p tio n h with valu e 'lo calh o st'
o p tio n d with valu e 'tp cc1 0'
o p tio n u with valu e 'ro o t'
o p tio n p with valu e 'p asswo rd '
o p tio n w with valu e '1 0'
o p tio n c with valu e '32'
o p tio n r with valu e '1 0'
o p tio n l with valu e '600'
< Param e te rs>
[se rve r]: lo calh o st
[p o rt]: 3306
[D Bn am e ]: tp cc1 0
[u se r]: ro o t
[p ass]: p asswo rd
[ware h o u se ]: 1 0
[co n n e ctio n ]: 32
[ram p u p ]: 1 0 (se c.)
[m e asu re ]: 600 (se c.)
93
95. tpcc-mysql
benchmark results
< Raw Re su lts>
[0] sc:1 25242 lt:3 rt:0 fl:0
[1 ] sc:1 25252 lt:0 rt:0 fl:0
[2] sc:1 2522 lt:0 rt:0 fl:0
[3] sc:1 2525 lt:0 rt:0 fl:0
[4] sc:1 2526 lt:0 rt:0 fl:0
in 600 se c.
< Raw Re su lts2(su m ve r.)>
[0] sc:1 25251 lt:3 rt:0 fl:0
[1 ] sc:1 25254 lt:0 rt:0 fl:0
[2] sc:1 2524 lt:0 rt:0 fl:0
[3] sc:1 2525 lt:0 rt:0 fl:0
[4] sc:1 2527 lt:0 rt:0 fl:0
95
96. tpcc-mysql
benchmark results
< Co n strain t Ch e ck> (all m u st b e [O K])
[tran sactio n p e rce n tage ]
Paym e n t: 43.48% (> = 43.0% ) [O K]
O rd e r-Statu s: 4.35% (> = 4.0% ) [O K]
D e live ry: 4.35% (> = 4.0% ) [O K]
Sto ck-Le ve l: 4.35% (> = 4.0% ) [O K]
[re sp o n se tim e (at le ast 90% p asse d )]
N e w-O rd e r: 1 00.00% [O K]
Paym e n t: 1 00.00% [O K]
O rd e r-Statu s: 1 00.00% [O K]
D e live ry: 1 00.00% [O K]
Sto ck-Le ve l: 1 00.00% [O K]
< Tp m C>
1 2524.500 Tp m C
96
98. OS Statistics
Monitor what OS is doing
Monitor what the HW is doing
– CPU
– Memory
– Swap
– Network
– IO
Monitor running processes
98
99. OS Statistics
Tools are OS-specific. Common on Linux :
vmstat
iostat
ps
top / atop / htop
sar
strace
vnstat
99
ifstat
100. OS Statistics - vmstat
Example:
sh e ll> vm stat 1 0 8
p ro cs -----------m e m o ry---------- ---swap -- -----io ---- -syste m -- ----cp u ----
r b swp d fre e b u ff cach e si so b i b o in cs u s sy id wa
5 2 0 1 798008 92568 9738680 0 0 565 1 850 991 0 1 0207 1 0 1 88 1
2 0 0 1 797864 92580 9742456 0 0 390 1 398 9891 1 01 60 1 0 1 89 1
1 0 0 1 794728 92580 9746048 0 0 554 1 890 9730 1 0020 1 0 1 88 1
4 0 0 1 789768 92580 9750536 0 0 685 2029 9961 1 0388 1 0 1 87 1
1 0 0 1 787252 92584 9753788 0 0 387 1 741 9773 1 01 40 1 0 1 88 1
6 0 0 1 780868 92584 9757940 0 0 41 0 1 972 9552 9994 9 1 89 1
9 0 0 1 778524 92588 9761 1 80 0 0 509 1 790 1 0065 1 0540 1 1 1 87 1
1 0 0 1 774904 92592 9764996 0 0 685 1 837 1 0096 1 0608 1 1 1 87 1
100
101. OS Statistics - vmstat
procs ( processes )
– r : waiting for CPU
– b : blocked on uninterruptible sleep ( waiting
for IO )
memory (1KB blocks)
– swpd : swapped memory
– free : free memory
– buff : used as buffer
– cache : used for cache
101
swap (1KB blocks)
102. OS Statistics – vmstat
io (1KB blocks)
– bi : blocks received from block devices
– bo : blocks sent to block devices
system
– in : interrupts
– cs : context switches
cpu
– us : in user space
– sy : in kernel code 102
– id : idle
103. OS Statistics - iostat
Example:
sh e ll> io stat -k -d -x 1 0 3 /d e v/sd ?
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd a 0.50 6.31 91 .33 78.02 1 092.28 21 62.86 38.44 0.04 0.21 1 .01 1 7.1 2
sd b 0.00 0.09 0.25 2.98 26.99 1 75.1 1 1 24.99 0.02 4.89 0.74 0.24
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd a 0.00 1 .50 58.60 97.00 358.40 2520.40 37.00 0.42 2.70 0.93 1 4.40
sd b 0.00 0.00 0.00 2.40 0.00 240.75 200.62 0.01 2.67 0.33 0.08
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd a 0.00 1 .50 54.00 61 .1 0 351 .60 1 556.70 33.1 6 0.25 2.1 3 1 .46 1 6.80
sd b 0.00 0.00 0.00 2.20 0.00 1 85.05 1 68.23 0.00 0.91 0.1 8 0.04
103
104. OS Statistics - iostat
rrqm/s : read requests merged per second
wrqm/s : write requests merged per second
r/s : read requests per second
w/s : write requests per second
rKB/s : KBs read per second
wKB/s : KBs written per second
avgrq-sz : average size (in sectors) of requests
avgqu-sz : average queue length of requests
await : average time (milliseconds) for requests to
be served ( queue time + service time) 104
105. OS Statistics - iostat
Example:
sh e ll> io stat -k -d -x 1 0 3 /d e v/sd ?
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd d 0.00 0.30 0.00 541 .90 0.00 246928.30 91 1 .34 1 1 1 .64 205.75 1 .85 1 00.00
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd d 0.00 1 .1 0 0.00 543.1 0 0.00 247461 .60 91 1 .29 1 1 2.1 1 205.99 1 .84 1 00.02
D e vice : rrq m /s wrq m /s r/s w/s rkB/s wkB/s avgrq -sz avgq u -sz await svctm % u til
sd d 0.00 0.80 0.00 541 .40 0.00 246080.00 909.05 1 1 1 .97 206.90 1 .85 1 00.01
105
106. OS Statistics - top
Example:
to p - 05:05:25 u p 264 d ays, 7:28, 1 3 u se rs,lo ad ave rage : 4.03, 4.28, 4.1 3
Tasks: 333 to tal, 1 ru n n in g, 328 sle e p in g, 0 sto p p e d , 4 zo m b ie
Cp u (s): 1 9.4% u s, 0.5% sy, 0.0% n i, 79.1 % id , 0.3% wa, 0.3% h i, 0.4% si, 0.0% st
M e m : 49508976k to tal, 481 01 200k u se d , 1 407776k fre e , 94028k b u ffe rs
Swap : 23438824k to tal, 0k u se d , 23438824k fre e , 1 01 28656k cach e d
PID U SER PR N I VIRT RES SH R S % CPU % M EM TIM E+ CO M M AN D
28384 m ysq l 20 0 35.5g 34g 7620 S 388 73.7 49961 :09 mysqld
1 ro o t 20 0 1 031 2 336 208 S 0 0.0 1 :38.1 2 in it
2 ro o t 1 5 -5 0 0 0 S 0 0.0 0:00.24 kth re ad d
3 ro o t RT -5 0 0 0 S 0 0.0 1 5:56.46 m igratio n /0
4 ro o t 1 5 -5 0 0 0 S 0 0.0 0:21 .74 kso ftirq d /0
5 ro o t RT -5 0 0 0 S 0 0.0 1 :59.25 watch d o g/0
106
107. OS Statistics - ifstat
Example:
sh e ll> ifstat -i e th 1 5 8
e th 1
KB/s in KB/s o u t
4091 .66 6565.1 5
3828.57 5750.80
3772.95 5725.60
3624.42 5597.97
3838.65 5936.50
381 3.1 7 5773.01
3424.67 5264.98
3981 .78 6020.65
107
110. Slow query log
By default logs on file
Logs SQL statements that:
– Run for more than long_query_time
– Do not use indexes
(log_queries_not_using_indexes)
Other options:
– log_slow_admin_statements
– log_slow_slave_statements
– (Percona) log_slow_verbosity ( query_plan / 110
innodb / profiling )
112. Profiling from slow query log
SET GLOBAL long_query_time=0;
Force all the connections to close;
Move / delete the current slow query log;
FLUSH LOGS;
SET GLOBAL slow_query_log_file =
'slow.log';
Leave it running for hours
Keep an eye on disk space 112
116. pt-log-player
It is not a benchmark tool
It is a load simulator
It splits slow query log into files
It replays the queries in sessions
116
118. pt-log-player : play
mkdir ./results
pt-log-player --play ./sessions –threads=16
--base-dir ./results h=dbserver 2> /dev/null
Found 32 session files.
Running processes...
All processes are running; waiting for them to finish...
Process 15 finished with exit status 0.
….
All processes have finished.
118
121. Analysis with pt-query-digest
# Query 1: 0 QPS, 0x concurrency, ID 0x556DDA838C37A12A at byte 672169 ___
# This item is included in the report because it matches --limit.
# Scores: Apdex = 1.00 [1.0], V/M = 0.01
# Query_time sparkline: | _^_ |
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 0 335402
# Exec time 31 61313s 81ms 1s 183ms 230ms 33ms 171ms
# Query size 1 115.89M 361 364 362.30 363.48 1.50 346.17
# String:
# Databases dbname
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms #
# 100ms ################################################################
# 1s #
# 10s+
# Tables
# SHOW TABLE STATUS FROM `dbname` LIKE 'tablename1'G
# SHOW CREATE TABLE `dbname`.`tablename1`G
# SHOW TABLE STATUS FROM `dbname` LIKE 'tablename2'G
# SHOW CREATE TABLE `dbname`.`tablename2`G
# EXPLAIN /*!50100 PARTITIONS*/
select eo.*, ca.value cavalue from tablename1 eo left join tablename2 ca on eo.caid=ca.id and eo.from_cid = ca.cid
where eo.expired = 0 and ca.cid = 62 and eo.hidden_until < unix_timestamp() and eo.value > 0 and eo.created >
unix_timestamp(now() - interval 5 day) order by eo.aer limit 0, 10G
121
122. Analysis with pt-query-digest
Analysis of pt-log-player result files reports:
– Execution time
– Count
– Distribution
Analysis is done client side
122
124. pt-log-player and slow query log
Enable slow query log on server
Run pt-log-player
Process the slow query log with pt-query-
digest
Provides more useful information
124
125. pt-log-player and slow query log
SET GLOBAL long_query_time=0;
pt-log-player --play ./sessions –threads=16
--base-dir ./results h=dbserver 2>
/dev/null
SET GLOBAL long_query_time=2;
pt-query-digest slow.log > slow.digest.txt
125
129. pt-query-digest query #1
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms #
# 100ms ################################################################
# 1s #
# 10s+
# Tables
# SHOW TABLE STATUS FROM `dbname` LIKE 'tablename1'G
# SHOW CREATE TABLE `dbname`.`tablename1`G
# SHOW TABLE STATUS FROM `dbname` LIKE 'tablename2'G
# SHOW CREATE TABLE `dbname`.`tablename2`G
# EXPLAIN /*!50100 PARTITIONS*/
select eo.*, ca.value cavalue from tablename1 eo left join tablename2 ca on
eo.caid=ca.id and eo.from_cid = ca.cid where eo.expired = 0 and ca.cid =
62 and eo.hidden_until < unix_timestamp() and eo.value > 0 and eo.created
> unix_timestamp(now() - interval 5 day) order by eo.aer limit 0, 10G
129
130. EXPLAIN query #1
mysql> EXPLAIN select eo.*, ca.value cavalue from tablename1 eo left join
tablename2 ca on eo.caid=ca.id and eo.from_cid = ca.cid where eo.expired =
0 and ca.cid = 62 and eo.hidden_until < unix_timestamp() and eo.value > 0
and eo.created > unix_timestamp(now() - interval 5 day) order by eo.aer
limit 0, 10;
+----+-------------+-------+--------+---------------+---------+---------
+----------------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len |
ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------
+----------------+--------+-----------------------------+
| 1 | SIMPLE | eo | ALL | caid | NULL | NULL |
NULL | 161517 | Using where; Using filesort |
| 1 | SIMPLE | ca | eq_ref | PRIMARY,cid | PRIMARY | 4 |
dbname.eo.caid | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------
+---------- ---+--------+-----------------------------+
2 rows in set (0.00 sec)
130
131. EXPLAIN query #1
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: eo
type: ALL
possible_keys: caid
key: NULL
key_len: NULL
ref: NULL
rows: 161517
Extra: Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: ca
type: eq_ref
possible_keys: PRIMARY,cid
key: PRIMARY
key_len: 4
ref: dbname.eo.caid
rows: 1
Extra: Using where
131
133. EXPLAIN
Explains the execution plan
Works only for SELECT statements
Returns one row for each table in the
query
– also subqueries and UNION
133
134. EXPLAIN output : id
Indicates which SELECT is referred
Distinguish nested SELECT
134
135. EXPLAIN output : select_type
Defines the type of SELECT:
SIMPLE : no subqueries or unions
PRIMARY : outer SELECT
UNION : not first SELECT in a union
UNION RESULT : result of a union
DERIVED : subquery in FROM clause
DEPENDANT UNION : union is dependent
on the outer query
135
DEPENDANT SUBQUERY : subquery is
136. EXPLAIN output : table
shows the name of the table
order of the tables is the order of the JOINs
Indexes affect JOINs order
136
137. EXPLAIN output : type
Defines the type of join:
system : table has only 1 row
const : only 1 row matching
eq_ref : only 1 row matching for this referenced
table ( ex. Unique key )
ref : all rows with matching index values are
read
ref_or_null : as “ref”, but also for NULL values
index_merge : more than one index is used, and
137
result merged
138. EXPLAIN output : possible_keys
Lists of keys the optimizer can choose to
perform the join
If NULL : no relevant indexes
138
139. EXPLAIN output : key
The key that the optimizer has chosen
If the key is not listed in possible_keys:
– No suitable indexes for rows lookup and the
index is a covering index
139
140. EXPLAIN output : key_len
Length of a single value in the index
In case of multi-column index returns the
length used
140
141. EXPLAIN output
ref: Column or constraint used to compare
the index in “ref”
rows: estimated number of rows that MySQL
will examine
Extra : additional information
141
142. EXPLAIN output : Extra
Distinct : looking only for DISTINCT values
Impossible WHERE : WHERE clause is
always false
Using filesort : extra pass for sorting rows
Using index : column information retrieved
from the index and not from the row
Using temporary : temporary tables are
created 142
Using where : WHERE clause used to filter
146. ADD INDEX
ALTER TABLE tablename1 ADD INDEX (expired, from_cid);
CREATE TABLE `tablename1` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cid` int(10) unsigned NOT NULL,
`caid` int(10) unsigned NOT NULL,
`value` decimal(10,2) unsigned DEFAULT '1.00',
`from_cid` tinyint(3) unsigned NOT NULL DEFAULT '1',
`aer` decimal(10,3) unsigned DEFAULT '1.000',
`created` int(10) unsigned NOT NULL,
`expired` int(11) NOT NULL,
`hidden_until` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `cid` (`cid`),
KEY `aid` (`caid`),
KEY `expired` (`expired`,`from_cid`)
) ENGINE=InnoDB AUTO_INCREMENT=188988 DEFAULT CHARSET=latin1
146
147. New EXPLAIN query #1
EXPLAIN select eo.*, ca.value cavalue from tablename1 eo left join tablename2 ca on
eo.caid=ca.id and eo.from_cid = ca.cid where eo.expired = 0 and ca.cid = 62 and
eo.hidden_until < unix_timestamp() and eo.value > 0 and eo.created >
unix_timestamp(now() - interval 5 day) order by eo.aer limit 0, 10;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: eo
type: ref
possible_keys: caid,expired
key: expired
key_len: 5
ref: const,const
rows: 660
Extra: Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: ca
type: eq_ref
possible_keys: PRIMARY,cid
key: PRIMARY
key_len: 4
ref: dbname.eo.caid
rows: 1
Extra: Using where
147
148. pt-query-digest query #2
# Query 2: 26.90 QPS, 3.84x concurrency, ID 0x97EA420234E19A02 at byte
319276140
# This item is included in the report because it matches --limit.
# Scores: Apdex = 1.00 [1.0], V/M = 0.01
# Query_time sparkline: | _^ |
# Time range: 2012-03-25 17:28:34 to 20:56:19
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 0 335355
# Exec time 24 47851s 50ms 828ms 143ms 180ms 29ms 141ms
# Lock time 0 20s 42us 8ms 59us 69us 19us 57us
# Rows sent 0 327.50k 1 1 1 1 0 1
# Rows examine 45 48.48G 151.58k 151.58k 151.58k 151.58k 0 151.58k
# Rows affecte 0 0 0 0 0 0 0 0
# Rows read 0 327.50k 1 1 1 1 0 1
# Bytes sent 0 20.53M 64 65 64.20 62.76 0.00 62.76
# Tmp tables 0 0 0 0 0 0 0 0
# Tmp disk tbl 0 0 0 0 0 0 0 0
# Tmp tbl size 0 0 0 0 0 0 0 0
# Query size 0 65.82M 205 206 205.80 202.40 0 202.40
148
149. EXPLAIN query #2
Before ADD INDEX:
EXPLAIN select ceil(count(1)/10) maxPages from tablename1 where from_cid =
62 and value >= 1 and expired = 0 and hidden_until <= unix_timestamp() and
created > unix_timestamp(now() - interval 5 day)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: eo
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 161517
Extra: Using where
149
150. EXPLAIN query #2
After ADD INDEX:
EXPLAIN select ceil(count(1)/10) maxPages from tablename1 where from_cid =
62 and value >= 1 and expired = 0 and hidden_until <= unix_timestamp() and
created > unix_timestamp(now() - interval 5 day)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: eo
type: ref
possible_keys: expire
key: expire
key_len: 5
ref: const,const
rows: 660
Extra: Using where
150
152. Cacti
Data logging
RRDTool (round-robin database)
Trending
Track history
Useful to spot change in workload
152
153. Percona MySQL Monitoring
Template for Cacti
Plugin for Cacti
Formely known as
“MySQL Cacti Template”
Avaliable at :
http://www.percona.com/software/percona-monitoring-plugins/
153