دیتابیس

نحوه ریست کردن رمز عبور Root در MySQL یا MariaDB

مقدمه

می‌توانید رمز عبور root مربوط به MySQL یا MariaDB را بدون رمز قدیمی ریست کنید؛ تا وقتی که به سرور و کاربر دارای sudo دسترسی دارید. این آموزش نشان می‌دهد چطور با دو روش root را بازیابی کنید: شروع سرور با --skip-grant-tables (و اختیاری --skip-networking)؛ یا رویکرد امن‌تر یعنی --init-file. برای MySQL 5.7+، MySQL 8.0+، MariaDB 10.1+ و MariaDB 10.4+ اعمال می‌شود؛ و روی اوبونتو 20.04، 22.04 و 24.04، دبیان ۱۱ و ۱۲، و RHEL/AlmaLinux/Rocky ۸ و ۹ اعتبارسنجی شده است. SQL دقیق و نام‌های سرویس به دیتابیس و نسخه‌تان بستگی دارند؛ پس اولین گام، شناسایی اینکه کدام را اجرا می‌کنید است.

نکات کلیدی

  • دو روش اصلی ریست رمز root: سرور را با --skip-grant-tables--skip-networking) شروع کنید تا بدون رمز به‌عنوان root وصل شوید؛ سپس از طریق SQL رمز جدیدی تنظیم کنید. از این روش برای بازیابی سریع روی سیستم‌های غیر-پروداکشن استفاده کنید.
  • برای پروداکشن، به‌جایش از روش –init-file استفاده کنید. SQLِ تغییر رمز را در فایل موقتی بنویسید، سرور را با --init-file=/tmp/mysql-init-pwd.sql شروع کنید؛ سپس فایل را حذف کنید. سرور با جدول‌های Grant بارگذاری‌شده شروع می‌شود؛ پس هیچ FLUSH PRIVILEGESای لازم نیست.
  • تفاوت‌های پلاگین احراز هویت مهم‌اند: MySQL 8.0+ به‌طور پیش‌فرض از caching_sha2_password استفاده می‌کند (mysql_native_password در 8.4 حذف شد). MariaDB 10.4+ به‌طور پیش‌فرض از unix_socket برای root استفاده می‌کند؛ پس ریست رمز ممکن است تغییر پلاگین احراز هویت را هم لازم داشته باشد.

پیش‌نیازها

  • دسترسی به سرور لینوکسی که MySQL یا MariaDB روی آن نصب شده.
  • حساب کاربری با sudo تا بتوانید سرویس دیتابیس را متوقف و شروع کنید و در صورت نیاز mysqld یا mysqld_safe را اجرا کنید.

مراحل این آموزش برای توزیع‌های زیر معتبرند و با نسخه‌های فعلی پکیج‌ها اعتبارسنجی شده‌اند:

  • اوبونتو 20.04، 22.04 و 24.04 با MySQL 8.0 از مخزن APT اوبونتو یا MySQL 8.4 از مخزن APT مربوط به MySQL؛ و MariaDB 10.x از مخزن APT مربوط به MariaDB.
  • دبیان ۱۱ و ۱۲ با MySQL 8.0 یا MariaDB 10.x.
  • RHEL، CentOS Stream، AlmaLinux و راکی لینوکس ۸ و ۹ با MySQL 8.0 از مخزن RPM مربوط به MySQL یا MariaDB 10.x از مخزن RPM مربوط به MariaDB.

اگر توزیع شما MySQL را از مخازن پیش‌فرض سیستم‌عامل نصب می‌کند؛ معمولاً روی اوبونتو 22.04+، اوبونتو 24.04 و دبیان ۱۲، MySQL 8.0 خواهد بود. روی اوبونتو 20.04 هم پیش‌فرض MySQL 8.0 است. روی RHEL 8/9 و مشتقاتش، استریم ماژول پیش‌فرض MySQL 8.0 است. نسخه‌تان را در گام ۱ با mysql --version تأیید کنید.

نکته: این مراحل نیازمند دسترسی مستقیم SSH به سرور و دسترسی‌های سطح-سیستم‌عاملِ root هستند. برای سرویس‌های دیتابیس مدیریت‌شده مانند دیتابیس‌های مدیریت‌شده پارمین کلود، Amazon RDS یا هر دیتابیس میزبانی‌شده‌ای که دسترسی سطح-OS ندارید، اعمال نمی‌شوند.

اگر اول لازم است سرور را نصب کنید، راهنمای نصب MySQL روی اوبونتو در پارمین کلود را ببینید.

گام ۱ — شناسایی نسخه دیتابیس

دستورات و SQLای که استفاده می‌کنید بستگی دارد به اینکه MySQL یا MariaDB و کدام نسخه را اجرا می‌کنید. با این چک کنید:

mysql --version

از خروجی برای انتخاب دستورالعمل‌های درست در ادامه استفاده کنید:

  • MySQL 8.0 یا جدیدتر: از ALTER USER ... IDENTIFIED WITH caching_sha2_password BY '...'; استفاده خواهید کرد. روی بسیاری از سیستم‌ها، mysqld_safe موجود نیست؛ از sudo -u mysql mysqld --skip-grant-tables --skip-networking یا روش --init-file استفاده کنید.
  • MySQL 5.7.x: از ALTER USER 'root'@'localhost' IDENTIFIED BY '...'; استفاده خواهید کرد. در صورت موجود بودن، می‌توانید از mysqld_safe --skip-grant-tables --skip-networking استفاده کنید.
  • MariaDB 10.4 یا جدیدتر: root ممکن است از احراز هویت unix_socket استفاده کند؛ اگر رمز لازم دارید، از ALTER USER استفاده و اختیاری پلاگین را روی mysql_native_password تنظیم کنید.
  • MariaDB 10.1.20 و جدیدتر (شامل 10.2، 10.3): ALTER USER 'root'@'localhost' IDENTIFIED BY '...'; معتبر است.

نمونه خروجی برای MySQL 5.7:

mysql  Ver 14.14 Distrib 5.7.16, for Linux (x86_64) using  EditLine wrapper

نمونه خروجی برای MySQL 8:

mysql  Ver 8.0.35 for Linux on x86_64 (MySQL Community Server - GPL)

نمونه خروجی برای MariaDB:

mysql  Ver 15.1 Distrib 10.5.21-MariaDB, for Linux (x86_64) using readline 5.1

گام ۲ — متوقف کردن سرور دیتابیس

سرویس دیتابیس را متوقف کنید تا بتوانید دستی و با بررسی دسترسیِ غیرفعال‌شده شروعش کنید. نام سرویس به سیستم‌عامل و اینکه MySQL یا MariaDB اجرا می‌کنید بستگی دارد:

  • دبیان/اوبونتو (MySQL): نام سرویس mysql است.
  • RHEL/CentOS/AlmaLinux/Rocky (MySQL): نام سرویس mysqld است. فایل PID اغلب /var/run/mysqld/mysqld.pid یا زیر /var/lib/mysql/ بسته به توزیع است.
  • MariaDB (همه توزیع‌های پشتیبانی‌شده): نام سرویس mariadb است.

مثال‌ها:

MySQL روی دبیان/اوبونتو:

sudo systemctl stop mysql

MySQL روی RHEL/CentOS/AlmaLinux/Rocky:

sudo systemctl stop mysqld

MariaDB:

sudo systemctl stop mariadb

توقف سرویس را تأیید کنید:

MySQL:

sudo systemctl status mysql

MariaDB:

sudo systemctl status mariadb

سرویس متوقف‌شده Active: inactive (dead) را در خروجی نشان می‌دهد. سپس به شروع سرور بدون جدول‌های Grant بروید.

