Apague vários bancos MySQL ou MariaDB de uma vez sem susto: liste pelo prefixo, faça backup de cada um, confirme e só então rode o DROP DATABASE.
O DROP DATABASE não tem lixeira nem "desfazer": o banco some na hora, com todas as tabelas. Scripts que circulam na internet fazem um laço que apaga tudo o que começa com um nome, sem mostrar a lista, sem backup e com a senha do root escrita no próprio arquivo. Abaixo está um jeito seguro de fazer a mesma limpeza.
Antes de começar
- Acesso root ao banco sem digitar senha na linha de comando. No Ubuntu e no Debian, rodando como root,
mysqlentra pelo socket. Em servidor cPanel, o root já tem o arquivo/root/.my.cnf. Senha passada com-p'senha'fica visível na lista de processos e no histórico do shell. - Espaço em disco para os backups. Veja o tamanho dos bancos antes (consulta no passo 1) e o espaço livre com
df -h /root. - Sistemas desligados. Confirme que nenhum site ou serviço ainda usa os bancos que você vai apagar.
Passo 1: liste os bancos pelo prefixo
Primeiro só olhe. Este comando mostra os bancos que começam com teste_ e o tamanho de cada um:
mysql -e "SELECT table_schema AS banco,
ROUND(SUM(data_length + index_length)/1024/1024, 1) AS mb
FROM information_schema.tables
WHERE table_schema LIKE 'teste\_%'
GROUP BY table_schema ORDER BY table_schema;"
LIKE, o _ significa "qualquer caractere". Sem a barra, 'teste_%' também pega testes2024 e testeloja. Por isso o padrão leva \_. Bancos vazios (sem tabelas) não aparecem nesta consulta; o script abaixo usa outra que mostra todos.Passo 2: use um script com backup e confirmação
Salve o conteúdo abaixo em /root/apagar-bancos.sh. Ele recusa prefixos curtos ou com caracteres estranhos, ignora os bancos do sistema, faz um backup compactado de cada banco e só apaga depois que você digitar APAGAR.
#!/bin/bash
# apagar-bancos.sh - apaga bancos por prefixo, com backup e confirmação
# Uso: ./apagar-bancos.sh teste_
set -euo pipefail
PREFIXO="${1:-}"
MYSQL="mysql" # no MariaDB 11 você pode usar: mariadb
DUMP="mysqldump" # no MariaDB 11 você pode usar: mariadb-dump
DESTINO="/root/backup-bancos/$(date +%Y%m%d-%H%M%S)"
if [[ ! "$PREFIXO" =~ ^[[:alnum:]_]{3,}$ ]]; then
echo "Informe um prefixo com 3 ou mais letras, números ou _ (ex.: teste_)"
exit 1
fi
# No LIKE o _ vale "qualquer caractere"; a barra faz ele valer só o _
PADRAO="$(printf '%s' "$PREFIXO" | sed 's/_/\\_/g')%"
BANCOS=()
while IFS= read -r b; do
BANCOS+=("$b")
done < <($MYSQL -NBe "SELECT schema_name FROM information_schema.schemata
WHERE schema_name LIKE '$PADRAO'
AND schema_name NOT IN ('mysql','information_schema','performance_schema','sys')
ORDER BY schema_name")
if [ ${#BANCOS[@]} -eq 0 ]; then
echo "Nenhum banco começa com '$PREFIXO'. Nada a fazer."
exit 0
fi
echo "Bancos encontrados (${#BANCOS[@]}):"
for b in "${BANCOS[@]}"; do
if [[ ! "$b" =~ ^[[:alnum:]_-]+$ ]]; then
echo "Nome fora do padrão: $b. Apague esse manualmente."
exit 1
fi
echo " $b"
done
mkdir -p "$DESTINO" && chmod 700 "$DESTINO"
for b in "${BANCOS[@]}"; do
echo "Backup de $b..."
$DUMP --single-transaction --routines --events --triggers \
--databases "$b" | gzip > "$DESTINO/$b.sql.gz"
done
echo "Backups gravados em $DESTINO"
read -r -p "Para apagar esses ${#BANCOS[@]} bancos, digite APAGAR: " RESPOSTA
if [ "$RESPOSTA" != "APAGAR" ]; then
echo "Cancelado. Nenhum banco foi apagado."
exit 0
fi
for b in "${BANCOS[@]}"; do
echo "Apagando $b"
$MYSQL -e "DROP DATABASE \`$b\`"
done
echo "Concluído. Os backups continuam em $DESTINO"
Dê permissão e rode informando o prefixo:
chmod 700 /root/apagar-bancos.sh
/root/apagar-bancos.sh teste_
O script mostra a lista, grava os backups em /root/backup-bancos/DATA-HORA/ e pergunta antes de apagar. Qualquer resposta diferente de APAGAR cancela sem tocar em nada. Se um backup falhar, o script para antes de apagar qualquer banco.
mysqldump de cada um e depois um único comando: mysql -e 'DROP DATABASE teste_a; DROP DATABASE teste_b;'. Revise a linha duas vezes antes do Enter.Como restaurar um banco apagado pelo script
Como o backup foi feito com --databases, o arquivo já recria o banco com o nome original:
zcat /root/backup-bancos/20261006-153000/teste_a.sql.gz | mysql
Guarde a pasta de backups por alguns dias e só então apague.
Em servidor cPanel: apague pelo painel ou pela API
O cPanel mantém um registro de quais bancos e usuários pertencem a cada conta. Um DROP DATABASE feito direto no terminal deixa esse registro desatualizado. Use uma destas opções:
- Pelo cPanel da conta: em Bancos de dados MySQL (Manage My Databases), clique em Excluir ao lado de cada banco.
- Pelo WHM, como root: SQL Services » Manage Databases.
- Em lote, pela UAPI, depois de fazer o backup de cada um com
mysqldump:
for db in conta_teste1 conta_teste2 conta_teste3; do
uapi --output=jsonpretty --user=conta Mysql delete_database name="$db"
done
Troque conta pelo usuário cPanel dono dos bancos. Na saída, "status": 1 indica que deu certo.
Problemas comuns
ERROR 1010: Error dropping database (can't rmdir './banco', errno: 39)
Sobrou algum arquivo que não pertence ao banco dentro da pasta dele no diretório de dados (normalmente /var/lib/mysql/banco), por exemplo um backup antigo copiado para lá. Liste a pasta, mova o arquivo estranho para outro lugar e rode o DROP DATABASE de novo.
ERROR 1044 ou 1045: Access denied
Você não está como root do banco, ou o root exige senha. Em servidor comum, rode o script com sudo. Se o root usa senha, crie um /root/.my.cnf com permissão 600 contendo [client], user=root e password=....
mysqldump: command not found
Em instalações novas do MariaDB 11, os comandos com nome mysql* podem não existir. Troque no início do script MYSQL="mariadb" e DUMP="mariadb-dump".
Apaguei o banco errado e não tenho o backup do script
Restaure do backup do servidor (JetBackup, snapshot do VPS ou o backup que você usa). Se não houver nenhum, não grave nada no disco e peça ajuda ao suporte o quanto antes; quanto mais escrita depois do erro, menor a chance de recuperação.