MySQL/MariaDB
Monitor MySQL and MariaDB database logs including query logs, error logs, slow query analysis, and replication monitoring using the File Stream plugin
MySQL/MariaDB Integration
Monitor and analyze MySQL and MariaDB database logs in real-time using LogFlux Agent’s File Stream plugin. This configuration-based approach provides comprehensive database monitoring, query performance analysis, and replication tracking for MySQL-compatible databases.
Overview
The MySQL/MariaDB integration leverages LogFlux Agent’s File Stream plugin to:
- Real-time monitoring of general query logs, error logs, and slow query logs
- Query performance analysis with execution time tracking and optimization insights
- Replication monitoring for master-slave configurations and binary log analysis
- Security auditing with connection attempts and privilege monitoring
- InnoDB monitoring with transaction logs and deadlock detection
- Binary log analysis for data change tracking and point-in-time recovery
Installation
The File Stream plugin is included with LogFlux Agent. Enable it for MySQL/MariaDB log monitoring:
1
2
3
4
5
|
# Enable File Stream plugin
sudo systemctl enable --now logflux-filestream
# Verify plugin status
sudo systemctl status logflux-filestream
|
MySQL/MariaDB Configuration
Configure MySQL/MariaDB logging in /etc/mysql/mysql.conf.d/mysqld.cnf
or /etc/my.cnf
:
Basic Logging Configuration
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
|
[mysqld]
# Error log
log-error = /var/log/mysql/error.log
# General query log
general_log = 1
general_log_file = /var/log/mysql/general.log
# Slow query log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
log_slow_admin_statements = 1
# Binary log (replication)
log-bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7
max_binlog_size = 100M
# InnoDB logging
innodb_print_all_deadlocks = 1
innodb_status_output = 1
innodb_status_output_locks = 1
# Connection logging
log_warnings = 2
|
MariaDB-Specific Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[mysqld]
# MariaDB audit plugin
plugin-load-add = server_audit
server_audit_logging = ON
server_audit_events = 'CONNECT,QUERY,TABLE'
server_audit_output_type = file
server_audit_file_path = /var/log/mysql/audit.log
server_audit_file_rotate_size = 100000000
# MariaDB error log format
log_error_verbosity = 3
log_error_services = 'log_filter_internal; log_sink_system'
# Performance Schema (MySQL 5.6+/MariaDB 10.0+)
performance_schema = ON
performance_schema_consumer_events_statements_current = ON
performance_schema_consumer_events_statements_history = ON
|
Basic Configuration
Configure the File Stream plugin to monitor MySQL/MariaDB logs by creating /etc/logflux-agent/plugins/filestream-mysql.toml
:
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
31
32
33
34
35
|
[filestream.mysql_error]
paths = ["/var/log/mysql/error.log"]
format = "mysql_error"
tags = ["mysql", "database", "error"]
fields = {
service = "mysql",
log_type = "error"
}
[filestream.mysql_general]
paths = ["/var/log/mysql/general.log"]
format = "mysql_general"
tags = ["mysql", "database", "query"]
fields = {
service = "mysql",
log_type = "general"
}
[filestream.mysql_slow]
paths = ["/var/log/mysql/slow.log"]
format = "mysql_slow"
tags = ["mysql", "database", "slow", "performance"]
fields = {
service = "mysql",
log_type = "slow_query"
}
[filestream.mysql_binlog]
paths = ["/var/log/mysql/mysql-bin.*"]
format = "mysql_binlog"
tags = ["mysql", "database", "replication"]
fields = {
service = "mysql",
log_type = "binary_log"
}
|
1
2
3
4
5
6
7
|
[filestream.mysql_error_detailed]
paths = ["/var/log/mysql/error.log"]
format = "regex"
regex = '^(?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z) (?P<thread_id>\d+) \[(?P<level>\w+)\] (?P<message>.*)$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02T15:04:05.000000Z"
|
Alternative error log format:
1
2
3
4
5
6
7
|
[filestream.mysql_error_legacy]
paths = ["/var/log/mysql/error.log"]
format = "regex"
regex = '^(?P<timestamp>\d{6} \d{1,2}:\d{2}:\d{2}) \[(?P<level>\w+)\] (?P<message>.*)$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "060102 15:04:05"
|
1
2
3
4
5
6
7
|
[filestream.mysql_general_detailed]
paths = ["/var/log/mysql/general.log"]
format = "regex"
regex = '^(?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z)\s+(?P<thread_id>\d+) (?P<command>\w+)\s+(?P<argument>.*)$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02T15:04:05.000000Z"
|
1
2
3
4
5
6
7
8
9
10
11
|
[filestream.mysql_slow_detailed]
paths = ["/var/log/mysql/slow.log"]
format = "regex"
regex = '^# Time: (?P<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z)$'
multiline = true
multiline_pattern = '^# Time:'
multiline_negate = false
multiline_match = after
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02T15:04:05.000000Z"
|
Binary Log Analysis (using mysqlbinlog)
1
2
3
4
5
6
7
8
|
[filestream.mysql_binlog_parsed]
paths = ["/var/log/mysql/binlog-parsed.log"]
format = "text"
tags = ["mysql", "binlog", "parsed"]
fields = {
service = "mysql",
log_type = "binlog_parsed"
}
|
Create binary log parsing script:
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/bin/bash
# Parse binary logs continuously
MYSQL_BIN_DIR="/var/log/mysql"
OUTPUT_LOG="/var/log/mysql/binlog-parsed.log"
mysqlbinlog --read-from-remote-server \
--host=localhost \
--user=replication_user \
--password=replication_pass \
--raw \
--result-file="$OUTPUT_LOG" \
mysql-bin.000001
|
Advanced Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[filestream.mysql_performance]
paths = ["/var/log/mysql/slow.log"]
format = "mysql_slow"
tags = ["mysql", "performance"]
fields = {
service = "mysql",
log_type = "performance"
}
# Extract performance metrics from slow log
[filestream.mysql_performance.processors.extract]
source_field = "message"
patterns = [
'Query_time: (?P<query_time>\d+\.\d+)',
'Lock_time: (?P<lock_time>\d+\.\d+)',
'Rows_sent: (?P<rows_sent>\d+)',
'Rows_examined: (?P<rows_examined>\d+)'
]
[filestream.mysql_performance.processors.add_fields]
fields = {
efficiency_ratio = "{{ if gt .rows_examined 0.0 }}{{ div .rows_sent .rows_examined }}{{ else }}0{{ end }}",
slow_query = "{{ if gt .query_time 5.0 }}true{{ else }}false{{ end }}"
}
|
Replication Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[filestream.mysql_replication]
paths = ["/var/log/mysql/mysql-bin.*", "/var/log/mysql/relay-bin.*"]
format = "text"
tags = ["mysql", "replication"]
fields = {
service = "mysql",
log_type = "replication"
}
# Monitor replication status via script
[filestream.mysql_repl_status]
paths = ["/var/log/mysql/replication-status.log"]
format = "json"
tags = ["mysql", "replication", "status"]
|
Replication monitoring script:
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/bin/bash
# Monitor MySQL replication status
while true; do
mysql -e "SHOW SLAVE STATUS\G" | grep -E "(Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Last_Error)" | \
awk -F': ' '{
if (NR == 1) printf "{"
printf "\"%s\": \"%s\"", $1, $2
if (NR < 4) printf ", "
if (NR == 4) printf ", \"timestamp\": \"%s\"}\n", strftime("%Y-%m-%dT%H:%M:%S.000Z")
}' >> /var/log/mysql/replication-status.log
sleep 30
done
|
Security and Audit Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[filestream.mysql_audit]
paths = ["/var/log/mysql/audit.log"]
format = "csv"
csv_headers = ["timestamp", "serverhost", "username", "host", "connectionid", "queryid", "operation", "database", "object", "retcode"]
tags = ["mysql", "audit", "security"]
fields = {
service = "mysql",
log_type = "audit"
}
# Filter for security events
[filestream.mysql_audit.processors.grep]
patterns = [
"operation:CONNECT",
"operation:FAILED_CONNECT",
"operation:DISCONNECT",
"retcode:[1-9]"
]
|
Deadlock and Lock Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[filestream.mysql_deadlocks]
paths = ["/var/log/mysql/error.log"]
format = "mysql_error"
tags = ["mysql", "deadlocks", "locks"]
fields = {
service = "mysql",
log_type = "deadlocks"
}
# Filter for deadlock events
[filestream.mysql_deadlocks.processors.grep]
patterns = [
"LATEST DETECTED DEADLOCK",
"deadlock",
"lock wait timeout",
"Lock wait timeout exceeded"
]
|
Usage Examples
Monitor MySQL Database
1
2
3
4
5
6
7
8
|
# Stream all MySQL logs
logflux-cli stream --filter 'service:mysql'
# Monitor specific log type
logflux-cli stream --filter 'service:mysql AND log_type:slow_query'
# Track error logs only
logflux-cli stream --filter 'service:mysql AND log_type:error'
|
1
2
3
4
5
6
7
8
|
# Monitor slow queries (>5 seconds)
logflux-cli stream --filter 'service:mysql AND query_time:>5'
# Track queries with low efficiency
logflux-cli stream --filter 'service:mysql AND efficiency_ratio:<0.1'
# Monitor lock waits
logflux-cli stream --filter 'service:mysql AND lock_time:>1'
|
Security Monitoring
1
2
3
4
5
6
7
8
|
# Track failed connections
logflux-cli stream --filter 'service:mysql AND operation:FAILED_CONNECT'
# Monitor privilege escalation
logflux-cli stream --filter 'service:mysql AND (message:Access OR message:denied)'
# Track administrative operations
logflux-cli stream --filter 'service:mysql AND (command:DROP OR command:CREATE OR command:ALTER)'
|
Replication Monitoring
1
2
3
4
5
6
7
8
|
# Monitor replication status
logflux-cli stream --filter 'service:mysql AND log_type:replication'
# Track replication lag
logflux-cli stream --filter 'service:mysql AND Seconds_Behind_Master:>30'
# Monitor binary log operations
logflux-cli stream --filter 'service:mysql AND log_type:binary_log'
|
Database-Specific Monitoring
Monitor Performance Schema tables:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
-- Enable Performance Schema consumers
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE '%events_statements%';
-- Monitor long-running queries
SELECT
THREAD_ID,
EVENT_ID,
SQL_TEXT,
TIMER_WAIT/1000000000000 as DURATION_SECONDS,
LOCK_TIME/1000000000000 as LOCK_SECONDS,
ROWS_SENT,
ROWS_EXAMINED
FROM performance_schema.events_statements_history_long
WHERE TIMER_WAIT/1000000000000 > 5
ORDER BY TIMER_WAIT DESC;
|
InnoDB Status Monitoring
1
2
3
4
5
6
7
8
|
#!/bin/bash
# InnoDB status monitoring
while true; do
mysql -e "SHOW ENGINE INNODB STATUS\G" | \
grep -E "(deadlocks|lock waits|pending|fsyncs)" | \
logger -t mysql-innodb
sleep 60
done
|
Table Statistics Monitoring
1
2
3
4
5
6
7
8
9
10
11
|
-- Monitor table usage statistics
SELECT
TABLE_SCHEMA,
TABLE_NAME,
TABLE_ROWS,
DATA_LENGTH,
INDEX_LENGTH,
(DATA_LENGTH + INDEX_LENGTH) as TOTAL_SIZE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
ORDER BY TOTAL_SIZE DESC;
|
Monitoring and Alerting
Key Metrics to Monitor
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
31
32
33
34
|
# Slow query alert
[alerts.mysql_slow_queries]
query = "service:mysql AND query_time:>10"
threshold = 5
window = "2m"
message = "MySQL slow queries detected: {{ .database }}"
# Replication lag alert
[alerts.mysql_replication_lag]
query = "service:mysql AND Seconds_Behind_Master:>60"
threshold = 1
window = "1m"
message = "MySQL replication lag: {{ .Seconds_Behind_Master }} seconds"
# Connection failure alert
[alerts.mysql_connection_failures]
query = "service:mysql AND operation:FAILED_CONNECT"
threshold = 10
window = "1m"
message = "High MySQL connection failure rate"
# Deadlock alert
[alerts.mysql_deadlocks]
query = "service:mysql AND message:deadlock"
threshold = 1
window = "30s"
message = "MySQL deadlock detected"
# Error rate alert
[alerts.mysql_error_rate]
query = "service:mysql AND log_type:error AND level:ERROR"
threshold = 5
window = "1m"
message = "High MySQL error rate"
|
Dashboard Metrics
Monitor these key MySQL/MariaDB metrics:
- Query performance (execution time, slow queries count)
- Connection metrics (active connections, connection rate, failed attempts)
- Replication status (lag, I/O thread status, SQL thread status)
- Lock monitoring (deadlocks, lock waits, timeouts)
- Table statistics (table sizes, row counts, index usage)
- InnoDB metrics (buffer pool usage, log file usage)
- Binary log (log file size, rotation frequency)
- Error rates (by error type and severity)
Troubleshooting
Common Issues
MySQL logs not appearing:
1
2
3
4
5
6
7
8
|
# Check MySQL is running
sudo systemctl status mysql
# Verify log configuration
mysql -e "SHOW VARIABLES LIKE '%log%';"
# Check log file permissions
sudo ls -la /var/log/mysql/
|
Log parsing errors:
1
2
3
4
5
6
7
|
# Check log formats
mysql -e "SHOW VARIABLES LIKE 'log_timestamps';"
mysql -e "SHOW VARIABLES LIKE 'log_error_verbosity';"
# Test log entries
tail -n 10 /var/log/mysql/error.log
tail -n 5 /var/log/mysql/slow.log
|
Replication monitoring issues:
1
2
3
4
5
6
7
8
9
|
# Check replication status
mysql -e "SHOW SLAVE STATUS\G"
mysql -e "SHOW MASTER STATUS\G"
# Verify binary log configuration
mysql -e "SHOW VARIABLES LIKE 'log_bin%';"
# Check relay logs
ls -la /var/log/mysql/relay-bin.*
|
Performance Schema problems:
1
2
3
4
5
6
|
# Check Performance Schema status
mysql -e "SHOW VARIABLES LIKE 'performance_schema';"
mysql -e "SELECT * FROM performance_schema.setup_consumers WHERE ENABLED='NO';"
# Enable missing consumers
mysql -e "UPDATE performance_schema.setup_consumers SET ENABLED='YES' WHERE NAME LIKE '%events_statements%';"
|
Best Practices
- Enable slow query log with appropriate threshold
- Use Performance Schema for detailed query analysis
- Monitor binary log size and implement proper rotation
- Regular OPTIMIZE TABLE operations for MyISAM tables
Security
- Enable audit logging for security compliance
- Monitor failed connection attempts and implement rate limiting
- Log DDL operations for change tracking
- Use SSL connections for remote access
High Availability
- Monitor replication lag continuously
- Implement proper binary log backup procedures
- Monitor master-slave synchronization status
- Set up proper alerting for replication failures
Log Management
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# Optimize log rotation for MySQL
/var/log/mysql/*.log {
daily
rotate 30
missingok
notifempty
compress
delaycompress
postrotate
systemctl reload mysql.service > /dev/null 2>&1 || true
systemctl reload logflux-filestream.service > /dev/null 2>&1 || true
endpostrotate
}
|
Query Optimization
Enable additional logging for query optimization:
1
2
3
4
5
6
7
8
|
-- Enable general log temporarily for debugging
SET GLOBAL general_log = 'ON';
-- Run problematic queries
-- Analyze logs
SET GLOBAL general_log = 'OFF';
-- Use pt-query-digest for slow log analysis
-- pt-query-digest /var/log/mysql/slow.log
|
Integration Examples
Docker Deployment
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
|
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
volumes:
- mysql_data:/var/lib/mysql
- mysql_logs:/var/log/mysql
- ./my.cnf:/etc/mysql/conf.d/my.cnf
command: --log-bin=mysql-bin --server-id=1
logflux-agent:
image: logflux/agent:latest
volumes:
- mysql_logs:/var/log/mysql:ro
- ./logflux-config:/etc/logflux-agent/plugins
depends_on:
- mysql
volumes:
mysql_data:
mysql_logs:
|
Kubernetes Deployment
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
- name: MYSQL_DATABASE
value: "myapp"
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
- name: mysql-logs
mountPath: /var/log/mysql
- name: mysql-config
mountPath: /etc/mysql/conf.d/my.cnf
subPath: my.cnf
volumes:
- name: mysql-config
configMap:
name: mysql-config
- name: mysql-logs
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
|
Master-Slave Replication Monitoring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/bin/bash
# Complete replication health check
check_replication() {
local lag=$(mysql -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master" | awk '{print $2}')
local io_running=$(mysql -e "SHOW SLAVE STATUS\G" | grep "Slave_IO_Running" | awk '{print $2}')
local sql_running=$(mysql -e "SHOW SLAVE STATUS\G" | grep "Slave_SQL_Running" | awk '{print $2}')
echo "{\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\", \"lag\": $lag, \"io_running\": \"$io_running\", \"sql_running\": \"$sql_running\"}" >> /var/log/mysql/replication-health.log
}
while true; do
check_replication
sleep 30
done
|
This comprehensive MySQL/MariaDB integration provides real-time database monitoring, query performance analysis, and replication tracking using LogFlux Agent’s File Stream plugin. The configuration-based approach offers detailed insights into database operations, performance characteristics, and security events across different MySQL-compatible database deployments.
Disclaimer
The MySQL logo and trademarks are the property of Oracle Corporation and/or its affiliates. The MariaDB logo and trademarks are the property of MariaDB Corporation Ab. LogFlux is not affiliated with, endorsed by, or sponsored by Oracle Corporation or MariaDB Corporation Ab. The MySQL and MariaDB logos are used solely for identification purposes to indicate compatibility and integration capabilities.