Installer MariaDB

apt install mariadb-server -y
mysql_secure_installation

Configuration de MariaDB

Modifiez le fichier de configuration de MariaDB (my.cnf ou mariadb.cnf). Sur la plupart des systèmes, il se trouve dans /etc/mysql/ ou /etc/mariadb/.

cd /etc/mysql/
# ou, selon la distribution :
# cd /etc/mariadb/
nano /etc/mysql/mariadb.cnf

Ces valeurs sont également consultables dans phpMyAdmin, via Accueil / Variables et paramètres du serveur.

[mysqld]
#port = 3306
#bind-address = 127.0.0.1
#datadir = /var/lib/mysql
#socket = /var/run/mysqld/mysqld.sock
#log_error = /var/log/mysql/error.log
#pid-file = /var/run/mysqld/mysqld.pid
#
#max_connections = 100
#query_cache_size = 16M
#query_cache_type = 1
#innodb_buffer_pool_size = 256M
#innodb_log_file_size = 64M
#innodb_flush_log_at_trx_commit = 1
#
#skip-networking      # Désactive les connexions réseau, n'autorisant que les connexions locales via le socket Unix.
#skip-name-resolve    # Désactive la résolution de nom d'hôte pour améliorer les performances.
#
#log_bin = /var/log/mysql/mysql-bin.log
#server_id = 1          # Identifiant unique du serveur pour la réplication.
#binlog_format = MIXED  # (ROW, STATEMENT, MIXED)
#relay_log = /var/log/mysql/mysql-relay-bin.log
#
#default_storage_engine = InnoDB
#character_set_server = utf8mb4
#collation_server = utf8mb4_general_ci
systemctl restart mariadb
systemctl status mariadb

# Désinstallation complète
systemctl stop mariadb
apt-get remove --purge mariadb-server mariadb-client mariadb-common
apt-get autoremove
apt-get autoclean
rm -rf /etc/mysql /var/lib/mysql
deluser mysql
delgroup mysql

Se connecter et explorer les bases

mysql -u root -p                          # Ouvrir le client (le mot de passe est demandé)
mariadb -u root -p                        # Client MariaDB, équivalent sur les versions récentes
mysql -u app -p -h 127.0.0.1 ma_base      # Connexion réseau directement sur une base
SHOW DATABASES;                           -- Lister les bases
USE ma_base;                              -- Sélectionner la base courante
SHOW TABLES;                              -- Lister les tables de la base courante
DESCRIBE clients;                         -- Colonnes et types d'une table
SHOW CREATE TABLE clients\G               -- Instruction de création complète (\G = affichage vertical)
SELECT VERSION();                         -- Version du serveur
STATUS;                                   -- Informations de connexion et du serveur
EXIT;                                     -- Quitter le client (ou \q)

Commandes SQL de base

-- Créer une base et une table
CREATE DATABASE boutique CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE boutique;

