In this blog post, I’ll look at how you can analyze MySQL audit logs (Percona Server for MySQL) with ClickHouse and ClickTail.
Audit logs are available with a free plugin for Percona Server for MySQL (https://www.percona.com/doc/percona-server/LATEST/management/audit_log_plugin.html). Besides providing insights about activity on your server, you might need the logs forΒ compliance purposes.
However, on an active server, the logs can get very large. Under aΒ sysbench-tpcc workload, for example, I was able to generate 24GB worth of logs just within one hour.
So we are going to use the ClickTail tool, which Peter Zaitsev mentioned inΒ Analyze Your Raw MySQL Query Logs with ClickHouseΒ and the Altinity team describes in theΒ ClickTail Introduction.
Clicktail extracts all fields available in Percona Server for MySQL’s audit log in JSON format, as you can see in Schema. I used the command:
clicktail --dataset='clicktail.mysql_audit_log' --parser=mysqlaudit --file=/mnt/nvmi/mysql/audit.log --backfill
In my setup, ClickTailΒ imported records at the rate of 1.5 to 2 million records/minute.Β Once we have ClickTail setup, we can do some work on audit logs. Below are some examples of queries.
Check if some queries were run with errors:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
SELECT status AS c1, count(*) FROM mysql_audit_log GROUP BY c1 ββββc1ββ¬ββcount()ββ β 0 β 46197504 β β 1160 β 1 β β 1193 β 1274 β β 1064 β 5096 β ββββββββ΄βββββββββββ 4 rows in set. Elapsed: 0.018 sec. Processed 46.20 million rows, 184.82 MB (2.51 billion rows/s., 10.03 GB/s.) |
First, it is very impressive to see the performance of 2.5 billionΒ row/s analyzed. And second, there are really some queries with non-zero (errors) statuses.
We can dig into and check what exactly caused an 1193 error (MySQL Error Code: 1193. Unknown system variable):
1 2 3 4 5 6 7 8 |
SELECT * FROM mysql_audit_log WHERE status = 1193 LIMIT 1 ββββββββββββββββ_timeββ¬ββββββ_dateββ¬β_msββ¬βcommand_classββ¬βconnection_idββ¬βdbββ¬βhostβββββββ¬βipββ¬βnameβββ¬βos_userββ¬βos_loginββ¬βos_versionββ¬βmysql_versionββ¬βpriv_userββ¬βproxy_userββ¬βrecordββββββββββββββββββββββββ¬βsqltextβββββββββββββββββββββββββββββ¬βstatusββ¬βuserβββββββββββββββββββββββ¬βstartup_optionsiββ β 2018-03-12 20:34:49 β 2018-03-12 β 0 β select β 1097 β β localhost β β Query β β β β β β β 39782055_2018-03-12T20:21:21 β SELECT @@query_response_time_stats β 1193 β root[root] @ localhost [] β β βββββββββββββββββββββββ΄βββββββββββββ΄ββββββ΄ββββββββββββββββ΄ββββββββββββββββ΄βββββ΄ββββββββββββ΄βββββ΄ββββββββ΄ββββββββββ΄βββββββββββ΄βββββββββββββ΄ββββββββββββββββ΄ββββββββββββ΄βββββββββββββ΄βββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββ΄βββββββββ΄ββββββββββββββββββββββββββββ΄βββββββββββββββββββ |
So this was SELECT @@query_response_time_stats, which I believe comes from the Percona Monitoring and Management (PMM) MySQL Metrics exporter.
Similarly, we can check what queries types were run on MySQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
SELECT command_class, count(*) FROM mysql_audit_log GROUP BY command_class ββcommand_classβββββββββ¬ββcount()ββ β β 15882 β β show_storage_engines β 1274 β β select β 26944474 β β error β 5096 β β show_slave_status β 1274 β β begin β 1242555 β β update β 9163866 β β show_tables β 204 β β show_status β 6366 β β insert_select β 170 β β delete β 539058 β β commit β 1237074 β β create_db β 2 β β show_engine_status β 1274 β β show_variables β 450 β β set_option β 8102 β β create_table β 180 β β rollback β 5394 β β create_index β 120 β β insert β 7031060 β ββββββββββββββββββββββββ΄βββββββββββ 20 rows in set. Elapsed: 0.120 sec. Processed 46.20 million rows, 691.84 MB (385.17 million rows/s., 5.77 GB/s.) |
There are more fields available, like:
1 2 3 |
db String, host String, ip String, |
to understand who accessed a MySQL instance, and from where.
If you ever need to do some advanced work with MySQL audit logs, consider doing it with ClickHouse and ClickTail!