MySQL AIops
Disclaimer: Community-maintained open-source project. Not affiliated with, endorsed by, or sponsored by Oracle Corporation or the MariaDB Foundation. "MySQL" is a trademark of Oracle Corporation; "MariaDB" is a trademark of MariaDB plc; all product/trademark names belong to their respective owners. MIT licensed.
Governed AI-ops for MySQL 8.x and MariaDB 10.6+ DBA operations — connecting
to a server with PyMySQL and reading information_schema /
performance_schema — with a built-in governance harness: unified audit
log, policy engine, token/runaway budget guard, undo-token recording, and
graduated-autonomy risk tiers. The server flavor (mysql vs mariadb) is
detected from version() and flavor-dependent statements branch automatically
(SHOW REPLICA STATUS vs SHOW SLAVE STATUS).
What it does
Four flagship signature analyses, plus the guarded reads and writes around them:
- Slow-query RCA — take the worst
events_statements_summary_by_digestentry (plus an optionalEXPLAIN FORMAT=JSONplan) and map its numbers — no-index share (SUM_NO_INDEX_USED), lock-time share, rows-examined/sent ratio, tmp-disk spill, call count, plan access types — to a cited cause and a concrete action. Every finding carries its measured number, not a black-box verdict. - InnoDB lock-wait & deadlock chain RCA — build the wait-for tree from
performance_schema.data_lock_waits(MariaDB:information_schema.innodb_lock_waits), name the root blocker (blocks others, waits on none), and parse the last deadlock out ofSHOW ENGINE INNODB STATUS. - Replication lag RCA — map the replica's IO/SQL thread state,
Seconds_Behind_Sourceand error fields to a cited cause + action (stopped IO thread, failed applier statement, lagging applier, intentionalSQL_Delay). - Table fragmentation analysis — rank tables by reclaimable
data_freefrominformation_schema.tablesinto citedOPTIMIZE TABLEcandidates.
What works
- CLI (
mysql-aiops ...):init,overview,server,activity,query,index,table,repl,analyze,remediate,secret,doctor,mcp. - MCP server (
mysql-aiops mcpormysql-aiops-mcp): 35 tools (26 read, 9 write), every one wrapped with the bundled@governed_toolharness. - Encrypted credentials: the account password lives in an encrypted store
~/.mysql-aiops/secrets.enc(Fernet + scrypt) — never plaintext on disk. Unlock with a master password fromMYSQL_AIOPS_MASTER_PASSWORD(MCP/CI) or an interactive prompt (CLI). - Reversibility: mutating writes fetch the real before-state first and record a faithful inverse —
create_index↔drop_index;drop_indexcaptures the index definition out ofSHOW CREATE TABLEso undo recreates it exactly;set_global_variablecaptures the prior value fromSHOW GLOBAL VARIABLESso undo sets it back. Irreversible ops (kill_session,kill_query,optimize_table,analyze_table,reset_query_stats) record prior state for audit but declare no undo. - Safety: every state-changing CLI op supports
--dry-runand requires double confirmation; every write MCP tool takes adry_runpreview. All identifiers that cannot be parameterised (schema/table/index/column/variable names) are validated against a strict charset and backtick-quoted; all values are bound query parameters.
Security: read-only mode
This tool is meant to be handed to an AI agent, so its safety story is enforced by the server rather than requested in a prompt:
export MYSQL_READ_ONLY=1
With that set, the 9 write tools are never registered. An MCP client lists 26 tools instead of 35 — the writes are not hidden, not gated behind a flag, and not merely refused when called. They are absent from the session. A model cannot invoke a tool it was never offered, and cannot be argued into one.
That distinction is the whole point. A tool that exists but refuses still invites retry loops and "I'll describe the call instead" behaviour from smaller models, and it leaves a reviewer trusting a promise. An absent tool is a fact you can check: connect, list the tools, and see that the writes are not there.
Enforcement is two layers deep, so the switch cannot be sidestepped by changing entry point:
| Layer | What it does | Covers |
|---|---|---|
@governed_tool harness |
refuses every non-read operation outright | MCP, CLI, and in-process callers |
| MCP registration | write tools are removed from list_tools() |
anything speaking MCP |
Read operations are unaffected, and every call is still audited to
~/.mysql-aiops/audit.db.
The read/write split is derived from each tool's declared
risk_level, and a test asserts that this never disagrees with the[READ]/[WRITE]tag in the tool's own documentation — so a write can't quietly present itself as a read.
Running a smaller / local model? See agent-guardrails.md — it lists the guardrails this tool now enforces for you (so you don't spend prompt budget restating them) and gives a ready-made system prompt for what's left.
Capability matrix (35 MCP tools)
| Domain | Tools | Count | R/W |
|---|---|---|---|
| Overview | overview |
1 | read |
| Server | server_version, show_variables, show_status, list_databases, list_engines, connection_stats |
6 | read |
| Activity | list_sessions, long_running_queries, list_transactions, lock_waits |
4 | read |
| Queries | top_queries, explain_query |
2 | read |
| Indexes | unused_indexes, redundant_indexes, index_stats |
3 | read |
| Tables | table_sizes, table_fragmentation, table_status |
3 | read |
| Replication | replica_status, binlog_status |
2 | read |
| Analysis (flagship) | slow_query_rca, lock_wait_rca, replication_lag_rca, fragmentation_analysis |
4 | read |
| Writes | kill_session, kill_query, drop_index |
3 | write (high) |
optimize_table, analyze_table, create_index, set_global_variable, reset_query_stats |
5 | write (medium) | |
| Undo | undo_list, undo_apply |
2 | read / write |
The flagship analyses accept injected records for pure/offline analysis, or pull
live from a configured target. top_queries/slow_query_rca require
performance_schema=ON; the read account should have PROCESS,
REPLICATION CLIENT and SELECT on performance_schema.
Support scope
| Platform | Status |
|---|---|
| MySQL 8.0 / 8.4 | targeted (SHOW REPLICA STATUS, performance_schema.data_lock_waits) |
| MariaDB 10.6+ / 11.x | targeted (SHOW SLAVE STATUS, information_schema.innodb_lock_waits) |
| MySQL 5.7 and older | not targeted (EOL; pre-8.0 digest/lock views untested) |
| Cloud-managed MySQL (RDS/Aurora/Cloud SQL flavors) | wire-compatible reads should work; managed restrictions (KILL, SET GLOBAL) apply — untested |
Quick start
uv tool install mysql-aiops # or: pipx install mysql-aiops
mysql-aiops init # wizard: add a target + store the password (encrypted)
mysql-aiops doctor # verify config, secrets, connectivity, flavor, perf-schema
mysql-aiops overview # one-shot server health snapshot
mysql-aiops analyze slow-query # RCA the worst statement digest
mysql-aiops analyze fragmentation # OPTIMIZE TABLE candidates
Run as an MCP server (stdio):
export MYSQL_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
mysql-aiops-mcp
Claude Desktop / MCP client config:
{
"mcpServers": {
"mysql-aiops": {
"command": "uvx",
"args": ["--from", "mysql-aiops", "mysql-aiops-mcp"],
"env": { "MYSQL_AIOPS_MASTER_PASSWORD": "your-master-password" }
}
}
}
Env-block caveat: the
envblock above is the only environment the MCP server sees — GUI-launched clients do not inherit your shell profile. PutMYSQL_AIOPS_MASTER_PASSWORD(andMYSQL_AIOPS_HOME/MYSQL_AUDIT_APPROVED_BYif you use them) there, or the server cannot unlock the secret store.
Governance
Every MCP tool passes through the bundled @governed_tool harness:
- Audit — every call (params, result, status, duration, risk tier, approver,
rationale) is logged to
~/.mysql-aiops/audit.db(relocatable viaMYSQL_AIOPS_HOME). - Budget / runaway guard — token and call budgets trip a circuit breaker
(
MYSQL_MAX_TOOL_CALLS,MYSQL_MAX_TOOL_SECONDS,MYSQL_RUNAWAY_MAX). - Risk tiers — graduated autonomy, secure by default: with no
rules.yaml, high-risk writes require a named approver (MYSQL_AUDIT_APPROVED_BY/MYSQL_AUDIT_RATIONALE);mysql-aiops initseeds an explicit starterrules.yamlwith that dual-control tier. - Undo recording — reversible writes record an inverse descriptor built from the fetched before-state, replayable through the tool it names.
Scope
This is the MySQL / MariaDB DBA-ops member of the AIops-tools family
(governed AI-ops with audit + budget + undo + risk tiers). Do NOT use it
for PostgreSQL — use postgres-aiops. Do NOT use it for OT / industrial
edge — see the separate industrial-aiops line — nor for application-schema
migrations or ORM management.
Missing a capability?
Coverage is intentionally a curated subset of MySQL's catalogs and maintenance surface. Missing a view, a metric, or a maintenance command? Open an issue or PR — contributions welcome. 缺功能提 issue/PR 欢迎留言。
Verification status
Live-verified against MySQL 8.4.10 (2026-07-19); MariaDB still mock-only.
Connectivity, the reads, analyze slow-query on genuine full scans, and the full
governance loop (real create_index → audit row → undo actually dropping it) were
exercised against a real server, as was read-only mode. That run found and fixed a
real bug the mock suite could not see: SUM() aggregates come back as Decimal,
which is not JSON serializable.
The MariaDB flavor branch (SHOW SLAVE STATUS,
information_schema.innodb_lock_waits), replication against a real replica, and
lock-wait contention remain unverified.
docs/VERIFICATION.md records exactly what was checked and what
is still open. mysql-aiops doctor is the fastest live check (connectivity, flavor,
performance_schema, replica role).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mysql_aiops-0.2.1.tar.gz.
File metadata
- Download URL: mysql_aiops-0.2.1.tar.gz
- Upload date:
- Size: 207.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8febebcfb71fc65abf8eb955efeec87c037c40c4f2d1c9742d2fc081c6000f70
|
|
| MD5 |
a750af2fc8fc7c8a04842e522e90d3c7
|
|
| BLAKE2b-256 |
f90a441f90f5f6768abcdfd9b0cd376d57339e3547bfa05d407044d61b82e8f4
|
Provenance
The following attestation bundles were made for mysql_aiops-0.2.1.tar.gz:
Publisher:
publish.yml on AIops-tools/MySQL-AIops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mysql_aiops-0.2.1.tar.gz -
Subject digest:
8febebcfb71fc65abf8eb955efeec87c037c40c4f2d1c9742d2fc081c6000f70 - Sigstore transparency entry: 2200485883
- Sigstore integration time:
-
Permalink:
AIops-tools/MySQL-AIops@f2a7631ab04ca602323d2ea1e3c20efa10f2d1a6 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/AIops-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2a7631ab04ca602323d2ea1e3c20efa10f2d1a6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mysql_aiops-0.2.1-py3-none-any.whl.
File metadata
- Download URL: mysql_aiops-0.2.1-py3-none-any.whl
- Upload date:
- Size: 108.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c266277daaee3e2a82b231a9335d9cba3a36f116851d58f3801a98ffa4082455
|
|
| MD5 |
309b92dc0cc950e327b5dd88a444a0a6
|
|
| BLAKE2b-256 |
26ba2540720e1346f1cb9e0b1008593674955bd12945f9f9a4889c3a1ceee5a9
|
Provenance
The following attestation bundles were made for mysql_aiops-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on AIops-tools/MySQL-AIops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mysql_aiops-0.2.1-py3-none-any.whl -
Subject digest:
c266277daaee3e2a82b231a9335d9cba3a36f116851d58f3801a98ffa4082455 - Sigstore transparency entry: 2200486051
- Sigstore integration time:
-
Permalink:
AIops-tools/MySQL-AIops@f2a7631ab04ca602323d2ea1e3c20efa10f2d1a6 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/AIops-tools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f2a7631ab04ca602323d2ea1e3c20efa10f2d1a6 -
Trigger Event:
release
-
Statement type: