Réinitialiser le mot de passe root de MySQL et MariaDB

Publié le 18 min de lecture

Mot de passe root oublié ? Le plus souvent, vous n'en avez pas besoin. Et si c'est le cas, voici comment ouvrir la base de données pendant exactement une minute sans la livrer à la moitié d'Internet.

Le mot de passe root de la base de données fait partie de ces mots de passe que l'on définit une seule fois à l'installation et que l'on n'utilise plus jamais ensuite, puisque chaque application travaille avec son propre compte. Jusqu'au jour où il faut vraiment y revenir. Et là, vous lisez ceci :

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

La réponse standard que l'on trouve partout tient en une ligne : arrêter le service, le relancer avec --skip-grant-tables, définir le mot de passe, terminé. C'est exact, mais ce n'est que la moitié de l'histoire. Ce guide explique aussi pourquoi la commande recopiée partout reste sans effet sur Ubuntu avec MySQL 8, pourquoi vous n'avez bien souvent besoin d'aucun mot de passe, et quoi faire si le service refuse ensuite de démarrer.

Vérifier d'abord : vous n'avez probablement besoin d'aucun mot de passe

Sur Debian et Ubuntu, le compte root de la base de données n'est plus protégé par un mot de passe depuis des années, mais par l'identité de l'utilisateur système. MariaDB appelle ce mécanisme unix_socket, MySQL l'appelle auth_socket. Le principe est le même : celui qui se connecte par le socket local et qui est déjà root au niveau du système d'exploitation entre sans mot de passe. Le raisonnement est simple : un utilisateur système root accède de toute façon à tous les fichiers de données et à la mémoire du processus, un mot de passe supplémentaire ne représente donc aucun obstacle.

Votre premier essai devrait donc toujours être celui-ci :

sudo mariadb
sudo mysql

Attention : sudo mysql -u root -p ne fonctionne pas, car le -p bascule sur l'authentification par mot de passe. C'est exactement là que la plupart des tentatives échouent. Sans -p et avec sudo, vous arrivez en règle générale directement dans l'invite. De là, vous redéfinissez le mot de passe en deux secondes, sans même toucher à la base de données.

La deuxième porte de secours est le compte de maintenance de la distribution. Sur Ubuntu avec le paquet mysql-server, le fichier /etc/mysql/debian.cnf existe toujours : il contient les identifiants d'un compte disposant de tous les droits, lisible uniquement par root :

sudo ls -l /etc/mysql/debian.cnf
sudo mysql --defaults-file=/etc/mysql/debian.cnf -e "SELECT current_user();"

Si une ligne vous revient, vous êtes entré et vous pouvez continuer immédiatement. N'attendez pas root@localhost pour autant : la requête répond debian-sys-maint@localhost. C'est normal, car ce compte de maintenance possède ALL PRIVILEGES et suffit largement pour la réinitialisation, mais vous n'êtes pas root pour autant. Cette voie est par ailleurs propre à Debian et Ubuntu. Sur AlmaLinux, Rocky Linux et Oracle Linux, ni le répertoire /etc/mysql/ ni le compte n'existent : c'est la connexion par socket en tant que root, décrite dans la section précédente, qui prend le relais. À partir de MariaDB 10.4, ce compte n'est plus créé (le fichier y renvoie généralement simplement vers root via le socket), mais sur les installations existantes il est souvent encore présent. Un coup d'œil ne coûte rien et vous épargne, en cas de succès, tout le reste de ce guide.

Quelle base de données tourne réellement sur ce serveur ?

Ce n'est pas une formalité, la réponse conditionne chacune des commandes qui suivent. Sur Debian, le paquet mysql-server a disparu de l'archive officielle depuis des années, c'est donc pratiquement toujours MariaDB qui tourne, même si la commande mysql existe. Celle-ci n'est en effet qu'un lien symbolique vers le client MariaDB. Voici l'état actuel des distributions :

