> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anomalyarmor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL

> Connect AnomalyArmor to MySQL databases including RDS, Aurora MySQL, and PlanetScale

<div aria-hidden="true" style={{position:"absolute",width:"1px",height:"1px",overflow:"hidden",clip:"rect(0,0,0,0)",whiteSpace:"nowrap"}}>For LLM agents: documentation index at <a href="/llms.txt" tabIndex={-1}>/llms.txt</a>, full text at <a href="/llms-full.txt" tabIndex={-1}>/llms-full.txt</a>. Append .md to any page URL for plain markdown.</div>
Connect AnomalyArmor to any MySQL-compatible database. This guide covers self-hosted MySQL as well as managed services like Amazon RDS, Aurora MySQL, PlanetScale, and DigitalOcean.

<img src="https://mintcdn.com/anomalyarmor/CZXBGa_D1aE9spAI/images/diagrams/generic-database-connection-light.svg?fit=max&auto=format&n=CZXBGa_D1aE9spAI&q=85&s=0d73dc172b2c084477a9791c325df69c" alt="MySQL Connection Architecture" className="block dark:hidden" width="700" height="300" data-path="images/diagrams/generic-database-connection-light.svg" />

<img src="https://mintcdn.com/anomalyarmor/CZXBGa_D1aE9spAI/images/diagrams/generic-database-connection-dark.svg?fit=max&auto=format&n=CZXBGa_D1aE9spAI&q=85&s=89dc269bb813341a89cae6a1884f9f3b" alt="MySQL Connection Architecture" className="hidden dark:block" width="700" height="300" data-path="images/diagrams/generic-database-connection-dark.svg" />

## Supported Versions & Platforms

| Platform            | Minimum Version | Notes                     |
| ------------------- | --------------- | ------------------------- |
| MySQL               | 5.7+            | Self-hosted or any cloud  |
| Amazon RDS          | 5.7+            | All instance classes      |
| Amazon Aurora MySQL | 5.7+            | Cluster and serverless    |
| PlanetScale         | Any             | Serverless MySQL          |
| DigitalOcean        | 8.0+            | Managed databases         |
| Google Cloud SQL    | 5.7+            | Public or private IP      |
| Azure Database      | 5.7+            | Single server or flexible |
| MariaDB             | 10.3+           | MySQL-compatible fork     |

## Connection Settings

| Field               | Description            | Example            |
| ------------------- | ---------------------- | ------------------ |
| **Connection Name** | Friendly identifier    | `Production MySQL` |
| **Host**            | Hostname or IP address | `db.example.com`   |
| **Port**            | Database port          | `3306`             |
| **Database**        | Database name          | `myapp_production` |
| **Username**        | Database user          | `anomalyarmor`     |
| **Password**        | User password          | `••••••••`         |
| **SSL Mode**        | SSL configuration      | `require`          |

### SSL Mode Options

| Mode          | Description                     | When to Use                              |
| ------------- | ------------------------------- | ---------------------------------------- |
| `disable`     | No SSL                          | Local development only                   |
| `require`     | SSL required, no verification   | **Recommended** for most cloud providers |
| `verify-ca`   | Verify server certificate       | High security requirements               |
| `verify-full` | Verify certificate and hostname | Maximum security                         |

<Warning>
  Never use `disable` for production databases. Most cloud providers (RDS, Aurora, PlanetScale) require SSL.
</Warning>

## Creating a Read-Only User

Create a dedicated user with minimal permissions:

```sql theme={null}
-- Create the user
CREATE USER 'anomalyarmor'@'%' IDENTIFIED BY 'your-secure-password';

-- Grant read access to your database
GRANT SELECT ON your_database.* TO 'anomalyarmor'@'%';

-- Access to information_schema is implicit with SELECT
-- Flush privileges to apply changes
FLUSH PRIVILEGES;
```

### For Multiple Databases

If you want to monitor multiple databases:

