MySQL Primer - Benchmarking and Profiling
Introduction
This article described some basic usage of mysql server and introduce intermediate MySQL internals.
Table Of Contents
- Introduction
- Table Of Contents
- Overview
- Information Schema
- Performance Schema
- Storage Engines
- InnoDB
- MySQL Replication
- MySQL Performance
- Diagnose
- MySQL Plugins
- Appendix
- Benchmarking
- References
Overview
MySQL Workbench
mysql-workbench-community-6.3.6-src//plugins/wb.admin/frontend/wb_admin_monitor.py
Server Status
mforms.newServerStatusWidget()
Load
if self.server_profile.target_is_windows:
self.cpu_usage.set_description("CPU")
else:
self.cpu_usage.set_description("Load")
- CPU
- queued tasks
- MEM
- used and free
- IO
- NETWORK
Max & Mean
- Response Time
- Concurrent Connection
- TPS (Transaction per second)
- QPS (Query per second)
Connection
max_connections = 151 (+1)
The extra is used for privileged users.
Cache
table_open_cache
400
max_tmp_tables 32
tmp_table_size 16M
read_rnd_buffer_size
256K
sort_buffer_size
read_buffer_size
query_cache_size
SELECT SQL_NO_CACHE id, name FROM customer;
innodb_log_buffer_size
innodb_additional_mem_pool_size
innodb_buffer_pool_size
key_buffer_size
Information Schema
- INNODB_CMP
-
INNODB_CMP_RESET
- INNODB_CMPMEM
-
INNODB_CMPMEM_RESET
- INNODB_TRX
- INNODB_LOCKS
-
INNODB_LOCK_WAITS
- INNODB_BUFFER_PAGE_LRU <—-> BLOCK_ID
- INNODB_BUFFER_PAGE <—–> LRU_POSITION
- INNODB_BUFFER_POOL_STATS
INNODB_BUFFER_PAGE_LRU and INNODB_BUFFER_PAGE is performance issue related.
INNODB_BUFFER_POOL_STATS and
show status like 'Innodb_buffer%';
show engine innodb status;
select
table_name as 'table',
round(data_length/1024.0/1024.0, 2) as 'data (MB)',
round(index_length/1024.0/1024.0, 2) as 'index (MB)'
from
information_schema.TABLES
where
table_schema = 'VIEWS';
can be used to get similar information
Performance Schema
Tables
- mutex_instances
- rwlock_instances
- cond_instances
- file_instances
Storage Engines
- MyISAM
- InnoDB
InnoDB
InnoDB monitor
There are 4 InnoDB monitors:
Name | Table |
---|---|
Standard InnoDB Monitor | innodb_monitor |
InnoDB Lock Monitor | innodb_lock_monitor |
InnoDB Tablespace Monitor | innodb_tablespace_monitor |
InnoDB Table Monitor | innodb_table_monitor |
innodb_status_file = 1
innodb_status.pid
Standard Monitor:
# create innodb monitor
CREATE TABLE innodb_monitor (a int) ENGINE = INNODB;
# drop innodb monitor
DROP innodb_monitor
Lock Monitor:
CREATE TABLE innodb_lock_monitor (a INT) ENGINE = INNODB;
DROP innodb_lock_monitor
InnoDB Status
- read reqs: Innodb_buffer_pool_read_requests /second
- write reqs: Innodb_buffer_pool_write_requests / second
- InnoDB Buffer Pool Utilization:
-
disk reads: Innodb_buffer_pool_reads / second
- Redo Log:
- data written: Innodb.os_log_written / second
- writes: Innodb_log_writes / second
- Double write buffer:
- writes: Innodb_dbuffer_writes / second
- InnoDB Disk Writes: Innodb_data_written / second
- InnoDB Disk Reads: Innodb_data_reads / second
- Innodb_read_ahead_threshold:
- inspect (
show engine innodb status
)
- inspect (
show engine innodb status
- status
- log
- background thread
- buffer pool and memory
- semaphers
- row operations
- latest foreign key error
- latest detected deadlock
- transactions
- file I/O
- insert buffer and adaptive hash index
InnoDB File Format and Row Format
- Barracuda
- DYNAMIC
- COMPRESSED
- efficiency
- COMPACT
- REDUNDANT
- Antelope
- COMPACT
- REDUNDANT
Locks
innodb_lock_wait_timeout
only applies to innodb row locks.
InnoDB I/O
Selects per second: Com_select / second
InnoDB writes per second: Innodb_data_writes/second
Innodb reads per second: Innodb_data_reads / second
Innodb buffer usage:
\[\frac{Innodb\_buffer\_pool\_pages\_total - free}{total} \times 100\%\]Key efficiency:
\[(1 - \frac{Key\_reads}{Key\_read\_requests}) \times 100\%\]Network Status
Connections: Threads_connected
Incoming Network Traffic: Bytes_received /second
Outgoing Network Traffic: Bytes_sent / second
Client Connections: Thread_connected / max_connections
Table Open Cache Efficiency
\[\frac{Table\_open\_cache\_hits}{Table\_open\_cache\_hits + Table\_open\_cache\_misses}\]SQL Statments Executed
Com_select Com_insert Com_update Com_delete Com_create_db
Com_creawte_event Com_create_function Com_create_index
Com_create_procedure Com_create_server Com_create_table
Com_create_trigger Com_create_udf Com_create_user
Com_create_view Com_alter_db Com_alter_db_upgrade
Com_alter_event Com_alter_function Com_alter_procedure
Com_alter_server Com_alter_table Com_alter_tablepsace
Com_alter_user Com_drop_db Com_drop_event Comp_drop_fucntion
Com_drop_index Com_drop_procedure Com_drop_server
Com_drop_tabel Com_drop_trigger Com_drop_user COm_drop_view
MySQL Replication
Replication Delay
MySQL replication works with two threads:
-
IO_THREAD
connects to the master and read binary log events from the master as they come in and copies them over to a local log file called relay log.
depends on the network connectivity, network latency, …
-
SQL_THREAD
read events from a relay log stored locally on the replication slave (the file was written by IO thread) and then applies them as fast as possible.
show master|slave status;
MySQL Performance
- sort buffer size
- create index on orders ()
- query_cache
- query_cache_limit
- query_cache_size
- table compression
- zlib
- LZ77
- optimize table
Table Compressions
Pre Conditions
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_file_format=Barracuda;
Compress
CREATE TABLE t1
(c1 INT PRIMARY KEY)
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
KEY_BLOCK_SIZE
measure size of .idb file to see how well each performs with a realistic workload
These values compresses well:
- BLOB
- VARCHAR
- TEXT
overflow pages (off-page columns)
read for more often than written
information_schema.innodb_cmp (compress_ops_ok/compress_ops)
Compression and InnoDB Buffer Pool
Adaptive LRU:
- compressed pages
- uncompressed pages (evict)
is used to keep balance between:
- I/O bound
- CPU bound
Diagnose
- ERROR 1040 (HY000): Too many connections
if show processlist
contains too many sleeping connections; then:
wait_timeout
default 28800, set to a relative short period of time may help.
else you may consider increase max_connections
based on your workload.
Inspect
- processlist
- status
Questions
Slave_running
Threads_connected
Threads_running
Aborted_clients
Handler_%
;Opened_tables
Select_full_join
Select_scan
Slow_queries
Threads_created
- show status
- show plugins
- show engine innodb status
- show table status
-
profile
SET PROFILING = 1; SHOW profiles;
Use FLUSH STATUS
to reset status variables.
SUM(Com_xxx) + QCache_hits == Questions + statements executed within stored programs == Queries
Query Cache
Use flush query_cache
to flush query cache between measurements.
- Memory Utilization
- Hit Rate
Qcache_lowmem_prunes (LRU) -> query_cache_size
Query Cache Memory Fragmentation
- Qcache_total_blocks
- Qcache_free_blocks
Qcache entry consists of two parts:
- Query String (one block)
- Result Set (+1 block(s))
query_cache_wlock_invalidate = ON/OFF
Query Cache Features
- Caching full queryies only
- Works on packet level
- Works before parsing
- Exactly the same matching strategy
- Only select queries are cached
- Query must be deterministic
- Table level graunlarity in invalidation
- Fragmentation over time
- Limited amount of usable memory
- Demand operating mode
- Counting query cache efficiency
Disadvantages
- No control on invalidation
- It is not that fast (compared to dedicated cache system like memcached)
- Cannot retrieve multiple objs at the same time
- Is not distributed
MySQL Plugins
Query Rewrites
Query rewrites can be used to force index on some search.
Query rewrites can in placed in two points:
- pre-parse
- post-parse (more efficient)
Appendix
Inspect Examples
status;
--------------
mysql Ver 15.1 Distrib 5.5.47-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 11
Current database: information_schema
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 5.5.47-MariaDB MariaDB Server
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 1 day 17 hours 13 min 18 sec
Threads: 1 Questions: 181 Slow queries: 0 Opens: 0 Flush tables: 2 Open tables: 26 Queries per second avg: 0.001
--------------
show status;
+------------------------------------------+-------------+
| Variable_name | Value |
+------------------------------------------+-------------+
| Aborted_clients | 0 |
| Aborted_connects | 4 |
| Access_denied_errors | 0 |
| Aria_pagecache_blocks_not_flushed | 0 |
| Aria_pagecache_blocks_unused | 15737 |
| Aria_pagecache_blocks_used | 0 |
| Aria_pagecache_read_requests | 0 |
| Aria_pagecache_reads | 0 |
| Aria_pagecache_write_requests | 0 |
| Aria_pagecache_writes | 0 |
| Aria_transaction_log_syncs | 0 |
| Binlog_commits | 0 |
| Binlog_group_commits | 0 |
| Binlog_snapshot_file | |
| Binlog_snapshot_position | 0 |
| Binlog_bytes_written | 0 |
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Binlog_stmt_cache_disk_use | 0 |
| Binlog_stmt_cache_use | 0 |
| Busy_time | 0.000000 |
| Bytes_received | 4232 |
| Bytes_sent | 136174 |
...
show plugins;
+--------------------------------+----------+--------------------+---------+---------+
| Name | Status | Type | Library | License |
+--------------------------------+----------+--------------------+---------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| mysql_old_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| INNODB_RSEG | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_UNDO_LOGS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TABLE_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_INDEX_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES_BLOB | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| XTRADB_ADMIN_COMMAND | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CHANGED_PAGES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| FEDERATED | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| Aria | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEEDBACK | DISABLED | INFORMATION SCHEMA | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
+--------------------------------+----------+--------------------+---------+---------+
42 rows in set (0.00 sec)
show engine innodb status \G;
*************************** 1. row ***************************
Type: InnoDB
Name:
Status:
=====================================
160519 11:54:52 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 5 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 1 1_second, 1 sleeps, 0 10_second, 1 background, 1 flush
srv_master_thread log flush and writes: 1
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 2, signal count 2
Mutex spin waits 2, rounds 37, OS waits 0
RW-shared spins 2, rounds 60, OS waits 2
RW-excl spins 0, rounds 0, OS waits 0
Spin rounds per wait: 18.50 mutex, 30.00 RW-shared, 0.00 RW-excl
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
154 OS file reads, 3 OS file writes, 3 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
insert 0, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
Hash table size 276671, node heap has 0 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 1597945
Log flushed up to 1597945
Last checkpoint at 1597945
Max checkpoint age 7782360
Checkpoint age target 7539162
Modified age 0
Checkpoint age 0
0 pending log writes, 0 pending chkp writes
8 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137756672; in additional pool allocated 0
Total memory allocated by read views 88
Internal hash tables (constant factor + variable factor)
Adaptive hash index 2217584 (2213368 + 4216)
Page hash 139112 (buffer pool 0 only)
Dictionary cache 593780 (554768 + 39012)
File system 83536 (82672 + 864)
Lock system 333248 (332872 + 376)
Recovery system 0 (0 + 0)
Dictionary memory allocated 39012
Buffer pool size 8191
Buffer pool size, bytes 134201344
Free buffers 8048
Database pages 143
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 143, created 0, written 0
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 143, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
------------
TRANSACTIONS
------------
show profile for query 24;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000045 |
| checking permissions | 0.000005 |
| Opening tables | 0.000035 |
| After opening tables | 0.000002 |
| System lock | 0.000001 |
| Table lock | 0.000001 |
| After table lock | 0.000003 |
| init | 0.000008 |
| optimizing | 0.005735 |
| statistics | 0.000023 |
| preparing | 0.000007 |
| executing | 0.000002 |
| Filling schema table | 0.000122 |
| checking permissions | 0.000165 |
| checking permissions | 0.000163 |
| checking permissions | 0.000044 |
| checking permissions | 0.000007 |
| executing | 0.000007 |
| Sending data | 0.000105 |
| end | 0.000005 |
| query end | 0.000003 |
| closing tables | 0.000001 |
| removing tmp table | 0.000005 |
| closing tables | 0.000002 |
| freeing items | 0.000004 |
| updating status | 0.000163 |
| cleaning up | 0.000004 |
+----------------------+----------+
27 rows in set (0.00 sec)