Systèmemysql-servermariadb-server
Debian 13absent11.8
Debian 12absent10.11
Ubuntu 24.048.010.11
Ubuntu 22.048.010.6

Interrogez le serveur lui-même, pas le client :

systemctl list-units --type=service --all | grep -Ei 'mysql|mariadb'
mysqladmin --version
mariadbd --version

Le --all fait partie de la commande, car sans lui list-units n'affiche que les units chargées et actives. Or dans le cas précis où vous avez besoin de cette commande, c'est-à-dire pour un service qui ne tourne pas, la sortie resterait vide. mysqladmin --version existe des deux côtés et nomme le moteur en clair, les systèmes MariaDB répondent ... Distrib 11.8.6-MariaDB .... Pour mariadbd --version, un command not found sur un système purement MySQL est le résultat attendu et non une erreur, et l'inverse vaut tout autant pour les commandes propres à mysqld sur un système purement MariaDB.

Si l'unit s'appelle mariadb.service, vous travaillez avec MariaDB. Si elle s'appelle mysql.service, avec MySQL. Sur les systèmes équipés de MariaDB, il existe en plus un alias mysql.service qui pointe vers mariadb.service : la sortie de systemctl list-units est donc plus parlante que la simple présence d'un nom.

Les noms des units diffèrent d'une famille de distributions à l'autre, et tous les appels systemctl de ce guide sont écrits pour Debian et Ubuntu. Dans la famille Red Hat, il n'existe aucune unit nommée mysql.service, et systemctl status mysql y répond Unit mysql.service could not be found. Dans ce cas, utilisez systématiquement les noms de la colonne de droite, y compris dans le chemin du répertoire de drop-in :

ÉlémentDebian et UbuntuAlmaLinux, Rocky, RHEL
Unit MariaDBmariadb.servicemariadb.service
Unit MySQLmysql.servicemysqld.service
Répertoire de drop-in MySQL/etc/systemd/system/mysql.service.d//etc/systemd/system/mysqld.service.d/
Binaire serveur MySQL/usr/sbin/mysqld/usr/libexec/mysqld --basedir=/usr
Configuration/etc/mysql//etc/my.cnf et /etc/my.cnf.d/

Cloisonner d'abord : pourquoi cette étape n'est pas optionnelle

Avec --skip-grant-tables, le serveur ne charge pas les tables de droits. Cela ne signifie pas « root entre sans mot de passe », mais « n'importe qui fait n'importe quoi, sans mot de passe, sous l'identité de n'importe quel utilisateur ». Dans cet état, il n'y a plus ni authentification ni contrôle des droits, pas davantage pour vos bases de données clients.

Dans ce cas de figure, MySQL 8 active automatiquement skip_networking et n'accepte donc plus aucune connexion TCP. Ne vous fiez pas pour autant à ce comportement, ajoutez toujours l'option vous-même. Chez MariaDB, c'est de toute façon la recommandation documentée, et quand on administre les deux systèmes, on préfère ne pas avoir à retenir lequel des deux pense à votre place.

--skip-grant-tables --skip-networking

Deux points passent souvent à la trappe. Premièrement : skip_networking ne ferme que le port réseau. Le socket Unix situé sous /run/mysqld/mysqld.sock reste ouvert, et sur beaucoup de systèmes il est accessible à tous les utilisateurs locaux. Un processus PHP compromis tournant sous www-data peut, pendant cette fenêtre, lire toutes les bases du serveur. Gardez donc cette fenêtre aussi courte que possible et n'effectuez pas l'opération pendant qu'un serveur web exécute du code inconnu. Deuxièmement : arrêtez au préalable tout ce qui se connecte automatiquement, c'est-à-dire le serveur web et les services applicatifs. Leurs tentatives de connexion ne font pas que gêner, elles s'exécutent dans cet état avec tous les droits.

Si le serveur est joignable depuis l'extérieur, fermez en plus le pare-feu. La mise en place propre et durable est décrite dans Configurer le pare-feu UFW.