CREATE TABLE clients (
  id       INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nom      VARCHAR(100) NOT NULL,
  email    VARCHAR(150) NOT NULL UNIQUE,
  cree_le  DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Insérer des données
INSERT INTO clients (nom, email) VALUES ('Ada Lovelace', 'ada@exemple.fr');
INSERT INTO clients (nom, email) VALUES
  ('Grace Hopper', 'grace@exemple.fr'),
  ('Alan Turing',  'alan@exemple.fr');

-- Lire (SELECT)
SELECT * FROM clients;
SELECT nom, email FROM clients WHERE nom LIKE 'A%' ORDER BY nom ASC LIMIT 10;
SELECT COUNT(*) FROM clients;

-- Jointure entre deux tables
SELECT c.nom, co.total
FROM clients c
JOIN commandes co ON co.client_id = c.id
WHERE co.total > 100;

-- Mettre à jour et supprimer (ne jamais oublier le WHERE)
UPDATE clients SET email = 'ada.l@exemple.fr' WHERE id = 1;
DELETE FROM clients WHERE id = 3;

-- Faire évoluer la structure et indexer
ALTER TABLE clients ADD COLUMN ville VARCHAR(80);
CREATE INDEX idx_clients_nom ON clients (nom);

-- Supprimer une table ou une base
DROP TABLE commandes;
DROP DATABASE boutique;

Gérer les utilisateurs et les privilèges

-- Créer un utilisateur : local (socket) puis réseau
CREATE USER 'app'@'localhost' IDENTIFIED BY 'MotDePasseFort';
CREATE USER 'app'@'%'         IDENTIFIED BY 'MotDePasseFort';   -- depuis n'importe quel hôte

-- Accorder des privilèges CIBLÉS sur une seule base (principe du moindre privilège)
GRANT SELECT, INSERT, UPDATE, DELETE ON boutique.* TO 'app'@'localhost';

-- Inspecter, retirer, supprimer
SHOW GRANTS FOR 'app'@'localhost';
REVOKE INSERT, UPDATE, DELETE ON boutique.* FROM 'app'@'localhost';
DROP USER 'app'@'localhost';

-- Changer un mot de passe
ALTER USER 'app'@'localhost' IDENTIFIED BY 'NouveauMotDePasse';

FLUSH PRIVILEGES;                         -- Recharger la table des privilèges

Accordez toujours le minimum nécessaire : une application web se contente en général de SELECT, INSERT, UPDATE, DELETE sur sa base, sans ALL PRIVILEGES ni GRANT OPTION, réservés à l'administration.

Sauvegarde et restauration

La sauvegarde logique repose sur mysqldump, qui exporte la structure et les données sous forme d'instructions SQL. La restauration réinjecte ce fichier avec le client mysql (ou mariadb).

Sauvegarder une base

# Une base précise
mysqldump -u root -p ma_base > ma_base.sql

# Compressée à la volée (recommandé) → fichier .sql.gz
mysqldump -u root -p ma_base | gzip > ma_base_$(date +%F).sql.gz

# Toutes les bases du serveur
mysqldump -u root -p --all-databases | gzip > full_$(date +%F).sql.gz

# Seulement la structure (sans les données)
mysqldump -u root -p --no-data ma_base > ma_base_schema.sql

# Seulement les données (sans le schéma)
mysqldump -u root -p --no-create-info ma_base > ma_base_data.sql

# Plusieurs bases nommées
mysqldump -u root -p --databases base1 base2 | gzip > bases_$(date +%F).sql.gz

Quelques options utiles pour une sauvegarde cohérente, en particulier sur des tables InnoDB :

mysqldump -u root -p \
  --single-transaction \  # dump cohérent sans verrouiller les tables (InnoDB)
  --quick \               # lit ligne par ligne, ménage la mémoire sur les grosses tables
  --routines \            # inclut les procédures stockées et fonctions
  --triggers \            # inclut les déclencheurs
  --events \              # inclut les événements planifiés
  ma_base | gzip > ma_base_$(date +%F).sql.gz

Sélectionner ou exclure des tables

On peut ne sauvegarder que certaines tables, ou au contraire en écarter. Les tables à inclure se listent après le nom de la base ; les tables à exclure passent par --ignore-table, à répéter et à préfixer par le nom de la base.

# Seulement certaines tables (les noms suivent la base)
mysqldump -u root -p ma_base clients commandes > ma_base_partiel.sql

# Toute la base SAUF certaines tables (--ignore-table à répéter, préfixé par la base)
mysqldump -u root -p ma_base \
  --ignore-table=ma_base.logs \
  --ignore-table=ma_base.sessions \
  | gzip > ma_base_sans_logs_$(date +%F).sql.gz

# Exclure les données volumineuses mais garder leur structure :
# 1) tout sauvegarder en excluant les données des tables lourdes
mysqldump -u root -p ma_base --ignore-table=ma_base.logs | gzip > ma_base_$(date +%F).sql.gz
# 2) ajouter uniquement le schéma des tables exclues
mysqldump -u root -p --no-data ma_base logs | gzip >> ma_base_$(date +%F).sql.gz

Pour exclure une même table sur toutes les bases lors d'un --all-databases, chaque --ignore-table doit malgré tout nommer la base concernée : il n'existe pas de motif générique, on répète l'option pour chaque couple base.table.

Restaurer une base

# La base cible doit exister au préalable
mysql -u root -p -e "CREATE DATABASE ma_base CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"

# Depuis un fichier .sql
mysql -u root -p ma_base < ma_base.sql

# Depuis un fichier compressé .sql.gz (sans le décompresser)
gunzip < ma_base_2026-07-05.sql.gz | mysql -u root -p ma_base
# variante équivalente :
zcat ma_base_2026-07-05.sql.gz | mysql -u root -p ma_base

Un dump créé avec --all-databases ou --databases contient déjà les instructions CREATE DATABASE / USE : on le restaure alors sans préciser de base.

zcat full_2026-07-05.sql.gz | mysql -u root -p

Avec le client mariadb et un utilisateur applicatif, le mot de passe peut être passé directement à la suite de -p (sans espace). Le dump --databases portant déjà le CREATE DATABASE / USE, aucune base n'est précisée :

# Restaurer : décompresser et réinjecter dans MariaDB
gunzip < /var/bases.sql.gz | mariadb -u user -p'password'

#  sauvegarder et compresser
mariadb-dump -u user -p'password' --databases bases | gzip > bases.sql.gz

Passer le mot de passe dans la commande l'expose dans l'historique du shell et la liste des processus (ps). Pour un usage régulier, préférez ~/.my.cnf (chmod 600) décrit plus bas, ou l'invite interactive avec -p seul. Sur MariaDB récent, mariadb/mariadb-dump remplacent mysql/mysqldump, qui restent disponibles comme alias.

Variante ZIP (.sql.zip)

Contrairement à gzip, zip produit une archive (elle peut contenir plusieurs fichiers) et non un simple flux compressé : on ne peut donc pas l'enchaîner par un pipe aussi directement. Il faut d'abord installer les outils :

apt install zip unzip -y
# Sauvegarder : dump vers un .sql, puis archivage en .sql.zip
mysqldump -u root -p --databases ma_base > ma_base.sql
zip ma_base.sql.zip ma_base.sql   # crée l'archive
rm ma_base.sql                    # on ne garde que le .zip

# Variante en une ligne, sans fichier intermédiaire :
# le contenu est envoyé sur l'entrée standard de zip (l'entrée s'appelle alors « - »)
mysqldump -u root -p --databases ma_base | zip ma_base.sql.zip -
# Restaurer : extraire le contenu de l'archive vers l'entrée de MariaDB
# -p écrit le fichier extrait sur la sortie standard (peu importe son nom dans l'archive)
unzip -p ma_base.sql.zip | mariadb -u synapxlab -p'xxxxxxxxxxxxxxxxx'

Un dump --databases embarquant déjà CREATE DATABASE / USE, aucune base n'est précisée à la restauration. À taille de données égale, zip compresse un peu moins bien que gzip sur un dump SQL ; on le choisit surtout pour la compatibilité (archive ouvrable sous Windows d'un double-clic).

