الدرس 1 من 12 · التثبيت والإعداد
MariaDB وMySQL في بيئة الإنتاج: التثبيت، والملفات، وmy.cnf
الهدف
تثبيت خادم MariaDB أو MySQL كما يُفعل في بيئة الإنتاج: الإصدار الصحيح، والمستودع الصحيح، وإعدادات في ملفاتك الخاصة، ونظام مهيّأ لقاعدة بيانات، واليقين من معرفة القيمة التي اعتمدها الخادم فعلًا.
أهم النقاط
- قاعدة بيانات الإنتاج هي دورة حياة: نختار إصدارًا LTS (دعم طويل الأمد) ونتابع إصداراته الفرعية التصحيحية.
- الملفات التي يجب معرفتها: مجلد البيانات (datadir) (
/var/lib/mysql)، والمقبس (socket) (/run/mysqld/mysqld.sock)، وسجل الأخطاء، وملفاتmy.cnf. - يُقرأ
my.cnfبترتيب محدّد، مع ملفات مُضمَّنة؛ وبالنسبة لخيار مكرّر، آخر قيمة هي التي تُعتمد. - لا نعدّل أبدًا ملفات الحزمة: نضيف ملفنا الخاص (
90-production.cnf) ونتحقّق من القيمة الفعلية. - يُضبط الخادم أيضًا حول القاعدة: حدود systemd، والـ swap، ووحدة تخزين مخصّصة مركّبة بخيار
noatime.
1. المهنة: ما يضيفه مدير قواعد البيانات (DBA) إلى « apt install »
أرتكم دروس Debian وRed Hat وUbuntu كيف تثبّتون MariaDB، وتنشئون قاعدة بيانات وحسابًا. هنا نأخذ مكان الشخص الذي يتحمّل مسؤولية القاعدة: يجب أن تصمد سنوات، وأن تتحمّل ضغط متجر MasterLinux ليلة التخفيضات، وأن تُنسخ احتياطيًا، وتُستنسخ، وتُراقب، وتُحدَّث دون ضياع.
أسئلة يجب طرحها قبل التثبيت:
| السؤال | لماذا |
|---|---|
| أي إصدار، ومدعوم إلى متى؟ | تنشر MariaDB إصدارات LTS (10.11، 11.4، 11.8…) تُصان لمدة 5 سنوات تقريبًا؛ ولـ MySQL إصدارها LTS 8.4 وإصدارات « Innovation » قصيرة العمر. |
| حزمة التوزيعة أم المستودع الرسمي؟ | يوفّر Debian 13 الإصدار MariaDB 11.8؛ أما مستودع MariaDB أو MySQL فيعطي إصدارًا محدّدًا وتحديثات أسرع. نختار مصدرًا واحدًا ونلتزم به. |
| محرّك التخزين؟ | InnoDB لكل شيء (المعاملات، والاستئناف بعد العطل). لا مكان لـ MyISAM في الإنتاج. |
| أي جهاز؟ | الذاكرة RAM (ذاكرة InnoDB المؤقتة)، وأقراص SSD/NVMe، ووحدة تخزين مخصّصة للبيانات. |
2. التثبيت وتحديد مواقع الملفات
apt install mariadb-server mariadb-backup # Debian / Ubuntu
dnf install mariadb-server mariadb-backup # Rocky / Alma (MySQL : dnf install mysql-server)
systemctl enable --now mariadb
mariadb -e "SELECT VERSION(), @@datadir, @@socket, @@log_error;"
| العنصر | Debian / Ubuntu | Rocky / Alma |
|---|---|---|
| الملف الرئيسي | /etc/mysql/my.cnf → mariadb.cnf |
/etc/my.cnf |
| المجلدات المُضمَّنة | /etc/mysql/conf.d/، /etc/mysql/mariadb.conf.d/ |
/etc/my.cnf.d/ |
| البيانات (datadir) | /var/lib/mysql |
/var/lib/mysql |
| سجل الأخطاء | سجل systemd (journalctl -u mariadb) أو /var/log/mysql/error.log |
/var/log/mariadb/mariadb.log |
| اسم الخدمة | mariadb (الاسم البديل mysql) |
mariadb أو mysqld |
أُعيدت تسمية الأوامر: mariadb (العميل)، وmariadb-dump، وmariadb-admin، وmariadb-backup، وmariadb-binlog. ما زالت الأسماء القديمة mysql* موجودة كروابط على أنظمة كثيرة، لكنها تختفي شيئًا فشيئًا.
3. كيف يُقرأ my.cnf
على Debian، يبدو /etc/mysql/mariadb.cnf هكذا:
[client-server]
socket = /run/mysqld/mysqld.sock
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mariadb.conf.d/
ثلاث قواعد يجب حفظها جيدًا:
- الأقسام (المجموعات) تحدّد من يقرأ الخيار:
[mysqld]، و[server]، و[mariadb]، و[mariadb-11.8](لهذا الإصدار فقط) بالنسبة للخادم؛ و[client]، و[mysql]، و[mariadb-dump]بالنسبة للأدوات. !includedirيقرأ ملفات المجلد بالترتيب الأبجدي، ولا يقرأ إلا تلك التي تنتهي بـ.cnf.- بالنسبة لخيار مكرّر، آخر ما يُقرأ هو الذي يُعتمد. ملف
99-vieux.cnfمنسيّ يتغلّب على ملفك90-production.cnf.
لمعرفة ما سيقرؤه الخادم، دون إعادة تشغيله:
my_print_defaults --mysqld # كل خيارات الخادم، بترتيب القراءة
mariadbd --print-defaults # الشيء نفسه، كما يراه الملف التنفيذي للخادم
mariadb -e "SELECT @@innodb_buffer_pool_size/1024/1024/1024 AS go, @@max_connections;" # القيمة الجارية حاليًا
في التطبيق العملي، يعطي الأمر cnf-effectif <option> القيمة النهائية التي سيأخذها الخادم عند الإقلاع (ما يعادل SELECT @@option).
المتغيّرات الديناميكية والثابتة
جزء من الإعدادات يمكن تغييره أثناء التشغيل:
SET GLOBAL max_connections = 300; -- فوري، لكنه يضيع عند إعادة التشغيل
SET GLOBAL innodb_buffer_pool_size = 10*1024*1024*1024; -- تغيير الحجم أثناء التشغيل (InnoDB)
وأخرى تتطلّب إعادة تشغيل (innodb_log_file_size في الإصدارات القديمة، وbind_address…). قاعدة تشغيلية: كل تغيير أثناء التشغيل يُكتب أيضًا في الملف، وإلا اختفى عند إعادة التشغيل التالية. يقترح MySQL 8 الأمر SET PERSIST، الذي يكتب في mysqld-auto.cnf داخل مجلد البيانات؛ هذا عملي، لكن يجب أن يكون هذا الملف معروفًا لدى الفريق كله، وإلا فلن يفهم أحد من أين تأتي قيمة ما.
4. الإعدادات المهمّة لخادم مخصّص
# /etc/mysql/mariadb.conf.d/90-production.cnf — ml-db-01, 16 Go de RAM, dédié
[mysqld]
bind_address = 10.10.20.11 # عنوان الشبكة الخاصة، وليس 0.0.0.0 أبدًا دون جدار ناري
skip_name_resolve = ON # لا DNS عكسي عند كل اتصال (حسابات حسب IP)
max_connections = 300
innodb_buffer_pool_size = 10G # من 60 إلى 70 % من ذاكرة خادم مخصّص
innodb_log_file_size = 2G # سجل redo: كبير بما يكفي لتسوية عمليات الكتابة
innodb_flush_log_at_trx_commit = 1 # 1 = لا تضيع أي معاملة مؤكَّدة في حالة العطل
innodb_file_per_table = ON # ملف لكل جدول (افتراضي)
- الـ Buffer pool (المخزن المؤقت): ذاكرة صفحات InnoDB المؤقتة. إذا كان صغيرًا جدًا، يذهب كل شيء إلى القرص؛ وإذا كان كبيرًا جدًا، يلجأ الخادم إلى الـ swap أو يقتله الـ OOM killer. نترك ذاكرة للنظام، وللاتصالات (كل واحد منها يستهلك مخازن مؤقتة)، ولذاكرة الملفات المؤقتة.
innodb_flush_log_at_trx_commit: القيمة1هي الإعداد الوحيد الذي يضمن الديمومة. القيمتان2أو0أسرع لكن قد تُضيعان آخر ثانية من المعاملات عند انقطاع التيار: تُخصَّصان لقاعدة يمكن إعادة بنائها.- مجموعة المحارف:
utf8mb4في كل مكان (الترميز القديمutf8في MySQL لا يخزّن إلا 3 بايت ويُفسد الرموز التعبيرية emojis وبعض المحارف).
5. تهيئة النظام
# /etc/systemd/system/mariadb.service.d/limites.conf
[Service]
LimitNOFILE=65535 # الجدول الواحد = ملفات مفتوحة؛ القيمة الافتراضية 1 024 لا تكفي
TimeoutStopSec=900 # منح الوقت لتفريغ buffer pool كبير عند الإيقاف
systemctl daemon-reload && systemctl restart mariadb
cat /proc/$(pidof mariadbd)/limits | grep 'open files'
إذا قتل systemd الخادم بعد 90 ثانية أثناء الإيقاف، تُعاد القاعدة في وضع الاستعادة بعد العطل (crash recovery): أطول، ومقلق في ليلة صيانة.
echo 'vm.swappiness = 1' > /etc/sysctl.d/60-mariadb.conf && sysctl --system # الـ swap كملاذ أخير
مجلد البيانات على وحدة تخزين مخصّصة (LVM): لا تملأ القاعدة /، ونكبّر الوحدة دون لمس النظام، ويمكن أخذ لقطة (snapshot). يتجنّب noatime عملية كتابة عند كل قراءة لملف.
/dev/vg_bdd/lv_mysql /var/lib/mysql xfs defaults,noatime 0 2
حسب الإصدار
| النقطة | MariaDB 10.11 | MariaDB 11.4 / 11.8 | MySQL 8.4 LTS |
|---|---|---|---|
| اسم الملف التنفيذي للخادم | mariadbd (mysqld كرابط) |
mariadbd |
mysqld |
| الترتيب (collation) الافتراضي لـ utf8mb4 | utf8mb4_general_ci |
uca1400_ai_ci (Debian 13) |
utf8mb4_0900_ai_ci |
تغيير innodb_log_file_size |
أثناء التشغيل منذ 10.11 | أثناء التشغيل | innodb_redo_log_capacity أثناء التشغيل |
| إعدادات دائمة أثناء التشغيل | لا (اكتب في الملف) | لا | SET PERSIST (mysqld-auto.cnf) |
| TLS للاتصالات | يجب إعداده | مفعّل افتراضيًا منذ 11.4 | مفعّل افتراضيًا (شهادات مولَّدة) |
أخطاء شائعة
- تعديل
50-server.cnf: يُستبدل أو يثير سؤالًا عند كل تحديث للحزمة. ملفك90-…يبقى ملكك. - ملف قديم يتغلّب: ملف
99-…cnfأوzz-…cnfمن مزوّد خدمة سابق يُلغي إعداداتك. تحقّق دائمًا من القيمة الفعلية. - إعادة التسمية بـ
.bakفي الاتجاه الخاطئ:fichier.cnf.bakلم يعد يُقرأ (جيد)، لكنfichier.bak.cnfما زال يُقرأ. - Buffer pool بنسبة 90 % من الذاكرة على خادم يشغّل أيضًا PHP أو Java: تقتل النواة
mariadbdفي منتصف النهار.
حالة واقعية
في مساء يوم جمعة، صار متجر MasterLinux بطيئًا جدًا. مع أن الخادم يملك 16 Go من الذاكرة، وقد « ضبط الفريق الـ buffer pool على 10 Go » في 90-production.cnf قبل ستة أشهر. يجيب SELECT @@innodb_buffer_pool_size… 256 Mo. كان ملف 99-optimisation-2023.cnf، المنسوخ من خادم قديم، يُقرأ في الأخير. كانت مجموعة البيانات كلها تمرّ عبر القرص. استغرق الإصلاح دقيقتين؛ أما الدرس فيبقى: نتحقّق من القيمة الفعلية بعد كل تغيير.
التطبيق العملي
على جهاز Debian 13 يحاكي شجرة ملفات MariaDB 11.8، ستقوم بما يلي:
- كتابة ملف إعدادات الإنتاج الخاص بك؛
- اكتشاف لماذا لن يعتمدها الخادم، وتصحيح ذلك دون حذف أي شيء؛
- إضافة ملف التجاوز الخاص بـ systemd؛
- ضبط الـ swap؛
- التصريح بوحدة التخزين المخصّصة للبيانات في
/etc/fstab.
يُظهر لك الأمران my_print_defaults --mysqld وcnf-effectif <option> ما سيقرؤه الخادم.
اختبار
- داخل مجلد مُضمَّن بواسطة
!includedir، بأي ترتيب تُقرأ الملفات، وأيّها يُقرأ؟ - ملفّان يحدّدان
max_connections: أيّهما يُعتمد؟ - لماذا
innodb_flush_log_at_trx_commit = 1في الإنتاج؟ - ما نسبة الذاكرة التي تُعطى للـ buffer pool على خادم مخصّص، ولماذا ليس أكثر؟
- ماذا يحدث إذا قتل systemd خادم MariaDB أثناء إيقاف طويل جدًا؟
الأجوبة
- بالترتيب الأبجدي، ولا تُقرأ إلا الملفات التي تنتهي بـ
.cnf. - الملف الذي يُقرأ في الأخير.
- لأنه الإعداد الوحيد الذي يكتب سجل redo على القرص عند كل تأكيد: لا تضيع أي معاملة مؤكَّدة في حالة العطل.
- حوالي 60 إلى 70 %: يجب ترك ذاكرة للنظام، وللاتصالات، ولذاكرة الملفات المؤقتة، وإلا حدث اللجوء إلى الـ swap أو تدخّل الـ OOM killer.
- يُعاد تشغيل الخادم في وضع الاستعادة بعد العطل (crash recovery)، وهي أطول، مع خطر أكبر؛ ومن هنا تأتي ضرورة إطالة
TimeoutStopSec.