گام ۳ — ری‌استارت کردن سرور دیتابیس بدون بررسی دسترسی

سرور را با --skip-grant-tables و --skip-networking شروع کنید. این به MySQL یا MariaDB می‌گوید بارگذاری داده‌های دسترسی کاربر را کاملاً رد کند؛ که به شما اجازه می‌دهد به‌صورت محلی و بدون رمز به‌عنوان root وصل شوید. فلگ --skip-networking تضمین می‌کند هیچ کلاینت ریموتی نتواند وصل شود وقتی سرور در این وضعیت بدون‌حفاظت است.

MySQL 5.7 (وقتی mysqld_safe موجود است):

sudo mysqld_safe --skip-grant-tables --skip-networking &

& پروسه را در پس‌زمینه اجرا می‌کند تا بتوانید به استفاده از ترمینال ادامه دهید.

MySQL 8.0+ (بدون mysqld_safe روی بسیاری از سیستم‌ها):

روی توزیع‌هایی که mysqld_safe حذف شده، مستقیماً mysqld را شروع کنید:

sudo -u mysql mysqld --skip-grant-tables --skip-networking &

امنیت: --skip-grant-tables احراز هویت را غیرفعال می‌کند. همیشه از --skip-networking استفاده کنید تا سرور اتصالات شبکه را نپذیرد. ریست را تا جای ممکن سریع اجرا کنید. برای پروداکشن، «روش جایگزین: استفاده از –init-file» را در پایین ترجیح دهید.

MariaDB:

sudo mysqld_safe --skip-grant-tables --skip-networking &

اگر mysqld_safe: command not found دیدید، مثل MySQL 8 از sudo -u mysql mysqld --skip-grant-tables --skip-networking & استفاده کنید.

به‌عنوان root وصل شوید (بدون رمز):

mysql -u root

باید فوراً پرامپتی بگیرید.

MySQL:

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

MariaDB:

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

گام ۴ — تغییر رمز عبور Root

با جدول‌های Grantِ رد‌شده، سرور هیچ قانون دسترسی‌ای را نمی‌شناسد و از اعمال تغییرات بر آن‌ها امتناع می‌کند. جدول‌های Grant چیزی هستند که MySQL و MariaDB برای تصمیم‌گیری درباره اینکه چه کسی چه کاری می‌تواند انجام دهد استفاده می‌کنند. اول آن‌ها را ریلود کنید تا سرور بتواند تغییر رمز‌تان را پردازش کند:

FLUSH PRIVILEGES;

سپس رمز جدید را با دستوری که با نسخه‌تان مطابقت دارد تنظیم کنید.

MySQL 8.0+ (پلاگین احراز هویت پیش‌فرض caching_sha2_password است؛ mysql_native_password در 8.0 منسوخ و در 8.4 حذف شده):

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'new_password';

برای مرجع کامل سینتکس، مستندات MySQL 8.0 برای ALTER USER و مستندات MariaDB برای ALTER USER را ببینید.

MySQL 5.7.6 و جدیدتر (نه 8.0):

ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

MariaDB 10.4+ (اگر root از unix_socket استفاده می‌کند و احراز هویت مبتنی بر رمز می‌خواهید، پلاگین و رمز را تنظیم کنید):

روی MariaDB 10.4+، احراز هویت root به‌طور پیش‌فرض unix_socket است. یعنی MariaDB به‌جای رمز عبور، هویت کاربر لینوکسی‌تان را چک می‌کند. اگر به‌عنوان کاربر root سیستم اجرا می‌کنید، MariaDB بدون رمز اجازه ورود می‌دهد. اگر دسترسی مبتنی بر رمز لازم دارید (مثلاً برای اپلیکیشنی که به‌عنوان root وصل می‌شود)، باید صریحاً پلاگین احراز هویت را عوض کنید:

ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('new_password');

یا برای فقط تنظیم رمز و نگه داشتن پلاگین موجود:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