Automatiser avec cron

crontab -e
# Sauvegarde quotidienne à 2 h, conservée 7 jours
0 2 * * * mysqldump -u root -p'MOT_DE_PASSE' --single-transaction --routines ma_base | gzip > /var/backups/mysql/ma_base_$(date +\%F).sql.gz
30 2 * * * find /var/backups/mysql -name '*.sql.gz' -mtime +7 -delete

Pour éviter d'exposer le mot de passe dans la ligne de commande ou la crontab, on le place dans un fichier protégé ~/.my.cnf :

# ~/.my.cnf  (chmod 600)
[client]
user = root
password = MOT_DE_PASSE

mysqldump et mysql liront alors ces identifiants automatiquement, sans option -u ni -p.

Maintenance, diagnostic et optimisation

SHOW PROCESSLIST;                         -- Requêtes en cours d'exécution
SHOW STATUS LIKE 'Threads_connected';     -- Connexions actives
SHOW VARIABLES LIKE 'max_connections';    -- Valeur d'un paramètre du serveur
EXPLAIN SELECT * FROM clients WHERE nom = 'Ada Lovelace';  -- Plan d'exécution (l'index est-il utilisé ?)
ANALYZE TABLE clients;                    -- Met à jour les statistiques d'index
OPTIMIZE TABLE clients;                   -- Défragmente et réordonne la table
CHECK TABLE clients;                      -- Vérifie l'intégrité
REPAIR TABLE clients;                     -- Répare (surtout utile en MyISAM)
# Vérifier et réparer toutes les tables depuis le shell
mysqlcheck -u root -p --all-databases --check
mysqlcheck -u root -p --all-databases --auto-repair --optimize

