Set up automated monitoring for MySQL backups with Prometheus metrics collection, alerting rules for backup failures, and comprehensive Grafana dashboards for backup status visualization.
Prerequisites
- MySQL 8.0 or later installed
- Root or sudo access
- At least 4GB RAM
- 10GB free disk space
What this solves
Database backup monitoring ensures your MySQL backups run successfully and alerts you immediately when they fail. This tutorial sets up automated monitoring using Prometheus to collect backup metrics, configures alerting rules for backup failures, and creates Grafana dashboards for visual tracking of backup status, timing, and storage usage.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions of all components.
sudo apt update && sudo apt upgrade -y
Install MySQL backup tools
Install mysqldump and Percona XtraBackup for creating reliable MySQL backups with consistent snapshots.
sudo apt install -y mysql-client-core-8.0 curl gnupg2
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt update
sudo apt install -y percona-xtrabackup-80
Create MySQL backup user
Create a dedicated MySQL user with minimal privileges required for backup operations.
mysql -u root -p
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'SecureBackupPassword123!';
GRANT SELECT, LOCK TABLES, SHOW VIEW, PROCESS, REPLICATION CLIENT ON . TO 'backup_user'@'localhost';
GRANT RELOAD ON . TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Create backup directory structure
Set up organized directories for storing backups and monitoring scripts with proper permissions.
sudo mkdir -p /var/backups/mysql/{daily,weekly,monthly}
sudo mkdir -p /opt/backup-monitoring
sudo chown mysql:mysql /var/backups/mysql
sudo chmod 750 /var/backups/mysql
Create backup monitoring script
Create a script that performs backups while collecting metrics for Prometheus monitoring.
#!/bin/bash
METRICS_FILE="/var/lib/node_exporter/textfile_collector/mysql_backup.prom"
BACKUP_DIR="/var/backups/mysql/daily"
LOG_FILE="/var/log/mysql-backup.log"
DB_USER="backup_user"
DB_PASS="SecureBackupPassword123!"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="mysql_backup_${DATE}.sql.gz"
Initialize metrics
echo "# HELP mysql_backup_duration_seconds Time taken for MySQL backup in seconds" > $METRICS_FILE
echo "# TYPE mysql_backup_duration_seconds gauge" >> $METRICS_FILE
echo "# HELP mysql_backup_size_bytes Size of MySQL backup file in bytes" >> $METRICS_FILE
echo "# TYPE mysql_backup_size_bytes gauge" >> $METRICS_FILE
echo "# HELP mysql_backup_success Backup success status (1=success, 0=failure)" >> $METRICS_FILE
echo "# TYPE mysql_backup_success gauge" >> $METRICS_FILE
echo "# HELP mysql_backup_timestamp_seconds Timestamp of last backup" >> $METRICS_FILE
echo "# TYPE mysql_backup_timestamp_seconds gauge" >> $METRICS_FILE
Start backup process
START_TIME=$(date +%s)
echo "$(date): Starting MySQL backup" >> $LOG_FILE
Perform backup
if mysqldump -u $DB_USER -p$DB_PASS --single-transaction --routines --triggers --all-databases | gzip > "${BACKUP_DIR}/${BACKUP_NAME}"; then
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
BACKUP_SIZE=$(stat -c%s "${BACKUP_DIR}/${BACKUP_NAME}")
echo "$(date): Backup completed successfully. Size: ${BACKUP_SIZE} bytes, Duration: ${DURATION}s" >> $LOG_FILE
# Update metrics
echo "mysql_backup_duration_seconds $DURATION" >> $METRICS_FILE
echo "mysql_backup_size_bytes $BACKUP_SIZE" >> $METRICS_FILE
echo "mysql_backup_success 1" >> $METRICS_FILE
echo "mysql_backup_timestamp_seconds $END_TIME" >> $METRICS_FILE
# Cleanup old backups (keep 7 days)
find $BACKUP_DIR -name "mysql_backup_*.sql.gz" -mtime +7 -delete
exit 0
else
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo "$(date): Backup failed" >> $LOG_FILE
# Update failure metrics
echo "mysql_backup_duration_seconds $DURATION" >> $METRICS_FILE
echo "mysql_backup_size_bytes 0" >> $METRICS_FILE
echo "mysql_backup_success 0" >> $METRICS_FILE
echo "mysql_backup_timestamp_seconds $END_TIME" >> $METRICS_FILE
exit 1
fi
sudo chmod +x /opt/backup-monitoring/mysql-backup-monitor.sh
sudo chown mysql:mysql /opt/backup-monitoring/mysql-backup-monitor.sh
Install and configure Node Exporter
Install Node Exporter to collect system metrics and expose the backup metrics to Prometheus.
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xvfz node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo mkdir -p /var/lib/node_exporter/textfile_collector
sudo chown node_exporter:node_exporter /var/lib/node_exporter/textfile_collector
Create Node Exporter systemd service
Configure Node Exporter as a systemd service with textfile collector enabled for backup metrics.
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile_collector
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter
Install and configure Prometheus
Install Prometheus to scrape metrics from Node Exporter and monitor backup status.
sudo apt install -y prometheus
Configure Prometheus scraping
Configure Prometheus to scrape Node Exporter metrics including the MySQL backup metrics.
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "/etc/prometheus/mysql_backup_rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
scrape_interval: 30s
metrics_path: /metrics
Create MySQL backup alerting rules
Define Prometheus alerting rules to detect backup failures and long-running backups.
groups:
- name: mysql_backup_alerts
rules:
- alert: MySQLBackupFailed
expr: mysql_backup_success == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MySQL backup failed"
description: "MySQL backup has failed. Last backup status: {{ $value }}"
- alert: MySQLBackupTooOld
expr: (time() - mysql_backup_timestamp_seconds) > 86400
for: 5m
labels:
severity: warning
annotations:
summary: "MySQL backup is too old"
description: "MySQL backup is older than 24 hours. Last backup was {{ $value | humanizeDuration }} ago."
- alert: MySQLBackupTooLong
expr: mysql_backup_duration_seconds > 3600
for: 1m
labels:
severity: warning
annotations:
summary: "MySQL backup taking too long"
description: "MySQL backup took {{ $value | humanizeDuration }} to complete, which is longer than expected."
- alert: MySQLBackupSizeUnusual
expr: mysql_backup_size_bytes < (mysql_backup_size_bytes offset 1d) * 0.5 and mysql_backup_size_bytes > 0
for: 5m
labels:
severity: warning
annotations:
summary: "MySQL backup size significantly smaller than previous day"
description: "Current backup size is {{ $value | humanizeBytes }}, which is less than 50% of yesterday's backup size."
sudo chown prometheus:prometheus /etc/prometheus/mysql_backup_rules.yml
Install and configure Alertmanager
Install Alertmanager to handle alert notifications from Prometheus rules.
sudo apt install -y prometheus-alertmanager
Configure Alertmanager notifications
Set up Alertmanager to send email notifications for backup alerts. For more advanced notifications, check out our Alertmanager webhook integration tutorial.
global:
smtp_smarthost: 'localhost:587'
smtp_from: 'alerts@example.com'
smtp_auth_username: 'alerts@example.com'
smtp_auth_password: 'your_smtp_password'
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'mysql-backup-team'
receivers:
- name: 'mysql-backup-team'
email_configs:
- to: 'dba-team@example.com'
subject: 'MySQL Backup Alert: {{ .GroupLabels.alertname }}'
body: |
{{ range .Alerts }}
Alert: {{ .Annotations.summary }}
Description: {{ .Annotations.description }}
Severity: {{ .Labels.severity }}
Time: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ end }}
sudo chown alertmanager:alertmanager /etc/alertmanager/alertmanager.yml
Start Prometheus and Alertmanager
Enable and start both Prometheus and Alertmanager services.
sudo systemctl enable --now prometheus
sudo systemctl enable --now alertmanager
sudo systemctl status prometheus
sudo systemctl status alertmanager
Install and configure Grafana
Install Grafana for creating visual dashboards to monitor backup metrics and trends.
sudo apt install -y software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana
Configure Grafana data source
Add Prometheus as a data source in Grafana and start the service.
sudo systemctl enable --now grafana-server
sudo systemctl status grafana-server
Create backup monitoring dashboard
Create a comprehensive Grafana dashboard for MySQL backup monitoring. Navigate to Grafana, add Prometheus as a data source (http://localhost:9090), then import this dashboard configuration.
{
"dashboard": {
"id": null,
"title": "MySQL Backup Monitoring",
"tags": ["mysql", "backup", "monitoring"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Backup Success Rate (24h)",
"type": "stat",
"targets": [{
"expr": "mysql_backup_success",
"legendFormat": "Success"
}],
"fieldConfig": {
"defaults": {
"thresholds": {
"steps": [
{"color": "red", "value": 0},
{"color": "green", "value": 1}
]
}
}
},
"gridPos": {"h": 8, "w": 6, "x": 0, "y": 0}
},
{
"id": 2,
"title": "Last Backup Size",
"type": "stat",
"targets": [{
"expr": "mysql_backup_size_bytes",
"legendFormat": "Size"
}],
"fieldConfig": {
"defaults": {
"unit": "bytes"
}
},
"gridPos": {"h": 8, "w": 6, "x": 6, "y": 0}
},
{
"id": 3,
"title": "Backup Duration",
"type": "stat",
"targets": [{
"expr": "mysql_backup_duration_seconds",
"legendFormat": "Duration"
}],
"fieldConfig": {
"defaults": {
"unit": "s"
}
},
"gridPos": {"h": 8, "w": 6, "x": 12, "y": 0}
},
{
"id": 4,
"title": "Time Since Last Backup",
"type": "stat",
"targets": [{
"expr": "time() - mysql_backup_timestamp_seconds",
"legendFormat": "Age"
}],
"fieldConfig": {
"defaults": {
"unit": "s"
}
},
"gridPos": {"h": 8, "w": 6, "x": 18, "y": 0}
},
{
"id": 5,
"title": "Backup Size Trend (7 days)",
"type": "graph",
"targets": [{
"expr": "mysql_backup_size_bytes",
"legendFormat": "Backup Size"
}],
"yAxes": [{
"unit": "bytes"
}],
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}
},
{
"id": 6,
"title": "Backup Duration Trend (7 days)",
"type": "graph",
"targets": [{
"expr": "mysql_backup_duration_seconds",
"legendFormat": "Duration"
}],
"yAxes": [{
"unit": "s"
}],
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}
}
],
"time": {
"from": "now-7d",
"to": "now"
},
"refresh": "30s"
}
}
Schedule backup automation
Set up a cron job to run backups daily and ensure consistent monitoring data collection.
sudo crontab -u mysql -e
# Run MySQL backup daily at 2 AM
0 2 * /opt/backup-monitoring/mysql-backup-monitor.sh >> /var/log/mysql-backup.log 2>&1
Run weekly backup on Sundays at 1 AM
0 1 0 /opt/backup-monitoring/mysql-backup-monitor.sh >> /var/log/mysql-backup.log 2>&1
Configure firewall access
Open required ports
Configure firewall rules to allow access to monitoring services.
sudo ufw allow 9090/tcp comment 'Prometheus'
sudo ufw allow 9093/tcp comment 'Alertmanager'
sudo ufw allow 3000/tcp comment 'Grafana'
sudo ufw allow 9100/tcp comment 'Node Exporter'
sudo ufw reload
Verify your setup
Test the complete backup monitoring pipeline to ensure all components work together correctly.
# Test backup script manually
sudo -u mysql /opt/backup-monitoring/mysql-backup-monitor.sh
Check metrics file
cat /var/lib/node_exporter/textfile_collector/mysql_backup.prom
Verify Prometheus is scraping metrics
curl http://localhost:9090/api/v1/query?query=mysql_backup_success
Check service statuses
sudo systemctl status prometheus
sudo systemctl status alertmanager
sudo systemctl status grafana-server
sudo systemctl status node_exporter
View backup logs
tail -f /var/log/mysql-backup.log
Access your monitoring services:
- Prometheus: http://your-server-ip:9090
- Alertmanager: http://your-server-ip:9093
- Grafana: http://your-server-ip:3000
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Backup script fails with permission denied | Incorrect file ownership or permissions | sudo chown mysql:mysql /opt/backup-monitoring/mysql-backup-monitor.sh && sudo chmod +x /opt/backup-monitoring/mysql-backup-monitor.sh |
| Metrics not appearing in Prometheus | Node Exporter not configured with textfile collector | Check Node Exporter service: sudo systemctl restart node_exporter |
| Alerts not triggering | Alertmanager not connected to Prometheus | Verify /etc/prometheus/prometheus.yml alertmanagers configuration |
| Grafana shows no data | Prometheus data source not configured | Add Prometheus data source: http://localhost:9090 |
| Backup user authentication fails | MySQL user privileges insufficient | Re-run MySQL user creation commands with proper grants |
| Large backup files consume disk space | No cleanup policy configured | Backup script includes cleanup: find $BACKUP_DIR -name "mysql_backup_*.sql.gz" -mtime +7 -delete |
Next steps
- Set up MySQL point-in-time recovery with binary logs for comprehensive disaster recovery
- Configure Prometheus Alertmanager with custom webhook integrations for Slack and Teams notifications
- Configure backup monitoring with Prometheus and Grafana for other database systems
- Set up MySQL backup encryption with GPG for enhanced security
- Configure MySQL backup replication to S3 for offsite storage
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Production MySQL Backup Monitoring Setup Script
# Configures Prometheus monitoring, Grafana dashboards, and automated MySQL backups
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Default values
MYSQL_ROOT_PASSWORD=""
BACKUP_PASSWORD="SecureBackupPassword123!"
# Usage function
usage() {
echo "Usage: $0 [--mysql-root-password PASSWORD] [--backup-password PASSWORD]"
echo " --mysql-root-password: MySQL root password (will prompt if not provided)"
echo " --backup-password: Password for backup user (default: SecureBackupPassword123!)"
exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--mysql-root-password)
MYSQL_ROOT_PASSWORD="$2"
shift 2
;;
--backup-password)
BACKUP_PASSWORD="$2"
shift 2
;;
--help|-h)
usage
;;
*)
echo -e "${RED}Error: Unknown argument $1${NC}"
usage
;;
esac
done
# Cleanup function for rollback
cleanup() {
echo -e "${YELLOW}Cleaning up on error...${NC}"
systemctl stop node_exporter 2>/dev/null || true
userdel backup_user 2>/dev/null || true
rm -f /etc/systemd/system/node_exporter.service
rm -rf /opt/backup-monitoring /var/backups/mysql
}
trap cleanup ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Error: This script must be run as root${NC}"
exit 1
fi
# Auto-detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
MYSQL_CLIENT="mysql-client-core-8.0"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
MYSQL_CLIENT="mysql"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
MYSQL_CLIENT="mysql"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
MYSQL_CLIENT="mysql"
;;
*)
echo -e "${RED}Error: Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Error: Cannot detect distribution${NC}"
exit 1
fi
echo -e "${GREEN}[1/8] Updating system packages...${NC}"
$PKG_UPDATE
echo -e "${GREEN}[2/8] Installing MySQL backup tools...${NC}"
$PKG_INSTALL $MYSQL_CLIENT curl gnupg2 wget
# Install Percona XtraBackup
if [[ "$PKG_MGR" == "apt" ]]; then
CODENAME=$(lsb_release -sc)
wget -q https://repo.percona.com/apt/percona-release_latest.${CODENAME}_all.deb
dpkg -i percona-release_latest.${CODENAME}_all.deb
apt update
$PKG_INSTALL percona-xtrabackup-80
rm -f percona-release_latest.${CODENAME}_all.deb
else
$PKG_INSTALL https://repo.percona.com/yum/percona-release-latest.noarch.rpm
percona-release enable-only tools release
$PKG_INSTALL percona-xtrabackup-80
fi
echo -e "${GREEN}[3/8] Installing Node Exporter...${NC}"
NODE_EXPORTER_VERSION="1.7.0"
wget -q https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xzf node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
cp node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter /usr/local/bin/
rm -rf node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64*
# Create node_exporter user
useradd --no-create-home --shell /bin/false node_exporter
mkdir -p /var/lib/node_exporter/textfile_collector
chown -R node_exporter:node_exporter /var/lib/node_exporter
chmod 755 /var/lib/node_exporter
chmod 755 /var/lib/node_exporter/textfile_collector
# Create systemd service
cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile_collector
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable node_exporter
systemctl start node_exporter
echo -e "${GREEN}[4/8] Creating backup directory structure...${NC}"
mkdir -p /var/backups/mysql/{daily,weekly,monthly}
mkdir -p /opt/backup-monitoring
mkdir -p /var/log
touch /var/log/mysql-backup.log
# Create mysql user if it doesn't exist
if ! id mysql >/dev/null 2>&1; then
useradd --system --home /var/lib/mysql --shell /bin/false mysql
fi
chown -R mysql:mysql /var/backups/mysql
chmod 750 /var/backups/mysql
chmod 750 /var/backups/mysql/{daily,weekly,monthly}
chmod 644 /var/log/mysql-backup.log
echo -e "${GREEN}[5/8] Creating MySQL backup user...${NC}"
if [[ -z "$MYSQL_ROOT_PASSWORD" ]]; then
echo -e "${YELLOW}Please enter MySQL root password:${NC}"
read -s MYSQL_ROOT_PASSWORD
fi
mysql -u root -p"$MYSQL_ROOT_PASSWORD" << EOF
CREATE USER IF NOT EXISTS 'backup_user'@'localhost' IDENTIFIED BY '$BACKUP_PASSWORD';
GRANT SELECT, LOCK TABLES, SHOW VIEW, PROCESS, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost';
GRANT RELOAD ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
EOF
echo -e "${GREEN}[6/8] Creating backup monitoring script...${NC}"
cat > /opt/backup-monitoring/mysql_backup.sh << EOF
#!/bin/bash
set -euo pipefail
METRICS_FILE="/var/lib/node_exporter/textfile_collector/mysql_backup.prom"
BACKUP_DIR="/var/backups/mysql/daily"
LOG_FILE="/var/log/mysql-backup.log"
DB_USER="backup_user"
DB_PASS="$BACKUP_PASSWORD"
DATE=\$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="mysql_backup_\${DATE}.sql.gz"
# Initialize metrics
{
echo "# HELP mysql_backup_duration_seconds Time taken for MySQL backup in seconds"
echo "# TYPE mysql_backup_duration_seconds gauge"
echo "# HELP mysql_backup_size_bytes Size of MySQL backup file in bytes"
echo "# TYPE mysql_backup_size_bytes gauge"
echo "# HELP mysql_backup_success Backup success status (1=success, 0=failure)"
echo "# TYPE mysql_backup_success gauge"
echo "# HELP mysql_backup_timestamp_seconds Timestamp of last backup"
echo "# TYPE mysql_backup_timestamp_seconds gauge"
} > \$METRICS_FILE
START_TIME=\$(date +%s)
echo "\$(date): Starting MySQL backup" >> \$LOG_FILE
if mysqldump -u \$DB_USER -p\$DB_PASS --single-transaction --routines --triggers --all-databases | gzip > "\${BACKUP_DIR}/\${BACKUP_NAME}"; then
END_TIME=\$(date +%s)
DURATION=\$((END_TIME - START_TIME))
BACKUP_SIZE=\$(stat -c%s "\${BACKUP_DIR}/\${BACKUP_NAME}")
echo "\$(date): Backup completed successfully. Size: \${BACKUP_SIZE} bytes, Duration: \${DURATION}s" >> \$LOG_FILE
{
echo "mysql_backup_duration_seconds \$DURATION"
echo "mysql_backup_size_bytes \$BACKUP_SIZE"
echo "mysql_backup_success 1"
echo "mysql_backup_timestamp_seconds \$END_TIME"
} >> \$METRICS_FILE
find \$BACKUP_DIR -name "mysql_backup_*.sql.gz" -mtime +7 -delete
exit 0
else
END_TIME=\$(date +%s)
DURATION=\$((END_TIME - START_TIME))
echo "\$(date): Backup failed after \${DURATION}s" >> \$LOG_FILE
{
echo "mysql_backup_duration_seconds \$DURATION"
echo "mysql_backup_size_bytes 0"
echo "mysql_backup_success 0"
echo "mysql_backup_timestamp_seconds \$END_TIME"
} >> \$METRICS_FILE
exit 1
fi
EOF
chmod 750 /opt/backup-monitoring/mysql_backup.sh
chown mysql:mysql /opt/backup-monitoring/mysql_backup.sh
echo -e "${GREEN}[7/8] Setting up cron job...${NC}"
echo "0 2 * * * mysql /opt/backup-monitoring/mysql_backup.sh" > /etc/cron.d/mysql-backup
chmod 644 /etc/cron.d/mysql-backup
echo -e "${GREEN}[8/8] Verifying installation...${NC}"
# Test backup script
sudo -u mysql /opt/backup-monitoring/mysql_backup.sh
# Verify services
if systemctl is-active --quiet node_exporter; then
echo -e "${GREEN}✓ Node Exporter is running${NC}"
else
echo -e "${RED}✗ Node Exporter failed to start${NC}"
exit 1
fi
# Verify metrics file
if [[ -f /var/lib/node_exporter/textfile_collector/mysql_backup.prom ]]; then
echo -e "${GREEN}✓ Backup metrics file created${NC}"
else
echo -e "${RED}✗ Backup metrics file not found${NC}"
exit 1
fi
# Verify backup file
if ls /var/backups/mysql/daily/mysql_backup_*.sql.gz 1> /dev/null 2>&1; then
echo -e "${GREEN}✓ MySQL backup completed successfully${NC}"
else
echo -e "${RED}✗ MySQL backup failed${NC}"
exit 1
fi
echo -e "${GREEN}Installation completed successfully!${NC}"
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Configure Prometheus to scrape Node Exporter on port 9100"
echo "2. Add alerting rules for mysql_backup_success metric"
echo "3. Import Grafana dashboard for backup monitoring"
echo "4. Backups are scheduled daily at 2 AM via cron"
Review the script before running. Execute with: bash install.sh