MySQL
Connect faz to a MySQL or MariaDB database. SQL queries, full DML support, schema discovery via information_schema.
faz's MySQL connector works against both MySQL and MariaDB (the wire protocol and information_schema layout are compatible). It speaks plain SQL gated by your permissions: block.
| Default port | Query language | Write support | Schema discovery | Driver |
|---|---|---|---|---|
| 3306 | SQL | Yes (RBAC-gated) | information_schema | pymysql |
Quick example
databases:
- name: <database> # used as --database <database> in queries
type: mysql
host: localhost
port: 3306
database: <db-name> # the actual MySQL database on the host
username: <username>
password: <password>
permissions:
- database: <database> # must match `name:` above
access: R
# access codes:
# R read only — SELECT, EXPLAIN
# W write only — INSERT, UPDATE, DELETE (no SELECT)
# RW read + write
# RA read + append — SELECT, EXPLAIN, INSERT
# RWA read + write, no DELETE
# A admin (incl. DDL)See Permissions for the full model, per-table overrides, and the operation matrix.
faz query "SELECT * FROM <table> LIMIT 5" --database <database> --table <table>uv run faz query "SELECT * FROM <table> LIMIT 5" --database <database> --table <table>python -m faz query "SELECT * FROM <table> LIMIT 5" --database <database> --table <table>Configuration
| Field | Type | Default | Notes |
|---|---|---|---|
host | string | localhost | MySQL host or IP. |
port | integer | 3306 | MySQL port. |
database | string | "" | Database name. Required. |
username | string | "" | MySQL user. |
password | string | "" | Password. Env-var interpolation isn't yet implemented — see Secrets. |
ssl | boolean | false | When true, enables TLS via pymysql's ssl argument. |
extra | mapping | {} | Reserved. |
Unlike Postgres, the MySQL connector opens a fresh connection per operation — there's no built-in pool. For high-traffic deployments, run faz behind a connection-multiplexing proxy (ProxySQL, MaxScale).
Capabilities
- Full SQL —
SELECT,INSERT,UPDATE,DELETE, JOINs, CTEs (MySQL 8+), subqueries. - DDL (
CREATE,ALTER,DROP,TRUNCATE) — only when the policy grantsA. - Schema discovery via
information_schema.TABLESandinformation_schema.COLUMNS. - Cardinality stats via
information_schema.STATISTICS(index cardinality used as a row-count estimate). - Works against MariaDB without configuration changes.
Limitations
-
Stacked statements are blocked at the connector level. A query string with more than one top-level statement separated by
;is rejected before it reaches MySQL — defense-in-depth against stacked-query injection. Even if RBAC would allow each statement individually, the connector refuses to send the combined string. Only literal;-separated stacking counts; complex single statements pass through fine.Blocked — two top-level statements separated by
;:SELECT * FROM <table-1>; DELETE FROM <table-2>;Allowed — single complex statements. RBAC checks every table they touch:
-- UNION across two SELECTs SELECT <col> FROM <table-1> UNION ALL SELECT <col> FROM <table-2>; -- Subquery in FROM SELECT * FROM (SELECT * FROM <table> WHERE <condition>) sub; -- CTE / WITH clause (MySQL 8+) WITH recent AS (SELECT * FROM <table>) SELECT * FROM recent JOIN <other-table> USING (<key>); -- Insert-from-select — one statement, RBAC checks BOTH tables INSERT INTO <archive-table> SELECT * FROM <source-table>;To run multiple statements, submit them as multiple separate
faz querycalls — one statement per call. -
No connection pooling. Each query opens and closes a connection, which adds ~5-15 ms of overhead per request. Heavy workloads should front faz with ProxySQL.
-
MariaDB-specific syntax (e.g.
ROW_FORMAT=COMPRESSEDtable options) isn't validated by sqlglot's MySQL dialect. The connector executes them; the safety pipeline doesn't have explicit rules for MariaDB-only DDL.
Troubleshooting
Can't connect to MySQL server — MySQL isn't listening on the configured host:port. Test with mysql -h <host> -P <port> -u <user>.
Access denied for user 'X'@'host' — credentials are wrong, or the user lacks privileges from this host. MySQL's user table is <user>@<host>-keyed; check SELECT user, host FROM mysql.user.
SSL connection error — your MySQL requires TLS. Set ssl: true.
Schema discovery is sparse — the user lacks SELECT on information_schema. By default, MySQL grants this to all users on tables they have visibility to, but custom grant setups can break it.
For the broader troubleshooting flow, see Connection failed.
Related
- Databases overview — cross-connector basics.
- Permissions — how access codes map to SQL ops.
- PostgreSQL — sibling SQL connector with a connection pool.