---
title: "Connect MySQL"
description: "Connect Datarelix to MySQL: username/password or connection-string auth, creating a read-only user, schema scope, and TLS for caching_sha2_password."
canonical: https://docs.datarelix.ai/guides/connections/mysql/
---

# Connect MySQL

Datarelix connects to MySQL through a read-only query service. All queries are validated and executed inside that service — the model never sees credentials or executes raw SQL against your database.

## Prerequisites

- A MySQL server (5.7+ or 8.x).
- A read-only MySQL user with `SELECT` on the database you want to analyze.
- Network reachability from Datarelix's egress IPs to your MySQL server.

## Auth modes

### Username & password

Standard MySQL authentication using a username and password. The password is stored encrypted; all other connection fields are stored as plain configuration. Works with both `mysql_native_password` and [`caching_sha2_password`](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html) plugins (MySQL 8 default).

**Setup — create a read-only user**

Run the following in your MySQL instance (as a user with `GRANT OPTION`):

```sql
CREATE USER 'datarelix_reader'@'%' IDENTIFIED BY 'choose-a-strong-password';
GRANT SELECT ON your_db.* TO 'datarelix_reader'@'%';
FLUSH PRIVILEGES;
```

Replace `your_db` with your actual database name. The `'%'` host wildcard allows connections from any IP — you can restrict it to a specific CIDR if your MySQL server enforces host-based access control. See the MySQL [`GRANT` reference](https://dev.mysql.com/doc/refman/8.0/en/grant.html) for the full privilege model.

**Where to find your credentials**

| Field | Where to get it |
|-------|----------------|
| Host | Your cloud console — [AWS RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html): instance endpoint; [GCP Cloud SQL](https://cloud.google.com/sql/docs/mysql/connect-overview): public/private IP; [Azure Database for MySQL](https://learn.microsoft.com/en-us/azure/mysql/flexible-server/connect-workbench): server hostname (`*.mysql.database.azure.com`) |
| Port | Default `3306`; visible under the connection info panel in your cloud console |
| Database | The database name — list with `SHOW DATABASES;` in the MySQL CLI |
| Username | The user you created above |
| Password | The password you set in `CREATE USER` |

**What to enter**

```ini
Host:      your-host.example.com
Port:      3306
Database:  your_db
Username:  datarelix_reader
Password:  ••••••••
```

---

### Connection string

Paste a `mysql://` URL instead of filling individual fields.

**Where to find your connection string**

- **[AWS RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html)** — RDS console → your DB instance → **Connectivity & security** → copy the endpoint, then build: `mysql://datarelix_reader:password@endpoint:3306/dbname`
- **[PlanetScale](https://planetscale.com/docs)** — Dashboard → your database → **Connect** → copy the connection details
- **Railway / Render** — connection details panel in your project's database service

**What to enter**

```
mysql://datarelix_reader:your-password@your-host.example.com:3306/your_db
```

---

## Scope semantics

MySQL has no schema concept separate from the database — the **database is the scope**. The connection is restricted to the single database you specify.

To analyze multiple databases on the same MySQL server, create one connection per database.

## Discovery

Fully supported. The introspector walks `INFORMATION_SCHEMA.TABLES`, `INFORMATION_SCHEMA.COLUMNS`, and `INFORMATION_SCHEMA.KEY_COLUMN_USAGE` to surface tables, columns, primary keys, and foreign keys.

**Case quirk**: MySQL's `INFORMATION_SCHEMA` returns column names in **UPPERCASE** on some platforms. The introspector aliases them to lowercase so downstream processing stays consistent.

**Vitess / PlanetScale**: Vitess-backed databases often don't enforce (or expose) foreign-key constraints, so discovery returns an empty relationship graph. That's expected — the LLM enrichment pass infers relationships from column-name conventions instead.

## Limitations

- One database per connection.
- No write or DDL queries — the validator rejects mutations at the AST layer.
- Table names on Linux MySQL are case-sensitive by default (`lower_case_table_names=0`); on Windows/macOS they're case-insensitive. Discovery surfaces names as MySQL stores them.
- Server-side row cap is enforced — queries without a `LIMIT` get one appended automatically.

## Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| `Access denied for user 'X'@'host'` | Bad credentials or host not allowed | Check `GRANT` and the user's allowed hosts (`'user'@'%'` vs `'user'@'10.%'`); MySQL matches user + host as a pair. On Azure, use the plain username — Flexible Server does **not** need the `user@servername` suffix (that was only for the retired Single Server). |
| `Unknown database 'X'` | Wrong database name | Test with `mysql -h host -u user -p X` first. |
| `Authentication plugin 'caching_sha2_password' ... requires secure connection` | MySQL 8's default plugin needs TLS (or RSA key exchange) to send the password | Connect over TLS, or set the user to `mysql_native_password` if TLS isn't available. |
| `Authentication plugin 'caching_sha2_password' cannot be loaded` | Missing `cryptography` package in a custom build | Not expected on the hosted service — [contact us](https://datarelix.ai/contact/) if you see it. |
| Empty results from a query you know matches rows | Case-sensitive table name on Linux | Check the exact name in `INFORMATION_SCHEMA.TABLES` and re-run discovery. |
