MariaDB desde cero (I): instalación y primeros pasos
Primera entrega de la serie MariaDB desde cero a pro. Tiempo de lectura estimado: 9 minutos.
Arranco la tercera serie sobre bases de datos: cinco posts sobre MariaDB, la implementación libre del linaje MySQL que hoy tiene roadmap propio y sigue siendo una opción muy sensata para muchos proyectos.
Si dudas entre MariaDB y MySQL como tecnologías, el post MySQL y MariaDB, MariaDB y MySQL es un buen punto de partida. Aquí doy por supuesto que ya te has decidido por MariaDB o que estás en un entorno donde lo tienes delante.
Esta serie va en paralelo a las de PostgreSQL y ClickHouse. Cuando una idea aparece también en las otras, la enlazo.
Por qué MariaDB hoy
MariaDB nació como fork de MySQL cuando Oracle compró Sun en 2009. Durante años fue un drop-in replacement, pero desde MySQL 8 y MariaDB 10.5 se han ido separando lo suficiente como para que conviene saber en cuál estás.
Razones por las que MariaDB sigue siendo una buena elección:
- GPL pura y desarrollo 100% abierto (MariaDB Foundation).
- Varios storage engines integrados: InnoDB, Aria, MyRocks, ColumnStore, Spider.
- Compatibilidad Oracle parcial: modo PL/SQL y sintaxis de secuencias desde 10.3.
- Funciones modernas de SQL: CTEs, window functions, análisis estadístico.
- Galera Cluster integrado para HA síncrona multi-master.
mariabackup, compatible con snapshots en caliente.
Para un sistema transaccional de tamaño mediano, MariaDB es una elección sin drama.
Instalación
Debian/Ubuntu
El repositorio oficial con paquetes actualizados:
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash
sudo apt update
sudo apt install -y mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation
mariadb-secure-installation hace lo típico: establece contraseña de root, elimina usuarios anónimos, desactiva login remoto de root, etc. Úsalo.
Docker
docker run -d \
--name mdb \
-e MARIADB_ROOT_PASSWORD=secret \
-p 3306:3306 \
-v mdbdata:/var/lib/mysql \
mariadb:11.4
Puerto 3306, el clásico. El directorio de datos mantiene el nombre histórico /var/lib/mysql/ por compatibilidad.
El cliente mariadb
Antiguamente mysql, hoy mariadb (el binario mysql sigue siendo un alias en la mayoría de paquetes). Acepta prácticamente las mismas opciones y meta-comandos.
mariadb -u root -p
Comandos útiles dentro del cliente:
\h -- ayuda
SHOW DATABASES;
USE nombre;
SHOW TABLES;
SHOW CREATE TABLE tabla\G
DESCRIBE tabla;
SHOW PROCESSLIST;
STATUS;
\e -- abre $EDITOR
\q -- salir
\G en lugar de ; muestra la salida en formato vertical, muy útil para filas anchas. Equivale al \x de psql.
Mi ~/.my.cnf básico (modo cliente):
[client]
user=javier
password=...
host=localhost
[mariadb]
prompt="\\u@\\h [\\d]> "
auto-rehash
prompt muestra usuario, host y base de datos activa. auto-rehash habilita autocompletado de tablas y columnas.
Autenticación por socket y usuarios
En Debian/Ubuntu modernos, el usuario root de MariaDB se autentica por Unix socket por defecto: si eres root del sistema, entras sin contraseña con sudo mariadb. Es seguro y cómodo.
Para crear usuarios:
-- Usuario local con contraseña
CREATE USER 'app'@'localhost' IDENTIFIED BY 'xxx';
-- Usuario accesible desde una red interna
CREATE USER 'app'@'10.0.%.%' IDENTIFIED BY 'xxx';
-- Permisos completos sobre una BD
GRANT ALL PRIVILEGES ON blog.* TO 'app'@'localhost';
-- Permisos granulares, como debería ser en producción
GRANT SELECT, INSERT, UPDATE, DELETE ON blog.* TO 'app'@'localhost';
FLUSH PRIVILEGES;
Un detalle clave que confunde al que viene de PostgreSQL: en MariaDB, el usuario es 'usuario'@'host'. El mismo nombre desde distintos hosts puede tener distintos permisos. Es peculiar pero muy útil.
Para roles (similar a PostgreSQL):
CREATE ROLE app_read;
GRANT SELECT ON blog.* TO app_read;
GRANT app_read TO 'reporter'@'localhost';
SET DEFAULT ROLE app_read FOR 'reporter'@'localhost';
Tu primera base de datos
CREATE DATABASE blog
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE blog;
CREATE TABLE authors (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
email VARCHAR(320) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY ux_authors_email (email)
) ENGINE=InnoDB;
CREATE TABLE posts (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
author_id BIGINT UNSIGNED NOT NULL,
title VARCHAR(300) NOT NULL,
slug VARCHAR(300) NOT NULL,
body MEDIUMTEXT NOT NULL,
published_at DATETIME NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY ux_posts_slug (slug),
KEY ix_posts_author_published (author_id, published_at),
CONSTRAINT fk_posts_author FOREIGN KEY (author_id) REFERENCES authors(id)
) ENGINE=InnoDB;
Piezas que ya introducen el sabor de MariaDB:
utf8mb4: el charset que quieres.utf8en MySQL/MariaDB es una versión limitada (3 bytes) por razones históricas. Conutf8mb4soportas emoji y todo Unicode.ENGINE=InnoDB: el storage engine transaccional. Lo desgranamos en la entrega II.UNSIGNED: enteros sin signo. Ahorras la mitad del rango negativo cuando no lo necesitas.AUTO_INCREMENT: la secuencia clásica. Desde 10.3 también están lasSEQUENCEal estilo Oracle/PostgreSQL.ON UPDATE CURRENT_TIMESTAMP: magia de MariaDB que mantieneupdated_atsolo.
Primeros INSERT y SELECT
INSERT INTO authors (name, email)
VALUES ('Javier', '[email protected]');
SELECT LAST_INSERT_ID();
-- Devuelve el id generado
INSERT INTO posts (author_id, title, slug, body, published_at)
VALUES
(1, 'Hola mundo', 'hola-mundo', 'Primer post', NOW()),
(1, 'En borrador', 'borrador', 'Aún no publicado', NULL);
SELECT id, title, published_at IS NOT NULL AS publicado
FROM posts
ORDER BY created_at DESC;
A diferencia de PostgreSQL, MariaDB no tiene RETURNING universal (aunque sí soporta un subset limitado: INSERT ... RETURNING desde 10.5). El patrón habitual para INSERT es LAST_INSERT_ID().
Transacciones
MariaDB con InnoDB soporta transacciones ACID:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- o ROLLBACK;
Savepoints:
START TRANSACTION;
INSERT INTO ... ;
SAVEPOINT sp1;
UPDATE ... ; -- podría fallar
ROLLBACK TO sp1;
COMMIT;
Nivel de aislamiento por defecto: REPEATABLE READ (distinto a PostgreSQL, que va con READ COMMITTED). Para una explicación larga de las diferencias, merece un post entero.
Configuración: los ficheros que importan
En Debian/Ubuntu, la configuración está dispersa en varios ficheros que se unen por el método include:
/etc/mysql/mariadb.cnf— fichero raíz./etc/mysql/conf.d/— configuración compartida con clientes./etc/mysql/mariadb.conf.d/50-server.cnf— la config del servidor.
Los ajustes más habituales van en 50-server.cnf o en tus propios .cnf en mariadb.conf.d/.
Parámetros para mirar cualquier valor:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW STATUS LIKE 'Threads_connected';
Y para ver estado global:
SHOW GLOBAL STATUS;
Log slow query
Lo primero que activo en un servidor que dudo:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- segundos
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Y en producción, persiste en el .cnf:
[mariadb]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
log_queries_not_using_indexes = 1
Con mariadb-dumpslow (antes mysqldumpslow) agregas el fichero para ver las consultas lentas agrupadas. Es la primera parada cuando algo va mal. Volveremos a ello en la entrega IV.
Character set y collation
Por omisión, usa utf8mb4. En versiones modernas de MariaDB ya es el default del servidor, pero conviene verificar:
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
Si heredas un sistema viejo con latin1 o utf8 (3 bytes), considéralo deuda técnica y planea una migración. Es un dolor de cabeza recurrente.
Por dónde seguir
- II: storage engines, tipos y restricciones — InnoDB, Aria, MyRocks, tipos numéricos, JSON, foreign keys.
- III: consultas, CTEs y window functions — el SQL moderno que MariaDB soporta desde 10.2.
- IV: índices, EXPLAIN y tuning — rendimiento en serio.
- V: replicación, Galera y producción — replicación async, cluster síncrono y operación.
Como lectura complementaria: MySQL y MariaDB, MariaDB y MySQL para tener clara la comparativa con MySQL.