Tratamento de erros e logs no MySQL

MySQLBeginner
Pratique Agora

Introdução

Neste laboratório, você vai aprender técnicas fundamentais de tratamento de erros e geração de logs no MySQL. Gerenciar erros com eficiência é essencial para criar aplicações de banco de dados robustas e fáceis de manter, pois isso ajuda a diagnosticar problemas, entender a execução das consultas e garantir a integridade dos dados.

Primeiro, você vai ativar o log geral de consultas para registrar todas as instruções SQL enviadas ao servidor. Essa é uma ferramenta poderosa para depuração e auditoria. Em seguida, você vai implementar o tratamento de erros em um procedimento armazenado usando DECLARE HANDLER para lidar corretamente com erros inesperados. Você também vai aprender a criar e disparar condições de erro personalizadas com a instrução SIGNAL para aplicar regras de negócio. Por fim, vai consultar o log de erros do MySQL, que contém informações importantes sobre as operações do servidor e problemas críticos.

Ao concluir este laboratório, você terá uma base sólida sobre tratamento de erros e geração de logs no MySQL, o que permitirá criar soluções de banco de dados mais confiáveis.

Ative e consulte o log geral de consultas

O log geral registra todas as instruções SQL recebidas dos clientes. Ele é uma ferramenta valiosa para depuração e auditoria, mas deve ser usado temporariamente, pois pode afetar o desempenho e ocupar bastante espaço em disco. Nesta etapa, você vai ativar o log, gerar algumas atividades e consultar o arquivo de log.

Primeiro, abra o terminal na área de trabalho.

Conecte-se ao servidor MySQL como usuário root. Neste ambiente de laboratório, você pode usar sudo para se conectar sem senha.

sudo mysql -u root

Quando o prompt mysql> aparecer, ative o log geral globalmente.

SET GLOBAL general_log = 'ON';

Por padrão, o arquivo de log fica no diretório de dados do MySQL. Para acessá-lo com mais facilidade, vamos alterar o local para o diretório /tmp.

SET GLOBAL general_log_file = '/tmp/mysql_general.log';

Para confirmar o novo local, execute:

SHOW VARIABLES LIKE 'general_log_file';

A saída deve confirmar o caminho que você acabou de definir.

+------------------+-------------------------+
| Variable_name    | Value                   |
+------------------+-------------------------+
| general_log_file | /tmp/mysql_general.log  |
+------------------+-------------------------+
1 row in set (0.01 sec)

Agora, execute alguns comandos para gerar entradas no log.

CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
SELECT 'Logging this query' AS message;

Depois de executar esses comandos, saia do shell do MySQL.

exit

De volta ao terminal, consulte o conteúdo do arquivo de log.

sudo cat /tmp/mysql_general.log

Você verá os comandos executados, além de informações sobre a conexão e os horários. Isso confirma que o log geral está funcionando corretamente.

/usr/sbin/mariadbd, Version: 10.6.18-MariaDB-0ubuntu0.22.04.1 (Ubuntu 22.04). started with:
Tcp port: 3306  Unix socket: /run/mysqld/mysqld.sock
Time                Id Command  Argument
250728 14:12:46     33 Query    SHOW VARIABLES LIKE 'general_log_file'
250728 14:12:50     33 Query    CREATE DATABASE IF NOT EXISTS testdb
                    33 Query    SELECT DATABASE()
                    33 Init DB  testdb
                    33 Query    show databases
                    33 Query    show tables
                    33 Query    SELECT 'Logging this query' AS message
250728 14:12:56     33 Quit

Por fim, é recomendável desativar o log quando terminar. Você pode fazer isso diretamente no terminal.

sudo mysql -u root -e "SET GLOBAL general_log = 'OFF';"

Assim, o log não continuará crescendo nem afetará o desempenho do servidor.

Trate erros em um procedimento armazenado

Procedimentos armazenados podem falhar por vários motivos, como uma tentativa de inserir dados duplicados em uma coluna de chave primária. Um handler de erro permite capturar esses erros e responder de forma adequada, em vez de deixar o procedimento falhar sem controle. Nesta etapa, você vai criar um procedimento armazenado com um handler para erros de chave duplicada.

Primeiro, conecte-se ao servidor MySQL.

sudo mysql -u root

Crie o banco de dados testdb, caso ainda não exista, e selecione-o. Em seguida, crie uma tabela products.

CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    quantity INT
);

Agora, crie um procedimento armazenado para inserir um produto. Esta versão inclui um DECLARE HANDLER que captura erros de chave duplicada (SQLSTATE 23000) e retorna uma mensagem personalizada.

O comando DELIMITER altera o terminador de instruções de ; para //. Isso permite que os pontos e vírgulas dentro do corpo do procedimento sejam processados corretamente.

DELIMITER //

CREATE PROCEDURE insert_product(IN p_id INT, IN p_name VARCHAR(255))
BEGIN
    -- Declare an EXIT handler for duplicate key errors
    DECLARE EXIT HANDLER FOR SQLSTATE '23000'
    BEGIN
        SELECT 'Error: Product with this ID already exists.' AS message;
    END;

    -- Attempt to insert the product
    INSERT INTO products (id, name, quantity) VALUES (p_id, p_name, 0);
    SELECT 'Product inserted successfully.' AS message;
END //

DELIMITER ;

Vamos testar o procedimento. Primeiro, insira um novo produto.

CALL insert_product(1, 'Laptop');

A operação deve ser concluída com sucesso e retornar uma mensagem de confirmação.

+--------------------------------+
| message                        |
+--------------------------------+
| Product inserted successfully. |
+--------------------------------+
1 row in set (0.00 sec)

Agora, tente inserir um produto com o mesmo id.

CALL insert_product(1, 'Desktop');

Desta vez, o handler de erro será acionado e você receberá a mensagem personalizada, em vez de um erro genérico do MySQL.

+-----------------------------------------------+
| message                                       |
+-----------------------------------------------+
| Error: Product with this ID already exists.   |
+-----------------------------------------------+
1 row in set (0.00 sec)

Este exemplo mostra como os handlers de erro podem tornar seus procedimentos armazenados mais robustos e fáceis de usar.

Gere erros personalizados com SIGNAL

Enquanto os handlers capturam erros, a instrução SIGNAL permite gerá-los. Isso é útil para aplicar regras de negócio que não são cobertas pelas restrições padrão do banco de dados. Nesta etapa, você vai criar um procedimento que usa SIGNAL para impedir que a quantidade de um produto seja definida como um valor negativo.

Você ainda deve estar no shell do MySQL. Caso contrário, conecte-se novamente.

sudo mysql -u root

Confirme que o banco de dados selecionado é testdb.

USE testdb;

Agora, crie um procedimento armazenado para atualizar a quantidade de um produto. O procedimento vai verificar se a nova quantidade é negativa. Se for, ele vai gerar um erro personalizado com SIGNAL.

DELIMITER //

CREATE PROCEDURE update_quantity(IN p_id INT, IN p_quantity INT)
BEGIN
    -- Check if the quantity is negative
    IF p_quantity < 0 THEN
        -- Raise a custom error
        SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = 'Error: Quantity cannot be negative.';
    END IF;

    -- Update the quantity if the check passes
    UPDATE products SET quantity = p_quantity WHERE id = p_id;
    SELECT 'Quantity updated successfully.' AS message;
END //

DELIMITER ;

Neste caso, SQLSTATE '45000' é um código de estado genérico para erros definidos pelo usuário. MESSAGE_TEXT define a mensagem de erro que o cliente verá.

Vamos testar o procedimento. Primeiro, tente atualizar com um valor válido a quantidade do produto 'Laptop', criado na etapa anterior.

CALL update_quantity(1, 50);

A operação deve ser concluída com sucesso.

+--------------------------------+
| message                        |
+--------------------------------+
| Quantity updated successfully. |
+--------------------------------+
1 row in set (0.00 sec)

Agora, tente atualizar a quantidade usando um número negativo.

CALL update_quantity(1, -10);

Esta chamada vai acionar a instrução SIGNAL, e o procedimento será encerrado com o erro personalizado.

ERROR 1644 (45000): Error: Quantity cannot be negative.

Isso confirma que você pode aplicar regras de negócio personalizadas no banco de dados usando SIGNAL.

Consulte o log de erros do MySQL

O log de erros do MySQL é o principal recurso para diagnosticar problemas no servidor. Ele registra eventos de inicialização e encerramento do servidor, erros críticos e avisos. Nesta etapa, você vai verificar a configuração do log de erros e comparar como os logs são tratados em ambientes conteinerizados e tradicionais.

Você ainda deve estar no shell do MySQL. Primeiro, consulte a variável log_error para localizar o arquivo de log de erros.

SHOW VARIABLES LIKE 'log_error';

Neste ambiente de VM do LabEx (contêiner Docker), o caminho do log de erros pode aparecer vazio:

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_error     |       |
+---------------+-------+
1 row in set (0.001 sec)

Observação: Em ambientes conteinerizados como esta VM do LabEx, o registro de erros do MySQL/MariaDB costuma ser direcionado ao fluxo de erro padrão do contêiner, em vez de a um arquivo de log tradicional. Essa é uma prática comum em contêineres Docker, que segue a metodologia dos "12 fatores" para aplicações.

Vamos demonstrar o tratamento de erros tentando acessar um banco de dados inexistente:

USE non_existent_database;

Como esperado, esse comando vai falhar no cliente.

ERROR 1049 (42000): Unknown database 'non_existent_database'

Agora, saia do shell do MySQL para voltar ao terminal.

exit

Em um ambiente de produção com uma instalação tradicional do MySQL, normalmente você encontraria o log de erros em /var/log/mysql/error.log nos sistemas Ubuntu. Você pode verificar se o arquivo de log tradicional existe:

sudo ls -la /var/log/mysql/ 2> /dev/null || echo "MySQL log directory not found (normal in containerized environments)"

Como funciona o registro de erros em diferentes ambientes:

  • Instalações tradicionais: os logs de erros são gravados em arquivos como /var/log/mysql/error.log
  • Ambientes conteinerizados: os erros costumam ser enviados para stdout/stderr e capturados pelo runtime do contêiner
  • Bancos de dados na nuvem: normalmente, você acessa os logs de erros pela interface de gerenciamento do provedor de nuvem

Em ambientes de produção, você revisaria os logs de erros regularmente usando comandos como:

  • sudo tail -f /var/log/mysql/error.log (para acompanhar os logs em tempo real)
  • sudo grep -i error /var/log/mysql/error.log (para procurar erros específicos)

Essa prática é essencial para monitorar a integridade do servidor e solucionar problemas como falhas na inicialização, tabelas corrompidas ou problemas de permissão.

Resumo

Neste laboratório, você aprendeu técnicas fundamentais de tratamento de erros e geração de logs no MySQL. Primeiro, ativou e configurou o log geral de consultas para rastrear instruções SQL, uma habilidade importante para depuração. Em seguida, implementou um tratamento robusto de erros em um procedimento armazenado usando DECLARE HANDLER, o que permite lidar corretamente com erros específicos.

Além disso, você aprendeu a aplicar regras de negócio gerando erros personalizados com a instrução SIGNAL, que fornece mensagens claras e específicas. Por fim, explorou conceitos de registro de erros no MySQL, incluindo as diferenças entre instalações tradicionais e ambientes conteinerizados, como os contêineres Docker.

Você aprendeu que, enquanto instalações tradicionais do MySQL gravam logs de erros em arquivos (como /var/log/mysql/error.log), ambientes conteinerizados geralmente redirecionam as mensagens de erro para stdout/stderr para facilitar a integração com plataformas de orquestração de contêineres. Esse conhecimento é essencial para trabalhar com ambientes modernos de implantação.

Ao dominar essas técnicas, você estará mais preparado para criar aplicações de banco de dados confiáveis, solucionar problemas com eficiência e garantir a integridade dos seus bancos de dados MySQL em diferentes cenários de implantação.