```sql theme={null}
-- Grant access to specific databases
GRANT SELECT ON database1.* TO 'anomalyarmor'@'%';
GRANT SELECT ON database2.* TO 'anomalyarmor'@'%';
GRANT SELECT ON analytics.* TO 'anomalyarmor'@'%';

FLUSH PRIVILEGES;
```

### Verifying Permissions

Test that the user can access metadata:

```sql theme={null}
-- Should return tables
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database' LIMIT 5;

-- Should return columns
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database' LIMIT 5;
```

## Provider-Specific Instructions

<Tabs>
  <Tab title="Amazon RDS">
    ### Amazon RDS MySQL

    **Connection Details**:

    * **Host**: Your RDS endpoint (e.g., `mydb.abc123.us-east-1.rds.amazonaws.com`)
    * **Port**: `3306` (default)
    * **SSL Mode**: `require`

    **Security Group Configuration**:

    1. Go to **AWS Console → RDS → Your Instance → Security Groups**
    2. Edit inbound rules
    3. Add rule:
       * Type: `MySQL/Aurora`
       * Port: `3306`
       * Source: AnomalyArmor IPs (see Settings → Security)

    <img src="https://mintcdn.com/anomalyarmor/-pFpKEip0ftEEXe9/images/diagrams/security-group-rules-light.svg?fit=max&auto=format&n=-pFpKEip0ftEEXe9&q=85&s=be7476718e42b9880b108b9facb90b9e" alt="AWS Security Group Rules" className="block dark:hidden" width="700" height="200" data-path="images/diagrams/security-group-rules-light.svg" />

    <img src="https://mintcdn.com/anomalyarmor/-pFpKEip0ftEEXe9/images/diagrams/security-group-rules-dark.svg?fit=max&auto=format&n=-pFpKEip0ftEEXe9&q=85&s=7db7e8e715ccb368c852f443f2633ad0" alt="AWS Security Group Rules" className="hidden dark:block" width="700" height="200" data-path="images/diagrams/security-group-rules-dark.svg" />

    **Parameter Group** (if using verify-ca or verify-full):

    * Ensure `require_secure_transport = ON`
    * Download RDS CA certificate bundle

    <Note>
      RDS instances in private subnets require NAT Gateway or VPC peering for AnomalyArmor access. Contact us for Enterprise VPC peering options.
    </Note>
  </Tab>

  <Tab title="Amazon Aurora MySQL">
    ### Amazon Aurora MySQL

    **Connection Details**:

    * **Host**: Cluster endpoint (reader or writer)
    * **Port**: `3306` (default)
    * **SSL Mode**: `require`

    **Choosing the Right Endpoint**:

    | Endpoint             | Use Case                                     |
    | -------------------- | -------------------------------------------- |
    | **Cluster (writer)** | If you need real-time schema changes         |
    | **Reader**           | Recommended - no impact on production writes |

    <img src="https://mintcdn.com/anomalyarmor/pPIiSU0b3Ixsp9az/images/diagrams/aurora-cluster-endpoints-light.svg?fit=max&auto=format&n=pPIiSU0b3Ixsp9az&q=85&s=432e896378f401655153d1adb6d9b34c" alt="Aurora cluster writer and reader endpoints" className="block dark:hidden" width="700" height="270" data-path="images/diagrams/aurora-cluster-endpoints-light.svg" />

    <img src="https://mintcdn.com/anomalyarmor/pPIiSU0b3Ixsp9az/images/diagrams/aurora-cluster-endpoints-dark.svg?fit=max&auto=format&n=pPIiSU0b3Ixsp9az&q=85&s=790c76600320d3f4ca793c5980e53c23" alt="Aurora cluster writer and reader endpoints" className="hidden dark:block" width="700" height="270" data-path="images/diagrams/aurora-cluster-endpoints-dark.svg" />

    **Aurora Serverless v2**:

    * Use the cluster endpoint
    * Ensure minimum ACU allows connections during discovery
    * Consider scheduling discovery during active hours
  </Tab>

  <Tab title="PlanetScale">
    ### PlanetScale

    **Connection Details**:

    * **Host**: Your branch endpoint (e.g., `aws.connect.psdb.cloud`)
    * **Port**: `3306`
    * **SSL Mode**: `require` (mandatory)

    **Getting Credentials**:

    1. Go to **PlanetScale Dashboard → Your Database → Settings → Passwords**
    2. Create a new password with **Read-only** access
    3. Copy the connection details

    **Important Notes**:

    * PlanetScale requires SSL - `disable` mode will fail
    * Use the `main` branch for production monitoring
    * Create separate credentials for AnomalyArmor

    <Warning>
      PlanetScale uses Vitess which may show slightly different table metadata than standard MySQL. All core functionality works correctly.
    </Warning>
  </Tab>

  <Tab title="Self-Hosted">
    ### Self-Hosted MySQL

    **Connection Details**:

    * **Host**: Your server's hostname or IP
    * **Port**: `3306` (or custom port)
    * **SSL Mode**: Depends on your setup

    **Firewall Configuration**:

    Allow inbound connections from AnomalyArmor IPs:

    ```bash theme={null}
    # iptables example
    iptables -A INPUT -p tcp --dport 3306 -s 34.xxx.xxx.xxx -j ACCEPT
    iptables -A INPUT -p tcp --dport 3306 -s 34.xxx.xxx.xxx -j ACCEPT
    ```

    **MySQL Configuration** (my.cnf):

    Allow remote connections:

    ```ini theme={null}
    [mysqld]
    bind-address = 0.0.0.0
    ```

    **SSL Setup** (if not already configured):

    ```bash theme={null}
    # Generate certificates
    mysql_ssl_rsa_setup --uid=mysql

    # Enable in my.cnf
    [mysqld]
    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
    ```

    **User Host Configuration**:

    Ensure user is created for remote access:

    ```sql theme={null}
    -- Allow from any host
    CREATE USER 'anomalyarmor'@'%' IDENTIFIED BY 'password';

    -- Or allow from specific IPs only
    CREATE USER 'anomalyarmor'@'34.xxx.xxx.xxx' IDENTIFIED BY 'password';
    ```
  </Tab>

  <Tab title="Google Cloud SQL">
    ### Google Cloud SQL for MySQL

    **Connection Methods**:

    | Method              | Description                                 |
    | ------------------- | ------------------------------------------- |
    | **Public IP**       | Add AnomalyArmor IPs to authorized networks |
    | **Cloud SQL Proxy** | For private IP instances (self-managed)     |

    **Public IP Setup**:

    1. Go to **Cloud Console → SQL → Your Instance → Connections**
    2. Under **Authorized Networks**, click **Add Network**
    3. Add each AnomalyArmor IP

    **Connection Details**:

    * **Host**: Public IP from instance overview
    * **Port**: `3306`
    * **SSL Mode**: `require`

    <Note>
      Cloud SQL requires SSL by default. If you need `verify-ca`, download the server certificate from the instance details.
    </Note>
  </Tab>

  <Tab title="DigitalOcean">
    ### DigitalOcean Managed MySQL

    **Connection Details**:

    * **Host**: Your database cluster hostname
    * **Port**: `25060` (DigitalOcean uses non-standard port)
    * **SSL Mode**: `require` (mandatory)

    **Getting Credentials**:

    1. Go to **DigitalOcean → Databases → Your Cluster**
    2. Click **Connection Details**
    3. Select **Direct Connection** or **Connection Pool**

    **Trusted Sources**:

    1. Go to **Settings → Trusted Sources**
    2. Add AnomalyArmor IP addresses

    <Note>
      DigitalOcean requires SSL and uses port 25060 by default.
    </Note>
  </Tab>
