Database audit logging
for GDPR compliance
GDPR Article 32 requires that every operation on personal data is logged, attributed to a named individual, and stored in a manner that prevents alteration — even by database administrators. No major database engine does this by default.
The guides below cover the four databases most commonly found in EU production stacks: what each engine logs natively, how to enable compliant audit logging, and where native tooling falls short of Article 32.
What Article 32 actually requires
A GDPR-compliant database audit trail must satisfy four properties simultaneously. Native database logging satisfies at most one or two of them.
Complete
Every operation logged — reads, writes, deletes, and denied requests. Connection events alone are not sufficient.
Attributable
Each entry linked to a verified human identity. A shared application role (app_user, postgres) is not an identity.
Tamper-evident
Structurally impossible to modify or delete, even by database superusers. Log files are not tamper-evident.
Searchable
Queryable by data subject, time range, and data category to support DSR responses within 30 days.
Implementation guides by database
Each guide covers the native audit mechanism, its GDPR compliance gaps, and the additional infrastructure required to close them.
PostgreSQL audit logging for GDPR
Most citedpg_audit extension
The most complete implementation. pg_audit provides per-role session and object logging. Covers the shared-role attribution problem and tamper-evidence gaps that pg_audit alone cannot fix.
MySQL audit logging for GDPR
audit_log plugin (Enterprise) / server_audit (MariaDB)
MySQL Enterprise's audit_log plugin supports per-user, per-table filtering with JSON output. MariaDB ships a free equivalent. Covers general_log limitations and what each approach logs.
MongoDB audit logging for GDPR
auditLog (Enterprise only)
MongoDB's auditLog is an Enterprise-only feature. Community Edition has no per-operation audit logging. Covers what Community Edition cannot do and the MongoDB Atlas audit configuration.
Redis audit logging for GDPR
ACL LOG / Redis Enterprise audit
Redis ACL LOG captures access control violations, not all commands. MONITOR is not production-safe. Covers what GDPR compliance actually requires for Redis and where community Redis falls short.
Database audit logging — frequently asked questions
What does GDPR require for database audit logs?
GDPR Article 32 requires appropriate technical measures to ensure the confidentiality, integrity, and availability of personal data. For database access, this means four things: (1) every operation on personal data must be logged — reads, writes, deletes, and denied requests; (2) each log entry must be attributed to a verified human identity, not a shared application role; (3) the log must be tamper-evident — structurally impossible to modify or delete, even by database administrators; (4) the log must be searchable by data subject, time range, and data category to support Data Subject Request responses within 30 days.
Is native database logging enough for GDPR Article 32?
No native database logging mechanism satisfies all four GDPR requirements by default. PostgreSQL's default log captures connection events but not individual queries. MySQL's general_log captures all queries but has significant performance overhead and no per-user filtering. MongoDB Community has no per-operation audit log at all. Redis has ACL LOG for access violations but not normal command logging. In all cases, the logs are writable by superusers — meaning a determined administrator can modify or delete them. GDPR Article 32 requires tamper-evident storage, which no native log file provides.
What is a tamper-evident database audit trail?
A tamper-evident audit trail is one where the structure of the log itself prevents modification, not just access controls. The strongest implementation is an INSERT-only schema: log entries can only be appended, never updated or deleted, even by the database owner. Log files (pg_audit output, MySQL general_log, MongoDB auditLog) are not tamper-evident — a superuser can truncate, rotate, or modify them. A supervisory authority investigating a data breach will ask whether your audit log could have been modified after the fact. With file-based logging, the honest answer is yes.
How do I attribute database queries to individual users, not shared roles?
Most production applications connect to the database via a single shared application role (e.g., app_user or postgres). When pg_audit or MySQL audit_log logs a query, it records the role — not the human operator. To achieve per-human attribution, you need one of: (1) per-operator database roles (high operational overhead, breaks most ORMs); (2) a connection-level identity variable like PostgreSQL's SET LOCAL app.current_user — application-level, cannot be verified by the database; (3) a database access layer that authenticates the human before passing the connection, like Scalple, which logs human identity independently of the database role.
Do audit logs themselves need to be GDPR-compliant?
Yes. If your audit log contains query content — SELECT id, email FROM users WHERE id = 4892 — it contains personal data. That log must itself comply with GDPR: stored in the EU, subject to data minimisation, accessible only to authorized roles, included in your Record of Processing Activities, and available for data subject export or deletion requests. A log that captures everything indefinitely in a file readable by all DBAs is not GDPR-compliant log storage.
Audit logs that satisfy a DPA inquiry
Scalple replaces native database logging with an INSERT-only audit trail attributed to human identities — not shared roles. Every query is logged before execution. No superuser can delete it. Book a demo or deploy self-hosted on your EU infrastructure.