Gestión de errores y registro en MySQL

MySQLBeginner
Practicar Ahora

Introducción

En este laboratorio aprenderá técnicas fundamentales de gestión de errores y registro en MySQL. Una gestión eficaz de errores es esencial para crear aplicaciones de bases de datos sólidas y fáciles de mantener, ya que le ayuda a diagnosticar problemas, entender la ejecución de las consultas y garantizar la integridad de los datos.

Primero habilitará el registro general de consultas para capturar todas las instrucciones SQL que se envían al servidor. Se trata de una herramienta muy útil para depurar y auditar. A continuación, implementará la gestión de errores en un procedimiento almacenado mediante DECLARE HANDLER para controlar adecuadamente los errores inesperados. También aprenderá a crear y activar condiciones de error personalizadas con la instrucción SIGNAL para hacer cumplir las reglas de negocio. Por último, revisará el registro de errores de MySQL, que contiene información importante sobre las operaciones del servidor y los problemas críticos.

Al terminar este laboratorio, tendrá una base sólida sobre la gestión de errores y el registro en MySQL, lo que le permitirá crear soluciones de bases de datos más fiables.

Habilitar y revisar el registro general de consultas

El registro general de consultas guarda todas las instrucciones SQL que recibe el servidor de los clientes. Es una herramienta muy valiosa para depurar y auditar, pero conviene usarla solo temporalmente, ya que puede afectar al rendimiento y ocupar mucho espacio en disco. En este paso, habilitará el registro, generará actividad y revisará el archivo de registro.

Primero, abra el terminal desde el escritorio.

Conéctese al servidor MySQL como usuario root. En este entorno de laboratorio, puede usar sudo para conectarse sin contraseña.

sudo mysql -u root

Cuando vea el prompt mysql>, habilite globalmente el registro general de consultas.

SET GLOBAL general_log = 'ON';

De forma predeterminada, el archivo de registro se guarda en el directorio de datos de MySQL. Para acceder a él con más facilidad, cambie su ubicación al directorio /tmp.

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

Compruebe la nueva ubicación con este comando:

SHOW VARIABLES LIKE 'general_log_file';

El resultado debe confirmar la ruta que acaba de establecer.

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

Ahora, ejecute algunos comandos para generar entradas en el registro.

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

Después de ejecutar estos comandos, salga del intérprete de comandos de MySQL.

exit

De vuelta en el terminal, muestre el contenido del archivo de registro.

sudo cat /tmp/mysql_general.log

Verá los comandos que ejecutó, junto con información de conexión y marcas de tiempo. Esto confirma que el registro general de consultas funciona correctamente.

/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 último, es recomendable deshabilitar el registro cuando termine. Puede hacerlo directamente desde el terminal.

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

Así evitará que el registro siga creciendo y afecte al rendimiento del servidor.

Gestionar errores en un procedimiento almacenado

Los procedimientos almacenados pueden fallar por varios motivos, por ejemplo, si se intenta insertar datos duplicados en una columna de clave primaria. Un controlador de errores permite detectar estos errores y responder adecuadamente, en lugar de dejar que el procedimiento falle. En este paso, creará un procedimiento almacenado con un controlador de errores para las claves duplicadas.

Primero, conéctese al servidor MySQL.

sudo mysql -u root

Cree la base de datos testdb si aún no existe y selecciónela. Después, cree una tabla llamada products.

CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;

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

Ahora, cree un procedimiento almacenado para insertar un producto. Esta versión incluye un DECLARE HANDLER que detecta errores de clave duplicada (SQLSTATE 23000) y devuelve un mensaje personalizado.

El comando DELIMITER cambia el terminador de las instrucciones de ; a //. Así, el punto y coma dentro del cuerpo del procedimiento se procesa correctamente.

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 ;

Pruebe el procedimiento. Primero, inserte un producto nuevo.

CALL insert_product(1, 'Laptop');

La operación debe completarse correctamente y devolver un mensaje de confirmación.

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

Ahora, intente insertar un producto con el mismo valor de id.

CALL insert_product(1, 'Desktop');

Esta vez se activará el controlador de errores y recibirá el mensaje personalizado en lugar de un error genérico de MySQL.

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

Esto demuestra cómo los controladores de errores pueden hacer que los procedimientos almacenados sean más fáciles de usar y más robustos.

Generar errores personalizados con SIGNAL

Los controladores detectan errores, mientras que la instrucción SIGNAL permite generarlos. Esto resulta útil para hacer cumplir reglas de negocio que no cubren las restricciones estándar de la base de datos. En este paso, creará un procedimiento que usa SIGNAL para impedir que se asignen valores negativos a la cantidad de un producto.

Debería seguir en el intérprete de comandos de MySQL. Si ya salió, vuelva a conectarse.

sudo mysql -u root

Asegúrese de estar usando la base de datos testdb.

USE testdb;

Ahora, cree un procedimiento almacenado para actualizar la cantidad de un producto. El procedimiento comprobará si la nueva cantidad es negativa. Si lo es, generará un error personalizado con 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 ;

En este caso, SQLSTATE '45000' es un código de estado genérico para errores definidos por el usuario. MESSAGE_TEXT establece el mensaje de error que verá el cliente.

Pruebe el procedimiento. Primero, intente actualizar correctamente el producto «Laptop» que creó en el paso anterior.

CALL update_quantity(1, 50);

La instrucción debe ejecutarse correctamente.

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

Ahora, intente actualizar la cantidad con un número negativo.

CALL update_quantity(1, -10);

Esta llamada activará la instrucción SIGNAL y el procedimiento finalizará con el error personalizado.

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

Esto confirma que puede hacer cumplir reglas de negocio personalizadas en la base de datos mediante SIGNAL.

Revisar el registro de errores de MySQL

El registro de errores de MySQL es el recurso principal para diagnosticar problemas del servidor. Registra los eventos de inicio y apagado del servidor, así como los errores críticos y las advertencias. En este paso, comprobará la configuración del registro de errores y comparará el registro en entornos con contenedores y en instalaciones tradicionales.

Debería seguir en el intérprete de comandos de MySQL. Primero, consulte la variable log_error para averiguar dónde se encuentra el archivo de registro de errores.

SHOW VARIABLES LIKE 'log_error';

En este entorno de máquina virtual de LabEx (un contenedor Docker), es posible que la ruta del registro de errores aparezca vacía:

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

Nota: En entornos con contenedores, como esta máquina virtual de LabEx, el registro de errores de MySQL/MariaDB suele enviarse al flujo de error estándar del contenedor, en lugar de guardarse en un archivo de registro tradicional. Es una práctica habitual en los contenedores Docker y sigue la metodología de las «aplicaciones de 12 factores» («12-factor app»).

Para ver cómo se gestionan los errores, intente acceder a una base de datos que no existe:

USE non_existent_database;

Como es de esperar, el cliente mostrará un error.

ERROR 1049 (42000): Unknown database 'non_existent_database'

Ahora, salga del intérprete de comandos de MySQL para volver al terminal.

exit

En un entorno de producción con una instalación tradicional de MySQL, normalmente encontrará el registro de errores en /var/log/mysql/error.log en sistemas Ubuntu. Compruebe si existe el archivo de registro tradicional:

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

Cómo se registran los errores en distintos entornos:

  • Instalaciones tradicionales: los registros de errores se escriben en archivos como /var/log/mysql/error.log
  • Entornos con contenedores: los errores suelen enviarse a stdout/stderr y el entorno de ejecución del contenedor los captura
  • Bases de datos en la nube: normalmente se accede a los registros de errores a través de la interfaz de administración del proveedor de la nube

En entornos de producción, conviene revisar periódicamente los registros de errores con comandos como los siguientes:

  • sudo tail -f /var/log/mysql/error.log (para seguir el registro en tiempo real)
  • sudo grep -i error /var/log/mysql/error.log (para buscar errores concretos)

Esta práctica es esencial para supervisar el estado del servidor y diagnosticar problemas como fallos de inicio, tablas dañadas o problemas de permisos.

Resumen

En este laboratorio ha aprendido técnicas fundamentales de gestión de errores y registro en MySQL. Empezó por habilitar y configurar el registro general de consultas para rastrear instrucciones SQL, una habilidad clave para la depuración. Después, implementó una gestión robusta de errores en un procedimiento almacenado mediante DECLARE HANDLER, lo que le permitió controlar ciertos errores de forma adecuada.

Además, aprendió a hacer cumplir reglas de negocio generando errores personalizados con la instrucción SIGNAL, que proporciona mensajes claros y específicos. Por último, exploró los conceptos de registro de errores de MySQL, incluidas las diferencias entre las instalaciones tradicionales y los entornos con contenedores, como los contenedores Docker.

Aprendió que las instalaciones tradicionales de MySQL escriben los registros de errores en archivos, como /var/log/mysql/error.log, mientras que los entornos con contenedores suelen redirigir la salida de errores a stdout/stderr para integrarla mejor con las plataformas de orquestación de contenedores. Este conocimiento es fundamental para trabajar con entornos de implementación modernos.

Al dominar estas técnicas, estará mejor preparado para crear aplicaciones de bases de datos fiables, diagnosticar problemas con eficacia y garantizar la integridad de sus bases de datos MySQL en distintos escenarios de implementación.