Quando o cPanel esconde componentes que existem fisicamente#
Como administrador de sistemas, frequentemente confio em camadas de abstração (como cPanel/WHM) para gerenciar complexidades. No entanto, o que acontece quando a "verdade" do motor (MySQL/MariaDB) diverge da "verdade" da interface? Recentemente, enfrentei um cenário onde 18 bancos de dados existiam fisicamente, mas apenas 16 eram renderizados no painel.
Neste post, faço um deep dive técnico sobre como o cPanel v134 gerencia metadados, por que as APIs podem falhar em ambientes com recursos limitados (1GB RAM) e como realizar uma cirurgia de dados via CLI.
1. A anatomia da verdade: as três camadas de abstração#
Para entender o erro, é preciso primeiro entender como o cPanel v134 (especialmente em arquiteturas CloudLinux 9.x) enxerga um banco de dados. Ele não executa um SHOW DATABASES em tempo real para o usuário; ele utiliza um sistema de três pilares:
- Engine Layer (A Realidade): O binário do MariaDB/MySQL e os arquivos físicos em
/var/lib/mysql. É aqui que o comandomysql -u root -e 'show databases;'obtém sua resposta através da syscallgetdents64no diretório de dados. - Metadata Layer (A Fonte da Verdade): Um arquivo JSON localizado em
/var/cpanel/databases/user.json. Este arquivo é o "cartório" do cPanel. Se o banco não estiver aqui, ele não pertence a ninguém. - Indexing Layer (A Performance): Um banco de dados SQLite global em
/var/cpanel/databases/dbindex.db. Este índice é alimentado pelo daemoncpanel-dbindexe é o que a UI do WHM/cPanel realmente consulta para renderizar tabelas de forma rápida.
2. Quando o índice entra em desprezo#
No caso analisado, os bancos user_prod_host_110 e user_prod_host_1102 estavam presentes na Engine Layer e parcialmente na Metadata Layer, mas eram ignorados pela Indexing Layer.
Por que a API falhou (unknown app error)?#
Ao tentar rodar whmapi1 set_autodetect_database_assignments, o sistema retornou: reason: Unknown app ("set_autodetect_database_assignments")
Rastreabilidade Técnica: Este erro não significa que a função não existe, mas sim que o despachante de API do cPanel (cpsrvd) falhou ao carregar o manifesto do módulo Perl Cpanel::Internal::API::Mysql.
- Causa provável: Em instâncias com 1GB de RAM, o kernel pode invocar o OOM Killer ou causar um soft-fault durante o
mmap()de bibliotecas compartilhadas do Perl, resultando em um carregamento parcial da árvore de funções na memória.
3. Diagnóstico de baixo nível#
Antes de corrigir, é preciso validar a integridade dos índices. O uso do sqlite3 revelou que a tabela databases estava ausente no dbindex.db.
# Verificando se o índice global está corrompido
sqlite3 /var/cpanel/databases/dbindex.db ".tables"
Se o retorno for vazio, o daemon cpanel-dbindex falhou ao inicializar o esquema. Isso acontece quando o SQLite tenta realizar um journal_mode=WAL e encontra contenção de I/O ou falta de espaço/inodes no diretório /var.
4. A solução: cirurgia de metadados via Python#
Quando a UAPI e o WHMAPI1 falham, a solução é intervir diretamente na Metadata Layer. O JSON do usuário estava estruturalmente correto, mas faltavam as chaves de visibilidade no nó principal "dbs".
O script de reconciliação#
Este script sincroniza a realidade do MySQL com o "cartório" do cPanel:
import json
import subprocess
# Caminho do metadado do usuário
user_json = "/var/cpanel/databases/user.json"
server_ip = "51.222.205.161" # IP do nó DB
# 1. Obter a lista real do motor SQL
cmd = "mysql -u root -e 'show databases;' | grep ^user_"
mysql_dbs = subprocess.check_output(cmd, shell=True).decode().split()
with open(user_json, "r") as f:
data = json.load(f)
# 2. Injeção de Visibilidade (Nó Master)
for db in mysql_dbs:
if db not in data["MYSQL"]["dbs"]:
data["MYSQL"]["dbs"][db] = server_ip
# 3. Injeção de Privilégios (Nó dbusers)
if "user" in data["MYSQL"]["dbusers"]:
for db in mysql_dbs:
if db not in data["MYSQL"]["dbusers"]["user"]["dbs"]:
data["MYSQL"]["dbusers"]["user"]["dbs"][db] = server_ip
with open(user_json, "w") as f:
json.dump(data, f)
5. Forçando o rebuild da indexação#
Injetar no JSON não é suficiente; é preciso "acordar" o kernel e os daemons do cPanel.
Comandos de sincronização L3:#
- Mapeamento de Inodes: O
setupdbmaptraduz as alterações do JSON para as permissões de sistema.
/usr/local/cpanel/bin/setupdbmap --user=user --db=mysql --update
- Reset do Daemon de Indexação: Na v134, o
cpanel-dbindexmantém um cache em memória. O restart força a leitura do novo JSON.
systemctl restart cpanel-dbindex
- Bypass de Cache do Usuário (CageFS): Em CloudLinux, o usuário opera em um sistema de arquivos virtualizado. Se não remontarmos, ele continuará vendo a versão antiga do JSON.
cagefsctl --update user
cagefsctl --remount user
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários