由于mysql5.6社区版没有企业版特有的audit审计插件,最近需要对生产的mysql数据库增加审计功能,在考虑了percona、maridb和macfee3个版本的audit,最终选择了较为熟悉的percona版。
这里注意下,最好采用同一子版本的PXC的audit_log.so文件,即下载PXC的二进制包文件并直接copy其内置的audit_log.so插件即可。
启用了audit审计功能,对数据库的性能存在一定的损耗,具体是多少,需要通过测试验证。在虚拟机上做了一个测试如下:
测试虚拟机环境:
主机:
CPU:Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz 4核
内存:1G
磁盘:SCSI硬盘 10G
数据库:
版本:5.6.34
参数: innodb_buffer_pool_size = 128M、 innodb_io_capacity = 2000
以下是我的测试脚本:cat for_sysbench.sh
#!/bin/sh
time=3600
#0.0
for thread in {16,32,64,128,256}
do
echo "now the number of theads is $thread"
echo "============================================================================================================================================"
/bin/sh /home/linzj/shell/mysql.sh restart
sleep 30
sysbench --test=oltp --mysql-host=192.168.110.100 --mysql-port=3306 --mysql-user=root --mysql-password=root --mysql-db=sbtest1 --oltp-num-tables=10 --oltp-table-size=500000 --report-interval=10 --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=$time --num-threads=$thread run
echo "============================================================================================================================================"
done >> /tmp/sysbench.log.0.0
#1.1
sed -i 's/sync_relay_log=0/sync_relay_log=1/g' /etc/my.cnf
sed -i 's/sync_binlog=0/sync_binlog=1/g' /etc/my.cnf
sed -i 's/innodb_flush_log_at_trx_commit = 0/innodb_flush_log_at_trx_commit = 1/g' /etc/my.cnf
for thread in {32,256}
do
echo "now the number of theads is $thread"
echo "============================================================================================================================================"
/bin/sh /home/linzj/shell/mysql.sh restart
sleep 30
sysbench --test=oltp --mysql-host=192.168.110.100 --mysql-port=3306 --mysql-user=root --mysql-password=root --mysql-db=sbtest1 --oltp-num-tables=10 --oltp-table-size=500000 --report-interval=10 --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=$time --num-threads=$thread run
echo "============================================================================================================================================"
done >> /tmp/sysbench.log.1.1
#100.2
sed -i 's/sync_relay_log=1/sync_relay_log=100/g' /etc/my.cnf
sed -i 's/sync_binlog=1/sync_binlog=100/g' /etc/my.cnf
sed -i 's/innodb_flush_log_at_trx_commit = 1/innodb_flush_log_at_trx_commit = 2/g' /etc/my.cnf
for thread in {32,256}
do
echo "now the number of theads is $thread"
echo "============================================================================================================================================"
/bin/sh /home/linzj/shell/mysql.sh restart
sleep 30
sysbench --test=oltp --mysql-host=192.168.110.100 --mysql-port=3306 --mysql-user=root --mysql-password=root --mysql-db=sbtest1 --oltp-num-tables=10 --oltp-table-size=500000 --report-interval=10 --max-requests=0 --oltp-test-mode=nontrx --oltp-nontrx-mode=select --oltp-read-only=off --max-time=$time --num-threads=$thread run
echo "============================================================================================================================================"
done >> /tmp/sysbench.log.100.2
其实这里测试时间不应该只有3600s,表个数和行数也不是太大,如果要获得更为准确的压测值,建议调大测试时间、表的行数和线程并发数。
测试出来的数据如下:
| not audit_log.so |
sync_binlog=0 innodb_flush_log_at_trx_commit=0 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
sync_binlog=1 innodb_flush_log_at_trx_commit=1 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
sync_binlog=100 innodb_flush_log_at_trx_commit=2 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
| thread number |
transactions |
95% response time |
transactions |
95% response time |
transactions |
95% response time |
| 16 |
32213495 |
0.25ms |
29410504 |
0.25ms |
30523665 |
0.35ms |
| 32 |
26159190 |
0.98ms |
27709880 |
0.66ms |
26933062 |
0.68ms |
| 64 |
83298987 |
0.23ms |
86423634 |
0.23ms |
77157030 |
0.27ms |
| 128 |
88715124 |
0.34ms |
90817420 |
0.35ms |
81349362 |
0.41ms |
| 256 |
66369520 |
2.19ms |
69010422 |
1.98ms |
71505144 |
1.81ms |
| audit_log.so |
sync_binlog=0 innodb_flush_log_at_trx_commit=0 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
sync_binlog=1 innodb_flush_log_at_trx_commit=1 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
sync_binlog=100 innodb_flush_log_at_trx_commit=2 innodb_io_capacity = 2000 innodb_buffer_pool_size = 128M |
| thread number |
transactions |
95% response time |
transactions |
95% response time |
transactions |
95% response time |
| 16 |
28692966 |
0.50ms |
30227040 |
0.44ms |
30635231 |
0.43ms |
| 32 |
26350208 |
0.69ms |
26789217 |
0.64ms |
26515925 |
0.66ms |
| 64 |
58260078 |
0.45ms |
60129266 |
0.41ms |
62635925 |
0.37ms |
| 128 |
61384728 |
0.69ms |
62435697 |
0.67ms |
64455354 |
0.59ms |
| 256 |
55560177 |
2.83ms |
55683833 |
2.87ms |
56068342 |
2.79ms |
从测试的数据可以发现:
1、数据库的audit插件的使用,确实损耗了一定的数据库性能,如果以最佳压测性能的128个线程并发的数据来看,有audit功能的数据库在同等压测时间下,事务数占比少了30%以上,响应时间延长了1倍。
2、数据库性能并非同并发线程数呈线性关系,在并发数达到128时,事务数和响应时间均为最佳,接下来再继续增加并发,性能反而下降。
3、这里测试数据sync_binlog和innodb_flush_log_at_trx_commit为双1的时候,性能反而最高。这里应该是参数调整or压测时间不足导致。至少innodb_buffer_pool_size应该调整为内存的80%。所以这份测试数据也仅仅作为参考,需要再继续调整参数后再进行压测才能得到更为准确的数值。