</Tabs>

## What We Query

AnomalyArmor runs these types of queries:

```sql theme={null}
-- Tables and views
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys');

-- Columns
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database';

-- Freshness (for timestamp columns)
SELECT MAX(your_timestamp_column) FROM your_table;
```

**Impact**: Minimal. These are lightweight metadata queries.

## Excluded Schemas

AnomalyArmor automatically excludes MySQL system schemas:

* `mysql`
* `information_schema`
* `performance_schema`
* `sys`

Only user-created databases and tables are monitored.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Can't connect to MySQL server">
    **Causes**:

    * Firewall blocking the connection
    * Wrong hostname or port
    * Database not running

    **Solutions**:

    1. Verify AnomalyArmor IPs are allowlisted
    2. Check security group rules (for RDS/Aurora)
    3. Test connectivity: `nc -zv hostname 3306`
    4. Verify MySQL is running: `systemctl status mysql`
  </Accordion>

  <Accordion title="Access denied for user">
    **Causes**:

    * Wrong password
    * User doesn't exist for connecting host
    * User lacks privileges

    **Solutions**:

    1. Verify password (copy-paste to avoid typos)
    2. Confirm user exists: `SELECT User, Host FROM mysql.user;`
    3. Check user is created for `%` or specific IP
    4. Verify grants: `SHOW GRANTS FOR 'anomalyarmor'@'%';`
  </Accordion>

  <Accordion title="SSL connection error">
    **Causes**:

    * Database requires SSL but connection uses `disable`
    * SSL certificate issues

    **Solutions**:

    1. Set SSL Mode to `require`
    2. For RDS/Aurora/PlanetScale: SSL is required
    3. For self-hosted: Enable SSL or allow non-SSL (not recommended)
  </Accordion>

  <Accordion title="Unknown database">
    **Causes**:

    * Database name is incorrect
    * Database names are case-sensitive on Linux

    **Solutions**:

    1. Verify database name: `SHOW DATABASES;`
    2. Use exact case for database name
    3. Check you have access: `SHOW DATABASES;` (shows only accessible DBs)
  </Accordion>

  <Accordion title="No tables found in discovery">
    **Causes**:

    * User can't see tables in information\_schema
    * Schema filter excluding all schemas

    **Solutions**:

    1. Test as the user: `SELECT * FROM INFORMATION_SCHEMA.TABLES LIMIT 5;`
    2. Check schema filter settings in AnomalyArmor
    3. Verify tables exist in the database
  </Accordion>
</AccordionGroup>

## Common Questions

### Which MySQL versions and managed services does AnomalyArmor support?

MySQL 5.7 and 8.0+, Amazon RDS for MySQL, Aurora MySQL, Google Cloud SQL for MySQL, Azure Database for MySQL, and PlanetScale. MariaDB is MySQL-compatible for most monitoring use cases but not officially supported - test before relying on it in production.

### Does MySQL 5.7 have any monitoring limitations compared to 8.0?

Minor. MySQL 5.7 doesn't expose some column-statistics views that 8.0 has, so a few metric baselines are coarser. Schema drift and freshness work identically on both versions - no migration urgency for observability alone.

### Can AnomalyArmor monitor PlanetScale branches?

Yes. Each connection points at one PlanetScale branch. Monitor `main` for production; add separate data sources per branch if you want pre-merge schema checks. PlanetScale's schema migration flow surfaces in AnomalyArmor as schema drift on the target branch.

### How should I configure SSL for RDS MySQL?

Set SSL Mode to `require` (RDS MySQL's default). Upload Amazon's RDS CA bundle in connection settings if your compliance program requires `verify-ca` or `verify-full`.

### Does AnomalyArmor read MySQL binlogs?

No. AnomalyArmor queries `information_schema` and runs bounded aggregates on a schedule. Binlog access is not required - if you've granted `REPLICATION CLIENT` to the AnomalyArmor user, you can safely revoke it.

## Next Steps

<CardGroup cols={2}>
  <Card title="Run Discovery" icon="magnifying-glass" href="/quickstart/run-first-discovery">
    Scan your MySQL database
  </Card>

  <Card title="Set Up Alerts" icon="bell" href="/quickstart/set-up-first-alert">
    Get notified of schema changes
  </Card>
</CardGroup>