sudo apt-get install -y ufw
sudo ufw deny 3306/tcp
sudo ss -ltnp | grep 3306

La première ligne n'est pas superflue : sur une installation Debian minimale, ufw n'est pas préinstallé et la commande se termine sinon par sudo: ufw: command not found. Sur AlmaLinux, Rocky Linux et RHEL, ufw n'existe tout simplement pas, le filtrage de paquets y passe par firewalld :

sudo firewall-cmd --permanent --remove-service=mysql
sudo firewall-cmd --reload

Sur toutes les installations Debian et Ubuntu vérifiées, bind-address est de toute façon réglé sur 127.0.0.1, ce que confirme ss -ltnp. Le serveur n'accepte alors aucune connexion venue de l'extérieur, et la règle de pare-feu constitue la deuxième sécurité, pas la protection principale.

MariaDB : réinitialiser le mot de passe

L'unit de MariaDB démarre le serveur avec ExecStart=/usr/sbin/mariadbd $MYSQLD_OPTS. Cette variable est prévue exactement pour ce genre de situation, vous n'avez donc aucun fichier à modifier. Vérifiez-le rapidement, vous saurez ainsi que la méthode qui suit fonctionne sur votre système :

systemctl cat mariadb | grep ExecStart

Ensuite, dans cet ordre :

sudo systemctl stop mariadb
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mariadb
sudo mariadb -u root

Dans l'invite, commencez par FLUSH PRIVILEGES. Sans cette étape, le serveur n'a pas encore les tables de droits en mémoire et refuse toute gestion de compte. Définissez ensuite le mot de passe :

FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('VotreNouveauMotDePasse');

Cette écriture un peu lourde est volontaire, et c'est le point spécifique à MariaDB le plus important de tout ce guide. Depuis la version 10.4, MariaDB peut gérer plusieurs mécanismes d'authentification par compte, et c'est exactement ainsi que root est configuré après une installation par paquet : d'abord le socket, à défaut le mot de passe. Si vous utilisez à la place le simple ALTER USER 'root'@'localhost' IDENTIFIED BY '...', vous remplacez toute la chaîne par une authentification par mot de passe uniquement. Cela fonctionne, mais sudo mariadb ne passe ensuite plus sans mot de passe, et les scripts de maintenance internes de la distribution, qui comptent sur le socket, tournent dans le vide. Vous n'aurez alors fait que repousser le problème d'un an.

Pour finir, supprimez cet état d'exception :

sudo systemctl stop mariadb
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl start mariadb

N'oubliez pas unset-environment. La variable est attachée au gestionnaire systemd, pas au service, et elle survit à chaque redémarrage du service. Si une mise à jour de paquets relance MariaDB pendant la nuit, votre base de données continue de tourner à partir de ce moment sans le moindre contrôle des droits, et personne ne le remarque. Seul un redémarrage complet du serveur efface la variable de lui-même.

MySQL 8 : la commande de la plupart des tutoriels ne fait rien ici

Pour MySQL, la même recette circule avec systemctl set-environment MYSQLD_OPTS=.... Elle provient de la documentation d'Oracle et correspond aux paquets d'Oracle. Or l'unit de l'archive Ubuntu est différente, on y lit simplement ExecStart=/usr/sbin/mysqld, sans variable. La commande s'exécute, ne signale aucune erreur, et le serveur démarre malgré tout tout à fait normalement, contrôle des droits actif. Vous vous retrouvez alors devant un Access denied sans comprendre. Vérifiez par vous-même :

systemctl cat mysql | grep ExecStart

Si $MYSQLD_OPTS n'y apparaît pas, il vous faut un drop-in. Et tant qu'à en créer un, autant prendre tout de suite la meilleure voie : --init-file. Le serveur démarre alors tout à fait normalement, avec contrôle des droits, et exécute au démarrage un fichier SQL avec tous les privilèges. Il n'existe aucune fenêtre pendant laquelle qui que ce soit pourrait entrer sans mot de passe. Oracle recommande explicitement cette variante plutôt que --skip-grant-tables.

