Backup all MySQL databases on a Linux server

Backup de todos os bancos de dados mysql em servidor linux

Backup All MySQL Databases on Linux Server

What you will need:

  • Access to the server’s Linux shell with root (or sudo) user privileges.
  • MySQL root user password.

Process description:

This process backup all MySQL databases available on the server. For each database, an individual backup is generated in SQL format. Each file is then compressed (.gz), using the database name followed by the execution date as the file name (e.g., mydatabase_2025-06-27.gz). This facilitates organization, specific recovery, and versioning of backups.

Creating the shell file for backup

Create a file in the Linux shell:

nano backup_mysql.sh

Paste the following content into this file:

#!/bin/bash

# Script de backup MySQL para usuário root
# Configurações do MySQL
MYSQL_USER="root"
MYSQL_PASSWORD="sua_senha_root_segura_do_mysql"
MYSQL_HOST="localhost"
MYSQL_PORT="3306"

# Diretório onde os backups serão salvos
BACKUP_DIR="/backup/mysql"
DATE=$(date +"%Y%m%d_%H%M%S")

# Verificar se está sendo executado como root
if [ "$EUID" -ne 0 ]; then
    echo "Este script deve ser executado como root (sudo)."
    echo "Use: sudo ./backup_mysql.sh"
    exit 1
fi

# Criar diretório de backup se não existir
mkdir -p "$BACKUP_DIR"

# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}=== Backup MySQL - Usuário Root ===${NC}"
echo "Data/Hora: $(date)"
echo "Usuário: root"
echo "Host: $MYSQL_HOST"
echo "Diretório de backup: $BACKUP_DIR"
echo ""

# Tentar várias formas de autenticação para root
echo "Tentando conectar como root..."

# Método 1: Sem senha (auth_socket)
mysql -u root -e "SELECT 1;" &>/dev/null
if [ $? -eq 0 ]; then
    echo -e "${GREEN}✓ Conectado usando auth_socket (sem senha)${NC}"
    AUTH_METHOD="no_password"
else
    # Método 2: Com senha
    if [ -z "$MYSQL_PASSWORD" ]; then
        echo -n "Digite a senha do MySQL root: "
        read -s MYSQL_PASSWORD
        echo ""
    fi
    
    mysql -u root -p"$MYSQL_PASSWORD" -e "SELECT 1;" &>/dev/null
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}✓ Conectado usando senha${NC}"
        AUTH_METHOD="with_password"
    else
        echo -e "${RED}Erro: Não foi possível conectar ao MySQL como root.${NC}"
        echo "Verifique se:"
        echo "1. O MySQL está rodando"
        echo "2. A senha está correta"
        echo "3. O usuário root tem permissões adequadas"
        exit 1
    fi
fi

echo ""

# Função para executar comandos MySQL baseado no método de autenticação
execute_mysql() {
    if [ "$AUTH_METHOD" = "no_password" ]; then
        mysql -u root "$@"
    else
        mysql -u root -p"$MYSQL_PASSWORD" "$@"
    fi
}

# Função para executar mysqldump baseado no método de autenticação
execute_mysqldump() {
    if [ "$AUTH_METHOD" = "no_password" ]; then
        mysqldump -u root "$@"
    else
        mysqldump -u root -p"$MYSQL_PASSWORD" "$@"
    fi
}

# Obter lista de todos os bancos de dados (excluindo system databases)
echo "Buscando bancos de dados..."
DATABASES=$(execute_mysql -e "SHOW DATABASES;" | grep -v -E "^(Database|information_schema|performance_schema|mysql|sys)$")

if [ -z "$DATABASES" ]; then
    echo -e "${YELLOW}Nenhum banco de dados de usuário encontrado para backup.${NC}"
    exit 0
fi

echo -e "${GREEN}Bancos de dados encontrados:${NC}"
for db in $DATABASES; do
    echo "  - $db"
done
echo ""

# Contador para estatísticas
TOTAL_DATABASES=$(echo "$DATABASES" | wc -l)
SUCCESS_COUNT=0
ERROR_COUNT=0

# Fazer backup de cada banco de dados
for DATABASE in $DATABASES; do
    echo -e "${YELLOW}Fazendo backup do banco: $DATABASE${NC}"
    
    # Nome do arquivo de backup
    BACKUP_FILE="$BACKUP_DIR/${DATABASE}_${DATE}.sql"
    
    # Executar mysqldump com opções otimizadas para root
    execute_mysqldump \
        --single-transaction \
        --routines \
        --triggers \
        --events \
        --hex-blob \
        --add-drop-database \
        --complete-insert \
        --disable-keys \
        --extended-insert \
        --quick \
        --lock-tables=false \
        --databases "$DATABASE" > "$BACKUP_FILE" 2>/dev/null
    
    # Verificar se o backup foi bem-sucedido
    if [ $? -eq 0 ] && [ -s "$BACKUP_FILE" ]; then
        FILE_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
        echo -e "${GREEN}  ✓ Dump criado: $FILE_SIZE${NC}"
        
        # Comprimir o arquivo
        echo "  Comprimindo arquivo..."
        gzip "$BACKUP_FILE"
        
        if [ $? -eq 0 ]; then
            COMPRESSED_SIZE=$(du -h "${BACKUP_FILE}.gz" | cut -f1)
            echo -e "${GREEN}  ✓ Comprimido: $COMPRESSED_SIZE${NC}"
            ((SUCCESS_COUNT++))
        else
            echo -e "${RED}  ✗ Erro na compressão${NC}"
            ((ERROR_COUNT++))
        fi
    else
        echo -e "${RED}  ✗ Erro no backup do banco: $DATABASE${NC}"
        ((ERROR_COUNT++))
        # Remover arquivo vazio ou corrompido
        [ -f "$BACKUP_FILE" ] && rm "$BACKUP_FILE"
    fi
    echo ""
done

# Definir permissões adequadas para os arquivos de backup
echo "Definindo permissões dos arquivos..."
chown root:root "$BACKUP_DIR"/*.gz 2>/dev/null
chmod 600 "$BACKUP_DIR"/*.gz 2>/dev/null

# Relatório final
echo -e "${BLUE}=== Relatório Final ===${NC}"
echo "Total de bancos processados: $TOTAL_DATABASES"
echo -e "${GREEN}Backups bem-sucedidos: $SUCCESS_COUNT${NC}"
if [ $ERROR_COUNT -gt 0 ]; then
    echo -e "${RED}Erros encontrados: $ERROR_COUNT${NC}"
fi
echo ""

# Mostrar espaço em disco usado
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" 2>/dev/null | cut -f1)
echo "Espaço total usado: $TOTAL_SIZE"
echo "Arquivos salvos em: $BACKUP_DIR"
echo ""

# Listar arquivos criados
echo -e "${GREEN}Arquivos de backup criados hoje:${NC}"
ls -lah "$BACKUP_DIR"/*_${DATE}.sql.gz 2>/dev/null | while read line; do
    echo "  $line"
done

# Limpeza de backups antigos (manter apenas os últimos 7 dias)
echo ""
echo -e "${YELLOW}Limpando backups antigos (mais de 7 dias)...${NC}"
DELETED_FILES=$(find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -print)
if [ -n "$DELETED_FILES" ]; then
    echo "Arquivos removidos:"
    echo "$DELETED_FILES" | while read file; do
        echo "  - $(basename "$file")"
    done
    find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
else
    echo "Nenhum arquivo antigo encontrado para remoção."
fi

# Verificar espaço em disco
echo ""
echo -e "${BLUE}Status do sistema:${NC}"
echo "Espaço livre em disco:"
df -h "$BACKUP_DIR" | tail -1 | awk '{print "  Usado: " $3 " | Disponível: " $4 " | Uso: " $5}'

echo ""
echo -e "${GREEN}Backup finalizado com sucesso!${NC}"
echo "Finalizado em: $(date)"

# Log do backup
LOG_FILE="$BACKUP_DIR/backup_$(date +%Y%m).log"
echo "$(date): Backup realizado - $SUCCESS_COUNT sucessos, $ERROR_COUNT erros" >> "$LOG_FILE"

save the file and exit nano (ctrl+x, y, enter)

Edit the file you created and change the line below with the mysql root password:

MYSQL_PASSWORD="sua_senha_root_segura_do_mysql"

save the file and exit nano (ctrl+x, y, enter)

Change the file permissions:

chmod +x backup_mysql.sh

By default, the backup will be created in /backup/mysql. If you wish, you can change the location to save the file by editing the created file and changing BACKUP_DIR=”/backup/mysql”.

Running the backup:

Run the file and wait for the process to complete:

./backup_mysql.sh

This is a simple but very useful script for backing up all MySQL databases on a Linux server.