نکته: برای تأیید درست به‌روزرسان شدن پلاگین، بعد از اتصال مجددِ معمول اجرا کنید: SELECT user, host, plugin FROM mysql.user WHERE user='root';

MariaDB 10.1.20 و جدیدتر (10.1، 10.2، 10.3):

ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

MySQL 5.7.5 و قدیمی‌تر / MariaDB 10.1.19 و قدیمی‌تر:

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');

new_password را با رمز انتخابی‌تان جایگزین کنید. موفقیت این‌طور است:

Query OK, 0 rows affected (0.00 sec)

نکته: اگر ALTER USER موجود نیست یا شکست می‌خورد، می‌توانید جدول Grant را مستقیم به‌روزرسانی کنید (MySQL 5.7 / MariaDB): UPDATE mysql.user SET authentication_string = PASSWORD('new_password') WHERE User = 'root' AND Host = 'localhost'; سپس دوباره FLUSH PRIVILEGES; را اجرا کنید. وقتی نسخه‌تان پشتیبانی می‌کند، ALTER USER را ترجیح دهید.

گام ۵ — ری‌استارت معمول سرور دیتابیس

پروسۀ MySQL یا MariaDBِ دستی-شروع‌شده را متوقف کنید. PID آن را پیدا و SIGTERM بفرستید تا تمیز خاموش شود.

MySQL یا MariaDB:

sudo kill $(cat /var/run/mysqld/mysqld.pid)

نکته: اگر مسیر فایل PID روی توزیع‌تان متفاوت است، از sudo mysqladmin -u root -p shutdown به‌عنوان جایگزین قابل اطمینان برای هر دوی MySQL و MariaDB استفاده کنید. برای پیدا کردن مکان فایل PID، دایرکتیو pid-file را در پیکربندی MySQL چک کنید:

grep pid-file /etc/my.cnf /etc/mysql/my.cnf 2>/dev/null

سپس سرویس را دوباره شروع کنید.

MySQL روی دبیان/اوبونتو:

sudo systemctl start mysql

MySQL روی RHEL/CentOS/AlmaLinux/Rocky:

sudo systemctl start mysqld

MariaDB:

sudo systemctl start mariadb

رمز جدید را تأیید کنید:

mysql -u root -p

رمز جدید را هنگام درخواست وارد کنید. ورود موفق این‌طور است:

MySQL:

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

MariaDB:

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

اگر ERROR 1045 (28000): Access denied for user 'root'@'localhost' دیدید، بخش «عیب‌یابی خطاهای رایج» را در پایین ببینید.

روش جایگزین: استفاده از –init-file (توصیه‌شده برای پروداکشن)

روش --init-file، فایل SQLای را یک‌بار هنگام استارت سرور اجرا، رمز جدید را تنظیم و سپس شما فایل را حذف می‌کنید. سرور با جدول‌های Grant بارگذاری‌شده و احراز هویت کاملِ در تمام طول اجرا شروع می‌شود. هرگز instanceای بدون احراز هویت را برای شبکه افشا نمی‌کنید؛ که این را به انتخاب امن‌تری برای سیستم‌های پروداکشن تبدیل می‌کند.

فایل SQL موقتی بسازید (مثلاً /tmp/mysql-init-pwd.sql) با دستور مناسب. از یکی از موارد زیر استفاده، سپس new_password را با رمز واقعی‌تان جایگزین کنید.

MySQL 8.0+:

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'new_password';

MySQL 5.7 (و MariaDB 10.1.20+ با احراز هویت استاندارد):

ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

MariaDB 10.4+ (برای تنظیم رمز و استفاده از mysql_native_password):

ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('new_password');

سرویس دیتابیس را با دستور مخصوص توزیع‌تان از گام ۲ متوقف کنید:

  • MySQL روی دبیان/اوبونتو: sudo systemctl stop mysql
  • MySQL روی RHEL/CentOS/AlmaLinux/Rocky: sudo systemctl stop mysqld
  • MariaDB: sudo systemctl stop mariadb

