Implementing Percona Audit Plugin for Percona XtraDB Cluster with ProxySQL

Table of Contents

Implementing Percona Audit Plugin for Percona XtraDB Cluster with ProxySQL



Introduction

Database auditing is crucial for compliance, security monitoring, and forensic analysis in enterprise environments. The Percona Audit Plugin provides comprehensive database activity logging for Percona XtraDB Cluster, enabling organizations to track user activities, data access patterns, and potential security threats.

This comprehensive runbook guides you through implementing the Percona Audit Plugin in a Percona XtraDB Cluster environment with ProxySQL load balancing. By the end of this guide, you’ll have a fully functional audit system that captures database activities across your entire cluster.

Why Use Percona Audit Plugin?

  • Compliance Requirements: Meet regulatory standards like SOX, HIPAA, PCI-DSS
  • Security Monitoring: Track unauthorized access attempts and suspicious activities
  • Performance Analysis: Identify slow queries and optimize database performance
  • Forensic Analysis: Investigate security incidents and data breaches
  • Change Tracking: Monitor schema modifications and data changes

Prerequisites

Before implementing the Percona Audit Plugin, ensure you have:

System Requirements

  • Operating System: CentOS 7+, Ubuntu 18.04+, or RHEL 7+
  • Memory: Minimum 4GB RAM per node (8GB+ recommended)
  • Storage: Adequate space for audit logs (plan for 10-20% of database size)
  • Network: Stable network connectivity between cluster nodes

Software Requirements

  • Percona XtraDB Cluster 8.0.28+ (minimum 3 nodes)
  • ProxySQL 2.6.0+ (2.7.x recommended for latest features)
  • Percona Server 8.0.28+ (includes Audit Plugin)
  • Root or sudo access on all cluster nodes

Version Compatibility Matrix

ComponentMinimum VersionRecommended VersionNotes
Percona XtraDB Cluster8.0.288.0.35+Audit plugin bundled
ProxySQL2.6.02.7.1+Latest features and fixes
Percona Server8.0.288.0.35+Includes audit_log plugin
Operating SystemCentOS 7/Ubuntu 18.04CentOS 8+/Ubuntu 20.04+Better security features

Network Configuration

# Cluster nodes
Node 1: 192.168.1.101
Node 2: 192.168.1.102
Node 3: 192.168.1.103

# ProxySQL server
ProxySQL: 192.168.1.100

Understanding the Architecture

Percona XtraDB Cluster Overview

Percona XtraDB Cluster is a high-availability solution that combines:

  • Percona Server for MySQL: Enhanced MySQL server
  • Galera: Synchronous multi-master replication
  • ProxySQL: Intelligent proxy for connection routing

Audit Plugin Architecture

The Percona Audit Plugin operates at the MySQL server level, capturing:

  • Connection Events: Login/logout activities
  • Query Events: All SQL statements executed
  • Table Events: Data manipulation operations
  • Global Events: Server startup/shutdown

Integration Points

Application Layer
       ↓
   ProxySQL
       ↓
Percona XtraDB Cluster
  ↓      ↓      ↓
Node1  Node2  Node3
  ↓      ↓      ↓
Audit  Audit  Audit
Logs   Logs   Logs

Installation and Setup

Step 1: Install Percona XtraDB Cluster

First, install Percona XtraDB Cluster on all nodes:

# Add Percona repository
sudo yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm

# Enable Percona XtraDB Cluster repository
sudo percona-release enable-only pxc-80
sudo percona-release enable tools

# Install Percona XtraDB Cluster
sudo yum install -y percona-xtradb-cluster

Step 2: Verify Audit Plugin Availability

The Percona Audit Plugin is bundled with Percona Server for MySQL and doesn’t require separate installation:

# Verify the audit plugin is available
# Plugin location may vary by distribution
find /usr/lib64/mysql/plugin/ -name "audit_log.so" 2>/dev/null || \
find /usr/lib/mysql/plugin/ -name "audit_log.so" 2>/dev/null

# Alternative verification after MySQL is running
mysql -u root -p -e "SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%audit%';"

Step 3: Install ProxySQL

Install ProxySQL on the proxy server:

# Add ProxySQL repository (using current version)
cat > /etc/yum.repos.d/proxysql.repo << EOF
[proxysql_repo]
name=ProxySQL Repository
baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.7.x/centos/8/
gpgcheck=1
gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key
EOF

# Install ProxySQL
sudo yum install -y proxysql2

Configuration Steps

Step 1: Configure Percona XtraDB Cluster

Configure the first node (/etc/my.cnf):

[mysqld]
# Basic configuration
server-id=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# Galera configuration
wsrep_provider=/usr/lib64/galera4/libgalera_smm.so
wsrep_cluster_name=pxc-cluster
wsrep_cluster_address=gcomm://192.168.1.101,192.168.1.102,192.168.1.103
wsrep_node_name=pxc-node1
wsrep_node_address=192.168.1.101
wsrep_sst_method=xtrabackup-v2

# InnoDB configuration
innodb_buffer_pool_size=2G
innodb_log_file_size=256M
innodb_flush_log_at_trx_commit=0
innodb_file_per_table=1

# Binary logging
log-bin=mysql-bin
binlog_format=ROW

# Audit plugin configuration (using loose_ prefix to prevent startup failures)
plugin-load-add=audit_log.so
loose_audit_log_file=/var/log/mysql/audit.log
loose_audit_log_format=JSON
loose_audit_log_rotate_on_size=100M
loose_audit_log_rotations=10
loose_audit_log_policy=ALL

Step 2: Initialize the Cluster

Create the audit log directory first:

# Create audit log directory with proper permissions
sudo mkdir -p /var/log/mysql
sudo chown mysql:mysql /var/log/mysql
sudo chmod 755 /var/log/mysql

Start the first node:

# Bootstrap the cluster
sudo systemctl start mysql@bootstrap.service

# Secure the installation
sudo mysql_secure_installation

# Create cluster user
mysql -u root -p << EOF
CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost';
FLUSH PRIVILEGES;
EOF

Step 3: Configure Additional Nodes

For nodes 2 and 3, modify the configuration:

# Node 2 (/etc/my.cnf)
server-id=2
wsrep_node_name=pxc-node2
wsrep_node_address=192.168.1.102

# Node 3 (/etc/my.cnf)
server-id=3
wsrep_node_name=pxc-node3
wsrep_node_address=192.168.1.103

Start the additional nodes:

# On nodes 2 and 3
sudo systemctl start mysql
sudo systemctl enable mysql

Step 4: Install and Configure Audit Plugin

On each cluster node, install the audit plugin:

-- Connect to MySQL
mysql -u root -p

-- Install the audit plugin
INSTALL PLUGIN audit_log SONAME 'audit_log.so';

-- Verify installation
SHOW PLUGINS;

-- Configure audit settings
SET GLOBAL audit_log_policy = 'ALL';
SET GLOBAL audit_log_format = 'JSON';
SET GLOBAL audit_log_file = '/var/log/mysql/audit.log';

ProxySQL Integration

Step 1: Configure ProxySQL

Edit the ProxySQL configuration (/etc/proxysql.cnf):

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="admin:admin;radmin:radmin"
    mysql_ifaces="0.0.0.0:6032"
    refresh_interval=2000
}

mysql_variables=
{
    threads=4
    max_connections=2048
    default_query_delay=0
    default_query_timeout=36000000
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033"
    default_schema="information_schema"
    stacksize=1048576
    server_version="8.0.25"
    connect_timeout_server=3000
    monitor_username="monitor"
    monitor_password="monitor"
    monitor_history=600000
    monitor_connect_interval=60000
    monitor_ping_interval=10000
    ping_interval_server_msec=120000
    ping_timeout_server=500
    commands_stats=true
    sessions_sort=true
}

Step 2: Add Cluster Nodes to ProxySQL

-- Connect to ProxySQL admin interface
mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- Add cluster nodes
INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight) VALUES
(0, '192.168.1.101', 3306, 900),
(0, '192.168.1.102', 3306, 900),
(0, '192.168.1.103', 3306, 900);

-- Create monitor user on cluster
CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor';
GRANT USAGE ON *.* TO 'monitor'@'%';

-- Load configuration
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

Step 3: Configure User Authentication

-- Add application users
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES
('app_user', 'app_password', 0),
('read_user', 'read_password', 1);

-- Load users
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

Testing and Validation

Step 1: Verify Cluster Status

Check cluster synchronization:

-- On each node
SHOW STATUS LIKE 'wsrep%';

-- Key metrics to check
wsrep_cluster_size: 3
wsrep_cluster_status: Primary
wsrep_connected: ON
wsrep_local_state_comment: Synced

Step 2: Test Audit Logging

Perform test operations and verify audit logs:

-- Create test database and table
CREATE DATABASE audit_test;
USE audit_test;
CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(50));

-- Insert test data
INSERT INTO test_table VALUES (1, 'Test Record');

-- Query data
SELECT * FROM test_table;

-- Update data
UPDATE test_table SET name = 'Updated Record' WHERE id = 1;

-- Delete data
DELETE FROM test_table WHERE id = 1;

Step 3: Verify Audit Log Output

Check the audit log file:

# View recent audit entries
tail -f /var/log/mysql/audit.log

# Example audit log entry (JSON format)
{
  "audit_record": {
    "name": "Query",
    "record": "1_2023-07-15T10:30:45",
    "timestamp": "2023-07-15T10:30:45 UTC",
    "command_class": "select",
    "connection_id": "8",
    "status": 0,
    "sqltext": "SELECT * FROM test_table",
    "user": "app_user[app_user] @ localhost []",
    "host": "localhost",
    "os_user": "",
    "ip": "127.0.0.1",
    "db": "audit_test"
  }
}

Step 4: Test ProxySQL Connectivity

Test connections through ProxySQL:

# Test connection through ProxySQL
mysql -u app_user -papp_password -h 192.168.1.100 -P 6033

# Verify connection routing
SELECT @@hostname, @@server_id;

Monitoring and Maintenance

Step 1: Set Up Log Rotation

Configure audit log rotation:

-- Configure automatic rotation
SET GLOBAL audit_log_rotate_on_size = 104857600; -- 100MB
SET GLOBAL audit_log_rotations = 10;

-- Manual rotation
SET GLOBAL audit_log_flush = ON;

Step 2: Monitor Disk Usage

Create monitoring script (/usr/local/bin/audit_monitor.sh):

#!/bin/bash

# Audit log monitoring script
AUDIT_DIR="/var/log/mysql"
THRESHOLD=80

# Check disk usage
USAGE=$(df -h $AUDIT_DIR | awk 'NR==2 {print $5}' | sed 's/%//')

if [ $USAGE -gt $THRESHOLD ]; then
    echo "WARNING: Audit log directory usage is ${USAGE}%"
    # Send alert or perform cleanup
    find $AUDIT_DIR -name "audit.log.*" -mtime +30 -delete
fi

# Check audit log file size
CURRENT_SIZE=$(stat -c%s "$AUDIT_DIR/audit.log" 2>/dev/null || echo 0)
MAX_SIZE=104857600  # 100MB

if [ $CURRENT_SIZE -gt $MAX_SIZE ]; then
    echo "INFO: Audit log rotation needed"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "SET GLOBAL audit_log_flush = ON;"
fi

Step 3: Performance Monitoring

Monitor audit plugin performance impact:

-- Check audit plugin status
SHOW GLOBAL STATUS LIKE 'audit_log%';

-- Monitor general performance
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Threads_connected';

Troubleshooting

Common Issues and Solutions

Issue 1: Plugin Load Failure

# Error: Plugin 'audit_log' cannot be loaded
# Solution 1: Check plugin file permissions and location
sudo find /usr/lib*/mysql/plugin/ -name "audit_log.so" -exec ls -la {} \;
sudo chown mysql:mysql /usr/lib*/mysql/plugin/audit_log.so
sudo chmod 755 /usr/lib*/mysql/plugin/audit_log.so

# Solution 2: Verify plugin is available in MySQL
mysql -u root -p -e "SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%audit%';"

# Solution 3: Check if using loose_ prefix in configuration
grep -E "^(loose_)?audit_log" /etc/my.cnf

Issue 2: Audit Log Rotation Problems

-- Error: Cannot rotate audit log
-- Solution: Check directory permissions
-- As root:
sudo chown -R mysql:mysql /var/log/mysql/
sudo chmod 755 /var/log/mysql/

-- Set proper log rotation
SET GLOBAL audit_log_rotate_on_size = 104857600;

Issue 3: High Disk Usage

# Compress old audit logs
find /var/log/mysql -name "audit.log.*" -mtime +7 -exec gzip {} \;

# Archive old logs
find /var/log/mysql -name "audit.log.*.gz" -mtime +30 -exec mv {} /backup/audit_archive/ \;

Issue 4: Performance Degradation

-- Reduce audit scope for performance
SET GLOBAL audit_log_policy = 'QUERIES';

-- Exclude specific databases
SET GLOBAL audit_log_exclude_databases = 'mysql,information_schema,performance_schema';

-- Exclude monitoring users to reduce log volume
SET GLOBAL audit_log_exclude_accounts = 'monitor@%,mysql.session@localhost';

-- Use connection-based auditing for less overhead
SET GLOBAL audit_log_policy = 'LOGINS';

Issue 5: SELinux Configuration Problems

# Comprehensive SELinux configuration for audit logs
sudo setsebool -P mysql_connect_any 1
sudo setsebool -P mysqld_can_networkconnect 1

# Set proper context for audit log directory
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?"
sudo restorecon -R /var/log/mysql

# Allow MySQL to write to audit log location
sudo setsebool -P allow_mysqld_log_write 1

# Verify SELinux status
sudo getsebool -a | grep mysql
sudo ls -Z /var/log/mysql/

Diagnostic Commands

# Check MySQL error log
sudo tail -f /var/log/mysqld.log

# Verify plugin status
mysql -u root -p -e "SHOW PLUGINS;" | grep audit

# Check audit log permissions
ls -la /var/log/mysql/audit.log*

# Monitor real-time audit activity
tail -f /var/log/mysql/audit.log | jq '.'

Best Practices

Security Best Practices

  1. Secure Audit Logs
    # Set restrictive permissions
    sudo chmod 640 /var/log/mysql/audit.log*
    sudo chown mysql:mysql /var/log/mysql/audit.log*
  2. Encrypt Audit Logs
    # Use log encryption for sensitive environments
    # Configure at filesystem level or use encrypted storage
  3. Regular Backups
    # Backup audit logs regularly
    rsync -av /var/log/mysql/audit.log* backup-server:/audit-backup/

Performance Best Practices

  1. Optimize Audit Scope
    -- Audit only necessary events
    SET GLOBAL audit_log_policy = 'QUERIES';
    SET GLOBAL audit_log_exclude_commands = 'show_processlist,show_status';
  2. Use Dedicated Storage
    # Mount audit logs on separate disk
    # Add to /etc/fstab:
    /dev/sdb1 /var/log/mysql ext4 defaults 0 2
  3. Monitor Resource Usage
    # Regular monitoring script
    iostat -x 1 5  # Check I/O performance
    top -u mysql   # Monitor MySQL processes

Operational Best Practices

  1. Centralized Log Management
    # Use rsyslog or similar for centralization
    # Configure in /etc/rsyslog.conf:
    # *.* @@log-server:514
  2. Automated Alerts
    # Set up monitoring alerts for:
    # - High disk usage
    # - Audit log rotation failures
    # - Suspicious activity patterns
  3. Regular Testing
    # Test audit functionality monthly
    # Verify log integrity
    # Test restoration procedures

Security Considerations

Access Control

Implement strict access controls for audit logs:

# Create dedicated audit user
sudo useradd -r -s /bin/false audit_reader

# Set file permissions
sudo chown mysql:audit_reader /var/log/mysql/audit.log*
sudo chmod 640 /var/log/mysql/audit.log*

# SELinux configuration (if enabled)
sudo setsebool -P mysql_connect_any 1
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql/audit\.log.*"
sudo restorecon -R /var/log/mysql/

Network Security

Secure network communications:

-- Enable SSL for cluster communications
-- Generate SSL certificates first:
-- sudo mysql_ssl_rsa_setup --uid=mysql

-- Add to my.cnf on all nodes:
[mysqld]
# SSL Configuration
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem
require_secure_transport=ON

# Galera SSL Configuration
wsrep_provider_options="socket.ssl_key=/var/lib/mysql/server-key.pem;socket.ssl_cert=/var/lib/mysql/server-cert.pem;socket.ssl_ca=/var/lib/mysql/ca.pem;socket.ssl_cipher=AES128-SHA"

# For ProxySQL SSL connections
[client]
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/client-cert.pem
ssl-key=/var/lib/mysql/client-key.pem

Audit Log Integrity

Ensure audit log integrity:

# Generate checksums for audit logs
find /var/log/mysql -name "audit.log*" -exec sha256sum {} \; > /var/log/mysql/audit_checksums.txt

# Verify integrity periodically
sha256sum -c /var/log/mysql/audit_checksums.txt

Performance Impact

Understanding Performance Impact

The Percona Audit Plugin introduces performance overhead that varies by workload:

  • CPU Impact: 2-15% increase depending on audit scope and query volume
  • I/O Impact: Additional disk writes for audit logs (size varies by activity)
  • Memory Impact: Minimal memory overhead (~1-2MB for buffers)
  • Network Impact: No direct network impact

Performance Impact Factors:

  • audit_log_policy setting: ALL > QUERIES > LOGINS > NONE
  • Query volume: High TPS environments see higher impact
  • Audit log format: JSON format has slightly higher overhead than OLD format
  • Storage performance: Slow disk storage increases I/O bottlenecks

Baseline Testing Results (based on sysbench OLTP workload):

  • Baseline: 10,000 QPS, 50ms avg response time
  • With audit_log_policy=ALL: 8,500 QPS, 60ms avg response time (~15% impact)
  • With audit_log_policy=QUERIES: 9,200 QPS, 55ms avg response time (~8% impact)
  • With audit_log_policy=LOGINS: 9,800 QPS, 51ms avg response time (~2% impact)

Optimization Strategies

  1. Selective Auditing
    -- Audit only specific users
    SET GLOBAL audit_log_include_accounts = 'admin@localhost,app_user@%';
    
    -- Exclude system users
    SET GLOBAL audit_log_exclude_accounts = 'mysql.session@localhost,mysql.sys@localhost';
  2. Optimized Storage
    # Use high-performance storage for audit logs
    # Consider SSD storage for better I/O performance
    # Mount with optimized options:
    mount -o noatime,nodiratime /dev/sdb1 /var/log/mysql
  3. Asynchronous Processing
    -- Configure buffer settings
    SET GLOBAL audit_log_buffer_size = 1048576;  -- 1MB buffer

Performance Monitoring

Regular performance monitoring:

-- Monitor audit-related metrics
SHOW GLOBAL STATUS LIKE 'audit_log%';

-- Check overall performance
SHOW GLOBAL STATUS LIKE 'Com_%';
SHOW GLOBAL STATUS LIKE 'Handler_%';
SHOW GLOBAL STATUS LIKE 'Innodb_%';

Conclusion

Implementing the Percona Audit Plugin for Percona XtraDB Cluster with ProxySQL provides comprehensive database activity monitoring while maintaining high availability and performance. This implementation offers:

Key Benefits Achieved

  • Complete Audit Trail: Track all database activities across the cluster
  • High Availability: Maintain service availability during audit implementation
  • Scalable Architecture: Support growing workloads with cluster scalability
  • Compliance Ready: Meet regulatory and security requirements
  • Performance Optimized: Minimize impact on database performance

Next Steps

After implementing this solution:

  1. Regular Monitoring: Establish routine monitoring procedures
  2. Log Analysis: Implement log analysis tools for security insights
  3. Automation: Automate log rotation and archival processes
  4. Documentation: Maintain updated documentation for operational procedures
  5. Training: Train team members on audit log analysis and troubleshooting

Maintenance Schedule

Establish a regular maintenance schedule:

  • Daily: Monitor disk usage and audit log rotation
  • Weekly: Review audit logs for suspicious activities
  • Monthly: Test backup and recovery procedures
  • Quarterly: Review and update audit policies
  • Annually: Conduct comprehensive security audits

This implementation provides a robust foundation for database auditing in enterprise environments, ensuring both security compliance and operational excellence.



Further Reading:

WiredTiger Storage Engine Internals

Tuning TiDB Server Parameters for Optimal Performance

Vector Index Algorithms in Milvus

Securing User Accounts in PostgreSQL

Troubleshooting InnoDB Cluster Write Throughput and Latency

About MinervaDB Corporation 124 Articles
Full-stack Database Infrastructure Architecture, Engineering and Operations Consultative Support(24*7) Provider for PostgreSQL, MySQL, MariaDB, MongoDB, ClickHouse, Trino, SQL Server, Cassandra, CockroachDB, Yugabyte, Couchbase, Redis, Valkey, NoSQL, NewSQL, Databricks, Amazon Resdhift, Amazon Aurora, CloudSQL, Snowflake and AzureSQL with core expertize in Performance, Scalability, High Availability, Database Reliability Engineering, Database Upgrades/Migration, and Data Security.

Be the first to comment

Leave a Reply