sudo systemctl stop mysql
printf "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'VotreNouveauMotDePasse';\n" | sudo tee /var/lib/mysql-files/kh-reset.sql
sudo chown mysql:mysql /var/lib/mysql-files/kh-reset.sql
sudo chmod 600 /var/lib/mysql-files/kh-reset.sql
sudo mkdir -p /etc/systemd/system/mysql.service.d

Le IDENTIFIED WITH caching_sha2_password est la partie décisive, et la raison pour laquelle d'innombrables tutoriels échouent à cet endroit sans afficher la moindre erreur. Sur Debian et Ubuntu, root@localhost utilise le plugin auth_socket, y compris avec MySQL. Un simple IDENTIFIED BY 'motdepasse' définit bien le hash du mot de passe, mais il ne change pas le plugin. Dans mysql.user, auth_socket reste inscrit ensuite, le service démarre proprement, pas un seul message d'erreur n'apparaît, et pourtant chaque connexion par mot de passe se termine par ERROR 1698 (28000): Access denied for user 'root'@'localhost'. Le piège est d'autant plus sournois que celui qui fait la contre-vérification en tant qu'utilisateur système root est laissé entrer sans mot de passe par auth_socket et croit sa réinitialisation réussie. Faites donc le test depuis un autre compte ou via TCP. Uniquement pour de très anciens clients qui ne gèrent pas caching_sha2_password, utilisez à la place mysql_native_password, avec les restrictions décrites dans le paragraphe plus bas.

Le répertoire /var/lib/mysql-files n'est pas choisi au hasard : il appartient à l'utilisateur de la base de données et il est autorisé dans le profil AppArmor de mysqld. Si vous placez le fichier dans /root ou /tmp, le démarrage peut échouer à cause d'AppArmor, et le message dans le log n'aide guère. Passons au drop-in :

[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld --init-file=/var/lib/mysql-files/kh-reset.sql

La première ligne ExecStart vide est obligatoire, sans elle systemd ajoute votre commande à celle qui existe déjà et refuse de lancer le service avec une erreur de configuration. Enregistrez le fichier sous /etc/systemd/system/mysql.service.d/override.conf, puis :

sudo systemctl daemon-reload
sudo systemctl start mysql
sudo mysql -u root -p

Si la connexion fonctionne, supprimez les deux, le fichier SQL et le drop-in :

sudo rm -f /var/lib/mysql-files/kh-reset.sql
sudo rm -f /etc/systemd/system/mysql.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart mysql

Si vous tenez malgré tout à la méthode classique, remplacez la ligne du drop-in par ExecStart=/usr/sbin/mysqld --skip-grant-tables --skip-networking, connectez-vous avec sudo mysql et lancez-y d'abord FLUSH PRIVILEGES;, puis ALTER USER. Une remarque sur le chiffrement : MySQL 8 utilise caching_sha2_password par défaut. Si une application très ancienne se manifeste ensuite avec « The server requested authentication method unknown to the client », IDENTIFIED WITH mysql_native_password BY '...' résout le problème. C'est toutefois une impasse, car ce mécanisme est considéré comme obsolète depuis la 8.0.34 et n'est plus présent dans MySQL 8.4. Mieux vaut mettre le client à jour.

Les messages d'erreur, mot pour mot

ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement. Vous avez oublié FLUSH PRIVILEGES;. Lancez la commande, et ALTER USER fonctionnera.

ERROR 1288 (HY000): The target table user of the UPDATE is not updatable. Vous suivez un vieux tutoriel qui propose UPDATE mysql.user SET password=.... Depuis MariaDB 10.4, les droits résident dans mysql.global_priv, et mysql.user n'en est plus qu'une vue. Utilisez ALTER USER ou SET PASSWORD. Au passage : écrire directement dans les tables de droits était déjà autrefois une excellente manière de détruire définitivement le compte.

ERROR 1698 (28000): Access denied for user 'root'@'localhost'. Ce n'est pas un mot de passe erroné, c'est l'inverse : le compte attend une authentification par socket, et vous n'êtes pas connecté en tant qu'utilisateur système root, ou bien vous avez passé -p. Réessayez avec sudo et sans -p.

ERROR 1524 (HY000): Plugin 'unix_socket' is not loaded. Le compte renvoie à un plugin que le serveur en cours d'exécution ne connaît pas, ce qui est typique après un passage de MariaDB à MySQL ou après la copie d'un répertoire de données. Reconfigurez le compte sur un mécanisme adapté en suivant la méthode ci-dessus.

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2). Le serveur ne tourne pas. Regardez d'abord systemctl status et le log, n'insistez pas du côté du client.