سرور را با فایل init شروع کنید (از ترمینال اجرا کنید؛ نه به‌عنوان کار پس‌زمینه تا ببینید کِی init را تمام کرده):

sudo -u mysql mysqld --init-file=/tmp/mysql-init-pwd.sql

منتظر بمانید سرور شروع را تمام کند. چون پروسه در پیش‌زمینه اجرا می‌شود، خروجی مستقیم در ترمینال‌تان ظاهر می‌شود. به دنبال خطی مثل این بگردید:

[Note] mysqld: ready for connections.

وقتی دیدیدش، سرور را با دستور مناسب توزیع‌تان تمیز متوقف کنید. ترمینال دومی باز کنید تا دستور توقف را اجرا کنید. در ترمینالی که mysqld در حال اجراست، از Ctrl+C یا SIGINT استفاده نکنید.

MySQL روی دبیان/اوبونتو:

sudo systemctl stop mysql

MySQL روی RHEL/CentOS/AlmaLinux/Rocky:

sudo systemctl stop mysqld

MariaDB:

sudo systemctl stop mariadb

اگر systemctl نتواند پروسه دستی-شروع‌شده را متوقف کند، از sudo mysqladmin -u root -p shutdown استفاده کنید (از شما رمز جدیدی که همین الان تنظیم کردید پرسیده می‌شود)؛ یا مستقیم SIGTERM بفرستید:

sudo kill $(cat /var/run/mysqld/mysqld.pid)

نکته: چون سرور هنگام استفاده از --init-file با جدول‌های Grant بارگذاری‌شده شروع می‌شود، لازم نیست FLUSH PRIVILEGES اجرا کنید. دستور ALTER USER فوراً اثر می‌گذارد.

فایل init را حذف کنید تا رمز روی دیسک باقی نماند:

sudo rm /tmp/mysql-init-pwd.sql

سرویس را معمول شروع و ورود را تست کنید.

MySQL روی دبیان/اوبونتو:

sudo systemctl start mysql

MySQL روی RHEL/CentOS/AlmaLinux/Rocky:

sudo systemctl start mysqld

MariaDB:

sudo systemctl start mariadb

سپس تأیید کنید رمز جدید کار می‌کند:

mysql -u root -p

عیب‌یابی خطاهای رایج

ERROR 1290 (HY000): The MySQL server is running with the –skip-grant-tables option

این وقتی ظاهر می‌شود که ALTER USER (یا سایر دستورات تغییر-دسترسی) را قبل از ریلود جدول‌های Grant اجرا کنید. با --skip-grant-tables، سرور تا وقتی FLUSH PRIVILEGES; را اجرا نکنید تغییرات دسترسی را اعمال نمی‌کند. اول FLUSH PRIVILEGES; را اجرا؛ سپس ALTER USER (یا SET PASSWORD) خود را دوباره اجرا کنید.

ERROR 1524 (HY000): Plugin ‘unix_socket’ is not loaded

روی MariaDB، root اغلب طوری پیکربندی شده که از احراز هویت unix_socket استفاده کند. اگر پلاگین socket بارگذاری نشده یا مسائل پیکربندی وجود دارد، این خطا را می‌بینید. مطمئن شوید به‌عنوان کاربر root سیستم (یا همان کاربر OS ای که مالک socket است) وصل می‌شوید. برای تغییر به احراز هویت مبتنی بر رمز، مثل گام ۴ از ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('...'); استفاده کنید.

mysqld_safe: command not found

روی MySQL 8.0+، بسیاری از پکیج‌ها دیگر mysqld_safe را عرضه نمی‌کنند. به‌جایش از sudo -u mysql mysqld --skip-grant-tables --skip-networking & استفاده کنید؛ یا از روش --init-file.