Si le mot de passe root est perdu, on redémarre MariaDB en mode sans privilèges pour le réinitialiser :

sudo systemctl stop mariadb
sudo mysqld_safe --skip-grant-tables --skip-networking &
mysql -u root
-- Une fois connecté sans mot de passe :
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NouveauMotDePasseRoot';
# Puis on arrête le mode dégradé et on relance normalement
sudo kill "$(pgrep mysqld)"
sudo systemctl start mariadb

phpMyAdmin

Accès via http://votre_ip/phpmyadmin.

apt install phpmyadmin -y

apt install pwgen      # générateur de mots de passe en ligne de commande
pwgen -syB 24 1
# -s → mode sécurisé (cryptographique)
# -y → inclure des caractères spéciaux
# -B → pas de caractères ambigus (0, O, l, 1...)

À la question « Faut-il configurer la base de données de phpMyAdmin avec dbconfig-common ? », répondre non permet de conserver la maîtrise de la configuration sans créer d'utilisateurs ou de bases superflus.

-- Accès : http://IP/phpmyadmin/
-- mysql -u root -p

CREATE USER 'admin'@'localhost' IDENTIFIED BY '+@%Xw7YVd5.ceO7uvJ_]';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Générer une clef blowfish_secret pour phpMyAdmin

blowfish_secret sert à sécuriser les cookies ; cette clef est indispensable au bon fonctionnement de phpMyAdmin en mode sécurisé. Elle doit comporter au minimum 32 caractères et être aléatoire.

blowfish=$(pwgen -syB 32 1)
echo "\$cfg['blowfish_secret'] = '$blowfish';"
# ou avec nano :
nano /var/lib/phpmyadmin/blowfish_secret.inc.php

Thèmes alternatifs pour phpMyAdmin (mode sombre)

Quelques dépôts de thèmes sombres :

cd /usr/share/phpmyadmin/themes/
apt install git -y
git clone https://github.com/evilpie/phpmyadmin-dark-theme.git darkmode
systemctl reload apache2
nano /etc/phpmyadmin/config.inc.php
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = 'phpmyadmin';
$cfg['Servers'][$i]['password'] = 'your_password';

$cfg['UploadDir'] = '';
$cfg['MaxFileSize'] = 16777216; // 16 MB en octets
$cfg['ExecTimeLimit'] = 300;    // 5 minutes

Privilèges et gestion des bases

-- mariadb
GRANT ALL PRIVILEGES ON *.* TO 'phpmyadmin'@'localhost' WITH GRANT OPTION;
SHOW GRANTS FOR 'phpmyadmin'@'localhost';
ALTER USER 'phpmyadmin'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'phpmyadmin'@'localhost' WITH GRANT OPTION;
CREATE USER 'doc_user'@'localhost' IDENTIFIED BY 'doc_password';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'doc_user'@'localhost';
FLUSH PRIVILEGES;
CREATE DATABASE testdb;
systemctl restart mariadb
systemctl restart apache2
mariadb -u phpmyadmin -p

Désinstaller phpMyAdmin

apt-get remove --purge phpmyadmin
apt-get autoremove
apt-get autoclean
rm -rf /usr/share/phpmyadmin /var/lib/phpmyadmin /etc/phpmyadmin
systemctl restart apache2