DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your MySQL Database with Vigilmon

How to Monitor Your MySQL Database with Vigilmon

MySQL is the world's most widely deployed open-source relational database. It powers WordPress, Shopify, Joomla, countless SaaS backends, and millions of production systems. And because it's so foundational, MySQL downtime is catastrophic — broken queries, failed logins, and app crashes that take your entire service with them.

This guide shows you how to monitor MySQL effectively with Vigilmon — from HTTP health endpoints to connection pool saturation and replication lag.


Why MySQL Needs Dedicated Monitoring

MySQL fails in predictable patterns that generic uptime monitors miss:

  • Too many connections — MySQL's max_connections limit causes ERROR 1040: Too many connections under load spikes
  • Replication lag — replica falls behind the primary; reads return stale data silently
  • Slow query accumulation — slow queries pile up, blocking faster queries behind them
  • InnoDB buffer pool pressure — disk I/O spikes when hot data doesn't fit in RAM
  • Disk full — MySQL stops accepting writes with no warning

You need both liveness monitoring (is MySQL responding?) and health monitoring (is MySQL responding correctly?).


Step 1: Create a MySQL Health Check Endpoint

The cleanest solution: expose a lightweight HTTP endpoint in your application that runs a simple MySQL query and returns 200 OK or 503.

Node.js (Express) example:

const mysql = require('mysql2/promise');
const express = require('express');
const app = express();

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  connectionLimit: 5
});

app.get('/health/db', async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT 1 AS ok');
    res.json({ status: 'ok', db: 'mysql', result: rows[0].ok });
  } catch (err) {
    res.status(503).json({ status: 'error', message: err.message });
  }
});

app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

Python (FastAPI) example:

from fastapi import FastAPI, Response
import aiomysql
import asyncio

app = FastAPI()

async def get_db():
    return await aiomysql.connect(
        host='localhost', user='root',
        password='secret', db='myapp'
    )

@app.get("/health/db")
async def health_db():
    try:
        conn = await get_db()
        async with conn.cursor() as cur:
            await cur.execute("SELECT 1")
            await conn.ensure_closed()
        return {"status": "ok", "db": "mysql"}
    except Exception as e:
        return Response(content=str(e), status_code=503)
Enter fullscreen mode Exit fullscreen mode

Step 2: Add an HTTP Monitor in Vigilmon

  1. Log in to vigilmon.online and click Add Monitor
  2. Type: HTTP(S)
  3. URL: https://your-app.com/health/db
  4. Interval: 60 seconds
  5. Alert condition: Status code is not 200, or response time > 2000ms
  6. Enable email or Slack alerts

Vigilmon checks from multiple global regions simultaneously. If your MySQL connection pool exhausts in US-East but not EU, you'll know exactly where the failure originated.


Step 3: Monitor MySQL Replication Lag

If you run MySQL replicas (read slaves), replication lag is a silent killer. Your application reads stale data without any visible error.

Add this to your health endpoint for replica instances:

@app.get("/health/replica")
async def health_replica():
    try:
        conn = await get_db()
        async with conn.cursor() as cur:
            await cur.execute("SHOW SLAVE STATUS")
            result = await cur.fetchone()
            if result is None:
                return Response(content="Not a replica", status_code=200)

            lag = result[32]  # Seconds_Behind_Master
            if lag is None or lag > 30:
                return Response(
                    content=f"Replica lag: {lag}s",
                    status_code=503
                )
        return {"status": "ok", "replication_lag_seconds": lag}
    except Exception as e:
        return Response(content=str(e), status_code=503)
Enter fullscreen mode Exit fullscreen mode

Now add a second Vigilmon monitor pointing to /health/replica with an alert threshold if it returns 503 (lag > 30 seconds).


Step 4: Connection Pool Saturation Check

MySQL's max_connections is frequently hit by apps during traffic spikes. Add a check:

SELECT 
    (SELECT COUNT(*) FROM information_schema.PROCESSLIST) AS current_connections,
    @@max_connections AS max_connections,
    ROUND(
        (SELECT COUNT(*) FROM information_schema.PROCESSLIST) / @@max_connections * 100, 1
    ) AS pct_used;
Enter fullscreen mode Exit fullscreen mode

Return 503 if connection pool utilization exceeds 80%:

app.get('/health/connections', async (req, res) => {
  const [[row]] = await pool.query(`
    SELECT 
      (SELECT COUNT(*) FROM information_schema.PROCESSLIST) AS curr,
      @@max_connections AS max_conn
  `);
  const pct = (row.curr / row.max_conn) * 100;
  if (pct > 80) {
    return res.status(503).json({ status: 'saturated', pct_used: pct });
  }
  res.json({ status: 'ok', pct_used: pct });
});
Enter fullscreen mode Exit fullscreen mode

MySQL Monitoring Coverage Table

Monitor Type Endpoint Alerts On
HTTP(S) /health/db DB unreachable or slow
HTTP(S) /health/replica Replication lag > 30s
HTTP(S) /health/connections Pool > 80% utilized
SSL Certificate yourdomain.com Cert expiry < 14 days

Common MySQL Failure Patterns Vigilmon Catches

Connection pool exhaustion: A Black Friday traffic spike exhausted max_connections=100 in 30 seconds. The health check fired before the 500 errors hit users.

Replication lag spike: A large batch DELETE on the primary caused the replica to fall 90 seconds behind. Reads served stale order data for 2 minutes — the replica monitor caught it at 31 seconds lag.

Disk full at 3 AM: MySQL stopped accepting INSERT statements when the data disk hit 100%. The DB health endpoint returned 503; Vigilmon paged the on-call within 90 seconds.


Conclusion

MySQL monitoring needs more than a simple ping. With Vigilmon's multi-region HTTP monitoring and custom health endpoints, you get real-time alerts for the failure modes that actually matter: connection exhaustion, replication lag, and disk pressure.

Start monitoring your MySQL database free at vigilmon.online

Top comments (0)