Access denied for user ‘root’@’localhost’ بعد از ریست

این معمولاً عدم تطابق پلاگین احراز هویت است. مثلاً، کلاینت یا سرویس دیگری mysql_native_password انتظار دارد اما سرور الان برای root از caching_sha2_password استفاده می‌کند.

اگر می‌توانید وارد شوید، پلاگین را مستقیم چک کنید:

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

اگر اصلاً نمی‌توانید وارد شوید، برای تشخیص بدون رمز به نشست skip-grant-tables برگردید. سرویس را متوقف، مثل گام ۳ با --skip-grant-tables --skip-networking ری‌استارت، با mysql -u root وصل شوید؛ سپس اجرا کنید:

SELECT user, host, plugin FROM mysql.user WHERE user='root';

وقتی پلاگین را دانستید، دستور ALTER USER درست را از گام ۴ اجرا کنید تا هم رمز و هم پلاگینی که کلاینت‌تان انتظار دارد تنظیم شود؛ سپس سرویس را معمول ری‌استارت کنید.

سوالات متداول

س: چطور رمز root مربوط به MySQL را بدون رمز قدیمی ریست کنم؟

ج: سرویس MySQL را متوقف، با --skip-grant-tables و --skip-networking ری‌استارت، بدون رمز به‌عنوان root وصل، FLUSH PRIVILEGES را اجرا؛ سپس از ALTER USER برای تنظیم رمز جدید استفاده کنید. مراحل کامل در این آموزش است.

س: تفاوت ریست رمز root در MySQL و MariaDB چیست؟

ج: سینتکس SQL برای نسخه‌های اخیر تقریباً یکسان است؛ اما MariaDB 10.4+ به‌طور پیش‌فرض از احراز هویت unix_socket برای root استفاده می‌کند؛ یعنی ممکن است اصلاً برای ورود محلی root رمزی لازم نباشد. اگر احراز هویت مبتنی بر رمز لازم دارید، باید صریحاً پلاگین احراز هویت را تغییر دهید.

س: چرا ALTER USER بعد از skip-grant-tables شکست می‌خورد؟

ج: وقتی MySQL یا MariaDB با --skip-grant-tables شروع می‌شود، توابع SQLِ مرتبط-با-دسترسی غیرفعال‌اند. باید اول FLUSH PRIVILEGES را اجرا کنید تا جدول‌های Grant قبل از اجرای موفق ALTER USER ریلود شوند.

س: آیا استفاده از –skip-grant-tables امن است؟

ج: فقط در محیط کنترل‌شده. گزینه --skip-grant-tables همه احراز هویت را غیرفعال می‌کند و بدون --skip-networking، دیتابیس را برای هر کلاینت شبکه‌ای افشا می‌کند. همیشه آن را با --skip-networking جفت کنید و ریست را تا جای ممکن سریع انجام دهید. برای سرورهای پروداکشن، روش --init-file امن‌تر است.

س: چطور رمز root مربوط به MySQL را روی اوبونتو ریست کنم؟

ج: روی اوبونتو، نام سرویس MySQL mysql است. با sudo systemctl stop mysql متوقفش کنید، مراحل skip-grant-tables را در این آموزش دنبال کنید؛ سپس با sudo systemctl start mysql ری‌استارتش کنید.

درباره نویسنده

این آموزش توسط نویسنده فنی با تجربه عملی در مدیریت MySQL و MariaDB روی سیستم‌های پروداکشن لینوکسی—شامل مهاجرت‌های نسخه، تغییرات پلاگین احراز هویت و عملیات بازیابی دیتابیس—نوشته و اعتبارسنجی شده است. برای منعکس کردن رفتار فعلی در MySQL 8.0+ و MariaDB 10.4+ مرور و به‌روز شده است.

نتیجه‌گیری

بعد از ریست کردن رمز root، ورود را با mysql -u root -p تأیید کنید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا