ErasureDocs
Guides

Connect MySQL

Add a MySQL system and Data Map for deletion plans. TLS, health check, discovery, and dry-run preview.

Connect MySQL

Source: app_docs/guide/connectors.md, app_docs/guide/data-maps.md, app_docs/api.md.

Goal

An enabled MySQL System with a Data Map that can support Rights deletion.

When to use it

User / personal data lives in MySQL and must be deleted via parameterized SQL plans from a Data Map.

Prerequisites

  • Organization with Rights access
  • Network path from the worker to the database
  • Connection string (production: include TLS, e.g. ?ssl=true or equivalent, unless SQL_ALLOW_INSECURE=true on a private network as documented for product deployments)

Steps

Workflow

  1. Open Rights → Systems (UI: #/rights/connector).
  2. Add MySQL with connection string (secrets encrypted at rest with CONNECTOR_SECRETS_KEY / AES-256-GCM).
  3. Save and run health check (POST …/connectors/:id/test).
  4. Open Data MapDiscover schema (information schema, capped table set).
  5. Accept suggestions or add entities: table + identifier columns + DELETE or SKIP.
  6. Ignore tables that are not personal data.
  7. Validate until the map is ready (delete without identifiers is invalid).
  8. Optional: Execution preview, COUNT matching rows only; never deletes.

Connection shape (example form, not a live credential)

mysql://erasure_ro:***@db.example.com:5432/users?ssl=true

Permissions (documented guidance)

Least privilege: SELECT (discovery/preview) + DELETE on mapped tables only.

Execution model

Parameterized DELETE FROM … WHERE identifier columns match the subject.
Identifier allowlist (no arbitrary SQL). Discovery table cap applies on large catalogs.

MySQL-specific notes for deletion plans

  • Constraint ordering matters. MySQL does not support DEFERRABLE foreign keys, so each statement is checked immediately. Delete child tables before parents in the map, or the DELETE fails on a constraint. Map ordering should reflect that dependency.
  • Keep FOREIGN_KEY_CHECKS on. Disabling it to get around ordering can leave orphaned rows, which are exactly the subject data the deletion is meant to remove. Fix the ordering instead.
  • Batch large child tables. Deleting a large row set in one statement takes InnoDB range locks that block other writes. Break the work into smaller deletes (the worker's job/retry model keeps each run durable); keep the identifier column indexed so deletes are range-scoped, not full-table scans.
  • Count before you delete. Use the execution preview to confirm the match count per table. A count of 0 in a table you expected to hit means the identifier does not resolve there, not that there is nothing to do.

Health statuses

StatusMeaning
HEALTHYRecent check succeeded
DEGRADEDSlow or partial issues
UNHEALTHYCheck failed
UNKNOWNNot checked yet
DISABLEDConnector off

API surface (operator session)

MethodPath
GET/api/platform/orgs/:orgId/rights/connectors
POST/api/platform/orgs/:orgId/rights/connectors
POST/api/platform/orgs/:orgId/rights/connectors/:id/test
GET/api/platform/orgs/:orgId/rights/connectors/:id/data-map
POST/api/platform/orgs/:orgId/rights/connectors/:id/data-map/entities
POST/api/platform/orgs/:orgId/rights/connectors/:id/preview

v1: one connector per type per organization.

Troubleshoot

IssueCheck
Auth failuresCredentials, rotate secrets (Owner)
TLSProduction ssl=true
NetworkWorker egress / firewall
Missing map entitiesDiscover + map DELETE entities
Constraint errors on runChild-before-parent ordering in the map
Count 0 in a mapped tableIdentifier mismatch for that table

Next

Connect PostgreSQL (same map patterns) · Handle a deletion request · Data Maps

Deleting subject data in MySQL at the SQL level is covered in the guide Deleting a user's data from MySQL.