mysqld: Can't create directory '/run/mysqld/' (Errcode: 13 - Permission denied) ou un démarrage qui s'interrompt aussitôt. Cela se produit quand le serveur a été lancé à la main plutôt que par systemd, car le répertoire d'exécution manque alors. Réparation :

sudo mkdir -p /run/mysqld
sudo chown mysql:mysql /run/mysqld

Job for mysql.service failed because the control process exited with error code. Ce message ne dit rien en soi. La cause réelle se trouve dans le journal et dans le log d'erreurs :

sudo journalctl -u 'mysql*' -u 'mariadb*' -n 60 --no-pager

Le motif reprenant les deux noms de units est délibéré, car la requête simple qui vient à l'esprit conduit à un piège silencieux. Sur Debian avec MariaDB, mysql.service n'est qu'un alias de mariadb.service. systemctl résout l'alias, mais le journal indexe les entrées sous le vrai nom de l'unit, et journalctl -u mysql répond donc -- No entries -- avec le code de sortie 0, alors même que le journal est plein. À l'inverse, journalctl -u mariadb renvoie lui aussi -- No entries -- sur un système Ubuntu équipé de MySQL.

Il en va de même pour le fichier d'erreurs. Le /var/log/mysql/error.log cité partout n'existe que sur Ubuntu avec MySQL. Sur Debian avec MariaDB, le répertoire /var/log/mysql/ n'existe pas du tout, parce que log_error est commenté dans 50-server.cnf et que MariaDB écrit dans le journal. La ligne qui convient selon le système :

Système et serveurCommande
Debian ou Ubuntu, MariaDBsudo journalctl -u mariadb -n 60 --no-pager
Ubuntu, MySQLsudo tail -n 60 /var/log/mysql/error.log
AlmaLinux, Rocky, RHEL, MySQLsudo tail -n 60 /var/log/mysql/mysqld.log
AlmaLinux, Rocky, RHEL, MariaDBsudo tail -n 60 /var/log/mariadb/mariadb.log

Si vous ne voulez pas deviner le chemin, interrogez le serveur lui-même : sudo mariadb -e "SHOW VARIABLES LIKE 'log_error';" ou la même chose avec mysql.

Les trois causes les plus fréquentes à ce stade : une faute de frappe dans le drop-in (systemd signale alors la ligne fautive), un disque plein (voir à ce sujet Disque plein sous Linux) ou un deuxième processus serveur encore actif qui maintient les fichiers de données verrouillés. Ce dernier point se vérifie avec pgrep -a mariadbd ou pgrep -a mysqld avant de redémarrer.

Si, après la réinitialisation, vous entrez bien mais que vos applications restent rejetées, le problème se situe ailleurs : des applications comme WordPress ou Nextcloud utilisent leurs propres utilisateurs de base de données, pas root. Les détails se trouvent dans Résoudre MySQL Access denied for user.

Comment savoir que l'opération a vraiment réussi

Une connexion réussie ne suffit pas comme preuve, car en mode dégradé elle passe aussi sans le moindre mot de passe. Vérifiez donc quatre points une fois que le service tourne de nouveau normalement.

Premièrement : plus aucune configuration exceptionnelle n'est active. La première sortie doit être vide, la seconde ne doit plus afficher d'options supplémentaires.

systemctl show-environment | grep MYSQLD_OPTS
systemctl cat mariadb | grep ExecStart

Deuxièmement : le contrôle des droits est de nouveau actif. Une connexion avec un mot de passe volontairement erroné doit échouer. Si elle aboutit, le serveur tourne toujours grand ouvert.

Troisièmement : le nouveau mot de passe et le mécanisme attendu sont bien inscrits dans le compte. Sous MariaDB, l'interrogation se fait ainsi, sous MySQL sans la colonne JSON :

sudo mariadb -e "SELECT user, host, plugin FROM mysql.user WHERE user='root';"
sudo mysql -e "SELECT user, host, plugin FROM mysql.user WHERE user='root';"

Quatrièmement : le port réseau se comporte de nouveau comme avant. Un serveur de base de données utilisé uniquement en local doit, après le nettoyage, écouter à nouveau exclusivement sur 127.0.0.1 :

sudo ss -ltnp | grep 3306
grep -rs bind-address /etc/mysql/ /etc/my.cnf /etc/my.cnf.d/

Le -s et les trois chemins sont volontaires. grep -r bind-address /etc/mysql/ seul s'interrompt dans la famille Red Hat avec No such file or directory, puisque /etc/mysql/ n'y existe pas. Avec -s, grep ignore silencieusement les chemins absents, et la ligne convient aux deux mondes.

Faire le ménage pour éviter une deuxième fois

Le mot de passe se trouve désormais peut-être à des endroits auxquels vous ne pensez pas. Une commande avec -e "ALTER USER ... IDENTIFIED BY '...'" atterrit dans ~/.bash_history, une commande saisie dans l'invite atterrit dans le fichier d'historique du client de base de données. Les deux doivent être nettoyés :

history -c
rm -f ~/.mysql_history ~/.mariadb_history

Les deux noms de fichiers sont nécessaires, car le client a changé de nom en cours de route. Jusqu'à MariaDB 10.11, donc jusqu'à Debian 12 inclus, il écrit dans ~/.mysql_history. À partir de MariaDB 11, donc à partir de Debian 13, il écrit dans ~/.mariadb_history. Celui qui n'y supprime que l'ancien fichier laisse traîner sur le disque le mot de passe saisi en clair, sans s'en apercevoir. Mieux encore : empêcher l'historique d'apparaître, avec export MYSQL_HISTFILE=/dev/null ou export MARIADB_HISTFILE=/dev/null avant la session, ou directement la méthode --init-file de la section MySQL, où le mot de passe ne passe jamais par une session interactive.

Plus judicieux qu'un mot de passe que vous aurez de nouveau oublié dans un an : une configuration sans mot de passe au quotidien. Sur Debian et Ubuntu, cela veut dire que root reste sur unix_socket ou auth_socket, et que pour tout le reste vous créez des utilisateurs normaux avec exactement les droits dont l'application concernée a besoin. Si vous avez besoin d'un accès depuis une autre machine, faites-le passer par un tunnel SSH au lieu d'ouvrir le port 3306, voir Se connecter au serveur en SSH.

Puisque vous travaillez de toute façon sur la base de données, réglez le reste dans la foulée : supprimer les utilisateurs anonymes, effacer la base de test, désactiver l'accès distant pour root. mariadb-secure-installation ou mysql_secure_installation s'en charge en quelques minutes, la procédure est décrite en détail dans Sécuriser MariaDB et MySQL. Et comme le mot de passe est rarement le seul point qui cloche sur un serveur fraîchement repris, un passage par la checklist pour les nouveaux serveurs root en vaut la peine.

Une dernière réflexion sur l'ordre des opérations : avant de faire basculer un serveur de production en fonctionnement dans cet état sans droits, faites une sauvegarde du répertoire de données ou un snapshot. La réinitialisation en elle-même est inoffensive, mais un service qui ne démarre plus après une faute de frappe dans l'unit ne l'est plus du tout à trois heures du matin.

Questions fréquentes

J'ai oublié le mot de passe root. Dois-je vraiment arrêter MySQL ?
La plupart du temps, non. Sur Debian et Ubuntu, le compte root de la base de données est protégé par le socket Unix, pas par un mot de passe. Essayez d'abord sudo mariadb ou sudo mysql, dans les deux cas sans l'option -p. Si cela fonctionne, définissez un nouveau mot de passe avec ALTER USER pendant que le serveur continue de tourner. Ce n'est que si cette voie échoue avec Access denied que vous aurez besoin du redémarrage avec le contrôle des droits désactivé.
Pourquoi ai-je ERROR 1290 alors que j'ai démarré avec skip-grant-tables ?
Parce que dans cet état le serveur n'a pas chargé les tables de droits et ne peut donc effectuer aucune gestion de compte. Lancez d'abord FLUSH PRIVILEGES dans l'invite, après quoi ALTER USER fonctionne comme d'habitude. Le message complet est le suivant : The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement.
Mon serveur est-il vulnérable pendant la réinitialisation ?
Oui, et totalement. Avec le contrôle des droits désactivé, il n'y a plus aucune authentification, et chaque tentative de connexion obtient tous les droits sur toutes les bases de données. MySQL 8 coupe automatiquement le port réseau, MariaDB pas nécessairement. Ajoutez donc toujours --skip-networking vous-même, arrêtez les serveurs web et les services applicatifs, et limitez la fenêtre à quelques minutes. Le socket local reste malgré tout ouvert à tous les utilisateurs système.
Quelle est la différence entre MySQL 8 et MariaDB pour la réinitialisation ?
Trois choses. D'abord l'unit systemd : chez MariaDB, systemctl set-environment MYSQLD_OPTS prend effet, chez le MySQL de l'archive Ubuntu non, et il vous faut alors un drop-in avec sa propre ligne ExecStart. Ensuite les tables de droits : à partir de MariaDB 10.4, mysql.user n'est plus qu'une vue sur mysql.global_priv, et les commandes UPDATE directes échouent avec ERROR 1288. Enfin la syntaxe des comptes : MariaDB sait gérer les deux mécanismes à la fois avec IDENTIFIED VIA unix_socket OR mysql_native_password, alors que MySQL n'en connaît qu'un seul par compte. Chez MySQL, le WITH est la partie décisive : ALTER USER ... IDENTIFIED BY ne définit que le hash du mot de passe et laisse le plugin sur auth_socket, si bien que la connexion par mot de passe échoue quand même avec ERROR 1698. La forme correcte est ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '...'.
Après la réinitialisation, j'entre en tant que root, mais mon site signale toujours Access denied. Pourquoi ?
Parce que des applications comme WordPress, Nextcloud ou les systèmes de boutique ne travaillent pas avec le compte root, elles utilisent leurs propres utilisateurs de base de données. Leurs mots de passe se trouvent dans le fichier de configuration de l'application concernée et ne sont pas touchés par la réinitialisation de root. Vérifiez l'utilisateur enregistré dans l'application et définissez le cas échéant son mot de passe en conséquence.
Que se passe-t-il si j'oublie systemctl unset-environment ?
La variable est attachée au gestionnaire systemd et survit à chaque redémarrage du service. Si une mise à jour de paquets relance la base de données pendant la nuit, celle-ci tourne à partir de ce moment durablement sans contrôle des droits, et personne ne le remarque. Seul un redémarrage complet du serveur l'efface de lui-même. Une fois le travail terminé, vérifiez avec systemctl show-environment que MYSQLD_OPTS n'est plus défini.

MySQL MariaDB Mot de passe root Debian Ubuntu systemd Base de données Administration serveur unix_socket Dépannage