المستخدمون والصلاحيات والنسخ الاحتياطي في MySQL
حتى الآن تعمل بالمستخدم root، وهو يملك كل شيء: يحذف أي جدول وأي قاعدة. هذا مقبول على جهازك، وخطير على خادم حقيقي: لو تسربت كلمة مروره من كود الموقع، ضاع كل شيء. في هذا الدرس الأخير ستتعلم مهارتين يحتاجهما كل من ينشر موقعاً: منح كل برنامج أقل صلاحيات تكفيه، وأخذ نسخة احتياطية تعيد بها بياناتك إذا وقعت الكارثة.
من يستطيع الدخول؟
Section titled “من يستطيع الدخول؟”SELECT user, host FROM mysql.user ORDER BY user;الناتج:
| user | host |
|---|---|
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
الحساب في MySQL اسم ومصدر اتصال معاً: root@localhost يعني المستخدم root عندما يتصل من الجهاز نفسه. والحسابات التي تبدأ بـ mysql. داخلية للنظام، فلا تلمسها.
إنشاء مستخدم
Section titled “إنشاء مستخدم”سننشئ حساباً خاصاً بتطبيق المتجر:
CREATE USER 'shop_app'@'localhost' IDENTIFIED BY 'Str0ng!Pass2026';
SHOW GRANTS FOR 'shop_app'@'localhost';الناتج:
| Grants for shop_app@localhost |
|---|
| GRANT USAGE ON *.* TO `shop_app`@`localhost` |
USAGE تعني «يستطيع تسجيل الدخول فقط»: لا صلاحية على أي بيانات. جرّبنا الدخول بالحساب الجديد:
mysql -u shop_app -pUSE shop;الناتج: ERROR 1044 (42000): Access denied for user 'shop_app'@'localhost' to database 'shop'
المستخدم الجديد لا يرى قاعدة shop أصلاً. هذا هو المبدأ الصحيح: كل شيء ممنوع حتى تسمح به.
GRANT: منح الصلاحيات
Section titled “GRANT: منح الصلاحيات”التطبيق يحتاج قراءة البيانات وإضافة الطلبات وتعديل المخزون، ولا يحتاج حذف الجداول أبداً. من حساب root:
GRANT SELECT, INSERT, UPDATE ON shop.* TO 'shop_app'@'localhost';
SHOW GRANTS FOR 'shop_app'@'localhost';الناتج:
| Grants for shop_app@localhost |
|---|
| GRANT USAGE ON *.* TO `shop_app`@`localhost` |
| GRANT SELECT, INSERT, UPDATE ON `shop`.* TO `shop_app`@`localhost` |
- بعد
GRANT: الصلاحيات الممنوحة. ON shop.*: على كل جداول قاعدةshop. ويمكن التحديد أكثر:shop.productsلجدول واحد.TO: الحساب المستفيد.
والآن بحساب shop_app:
SELECT COUNT(*) AS products_count FROM products;الناتج:
| products_count |
|---|
| 6 |
DELETE FROM orders WHERE id = 1;الناتج: ERROR 1142 (42000): DELETE command denied to user 'shop_app'@'localhost' for table 'orders'
القراءة تعمل، والحذف مرفوض. حتى لو اخترق أحدهم الموقع وحصل على كلمة مرور shop_app، لن يستطيع حذف الطلبات ولا إسقاط الجداول.
هذا هو مبدأ أقل الصلاحيات (Least Privilege). مثل مفاتيح الفندق: مفتاح النزيل يفتح غرفته فقط، ومفتاح عامل النظافة يفتح الغرف ولا يفتح الخزنة، والمفتاح الرئيسي مع المدير وحده.
| الصلاحية | تسمح بـ |
|---|---|
SELECT |
قراءة البيانات |
INSERT و UPDATE و DELETE |
إضافة الصفوف وتعديلها وحذفها |
CREATE و ALTER و DROP |
إنشاء الجداول وتعديل بنيتها وحذفها |
ALL PRIVILEGES |
كل ما سبق. لا تمنحها لتطبيق |
صلاحية على عرض فقط
Section titled “صلاحية على عرض فقط”في الدرس السابق أنشأنا العرض order_details. سنمنح موظف التقارير حق القراءة منه وحده:
CREATE USER 'reports'@'localhost' IDENTIFIED BY 'R3ports!Only';GRANT SELECT ON shop.order_details TO 'reports'@'localhost';وبحساب reports:
SHOW TABLES;الناتج:
| Tables_in_shop |
|---|
| order_details |
SELECT * FROM customers;الناتج: ERROR 1142 (42000): SELECT command denied to user 'reports'@'localhost' for table 'customers'
يرى تقرير الطلبات كاملاً، ولا يرى جدول العملاء ولا يعلم بوجود بقية الجداول.
REVOKE: سحب الصلاحيات
Section titled “REVOKE: سحب الصلاحيات”REVOKE UPDATE ON shop.* FROM 'shop_app'@'localhost';
SHOW GRANTS FOR 'shop_app'@'localhost';الناتج:
| Grants for shop_app@localhost |
|---|
| GRANT USAGE ON *.* TO `shop_app`@`localhost` |
| GRANT SELECT, INSERT ON `shop`.* TO `shop_app`@`localhost` |
REVOKE عكس GRANT بالصيغة نفسها، مع FROM بدل TO. بعدها أي UPDATE من هذا الحساب يُرفض بالخطأ 1142.
تغيير كلمة المرور وحذف المستخدم
Section titled “تغيير كلمة المرور وحذف المستخدم”ALTER USER 'shop_app'@'localhost' IDENTIFIED BY 'N3w!Pass2027';
DROP USER 'reports'@'localhost';بعد ALTER USER تُرفض الكلمة القديمة فوراً:
الناتج: ERROR 1045 (28000): Access denied for user 'shop_app'@'localhost' (using password: YES)
وهذه هي الرسالة نفسها التي تظهر عند أي كلمة مرور خاطئة أو حساب محذوف. MySQL لا تخبرك أيهما الخطأ، حتى لا تساعد المتسللين.
النسخ الاحتياطي: mysqldump
Section titled “النسخ الاحتياطي: mysqldump”القرص يتلف، و DELETE بلا WHERE يحدث، والخادم يُخترق. النسخة الاحتياطية هي الفرق بين «يوم سيئ» و«نهاية المشروع». الأداة mysqldump تأتي مع MySQL وتُشغَّل من الطرفية لا من داخل mysql:
mysqldump -u root -p shop > shop_backup.sqlالناتج ملف نصي عادي فيه أوامر SQL تعيد بناء القاعدة كلها. افتحه بأي محرر وستجد شيئاً كهذا:
-- MySQL dump 10.13 Distrib 8.4.11, for Win64 (x86_64)
CREATE TABLE `customers` ( ...);
INSERT INTO `customers` VALUES (1,'سارة','القاهرة'),(2,'عمر','الإسكندرية'),(4,'كريم','القاهرة');لكل جدول أمر CREATE TABLE ثم INSERT ببياناته، وفي آخر الملف تعريفات العروض. ولنسخ جداول محددة فقط اكتب أسماءها بعد اسم القاعدة: mysqldump -u root -p shop products customers > two_tables.sql.
الاستعادة
Section titled “الاستعادة”للاستعادة تنفّذ أوامر الملف على قاعدة فارغة. من داخل mysql:
CREATE DATABASE shop_copy CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;ثم من الطرفية:
mysql -u root -p shop_copy < shop_backup.sqlوللتأكد:
USE shop_copy;SHOW FULL TABLES;الناتج:
| Tables_in_shop_copy | Table_type |
|---|---|
| customers | BASE TABLE |
| order_details | VIEW |
| orders | BASE TABLE |
| product_status | VIEW |
| products | BASE TABLE |
| subscribers | BASE TABLE |
عادت الجداول الأربعة والعرضان، والمنتجات الستة والعملاء الثلاثة كما هم.
جرّب بنفسك
Section titled “جرّب بنفسك”- أنشئ مستخدماً
viewerبكلمة مرور قوية، وامنحهSELECTفقط علىshop.products. - ادخل بحسابه وجرّب قراءة المنتجات، ثم جرّب تعديل سعر، ولاحظ رسالة الخطأ.
- خذ نسخة احتياطية من قاعدة
shop، وافتح الملف في محرر النصوص واقرأ محتواه. - تحدٍّ: أنشئ قاعدة
shop_test، واستعد النسخة فيها، ثم احذف منتجاً منshop_testوتأكد أنshopالأصلية لم تتأثر.
أخطاء شائعة
Section titled “أخطاء شائعة”- استخدام root في التطبيق: أي ثغرة في الموقع تصبح سيطرة كاملة على الخادم. أنشئ حساباً محدود الصلاحيات لكل تطبيق.
GRANT ALLللسهولة: تمنح الحذف وتعديل البنية دون حاجة. امنح ما يحتاجه التطبيق فقط.- كلمة المرور في سطر الأمر: كتابة
-pPasswordتحفظها في سجل الطرفية. اكتب-pوحدها وأدخل الكلمة عند السؤال. - نسخ احتياطية على الخادم نفسه: إذا تلف القرص ضاعت القاعدة ونسختها معاً.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
تطبيق موقع يعرض المنتجات ويسجّل الطلبات. ما أنسب صلاحيات لحسابه؟
مبدأ أقل الصلاحيات: امنح ما يحتاجه التطبيق فعلاً، فيقل الضرر إذا تسربت كلمة المرور.
سؤال
ماذا يحتوي الملف الناتج عن mysqldump؟
ملف نصي فيه CREATE TABLE و INSERT لكل جدول، وتنفيذه يعيد بناء القاعدة.
الخلاصة
Section titled “الخلاصة”- الحساب في MySQL اسم ومصدر اتصال:
'user'@'host'، والحساب الجديد بلا صلاحيات. GRANT صلاحيات ON قاعدة.جدول TO حسابتمنح، وREVOKE ... FROMتسحب.- امنح كل تطبيق أقل صلاحيات تكفيه، ولا تستخدم
rootفي كود موقعك. mysqldumpتنسخ القاعدة إلى ملف SQL، والاستعادة بتنفيذ الملف على قاعدة فارغة.- مبروك! أنهيت كورس MySQL: من أول جدول إلى الفهارس والعروض والصلاحيات والنسخ الاحتياطي.