access logging without drowning in log volume
Anyone processing customer data in a Magento store must be able to prove, if it ever comes to that, who accessed which data and when. That is exactly what audit plugins are for: they log connections, queries, and administrative changes at the database level, regardless of whether access happened through the Magento application, a reporting tool, or straight from the command line. This article shows how MySQL Enterprise Audit and the free alternative, the Percona Audit Log Plugin, work, how to avoid log flood with targeted filters, and which GDPR-relevant use cases stand behind it.
Table of Contents
- 1. Why audit logging matters for Magento stores handling customer data
- 2. Overview: MySQL Enterprise Audit versus the Percona Audit Log Plugin
- 3. Installing and enabling the Percona Audit Log Plugin
- 4. Filter configuration: using audit_log_filter against log flood
- 5. Choosing a log format: JSON, rotation, and retention in practice
- 6. Practical use cases for Magento stores handling customer data
- 7. Performance overhead and tuning the logging
- 8. Integration with SIEM and log aggregation systems
- 9. Retention periods and protecting access to the audit logs themselves
- 10. Summary
- 11. FAQ
1. Why audit logging matters for Magento stores handling customer data
A Magento store keeps far more in its database than product data alone: customer addresses, order histories, sometimes payment references, and in many configurations also data from B2B special pricing or individual contract terms. The GDPR requires, under Article 32(1)(d), a process for regularly testing, assessing, and evaluating the effectiveness of technical measures for ensuring the security of processing, and an access log at the database level is one of the most direct forms of evidence for that.
Without audit logging it is often impossible to reconstruct afterward whether an unusual data access was caused by a legitimate administrative task, a misconfigured reporting job, or an actually compromised account. Especially during a security incident, the breach notification obligation under Article 33 GDPR requires a defensible assessment of scope within 72 hours, which is hard to produce credibly without a searchable access log.
2. Overview: MySQL Enterprise Audit versus the Percona Audit Log Plugin
MySQL itself ships the audit_log plugin as part of the paid Enterprise Edition, which logs connections, executed statements, and administrative actions in a structured format. In the freely available MySQL Community Edition, that plugin is entirely absent, which is a practical gap for many Magento operators who run Community editions or Percona Server for cost reasons.
Percona Server for MySQL, a binary-compatible, open-source fork, closes that gap with the Percona Audit Log Plugin, which offers an API largely compatible with its Enterprise counterpart and a very similar feature set, without licensing cost. Because Percona Server works as a drop-in replacement for standard MySQL in most Magento setups without issue, switching for audit-mandated environments is often the most economical path, unless an Enterprise license is already in place anyway.
3. Installing and enabling the Percona Audit Log Plugin
The plugin ships as a shared library already bundled with Percona Server and only needs to be enabled via INSTALL PLUGIN; a server restart is not required. Once enabled, the plugin immediately starts logging under its default settings, which apply no filtering yet and should absolutely be adjusted before production use, since otherwise substantial log volumes accumulate within a short time.
For persistent activation across restarts, an additional entry in the configuration file is recommended, so the plugin loads automatically again after every planned or unplanned restart without manual intervention.
-- Enable the plugin at runtime (no restart required)
INSTALL PLUGIN audit_log SONAME 'audit_log.so';
-- Anchor the activation permanently in the configuration
-- /etc/mysql/percona-server.conf.d/mysqld.cnf
-- [mysqld]
-- plugin-load-add = audit_log.so
-- audit_log_format = JSON
-- Check status
SHOW PLUGINS;
4. Filter configuration: using audit_log_filter against log flood
Without filtering, the plugin logs every single SQL statement by default, which on a busy Magento store quickly produces several gigabytes of log data per day, most of it irrelevant, read-only application traffic. The modern, JSON-based filter configuration through audit_log_filter solves this by letting you define rules per account and event class instead of writing everything indiscriminately.
In practice, an approach that works well excludes most read-only access from the regular Magento application account from logging, while fully logging administrative actions, schema changes, permission changes, and any access through privileged accounts such as the migration or DBA user. That targeted selection cuts log volume by an order of magnitude without losing the events that actually matter for security.
-- Define a filter: log administrative events in full
SELECT audit_log_filter_set_filter('log_admin', '{ "filter": { "class": { "name": "general", "event": { "name": ["error", "status"] } } } }');
-- Assign a specific user (DBA/migration) to the strict filter
SELECT audit_log_filter_set_user('ci_migration@%', 'log_admin');
-- Only log DDL/DCL for the regular application user
SELECT audit_log_filter_set_filter('log_app', '{ "filter": { "class": { "name": "table_access", "event": "insert" } } }');
SELECT audit_log_filter_set_user('magento_app@%', 'log_app');
5. Choosing a log format: JSON, rotation, and retention in practice
The JSON format is clearly preferable to the older XML format, since it is much easier to parse with standard tools such as jq and feed into modern log pipelines, whereas the original XML format survives mostly for compatibility with older analysis tools. Rotation is controlled through audit_log_rotate_on_size, which defines a maximum file size after which a new log file automatically begins.
The number of retained rotations is set through audit_log_rotations, though that value should not be considered in isolation from the actual, often legally mandated retention period. In many cases it makes more sense to keep only a few, short-lived rotations locally and offload the actual long-term archiving to an external, immutable storage system that specifically guards against later tampering.
6. Practical use cases for Magento stores handling customer data
One typical use case is establishing an unbroken trail of which administrative account accessed the customer_entity or customer_address_entity table, and when, outside the normal application logic, for example through a direct database access during a support request. Without an audit log, such access can, at best, be reconstructed after the fact from general shell history, which does not hold up as a defensible compliance record.
A second, equally important use case concerns admin user actions within Magento itself: changes to payment configurations, creating new admin accounts, or exporting customer data through the built-in export should be visible both at the application level through Magento's own admin action log and at the database level, so that any discrepancy between the two sources can be cross-checked.
7. Performance overhead and tuning the logging
Every logged statement adds write overhead that becomes clearly measurable under unfiltered, full logging on busy systems, especially when the log file lives on the same storage medium as the actual database files. Targeted filtering, as described in the previous section, is therefore not just a matter of readability but also of performance, since only a small fraction of all requests actually needs to be written.
The overhead can be reduced further by placing the audit log file on separate storage that does not compete with the I/O path of the InnoDB data files, and by choosing a deliberately moderate rotation size, which avoids keeping a single, very large log file open unnecessarily long on every write.
8. Integration with SIEM and log aggregation systems
An isolated audit log sitting on the database server itself is of limited use in a real incident if an attacker with sufficient privileges can simply delete or tamper with the log file. That is why timely forwarding to a central system, separate from the database server, belongs to the basic setup of any serious audit strategy, whether through rsyslog with file monitoring or a lightweight log shipper like Filebeat that forwards JSON entries directly to an Elasticsearch or OpenSearch instance.
In such a centralized environment, alerting rules can additionally be defined, for instance a notification whenever a privileged account accesses customer-related tables outside the usual maintenance windows, which adds a proactive detection layer on top of plain logging.
9. Retention periods and protecting access to the audit logs themselves
The concrete retention period for audit logs follows internal compliance requirements and industry-specific obligations, with a range of six to twelve months being common in practice, and it should be checked against the organization's own data protection deletion concepts so the logs themselves do not hold personal data longer than necessary. It matters that this period is enforced in external archiving independently of the technical rotation inside the database system.
Equally important is protecting access to the log files themselves: whoever has write access to the audit log could, in doubt, cover their own tracks, which is why restrictive file permissions, a separate target-system permission for log aggregation, and, where available, an append-only or write-once storage model for archived logs are all advisable. That closes the loop between technical logging and an actually defensible compliance record.
| Feature | MySQL Enterprise Audit | Percona Audit Log Plugin | MariaDB Audit Plugin |
|---|---|---|---|
| Licensing cost | Paid (Enterprise Edition) | Free, open source | Free, open source |
| Target system | MySQL Enterprise Edition | Percona Server / Percona XtraDB Cluster | MariaDB, sometimes community MySQL too |
| Filtering | JSON-based filter rules per user/event | JSON-based filter rules per user/event | Rule-based via system variables, less granular |
| Log format | JSON, XML, old-style | JSON, XML, old-style | CSV-like text format |
| Typical use | Existing Enterprise license in place | Percona Server environments under cost pressure | MariaDB-based Magento environments |
Mironsoft
Database performance, index tuning, and Magento DB optimization
A Magento shop suffering from slow database queries?
We analyze MySQL databases for performance bottlenecks, optimize indexes and queries with purpose, and set up backup and replication strategies that actually work when it counts.
Performance Audit
Systematically investigate the slow query log and explain plans for bottlenecks.
Index Optimization
Build indexes with purpose for the shop's actual query load.
Backup Strategy
Set up reliable backup and restore processes for production Magento databases.
10. Summary
Audit Plugin for Compliance at a Glance
Free alternative
The Percona Audit Log Plugin offers functionality comparable to Enterprise Audit without licensing cost.
Filtering is mandatory
audit_log_filter prevents log flood by fully logging only security-relevant events and privileged accounts.
GDPR relevance
A searchable access log supports both Article 32 and the 72-hour breach notification obligation under Article 33.
External aggregation
Forwarding to a central SIEM protects the logs from tampering by a compromised database account.