<?xml version="1.0"?>
<rss version="2.0"><channel><title>DevOps: MySQL</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/page/2/?d=4</link><description>DevOps: MySQL</description><language>ar</language><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Mytop &#x644;&#x645;&#x631;&#x627;&#x642;&#x628;&#x629; &#x623;&#x62F;&#x627;&#x621; MySQL</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-mytop-%D9%84%D9%85%D8%B1%D8%A7%D9%82%D8%A8%D8%A9-%D8%A3%D8%AF%D8%A7%D8%A1-mysql-r129/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_11/mytop-mysql.png.a8ce589b422810ea2ced9a699c31258e.png" /></p>

<p dir="rtl">إنّ <strong>Mytop</strong> هي أداة سطر أوامر مفتوحة المصدر open source تُستخدَم لمراقبة أداء MySQL، وهي مستوحاة من أداة مراقبة نظام لينِكس التي تُدعى top ومُشابِهة لها في الشّكل والمظهر، تتصل Mytop إلى خادوم MySQL وتقوم بشكل دوري بتشغيل الأمرين <span style="font-family:courier new,courier,monospace;">show processlist</span> و <span style="font-family:courier new,courier,monospace;">show global status</span>، وتقوم بعدها بتلخيص المعلومات بشكل مفيد، نستطيع باستخدام Mytop مراقبة (بشكلٍ آني real-time) مناقشات MySQL threads، الاستعلامات queries، وزمن التشغيل uptime، بالإضافة إلى أنّها ترى أي مستخدم يقوم بتنفيذ استعلامات على أي قاعدة بيانات، وأي الاستعلامات تجري ببطء والمزيد من ذلك، نستطيع استخدام كل هذه المعلومات لتحسين أداء خادوم MySQL.</p><p dir="rtl" style="text-align: center;"><a href="https://academy.hsoub.com/uploads/monthly_2015_11/mytop-mysql.png.fe1e4bb10d66f5636b686d05fa8e0cf8.png" class="ipsAttachLink ipsAttachLink_image"><img data-fileid="6664" src="https://academy.hsoub.com/uploads/monthly_2015_11/mytop-mysql.thumb.png.5e079f94612910720445032f54a321ec.png" class="ipsImage ipsImage_thumbnailed" alt="mytop-mysql.thumb.png.5e079f946129107204"></a></p><p dir="rtl">سنناقش في هذا الدّرس كيفيّة تثبيت، إعداد، واستخدام mytop.</p><h2 dir="rtl">المتطلبات الأساسية</h2><p dir="rtl">قبل البدء في هذا الدرس ينبغي أن نمتلك ما يلي لدينا:</p><ul dir="rtl"><li>CentOS 7 64-bit Droplet (تعمل أيضًا مع CentOS 6).</li><li>مستخدم غير جذري non-root مع صلاحيّات sudo سيتم تنفيذ جميع الأوامر عن طريق هذا المستخدم.</li><li>خادوم MySQL يعمل على الـ Droplet.</li></ul><h2 dir="rtl">الخطوة الأولى – تثبيت Mytop</h2><p dir="rtl">فلنقم بتثبيت الحِزَم المطلوبة من أجل mytop.</p><p dir="rtl">نحتاج في البداية إلى تثبيت مستودع yum الذي يُدعى (EPEL (Extra Packages for Enterprise Linux على الخادوم، إنّ EPEL هي مجموعة ذات اهتمامات مشتركة بتوزيعة Fedora تقوم بإنشاء، إدارة، والحفاظ على مجموعة حِزَم برمجيّة إضافيّة add-on مفتوحة المصدر عالية الجّودة من أجل Enterprise Linux، نقوم بتنفيذ الأمر التالي لتثبيت وتمكين مستودع EPEL على خادومنا:</p><p dir="rtl">على CentOS 7:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm</pre><p dir="rtl">على CentOS 6:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm</pre><p dir="rtl">وقبل المتابعة نتحقّق أنّه تم تمكين المستودع EPEL باستخدام:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo yum repolist</pre><p dir="rtl">إن تمّ تمكينه سنشاهد في الخَرْج ما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64</pre><p dir="rtl">فلنقم بعد ذلك بحماية الحِزَم الأساسيّة من EPEL باستخدام إضافة yum plugin التي تُدعى protectbase:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo yum install yum-plugin-protectbase.noarch -y</pre><p dir="rtl">الغرض من الإضافة <strong>protectbase</strong> هو حماية بعض مستودعات yum من تحديثات المستودعات الأخرى، فلن يتم تحديث أو تجاوز override الحِزَم الموجودة في المستودعات المحميّة بواسطة الحِزَم في المستودعات غير المحميّة حتى ولو كان المستودع غير المحمي يملك إصدارًا أحدث.</p><p dir="rtl">نحن الآن مستعدون لتثبيت حِزمة mytop، فلنقم بتنفيذ الأمر التالي لتثبيتها:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo yum install mytop -y</pre><p dir="rtl">سيقوم هذا الأمر بتثبيت حِزمة mytop بالإضافة إلى جميع اعتمادياتها dependencies والتي هي في معظمها وحدات perl modules.</p><h2 dir="rtl">الخطوة الثانية – ضبط إعدادات Mytop</h2><p dir="rtl">نقوم قبل استخدام mytop بإنشاء ملف إعدادات مُخصَّص من أجل mytop يُدعى<span style="font-family:courier new,courier,monospace;"> mytop.</span>، وذلك بكتابة الأمر التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo nano /root/.mytop</pre><p dir="rtl">نضيف المحتوى التالي إلى الملف ونقوم بحفظه وإغلاقه:</p><p><strong>root/.mytop/</strong></p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">host=localhost
db=mysql
delay=5
port=3306
socket=
batchmode=0
color=1
idle=1</pre><p dir="rtl">سيتم استخدام ملف الإعدادات عندما نقوم بتشغيل mytop بشكل مباشر كمستخدم جذري root وعندما نقوم بتشغيلها باستخدام الأمر sudo كمستخدم غير جذري يملك صلاحيّات sudo.</p><p dir="rtl">نستطيع القيام بتغييرات إلى ملف الإعدادات اعتمادًا على احتياجاتنا، على سبيل المثال يُحدِّد الخيار <span style="font-family:courier new,courier,monospace;">delay</span> الفترة الزمنيّة مقدرةً بالثانية بين تحديثات العرض display، فإن كُنّا نرغب بتحديث عرض mytop كل 3 ثوان بإمكاننا تحرير الملف <span style="font-family:courier new,courier,monospace;">root/.mytop/</span> باستخدام:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo nano /root/.mytop</pre><p dir="rtl">ومن ثمّ تغيير ما يلي:</p><p><strong>root/.mytop/</strong></p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">delay=3</pre><p dir="rtl">يُحدِّد المُعامِل <span style="font-family:courier new,courier,monospace;">idle</span> إذا ما كان سيسمح للمناقشات threads الخاملة idle (النائمة) بالظهور في قائمة شاشة عرض mytop، الوضع الافتراضي هو إظهار المناقشات الخاملة، إن تمّ حذف المناقشات الخاملة سينعكس ترتيب الفرز sorting الافتراضي بحيث تظهر أطول الاستعلامات قيد التشغيل في أعلى القائمة، إن كُنّا نرغب في فعل هذا نُحرّر الملف <span style="font-family:courier new,courier,monospace;">root/.mytop/</span> ونغيّر ما يلي:</p><p><strong>root/.mytop/</strong></p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">idle=0</pre><p dir="rtl">نستطيع الرجوع إلى صفحات mytop اليدويّة للمزيد من المعلومات عن جميع المُعامِلات في ملف الإعدادات والتي تحتوي على وصف لكل مُعامِل، للوصول إلى الصفحات اليدويّة نستخدم الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">man mytop</pre><p dir="rtl">نستطيع كتابة <strong>q</strong> للخروج من الدّليل.</p><h2 dir="rtl">الخطوة الثالثة – الاتصال إلى Mytop</h2><p dir="rtl">سنناقش في هذا القسم كيفيّة الاتصال إلى mytop واستخدامها لعرض استعلامات MySQL.</p><p dir="rtl">تتطلّب Mytop اعتمادات credentials للنفاذ إلى قاعدة البيانات، والتي يمكن تزويدها عبر مُحِث prompt في سطر الأوامر أو عبر تخزينها في ملف الإعدادات، سنستخدم من أجل أمان أفضل الخيار <span style="font-family:courier new,courier,monospace;">prompt--</span> والذي يسأل كل مرّة عن كلمة السّر.</p><p dir="rtl">فلنتصل إلى mytop باستخدام:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo mytop --prompt</pre><p dir="rtl">ونُدخِل كلمة سر المستخدم root في MySQL في المُحِث، بإمكاننا أيضًا استخدام العديد من مُعطيات arguments سطر الأوامر مع الأمر <span style="font-family:courier new,courier,monospace;">mytop</span>، نرجو الرجوع إلى الصفحات اليدويّة من أجل الحصول على قائمة كاملة بها، على سبيل المثال إن كُنّا نرغب باستخدام مستخدم mysql مُختلف مثل sammy للاتصال إلى mytop نقوم باستخدام الأمر التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo mytop -u sammy --prompt</pre><p dir="rtl">وللاتصال ومراقبة قاعدة بيانات مُحدّدة فقط نستخدم الأمر التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo mytop -d databasename --prompt</pre><p dir="rtl">للخروج من mytop والعودة إلى مُحث الصّدفة shell prompt نكتب <strong>q</strong>.</p><h2 dir="rtl">الخطوة الرابعة – عرض وتفسير شاشة عرض Mytop</h2><p dir="rtl">سنرى في هذا القسم كيفيّة تفسير شاشة عرض mytop والميزات المختلفة التي تُقدّمها هذه الأداة.</p><p dir="rtl">حالما نتصل إلى mytop باستخدام <span style="font-family:courier new,courier,monospace;">mytop --prompt </span>سيتم أخذنا إلى طريقة عرض المناقشات thread view، والتي ستظهر خَرْج مشابه لما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">Output of mytop

MySQL on localhost (5.5.41-MariaDB)                up 0+00:05:52 [01:33:15]
Queries: 148 qps: 0 Slow: 0.0              Se/In/Up/De(%): 09/00/00/00
qps now: 2 Slow qps: 0.0 Threads: 6 ( 5/ 0) 67/00/00/00
Key Efficiency: 2.0% Bps in/out: 14.7/320.7k Now in/out: 192.5/731.8k

Id   User   Host/IP     DB      Time   Cmd     Query or State
--   ----   -------     --      ----   ---     ----------
 2   root   localhost   mysql     0    Query    show full processlist
16   root   localhost             0             Sleep
17   root   localhost   testdb    0    Query    SELECT * FROM dept_emp
18   root   localhost   testdb    0    Query    SELECT * FROM dept_emp
19   root   localhost   testdb    0    Query    SELECT * FROM dept_emp
20   root   localhost   testdb    0    Query    SELECT * FROM dept_emp</pre><p dir="rtl">نستطيع العودة إلى طريقة العرض هذه إن كُنّا في طريقة عرض أخرى بكتابة <strong>t</strong>.</p><p dir="rtl">تُقسم شاشة العرض السّابقة إلى قسمين، تُؤلّف الأسطر الأربعة الأولى الترويسة header والتي يُمكن تشغيلها وإيقافها بضغط <span style="font-family:courier new,courier,monospace;">SHIFT-H</span>، تحتوي الترويسة على معلومات موجزة حول خادوم MySQL لدينا.</p><ul dir="rtl"><li>يُحدِّد السطر الأول اسم المضيف hostname للخادوم وإصدار MySQL الموجود، يُظهر القسم الأيمن منه زمن التشغيل uptime لعمليّة خادوم MySQL بصيغة الأيام+السّاعات:الدّقائق:الثواني (days+hours:minutes:seconds) بالإضافة للوقت الحالي.</li><li>يعرض السطر الثاني العدد الكلّي للاستعلامات التي قام الخادوم بمعالجتها (148 في حالتنا)، متوسط عدد الاستعلامات في الثانية، عدد الاستعلامات البطيئة، والنسبة المئوية للاستعلامات اختيار Select، إدخال Insert، تحديث Update، وحذف Delete.</li><li>يُظهِر السطر الثالث قيم آنيّة real-time منذ التحديث refresh الأخير لـ mytop، إنّ زمن التّحديث (التأخير) الطبيعي في mytop هو 5 ثوان، لذا إن تمّ إجراء 100 استعلام خلال آخر 5 ثوان منذ التحديث سيكون عدد<strong> qps now</strong> هو 20، الحقل الأول هو عدد الاستعلامات في الثانية (<strong>qps now: 2</strong>). القيمة الثانية هي عدد الاستعلامات البطيئة في الثانية، يُشير القسم Threads: 6 ( 5/ 0) إلى وجود 6 مناقشات threads مُتّصلة، 5 منها نشطة (واحدة منها نائمة) وعدم وجود أي مناقشات (الرقم 0) في الذّاكرة المؤقّتة cache للمناقشات، يُظهر الحقل الأخير في السّطر الثالث النّسبة المئويّة للاستعلام، كما هو الحال في السّطر السابق، ولكن منذ التحديث الأخير لـ mytop.</li><li>يعرض السّطر الرّابع فعاليّة key buffer (وهو عدد المرات التي فيها قراءة المفاتيح keys من الـ buffer بدلًا من القرص) وعدد البايتات التي أرسلتها واستقبلتها MySQL، كلاهما بالمجمل ومنذ آخر تحديث لـ mytop. تُظهِر <strong>Key Efficiency: 2.0%</strong> أنّه يتم قراءة 2% من المفاتيح من الـ buffer وليس من القرص، تُظهِر<strong> Bps in/out: 14.7/320.7k</strong> أنّه منذ بدء التشغيل تلقّت MySQL ما يُعادِل 14.7kbps من حركة البيانات traffic الواردة و 320.7kbps من حركة البيانات الصادرة، يُظهِر <strong>Now in/out</strong> حركة البيانات أيضًا ولكن منذ آخر تحديث لـ mytop.</li></ul><p dir="rtl">يعرض القسم الثاني من شاشة العرض مناقشات MySQL الحاليّة مع فرزها بحسب زمن خمولها (الأقل خمولًا أولًا)، نستطيع عكس ترتيب الفرز بضغط O عند الحاجة لذلك، يتم هنا أيضًا عرض مُعرِّف المناقشة thread id، اسم المستخدم، المُضيف الذي يتصل منه المستخدم، قاعدة البيانات التي يتصل إليها المستخدم، زمن الخمول مُقدّرًا بالثانية، الأمر الذي تقوم المناقشة بتنفيذه (أو حالة المناقشة)، والقسم الأول من معلومات الاستعلام، إن كانت المناقشة في حالة استعلام Query (أي يعرض العمود <strong>Cmd</strong> القيمة Query) فسيعرض العمود التالي الذي يُدعى <strong>Query or State</strong> القسم الأول من الاستعلام الذي يتم تنفيذه، أمّا إن كانت حالة الأمر هي نائم Sleep أو خامل Idle فسيكون العمود Query or State فارغًا عادةً، في مثال الخَرْج السّابق لدينا فإنّ المناقشة ذات المُعرِّف id 2 هي فعليًّا mytop والتي تقوم بتشغيل الاستعلام<span style="font-family:courier new,courier,monospace;"> show processlist</span> لجمع المعلومات، والمناقشة ذات المُعرِّف 16 نائمة (أي لا تقوم بمعالجة استعلام ولكنّها تبقى متصلة)، والمناقشة ذات المُعرِّف 17 تقوم بتشغيل استعلام SELECT على قاعدة البيانات testdb.</p><p dir="rtl">الآن وقد فهمنا أساسيّات شاشة عرض mytop، سنرى كيفيّة استخدامها لجمع المزيد من المعلومات حول مناقشات واستعلامات MySQL، فلنلقِ نظرة على شاشة عرض mytop التّالية:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">[secondary_output Output of mytop]

MySQL on localhost (5.5.41-MariaDB) up 0+00:13:10 [23:54:45]
Queries: 2.8k qps: 4 Slow: 51.0 Se/In/Up/De(%): 45/00/00/00
qps now: 17 Slow qps: 0.0 Threads: 52 ( 51/ 0) 96/00/00/00
Key Efficiency: 100.0% Bps in/out: 215.4/ 7.6M Now in/out: 2.0k/16.2M

Id     User   Host/IP     DB       Time   Cmd     Query or State
--     ----   -------     --       ----   ---     ----------
  34   root   localhost   testdb    0     Query   show full processlist
1241   root   localhost             1             Sleep
1242   root   localhost   testdb    1     Query   SELECT * FROM dept_emp
1243   root   localhost   testdb    1     Query   SELECT * FROM dept_emp
1244   root   localhost   testdb    1     Query   SELECT * FROM dept_emp
1245   root   localhost   testdb    1     Query   SELECT * FROM dept_emp
1246   root   localhost   testdb    1     Query   SELECT * FROM dept_emp
1247   root   localhost   testdb    1     Query   SELECT * FROM dept_emp</pre><p dir="rtl">تكون الاستعلامات مبتورة في طريقة عرض المناقشات thread view (طريقة العرض الافتراضيّة)، ولمشاهدة كامل الاستعلام بإمكاننا أن نضغط <strong>F </strong>وسيتم سؤالنا كما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">Full query for which thread id:</pre><p dir="rtl">نُدخِل مُعرِّف المناقشة thread id التي نريد عرض استعلامها، على سبيل المثال نكتب <strong>1244</strong> وسنشاهد ما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">Thread 1244 was executing following query:

SELECT * FROM dept_emp WHERE ...

-- paused. press any key to resume or (e) to explain --</pre><p dir="rtl">نستطيع كتابة <strong>e</strong> لشرح explain الاستعلام، والذي يقوم بشرح الاستعلام الذي يتم تنفيذه حتى نعرف إذا ما كان هذا هو الاستعلام الأمثل، إنّ <strong>EXPLAIN</strong> هي واحدة من أقوى الأدوات لفهم وتحسين استعلامات MySQL الصعبة، على سبيل المثال:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">EXPLAIN SELECT * FROM dept_emp:

*** row 1 ***
        table: dept_emp
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 332289
        Extra: NULL
-- paused. press any key to resume --</pre><p dir="rtl">بإمكاننا أن نضغط على أي مفتاح للخروج من هذا الوضع أو نكتب <strong>t</strong> للعودة إلى طريقة عرض المناقشات الافتراضيّة.</p><p dir="rtl">ومن طرق العرض المفيدة الأخرى المتاحة في mytop هي طريقة عرض الأوامر command view، وللوصول إليها نكتب <strong>c</strong>، ستبدو مشابهة لما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">         Command   Total   Pct  |  Last Pct
         -------   -----   ---  |  ---- ---
          select    1782   55%  |  100 8%
     show status     723   22%  |  533 45%
show processlist     708   22%  |  532 45%
       change db       2    0%  |    0 0%
  show variables       1    0%  |    0 0%
     Compression       0    0%  |    0 0%</pre><p dir="rtl">يُظهِر العمود <strong>Command</strong> نوع الأمر أو الاستعلام الذي يتم تنفيذه، يرمز العمود <strong>Total</strong> إلى العدد الإجمالي لهذا النوع من الأوامر التي تم تنفيذها منذ بدء تشغيل الخادوم، ويُظهِر العمود <strong>Pct</strong> نفس ما سبق ولكن بالنسبة المئوية. وعلى الناحية الأخرى من الخط العمودي نجد العمود <strong>Last</strong> والذي يُخبرنا بعدد هذا النوع من الأوامر التي تم تشغيلها منذ آخر تحديث لـ mytop، تُعطينا هذه المعلومات فكرة عمّا يقوم به خادوم MySQL على المدى القريب والبعيد.</p><p dir="rtl">ناقشنا في هذا الدّرس بعضًا من ميّزات mytop الهامّة والمفيدة، هناك العديد من الميّزات الأخرى المتاحة، ولعرض قائمة كاملة من الخيارات نستطيع أن نضغط المفتاح أثناء تشغيل mytop.</p><h2 dir="rtl">الخاتمة</h2><p dir="rtl">يجب أن يكون لدينا الآن معرفة جيّدة حول كيفيّة استخدام mytop لمراقبة خادوم MySQL لدينا، وهي أيضًا نقطة انطلاق لإيجاد مشاكل استعلامات SQL وتحسينها، وبالتالي زيادة الأداء الإجمالي للخادوم.</p><p dir="rtl">ترجمة -وبتصرّف- لـ <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-use-mytop-to-monitor-mysql-performance">How To Use Mytop to Monitor MySQL Performance</a> لصاحبته Veena K John.</p>
]]></description><guid isPermaLink="false">129</guid><pubDate>Tue, 03 Nov 2015 22:13:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x642;&#x648;&#x645; &#x628;&#x627;&#x644;&#x646;&#x633;&#x62E; &#x627;&#x644;&#x627;&#x62D;&#x62A;&#x64A;&#x627;&#x637;&#x64A; &#x644;&#x642;&#x648;&#x627;&#x639;&#x62F; &#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; MySQL &#x639;&#x644;&#x649; Ubuntu</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81-%D8%AA%D9%82%D9%88%D9%85-%D8%A8%D8%A7%D9%84%D9%86%D8%B3%D8%AE-%D8%A7%D9%84%D8%A7%D8%AD%D8%AA%D9%8A%D8%A7%D8%B7%D9%8A-%D9%84%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-mysql-%D8%B9%D9%84%D9%89-ubuntu-r110/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-backup.png.e987ffd283997d098e8d9520daad50a9.png" /></p>

<div id="wmd-preview-section-34"><p style="text-align: center;"><a href="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-backup.png.c1bcf4c56ff575f5035b7ade0e73585a.png" class="ipsAttachLink ipsAttachLink_image"><img data-fileid="5300" src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-backup.thumb.png.abded8536dd94548e8541a850f8b4e9e.png" class="ipsImage ipsImage_thumbnailed" alt="mysql-backup.thumb.png.abded8536dd94548e"></a></p><h2 id="ما-هي-mysql">ما هي MySQL؟</h2><p>MySQL هي عبارة عن أداة إدارة قواعد بيانات شهيرة تستخدم لغة استعلامات SQL للوصول إلى البيانات والتعامل معها، يمكن استخدامها بسهولة لإدارة البيانات ضمن المواقع أو تطبيقات الويب.</p><p>عمليات النسخ الاحتياطي مهمة جدًا لأي نوع من البيانات، وهذا مرتبط بشدّة عندما نتحدث عن قواعد البيانات. يمكن نسخ قواعد بيانات MySQL احتياطيا بواسطة عدة طرق سنشرحها في هذا الدرس.</p><p>سنستخدم خادوم Ubuntu 12.04 مع MySQL 5.5 في شرحنا هذا. تأتي معظم توزيعات لينكس بإصداراتٍ حديثة من MySQL ويجب ألّا تواجه صعوبةً في تطبيق نفس المهام بطريقةٍ مشابهة على تلك التوزيعات.</p></div><div id="wmd-preview-section-35"><h2 id="نسخ-قاعدة-بيانات-mysql-باستخدام-mysqldump">نسخ قاعدة بيانات MySQL باستخدام mysqldump</h2><p>واحدة من أكثر الطرق شيوعا لعمل النسخ الاحتياطي لقاعدة بيانات MySQL هي استخدام أمرٍ يدعى "<strong><span style="font-family:courier new,courier,monospace;">mysqldump</span></strong>".</p></div><div id="wmd-preview-section-36"><h3 id="النسخ-الاحتياطي">النسخ الاحتياطي</h3><p>الشكل الأساسي للأمر هو:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysqldump -u username -p database_to_backup &gt; backup_name.sql</pre><h3>الاستعادة</h3></div><div id="wmd-preview-section-37"><p>لاستعادة نسخة قاعدة بيانات MySQL مصنوعة بـ<span style="font-family:courier new,courier,monospace;">mysqldump</span>، يمكنك ببساطة إعادة توجيه الملفّ إلى MySQL مرةً أخرى.</p><p>نحتاج إنشاء قاعدة بيانات فارغة لاستضافة البيانات التي سنقوم باستيرادها مجددًا. أوّلًا، قم بالولوج إلى MySQL عبر كتابة:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysql -u username -p</pre><p>أنشئ قاعدة بيانات جديدة الآن - والتي ستحوي جميع البيانات الموجودة في نسخة قاعدة البيانات التي قمت بنسخها مسبقًا - ومن ثمَّ، قم بالخروج:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">CREATE DATABASE database_name; exit</pre><p>الآن، يمكننا إعادة توجيه ملفّ النسخة إلى قاعدة البيانات الجديدة التي قمنا بإنشائها مسبقًا عبر استخدام الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysql -u username -p database_name &lt; backup_name.sql</pre><p>يجب أن يتم استعادة بياناتك الآن إلى قاعدة البيانات الجديدة التي أنشئتها.</p></div><div id="wmd-preview-section-38"><h2 id="نسخ-جدول-mysql-احتياطيا-إلى-ملف-نصي">نسخ جدول MySQL احتياطيا إلى ملف نصي</h2><p>يمكنك تصدير البيانات من جدول ما مباشرة إلى ملف نصي عبر استخدام جملة SELECT مع MySQL.</p><p>الشكل الأساسي للعملية هو:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">SELECT * INTO OUTFILE 'table_backup_file' FROM name_of_table;</pre><p>ستقوم هذه العملية بحفظ بيانات الجدول إلى الملف النصي المطلوب. وسيفشل في حال كان هناك اسم ملف آخر موجود بنفس المسار الذي قررت حفظ الملف إليه.</p><p><strong>ملاحظة</strong>: يقوم هذا الخيار بحفظ بيانات الجدول فقط. إذا كانت بنية جدولك معقّدة ويجب حفظها كما هي، فالأفضل أن تستخدم طريقةً أخرى.</p></div><div id="wmd-preview-section-39"><h2 id="نسخ-معلومات-mysql-احتياطيا-باستخدام-automysqlbackup">نسخ معلومات MySQL احتياطيا باستخدام automysqlbackup</h2><p>هناك برنامج أداة يدعى "<strong><span style="font-family:courier new,courier,monospace;">automysqlbackup</span></strong>" متوفّر في مستودعات توزيعة أوبونتو الرسمية.</p><p>يمكن أن يتم جدولة هذه الأداة يدويا للقيام بعمليات النسخ الاحتياطي بأوقات محددة.</p><p>لتثبيت هذا البرنامج، طبق الأمر التالي في الطرفية:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo apt-get install automysqlbackup</pre><p>وقم بتشغيله عبر الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo automysqlbackup</pre><p>ستجد ملف الإعدادات الرئيسي لـautomysqlbackup في المسار "<span style="font-family:courier new,courier,monospace;">etc/default/automysqlbackup/</span>". افتحه بصلاحيات الجذر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo nano /etc/default/automysqlbackup</pre><p>يمكنك أن ترى أن هذا الملف يقوم افتراضيا بتعيين العديد من المتغيرات باستخدام ملف MySQL الموجود في المسار "<span style="font-family:courier new,courier,monospace;">etc/mysql/debian.cnf/</span>".</p><p>وهو يقوم بقراءة اسم المستخدم وكلمة المرور وقواعد البيانات التي يجب نسخها احتياطيًا من هذا الملفّ.</p><p>المسار الافتراضي للنُسَخ الاحتياطية هو “/var/lib/automysqlbackup”. ابحث عن هذا المسار لترى بنية النُسَخ الاحتياطية:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">ls /var/lib/automysqlbackup daily monthly weekly</pre><p>إذا نظرنا إلى مجلد "<span style="font-family:courier new,courier,monospace;">daily</span>"، فإنّه يمكننا أن نرى مجلدا فرعيًا داخله لكل قاعدة بيانات، حيث يكون بداخلها أيضًا ملفات النُسَخ الاحتياطية لقاعدة البيانات مضغوطة بصيغة <strong>gzip.</strong> استخدم الأمر التالي لترى محتويات ذاك المسار:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">.: database_name information_schema performance_schema ./database_name: database_name_2013-08-27_23h30m.Tuesday.sql.gz ./information_schema: information_schema_2013-08-27_23h30m.Tuesday.sql.gz ./performance_schema: performance_schema_2013-08-27_23h30m.Tuesday.sql.gz</pre><p>تقوم Ubuntu بتثبيت <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%AC%D8%AF%D9%88%D9%84-%D9%85%D9%87%D8%A7%D9%85%D9%83-%D8%A7%D9%84%D8%B1%D9%88%D8%AA%D9%8A%D9%86%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A3%D8%AF%D8%A7%D8%AA%D9%8A-cron-%D9%88-anacron-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r82/">سكربت cron</a> مع هذا البرنامج لتشغيله كل يوم. سيقوم تلقائيًا بتنظيم الملفات إلى مسارها الصحيح.</p></div><div id="wmd-preview-section-40"><h2 id="كيفية-النسخ-الاحتياطي-عند-استخدام-النسخ-المتماثل">كيفية النسخ الاحتياطي عند استخدام النسخ المتماثل</h2><p>من الممكن استخدام النسخ المتماثل (Replication) في MySQL لعمل نسخة احتياطية عن البيانات مع الطرق المذكورة أعلاه كذلك.</p><p>النسخ المتماثل هو عملية تمرير البيانات من خادومٍ إلى آخر (من رئيسي إلى فرعي) أو تمرير التغييرات من خادومٍ رئيسي إلى خادومٍ رئيسيٍ آخر.</p><p>صحيح أن النسخ المتماثل يسمح بتمرير البيانات وحفظها، إلا أنه يعاني عندما تحاول حفظ البيانات من نقطة معينة من الزمان. هذا بسبب أن عملية النسخ المتماثل تحصل بشكل مستمر لتنسخ التغييرات الجديدة التي يتم إجراؤها على النظام.</p><p>لتفادي هذه المشكلة يمكننا: </p><ul><li>تعطيل النسخ المتماثل مؤقتًا. </li><li>جعل آلة النسخ الاحتياطي قابلة للقراءة فقط مؤقتًا.</li></ul></div><div id="wmd-preview-section-41"><h3 id="تعطيل-النسخ-المتماثل-مؤقتا">تعطيل النسخ المتماثل مؤقتا</h3><p>يمكنك تعطيل النسخ المتماثل للخادوم الفرعي مؤقتًا عبر تنفيذ:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysqladmin -u user_name -p stop-slave</pre><p>خيار آخر يمكنك استخدامه ولا يقوم بتعطيل عملية النسخ المتماثل بالكامل، بل يضعها بوضع الإيقاف المؤقت، هو تطبيق:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysql -u user_name -p -e 'STOP SLAVE SQL_THREAD;</pre><p>بعد إيقاف عملية النسخ المتماثل مؤقتًا، يمكنك القيام بعملية النسخ الاحتياطي باستخدام أحد الطرق المذكورة مسبقًا. يسمح لك هذا بإبقاء قاعدة البيانات الرئيسية نشطة بينما يتم نسخ قاعدة البيانات الفرعية.</p><p>عندما يكتمل هذا، قم بإعادة تفعيل النسخ المتماثل عبر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysqladmin -u user_name -p start-slave</pre><h3>جعل آلة النسخ الاحتياطي قابلة للقراءة فقط مؤقتا</h3></div><div id="wmd-preview-section-42"><p>يمكنك أيضًا أن تحافظ على البيانات على الخادوم عبر جعلها قابلة للقراءة فقط.</p><p>يمكنك تنفيذ هذه الخطوات سواء كان على الخادوم الرئيسي (Master) أو الفرعي (Slave).</p><p>أولا، قم بالولوج إلى MySQL بالصلاحيات اللازمة للقيام بذلك:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysql -u root -p</pre><p>الآن، يمكننا كتابة جميع التغييرات المحفوظة إلى القرص وجعل النظام قابلًا للقراءة فقط (read-only) عبر كتابة:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">FLUSH TABLES WITH READ LOCK; SET GLOBAL read_only = ON;</pre><p>الآن، قم بعمل النسخ الاحتياطي باستخدام mysqludump.</p><p>بمجرّد اكتمال عملية النسخ الاحتياطي، قم بإعادة النظام إلى وضعه الأصلي عبر كتابة:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">SET GLOBAL read_only = OFF; UNLOCK TABLES;
</pre></div><div id="wmd-preview-section-43"><h2 id="ملاحظة-عن-الطرق-التي-لم-تعد-مستحسنة">ملاحظة عن الطرق التي لم تعد مستحسنة</h2></div><div id="wmd-preview-section-44"><h3 id="mysqlhotcopy">mysqlhotcopy</h3><p>تتضمن MySQL سكربتا مكتوبا بلغة Perl لنسخ قواعد البيانات احتياطيا بسرعة ويدعى "<strong><span style="font-family:courier new,courier,monospace;">mysqlhotcopy</span></strong>". يمكن أن يتم استخدام هذه الأداة للقيام بنسخ قاعدة البيانات بسرعة على الآلة المحلّية، ولكنها تمتلك بعض التقييدات التي تجعلنا نتجنبها.</p><p>السبب الأهم الذي جعلنا لا نستخدمها هو أنها فقط تعمل مع البيانات التي تم تخزينها باستخدام محركات التخزين "MyISAM" و"Stroage" فقط.</p><p>معظم المستخدمين لا يقومون بتغيير المحرك الافتراضي للتخزين، وبدءً من الإصدار 5.5 من MySQL فإن المحرك الافتراضي هو "InnoDB". لهذا لا يمكن استخدام هذه الأداة لأنها لا تتوافق مع المحرك.</p><p>مشكلة أخرى مع هذا السكربت هو أنه يمكن تشغيله فقط على الآلة التي يتم تخزين قاعدة البيانات عليها. يمنعك هذا من القيام بعمليات النسخ الاحتياطي باستخدام آلة بعيدة (remote machine)، والذي يمكنه أن يكون مشكلة حقيقية في بعض الأحيان.</p></div><div id="wmd-preview-section-45"><h3 id="نسخ-ملفات-الجداول">نسخ ملفات الجداول</h3><p>طريقة أخرى تقتَرح بعض الأحيان هي القيام بنسخ الجداول التي تقوم MySQL بوضع البيانات فيها ببساطة ونقلها إلى مكان آخر.</p><p>تعاني هذه الطريقة من نفس مشكلة "<span style="font-family:courier new,courier,monospace;">mysqlhotcopy</span>".</p><p>قد يكون منطقيًا استخدام هذه الطريقة مع المحرّكات التي تقوم بتخزين بياناتها على شكل ملفات، إلا أن InnoDB (وهو المحرك الافتراضي الجديد لـMySQL) لا يمكن نسخ قواعد البيانات الخاصة به بهذه الطريقة.</p></div><div id="wmd-preview-section-46"><h2 id="الخاتمة">الخاتمة</h2><p>هناك العديد من الطرق لإجراء عمليات النسخ الاحتياطي لقواعد بيانات MySQL، جميعها يمتلك نقاط قوة وضعف، ولكن بعضها أسهل للمستخدم وأفضل للتطبيق من غيرها.</p><p>ستعتمد طريقة عملية النسخ الاحتياطي التي ستستخدمها بشكل رئيسي على احتياجاتك ومواردك، بالإضافة إلى بيئة العمل الخاصة بك. مهما كانت الطريقة التي تعتمد عليها، كن متأكدا من التحقق من النُسَخ الاحتياطية الخاصّة بك وحاول استرجاعها للتأكد من الأمر، لتكون متأكدا من أنها لا تحوي أي مشاكل.</p><p>ترجمة -وبتصرف- للمقال <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-backup-mysql-databases-on-an-ubuntu-vps">How to Backup MySQL Databases on an Ubuntu VPS</a> لصاحبه Justin Ellingwood.</p></div>
]]></description><guid isPermaLink="false">110</guid><pubDate>Mon, 28 Sep 2015 22:31:00 +0000</pubDate></item><item><title>&#x62A;&#x62B;&#x628;&#x64A;&#x62A; &#x648;&#x625;&#x639;&#x62F;&#x627;&#x62F; mysqlslap &#x644;&#x642;&#x64A;&#x627;&#x633; &#x623;&#x62F;&#x627;&#x621; &#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; MySQL - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x62B;&#x627;&#x646;&#x64A;</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-mysqlslap-%D9%84%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-mysql-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r109/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.png.f2cc421305651021494d03fe4ecf23ab.png" /></p>

<p><span style="line-height: 17.92px;"> بعد أن قمنا مسبقًا <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-mysqlslap-%D9%84%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-mysql-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%84-r107/">بتثبيت وإعداد خادوم قاعدة بيانات MySQL التجريبي الخاصّ بنا</a>، </span>يمكننا الآن البدء باستخدام mysqlslap. يمكن تشغيل mysqlslap عبر طرفية الصدفة العادية، لذا لن يكون هناك حاجة إلى الدخول إلى MySQL لتشغيله من هناك. وعلى الرغم من ذلك، فإننا سنقوم في درسنا هذا بفتح اتصالٍ جديد إلى خادومنا بالإضافة إلى بدء جلسة MySQL جديدة من هناك بواسطة المستخدم <strong>sysadmin</strong> الذي أنشأناه من قبل، لكي نتمكّن من التحقق من بعض الأمور وتحديث أخرى في MySQL بشكلٍ أسهل. لذا وفي المجمل، فإننا سنمتلك طرفيةً واحدة مفتوحة مع مستخدمٍ بصلاحيات إدارية (sudo)، وطرفية واحدة لـMySQL.</p><p style="text-align: center;"><a href="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.png.29a591098658347a9139ba1e85c3c7e5.png" class="ipsAttachLink ipsAttachLink_image"><img data-fileid="5088" src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.thumb.png.11ee5ce56c2136dfd23f4f19dc99bd07.png" class="ipsImage ipsImage_thumbnailed" alt="mysql-performance.thumb.png.11ee5ce56c21"></a></p><p>قبل أن ندخل في الأوامر الرئيسية المُستخدمة للاختبار، قد تودّ أن تلقي نظرةً على هذه القائمة لأكثر الخيارات المفيدة لـmysqlslap. يمكن أن يساعدك هذا على تصميم أوامر mysqlslap الخاصّ بك لاحقًا.</p><table><thead><tr><th>الخيار</th><th>وظيفته</th></tr></thead><tbody><tr><td>user--</td><td>اسم مستخدم MySQL الذي يجب الاتصال به على خادوم قاعدة البيانات</td></tr><tr><td>password--</td><td>كلمة المرور الخاصّة باسم المستخدم. من الأفضل تركها فارغة في سطر الأوامر</td></tr><tr><td>host--</td><td>اسم خادوم قاعدة بيانات MySQL</td></tr><tr><td>port--</td><td>رقم المنفذ الذي يجب من خلاله الاتصال بـMySQL إذا كان الافتراضي غير مستخدم</td></tr><tr><td>concurrency--</td><td>عدد اتصالات العملاء الافتراضية التي سيتم محاكاتها من طرف mysqlslap</td></tr><tr><td>iterations--</td><td>عدد المرّات التي سيتم تشغيل الاختبار فيها</td></tr><tr><td>create-schema--</td><td>قاعدة البيانات التي سيتم تشغيل الاختبار عليها</td></tr><tr><td>query--</td><td>عملية الاستعلام التي يجب تنفيذها. يمكن لهذا أن يكون متغيّر استعلام SQL أو مسارًا لملفّ سكربت SQL</td></tr><tr><td>create--</td><td>الاستعلام الذي يجب إنشاؤه كجدول، مجددًا، يمكن لهذا أن يكون متغيّر استعلام SQL أو مسارًا لملفّ SQL</td></tr><tr><td>delimiter--</td><td>الحائل الذي يجب استخدامه للفصل بين جُمَل SQL متعددة</td></tr><tr><td>engine--</td><td>محرّك قاعدة البيانات الذي يجب استخدامه، مثل InnoDB</td></tr><tr><td>auto-generate-sql--  </td><td>يسمح هذا الخيار لـMySQL بتنفيذ اختبار الحِمل باستخدام أمر SQL المُنشَئ تلقائيًا من طرف mysqlslap</td></tr></tbody></table><h2>حالة استخدام: اختبار الأداء مع بيانات واستعلامات SQL منشئة تلقائيا</h2><p>سنبدأ عبر استخدام ميّزة mysqlslap في الإنشاء التلقائي لجمل SQL. عندما نقوم باستخدامها، فإنّ mysqlslap سيقوم بإنشاء قاعدة بيانات مؤقّتة منفصلة تدعى "mysqlslap". ستحوي قاعدة البيانات هذه جدولًا بسيطًا يحوي هو الآخر عددًا صحيحًا واحدًا وعمودًا واحدًا من نوع varchar بداخله بيانات تجريبية. يمكن أن تكون هذه طريقةً سهلة وسريعة للتحقق من أداء خادوم قاعدة البيانات الكلّي.</p><p>سنبدأ عبر اختبار اتصال عميلٍ واحدٍ فقط يتم تكراره مرّةً واحدة كذلك باستخدام جملة SQL مُنشئة تلقائيًا:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --auto-generate-sql --verbose</pre><p>يجب أن يبدو الخرج كالتالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 0.009 seconds
        Minimum number of seconds to run all queries: 0.009 seconds
        Maximum number of seconds to run all queries: 0.009 seconds
        Number of clients running queries: 1
        Average number of queries per client: 0</pre><p>يقوم mysqlslap بإعطاء بعض الإحصائيات عن اختبار الأداء كما رأينا من الخرج السابق، حيث أنّه يقوم بإرجاع متوسّط، أقل وأعلى عدد من الثواني التي يحتاجها ليقوم بتنفيذ عملية الاستعلام. يمكننا أيضًا أن نرى أنّ عدد اتصالات العملاء المُستخدمة لاختبار الحِمل هذا كان واحدًا فقط.</p><p>الآن، جرّب محاكاة 50 اتصال، وقم باختيار تشغيل عملية الاستعلام المُنشَئة تلقائيًا 10 مرّات:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=10 --auto-generate-sql --verbose</pre><p>يعني هذا الأمر أنّه سيتم محاكاة 50 اتصالًا، يقوم كلّ منها بتنفيذ نفس عملية الاستعلام بنفس الوقت، وسيتم إعادة هذه الاختبار 10 مرّات.</p><p>يظهر لنا الخرج فرقًا واضحًا في الوقت مع ازدياد الحِمل:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 0.197 seconds
        Minimum number of seconds to run all queries: 0.168 seconds
        Maximum number of seconds to run all queries: 0.399 seconds
        Number of clients running queries: 50
        Average number of queries per client: 0</pre><p>لاحظ كيف أنّ حقل "Number of clients running queries" أصبح الآن يظهر الرقم 50، وأنّ عدد عمليات الاستعلام بواسطة العميل الواحد هو صفر.</p><p>تقوم SQL المُشَئة تلقائيًا بإنشاء جدولٍ بسيط يحوي حقلين اثنين، إلّا أنّه وفي معظم البيئات الإنتاجية فستكون بنية الجدول أكبر بكثير من هذا. يمكننا أن نفرض على mysqlslap أن يقوم بمحاكاة هذا عبر إضافة بعض الحقول الإضافية إلى جدول الاختبار. لفعل ذلك، يمكننا استخدام المُعامِلين الجديدين <span style="font-family:courier new,courier,monospace;">number-char-cols-- </span>و<span style="font-family:courier new,courier,monospace;">number-int-cols--</span>. تقوم هذه المُعامِلات بتحديد عدد الأعمدة من نوع varchar وint لإضافتها إلى جدول الاختبار.</p><p>سنختبر استعلام SQL مُنشَئ تلقائيًا عن جدولٍ بـ5 أعمدة رقمية و20 عمود نصّي في المثال التالي. سنحاكي أيضًا 50 اتصالًا من أجهزة العملاء في الوقت ذاته وسنقوم بتكرار الاختبار 100 مرّة:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=100 --number-int-cols=5 --number-char-cols=20 --auto-generate-sql --verbos</pre><p>سيستغرق هذا الأمر وقتًا أطول. يمكننا أن نتحوّل إلى الطرفية الأخرى الني قمنا بتشغيل جلسة MySQL الخاصّة بنا عليها لنرى ما يجري بينما يتم تنفيذ الاختبار. لاحظ أنّه في حال انتظرت وقتًا طويلًا، سيكتمل الاختبار ولن تتمكن من رؤية قاعدة البيانات الاختبارية.</p><p>من طرفية MySQL، طبّق:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">show databases;</pre><p>لاحظ وجود قاعدة mysqlslap:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| mysqlslap          |
| performance_schema |
+--------------------+
5 rows in set (0.01 sec)</pre><p>يمكنك أن تتحقق من الجدول في قاعدة البيانات الاختبارية إن أردت; إنّه يدعى <strong>t1</strong>.</p><p>تحقق من نافذة الطرفية الأخرى الآن. عندما ينتهي الاختبار، ستلاحظ أنّ الأداء قد انخفض بدرجةٍ أكبر من السابق بسبب الحِمل الزائد:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 0.695 seconds
        Minimum number of seconds to run all queries: 0.627 seconds
        Maximum number of seconds to run all queries: 1.442 seconds
        Number of clients running queries: 50
        Average number of queries per client: 0</pre><p>ارجع إلى نافذة طرفية MySQL. يمكننا أن نرى أنّ mysqlslap قد حذف قاعدة البيانات المؤقّتة الخاصّة به، طبّق:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">show databases;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)</pre><h2>حالة استخدام: اختبار الأداء مع استعلامات مخصصة</h2><p>استعلامات SQL المُنشَئة تلقائيًا جيّدة إذا كنت تريد تقييم موارد الخادوم الفيزيائية. هيَ مفيدة عندما تريد معرفة درجة الحِمل التي يمكن للنظام أن يتحمّلها.</p><p>عندما تريد التحقق من تطبيقٍ يعتمد على قاعدة بيانات، فإنّك ستودّ اختبار استعلاماتٍ حقيقية على بياناتٍ حقيقية. يمكن لهذه الاستعلامات أن تأتي من خادوم الويب الخاصّ بك أو من خادوم التطبيق الذي تشغّله.</p><p>الآن، سنفترض أنّك تعرف الاستعلامات المحددة التي تريد اختبارها. في القسم التالي، سنريك طريقةً لمعرفة عمليات الاستعلام التي يتم تنفيذها على خادومك.</p><p>يمكنك جعل mysqlslap ينفّذ عملية استعلام معيّنة عبر الخيار <span style="font-family:courier new,courier,monospace;">query--</span>. لا يمكن لجُمل الـSQL أن تحتوي على فواصل الأسطر (أكثر من سطر) ضمنها، ويجب فصلها بواسطة فاصلة منقوطة (;). يجب أيضًا إغلاق الاستعلامات بعلامتيّ تنصيص.</p><p>في الشفرة التالية، سنقوم بتشغيل عملية استعلام بسيطة عن الجدول deptemp. يحوي جدول "deptemp" أكثر من ثلاثمئة ألف سجل بداخله. لاحظ كيف قمنا بتحديد قاعدة البيانات employees مع الخيار <span style="font-family:courier new,courier,monospace;">create-schema--</span>:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=50 --iterations=10 --create-schema=employees --query="SELECT * FROM dept_emp;" --verbose</pre><p>سيستغرق هذا بعض الوقت ليكتمل. بعدها، يجب أن تتلقّى تقريرًا عن اختبار الأداء كالتالي بعد دقيقة أو اثنتين:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 18.486 seconds
        Minimum number of seconds to run all queries: 15.590 seconds
        Maximum number of seconds to run all queries: 28.381 seconds
        Number of clients running queries: 50
        Average number of queries per client: 1</pre><p>(ملاحظة: إذا استغرقت العملية حوالي 10 دقائق أو لم ترجع أيّ خرج، فيجب عليك المحاولة مجددًا مع عددٍ أقل للخيار <span style="font-family:courier new,courier,monospace;">concurrency--</span> و/أو <span style="font-family:courier new,courier,monospace;">iterations--</span>, أو محاولة تطبيقها على خادوم أقوى).</p><p>بعدها، سنستخدم أكثر من جملة SQL مع الخيار <span style="font-family:courier new,courier,monospace;">query--</span>. في المثال التالي، نقوم بإنهاء كلّ جملة بفاصلة منقوطة. سيعرف mysqlslap أننا نستخدم عددًا من أوامر SQL المنفصلة بسبب استخدامنا للخيار<span style="font-family:courier new,courier,monospace;">delimiter--</span>:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=20 --iterations=10 --create-schema=employees --query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" --delimiter=";" --verbose</pre><p>يستخدم هذا الاختبار نفس عدد الاتصالات ونفس عدد مرّات التكرار، إلّا أنّ الأداء كان أبطئ بشكلٍ ملحوظ بسبب استخدام أكثر من جملة SELECT واحدة (متوسّط 23.8 ثانية مقابل 18.486 ثانية).</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 23.800 seconds
        Minimum number of seconds to run all queries: 22.751 seconds
        Maximum number of seconds to run all queries: 26.788 seconds
        Number of clients running queries: 20
        Average number of queries per client: 5</pre><p>يمكن لجُمل SQL التي يتم استخدامها في بيئة إنتاجية أن تكون معقّدة. إضافة جملة SQL معقّدة إلى سكربت هو أسهل من وضعها للاختبارات، لذا، يمكننا أن نطلب من mysqlslap أن يقوم بقراءة الاستعلامات من ملفّ سكربت.</p><p>للقيام بهذا، فلنقم بإنشاء ملفّ سكربت من أوامر SQL. يمكننا استخدام الشفرة البرمجية أدناه لإنشاء الملفّ:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo echo "SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" &gt; ~/select_query.sql

sudo cp ~/select_query.sql /mysqlslap_tutorial/</pre><p>يحوي ملفّ <span style="font-family:courier new,courier,monospace;">select_query.sql</span> جميع عبارات SELECT الآن.</p><p>بما أنّ السكربت يحوي أكثر من عملية استعلام واحدة، فيمكننا استخدام مفهومٍ جديد في الاختبار. يمكن لـmysqlslap أن يقوم <em>بتوزيع</em> عمليات الاستعلام. يمكننا القيام بهذا عبر تحديد عدد الاستعلامات التي يجب على كلّ جهازٍ عميل متّصل أن ينفذّها. يسمح mysqlslap بفعل هذا عبر استخدام الخيار <span style="font-family:courier new,courier,monospace;">number-of-queries--</span>. لذا، إذا كان لدينا 50 اتصال و1000 عمليّة استعلام يجب تنفيذها، فإنّ كلّ جهاز عميل متّصل سينفّذ حوالي 20 عملية استعلام تقريبًا.</p><p>أخيرًا، يمكننا أيضًا استخدام الخيار <span style="font-family:courier new,courier,monospace;">debug-info--</span>، والذي سيظهر لنا حسبة تقريبية للموارد المستعملة.</p><p>في الشفرة البرمجية التالية، نطلب من mysqlslap أن يستخدم ملفّ السكربت الذي أنشأناه للتوّ. إننا نقوم أيضًا بتحديد المُعامِل number-of-queries. سيتم تكرار العمليّة مرّتين كما أننا نريد معلومات التنقيح (debug) ضمن الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=20 --number-of-queries=1000 --create-schema=employees --query="/mysqlslap_tutorial/select_query.sql" --delimiter=";" --verbose --iterations=2 --debug-info</pre><p>بعد أن يكتمل هذا الأمر، يجب أن نرى بعض النتائج المثيرة للاهتمام:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 217.151 seconds
        Minimum number of seconds to run all queries: 213.368 seconds
        Maximum number of seconds to run all queries: 220.934 seconds
        Number of clients running queries: 20
        Average number of queries per client: 50


User time 58.16, System time 18.31
Maximum resident set size 909008, Integral resident set size 0
Non-physical pagefaults 2353672, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 102785, Involuntary context switches 43</pre><p>هنا يكون متوسّط عدد الثواني اللازم لتنفيذ جميع عمليات الاستعلام في MySQL هو 217 ثانية، حوالي 4 دقائق. صحيحٌ أنّ هذا الرقم له علاقة بحجم الذاكرة العشوائية ونوع المعالج المُستخدم مع آلتنا الوهمية، إلّا أنّه كان كبيرًا أيضًا بسبب عدد الاستعلامات الكبير الذي كان كلّ جهاز عميل متصل يكرره مرّتين.</p><p>يمكننا أن نرى وجود عددٍ كبير من أخطاء الصفحات غير العتادية (البرمجية). تحصل أخطاء الصفحات (page faults) عندما لا يمكن العثور على البيانات في الذاكرة ويتوجّب على النظام أن يبحث عنها على قرص الـSwap. يظهر الخرج أيضًا بعض المعلومات المتعلّقة بالمعالج المركزي. في حالتنا، فإننا نرى عدد كبيرًا من تبديلات السياق كذلك.</p><h2>حالة استخدام: سيناريو اختبار أداء عملي مع التقاط مباشر للاستعلامات</h2><p>إلى الآن في أمثلتنا، كنّا نقوم بتطبيق عمليات الاستعلام مع قاعدة بيانات "employees" الخاصّة بنا، وهو ما قد لا يكون شيئًا يريدك مُدراء قواعد البيانات أن تفعله، وهناك سببٌ وجيهٌ لذلك. لا تريد أن تقوم بإضافة حِمل إضافي إلى قاعدة بياناتك الإنتاجية ولا تريد أن تقوم بتفيذ استعلامات اختبارية يمكنها أن تقوم بحذف، تحديث أو إدراج البيانات إلى جداول قاعدة البيانات الإنتاجية الخاصّة بك.</p><p>سنريك كيفيّة عمل نسخة احتياطية من قاعدة بيانات إنتاجية وكيفيّة نسخها إلى بيئة تجريبية، في هذا المثال وعلى نفس الخادوم، ولكنّك طبعًا قد تودّ نسخها إلى خادومٍ منفصل بنفس قدرات العتاد.</p><p>والأكثر أهميّة من ذلك، سنريك كيف تقوم بتسجيل الاستعلامات بشكلٍ حيّ أو مباشر (live) من قاعدة بيانات إنتاجية بالإضافة إلى كيفيّة إضافة الاستعلامات إلى سكربتٍ اختباري. في المجمل، ستحصل على الاستعلامات من بيئة عمل إنتاجية، ولكنّك ستقوم بتنفيذ الاختبارات على قاعدة البيانات التجريبية.</p><p>الخطوات العامّة هي كالتالي، ويمكنك استخدامها لأيّ اختبار mysqlslap:</p><ol><li>انسخ قاعدة البيانات الإنتاجية إلى بيئة اختبارية.</li><li>قم بإعداد MySQL لتسجيل والتقاط جميع طلبات الاتصال والاستعلام على قاعدة البيانات الإنتاجية.</li><li>قم بمحاكاة حالة الاستخدام التي تحاول اختبارها. كمثال، إذا كنتَ تدير موقع تسوّق، يجب أن تشتري شيئًا لتقوم بتفعيل جميع عمليات الاستعلام الأساسية ضمن تطبيقك.</li><li>قم بتعطيل تسجيل الاستعلامات.</li><li>انظر إلى سجل الاستعلامات وقم بعمل قائمة بالاستعلامات التي تريد اختبارها.</li><li>أنشئ ملفًّا اختباريًا لكلّ عملية استعلام تريد اختبارها.</li><li>نفّذ الاختبارات.</li><li>استخدم الخرج لتحسين أداء قاعدة البيانات الخاصّة بك.</li></ol><p>للبدء، قم بإنشاء نسخة احتياطية من قاعدة البيانات "employees". سنقوم بإنشاء مسارٍ منفصل لهذه النسخة الاحتياطية:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mkdir /mysqlslap_tutorial/mysqlbackup

cd /mysqlslap_tutorial/mysqlbackup</pre><p>أنشئ النسخة الاحتياطية وانقلها إلى المسار الجديد:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqldump --user sysadmin --password --host localhost employees &gt; ~/employees_backup.sql
</pre><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint" style="line-height: 17.92px;">sudo cp ~/employees_backup.sql /mysqlslap_tutorial/mysqlbackup/</pre><p>اذهب إلى خادوم MySQL التجريبي الخاصّ بك، وأنشئ قاعدة البيانات "employees_backup":</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">CREATE DATABASE employees_backup;</pre><p>في هذه النقطة، إذا كنتَ تستخدم خادومًا منفصلًا للاختبار، فيجب أن تنقل ملفّ <span style="font-family:courier new,courier,monospace;">employeesbackup.sql</span> إليه، ومن جلسة الطرفيّة الرئيسية، استورد بيانات النسخة الاحتياطية إلى قاعدة البيانات employeesbackup:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysql -u sysadmin -p employees_backup &lt; /mysqlslap_tutorial/mysqlbackup/employees_backup.sql</pre><p>على <strong>خادوم قاعدة بيانات MySQL الإنتاجية الخاصّ بك</strong>، فعّل سجل استعلامات MySQL العام وقم بتوفير اسم ملفٍّ خاصٍّ به. يقوم سجل الاستعلامات العام بالتقاط الاتصالات، الاتصالات المنقطعة وسجل الاستعلامات لقاعدة بيانات MySQL:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">SET GLOBAL general_log=1, general_log_file='capture_queries.log';</pre><p>الآن، شغّل الاستعلامات التي تريد اختبارها على خادوم MySQL الإنتاجي. في هذا المثال، سنقوم بتنفيذ عملية استعلام من سطر الأوامر. وعلى كلّ حال، قد تودّ إنشاء الاستعلامات من تطبيقك عوضًا عن تنفيذها بشكلٍ مباشر. إذا كنتَ تمتلك صفحة موقع تريد اختبار أدائها، فيجب عليك تنفيذ تلك العملية أو الوصول إلى تلك الصفحة الآن. كمثال، إذا كنتَ تدير موقع تسوّق إلكتروني، قد تودّ إكمال عملية الدفع الآن، والذي من شأنه أن يقوم بطلب جميع الاستعلامات المطلوبة على خادوم قاعدة البيانات.</p><p>هذه هي عملية الاستعلام التي سنقوم بطلبها على خادوم MySQL الإنتاجي الخاصّ بنا. أولًا، قم باستخدام قاعدة البيانات الصحيحة:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">USE employees;</pre><p>والآن عملية الاستعلام:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date;</pre><p>الخرج المتوقّع:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">489903 rows in set (4.33 sec)</pre><p>سنقوم بتعطيل التسجيل العام عندما تكتمل عملية الاستعلام:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">SET GLOBAL general_log=0;</pre><p>لاحظ أنّه في حال تركت التسجيل العام مفعّلًا، سيستمر إضافة الاستعلامات إلى السجل، والذي من شأنه جعل الاختبارات أصعب. لذا تأكّد أنّك قمت بتعطيل التسجيل مباشرةً بعد الإنتهاء من اختبارك. فلنتحقق من أنّ ملفّ السجل تمَّ إنشاؤه ضمن المسار <span style="font-family:courier new,courier,monospace;">var/lib/mysql/</span>:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo ls -l /var/lib/mysql/capt*
</pre><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint" style="line-height: 17.92px;">-rw-rw----. 1 mysql mysql 861 Sep 24 15:09 /var/lib/mysql/capture_queries.log</pre><p>فلننسخ هذا الملفّ إلى مسار MySQL الاختباري الخاصّ بنا. إذا كنتَ تستخدم خادومًا منفصلًا للاختبار، فقم بنسخه إلى ذلك الخادوم:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo cp /var/lib/mysql/capture_queries.log /mysqlslap_tutorial/</pre><p>يجب أن يكون هناك بعض البيانات داخل ملفّ السجل هذا. في مثالنا، يجب أن تكون الاستعلامات التي نريدها بالقرب من نهاية الملفّ. تحقق من آخر جزء من الملفّ عبر الأمر:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo tail /mysqlslap_tutorial/capture_queries.log</pre><p>الخرج المتوقّع:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">         6294 Query show databases
         6294 Query show tables
         6294 Field List    departments 
         6294 Field List    dept_emp 
         6294 Field List    dept_manager 
         6294 Field List    employees 
         6294 Field List    salaries 
         6294 Field List    titles 

140930 15:34:52  6294 Query SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date
140930 15:35:06  6294 Query SET GLOBAL general_log=0</pre><p>يظهر هذا السجل أوامر SQL والتوقيت الزمني الخاصّ بها. جملة SQL SELECT الموجودة بالقرب من نهاية الملفّ هي الجزء الذي نحن مهتمّون به. يجب أن يكون بالضبط هو الأمر الذي نقوم بتنفيذه على خادوم قاعدة البيانات الإنتاجية، حيث أننا قمنا من هناك بالتقاطه.</p><p>في مثالنا هذا، كنّا نعرف عملية الاستعلام بالفعل، ولكن، في بيئة عمل إنتاجية، يمكن أن تكون هذه الطريقة نافعة جدًا لمعرفة الاستعلامات التي ربّما لا تعرف بالضرورة أنّه يتم تشغيلها على خادومك.</p><p>لاحظ أنّه في حال قمت بطلب استعلامات مختلفة أثناء عملية التسجيل (logging)، فإنّ هذا الملفّ سيبدو مختلفًا تمامًا. في سيناريو حقيقي، يمكن أن يتمّ ملئ هذا الملفّ بالمئات من المُدخَلات القادمة من مختلف الاتصالات. هدفك هو العثور على الاستعلام أو الاستعلامات التي تسبب هذا الحِمل. يمكنك أن تبدأ عبر إنشاء قائمة بكلّ سطر يتضمّن الكلمة "Query". بعدها، ستمتلك قائمةً دقيقة بالاستعلامات التي تمّ تنفيذها على قاعدة البيانات الخاصّة بك أثناء الاختبار.</p><p>قم بنسخ كلّ استعلام تريد اختباره إلى ملفٍّ ينتهي بالامتداد sql.</p><p>كمثال:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo vi /mysqlslap_tutorial/capture_queries.sql</pre><p>يجب أن تكون المحتويات هي استعلامات MySQL التي تريد اختبارها، دون استخدام أيّ سطور إضافية (استخدم سطر واحد فقط) ودون فاصلة منقوطة بالنهاية:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN  dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY  e.first_name, e.last_name, d.dept_name, t.from_date</pre><p>بعدها، تأكّد أنّ نتائج الاستعلامات لم يتم تخزينها في ذاكرة الخبيئة (cache). ارجع إلى جلسة MySQL الخاصّة بالخادوم الاختباري وطبّق الأمر التالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">RESET QUERY CACHE;</pre><p>الآن، صار الوقت المناسب لتشغيل أداة mysqlslap مع ملفّ السكربت. تأكّد أنّك تستخدم اسم ملفّ السكربت الصحيح مع المُعامِل <span style="font-family:courier new,courier,monospace;">query--</span>. سنستخدم فقط 10 اتصالات افتراضية وسنكرر العمليّة مرّتين فقط. قم بتشغيل الأمر التالي من <strong>خادومك الاختباري</strong>:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=10 --iterations=2 --create-schema=employees_backup --query="/mysqlslap_tutorial/capture_queries.sql" --verbose</pre><p>يجب أن يبدو خرج اختبار الأداء شيئًا كالتالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Benchmark
        Average number of seconds to run all queries: 68.692 seconds
        Minimum number of seconds to run all queries: 59.301 seconds
        Maximum number of seconds to run all queries: 78.084 seconds
        Number of clients running queries: 10
        Average number of queries per client: 1</pre><p>إذًا، كيف يمكننا الآن تحسين هذا الأداء؟</p><p>ستحتاج معرفةً جيّدة باستعلامات MySQL لتقييم ما تفعله عمليات الاستعلام.</p><p>بالنظر مجددًا إلى الاستعلامات، يمكننا أن نرى أنّه تقوم بالعديد من عمليات الدمج على امتداد أكثر من جدول، تقوم الاستعلامات بإظهار تواريخ عمل الموظّف وأثناء القيام بذلك، تقوم بدمج أكثر من جدول عبر الحقل empno، كما أنّها تقوم باستخدام الحقل deptno للدمج، ولكن بما أنّه هناك أقسام سجلات قليلة فقط، فسنقوم بتجاهل هذا. بما أنّه هناك العديد من مُدخَلات empno في قاعدة البيانات، فمن المنطقي افتراضي أنّ إنشاء الفهارس في حقل empno يمكن أن يحسّن من أداء عمليات الاستعلام.</p><p>مع القليل من التمرّن، بمجرّد أن تجد الاستعلامات التي تسبب ضغطًا على خادوم البيانات (وهو القسم الذي سيساعدك mysqlslap فيه!)، ستكون قادرًا على تقييم عمليات الاستعلام المتوفّرة بناءً على معرفتك بـMySQL وقاعدة بياناتك.</p><p>بعدها، يمكنك محاولة تحسين قاعدة بياناتك أو الاستعلامات التي يتم تنفيذها عليها.</p><p>في حالتنا، فلنضف الفهارس التي ذكرناه بالأعلى، سنقوم بإنشاء 3 فهارس فارغة لـempno. سيتم إنشاء فهرس واحد في حقل empno في جدول employees، وسيتم إنشاء فهرس آخر في حقل empno بالجدول deptemp، وسيتم إنشاء الأخير في حقل emp_no في جدول titles.</p><p>فلنذهب إلى جلسة MySQL الاختبارية الخاصّة بنا ونطبّق الأوامر التالية:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">USE employees_backup;

CREATE INDEX employees_empno ON employees(emp_no);

CREATE INDEX dept_emp_empno ON dept_emp(emp_no);

CREATE INDEX titles_empno ON titles(emp_no);</pre><p>بالعودة إلى نافذة الطرفية الرئيسية على خادومنا الاختباري، إذا قمنا بتشغيل mysqlslap بنفس المُعاملات، فسنرى اختلافًا في نتائج اختبار الأداء:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysqlslap --user=sysadmin --password --host=localhost  --concurrency=10 --iterations=2 --create-schema=employees_backup --query="/mysqlslap_tutorial/capture_queries.sql" --verbose
</pre><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint" style="line-height: 17.92px;">Benchmark
        Average number of seconds to run all queries: 55.869 seconds
        Minimum number of seconds to run all queries: 55.706 seconds
        Maximum number of seconds to run all queries: 56.033 seconds
        Number of clients running queries: 10
        Average number of queries per client: 1</pre><p>يمكن أن نرى وجود تحسّن فوري في متوسّط، أدنى وأقصى وقت لتنفيذ عمليات الاستعلام. عوضًا عن متوسّط 68 ثانية، يتم تنفيذ الاستعلامات الآن بغضون 55 ثانية. هذا تحسّن بحوالي 13 ثانية لنفس الاستعلامات التي تمّ تنفيذها.</p><p>بما أنّ هذا التغيير في قاعدة البيانات أعادة نتيجةً جيّدة في البيئة الاختبارية، فإنّه يمكنك الآن أخذه بعين الاعتبار لتنفيذه على خادوم قاعدة البيانات الإنتاجية الخاصّة بك، ولكن لا تنسى أنّ تغييرات قاعدة البيانات لها دومًا إيجابيات وسلبيات عليك المفاضلة بينها.</p><p>يمكنك إعادة عملية اختبار الأوامر والتحسينات مع جميع الاستعلامات التي جمعتها من ملفّ السجل الخاصّ بك.</p><h2>استكشاف الأخطاء وإصلاحها: mysqlslap لا يظهر الخرج</h2><p>إذا قمت بتنفيذ أمر اختبار ولم يرجع لك خرجًا، فهذا مؤشّرٌ جيّد إلى أنّ موارد خادومك قد تكون امتلأت بالفعل. قد تتضمّن أعراض هذه المشكلة نقصًا في خرج Benchmark، أو رسالة خطأ مثل:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysqlslap: Error when storing result: 2013 Lost connection to MySQL server during query</pre><p>ربّما قد تودّ إعادة الاختبار مجددًا مع عددٍ أقل للمُعامِل <span style="font-family:courier new,courier,monospace;">concurrency--</span> أو <span style="font-family:courier new,courier,monospace;">iterations--</span>، أو يمكنك محاولة ترقية بيئة خادومك الاختباري لإصلاح المشكلة.</p><p>يمكن أن يكون هذا طريقةً جيّدة لمعرفة حدود سعة خادوم قاعدة البيانات الخاصّ بك.</p><h2>الخاتمة</h2><p>mysqlslap هو أداة بسيطة وخفيفة يمكنها أن تندمج بسهولة مع محرّك قاعدة بيانات MySQL. وهي متوفّر لجميع إصدارات MySQL بدءًا من الإصدار 5.1.4.</p><p>في هذا الدرس، رأينا كيفيّة استخدام mysqlslap مع خياراته المتعددة وجرّبنا الأمر مع قاعدة بيانات اختبارية كعيّنة. يمكنك تحميل قواعد بيانات عينية أخرى للاختبار من موقع MySQL والتمرّن عليها أيضًا. كما ذكرنا من قبل: <strong>رجاءًا لا تقم بتنفيذ الاختبارات على خادوم قاعدة بيانات إنتاجية</strong>.</p><p>آخر حالة استخدام في درسنا هذا تعلّقت بعملية استعلام واحدة فقط. صحيحٌ أننا قمنا بتحسين أداء عملية الاستعلام تلك عبر إضافة فهارس إضافية إلى جميع الجداول الثلاث، إلّا أنّ العملية قد لا تكون بتلك البساطة في الحياة الحقيقية. إضافة المزيد من الفهارس قد يبطئ - في بعض الأحيان - أداء النظام وغالبًا مع يحتاج مُدراء قواعد البيانات إلى قياس إيجابيات إضافتها على حساب التغيير في الأداء الذي سيحصل.</p><p>سيناريوهات الاختبار في الحياة الحقيقية أكثر تعقيدًا، ولكن هذا قد يعطيك الأدوات اللازمة للبدء في اختبار وتحسين أداء قاعدة البيانات الخاصّة بك.</p><p>ترجمة -وبتصرف- للمقال: <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-measure-mysql-query-performance-with-mysqlslap">How To Measure MySQL Query Performance with mysqlslap</a> لصاحبه: Sadequl Hussain.</p>
]]></description><guid isPermaLink="false">109</guid><pubDate>Wed, 23 Sep 2015 15:46:53 +0000</pubDate></item><item><title>&#x62A;&#x62B;&#x628;&#x64A;&#x62A; &#x648;&#x625;&#x639;&#x62F;&#x627;&#x62F; mysqlslap &#x644;&#x642;&#x64A;&#x627;&#x633; &#x623;&#x62F;&#x627;&#x621; &#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; MySQL - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x623;&#x648;&#x644;</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-mysqlslap-%D9%84%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-mysql-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%84-r107/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.png.96c498f8ba84a08a2f2ac3fdfb945e34.png" /></p>

<p>تأتي MySQL مع أداة تشخيص (diagnostic) تدعى <strong>mysqlslap</strong>، تمّ توفير هذه الأداة منذ الإصدار 5.1.4 من MySQL، وهي عبارة عن أداة قياس للأداء (benchmarking) يمكنها أن تساعد مدراء قواعد البيانات والمطورّين على أن يختبروا أداء خواديم قواعد البيانات الخاصّة بهم بسهولة.</p><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.png.c6d9617563c78c9ebac82d24a8cea882.png"><img data-fileid="4950" class="ipsImage ipsImage_thumbnailed" alt="mysql-performance.thumb.png.304097c9990a" src="https://academy.hsoub.com/uploads/monthly_2015_09/mysql-performance.thumb.png.304097c9990af0cbd53c35eb6908555e.png"></a></p><p>يمكن لـmysqlslap أن تحاكي عددًا كبيرًا من أجهزة العملاء التي تتصل بخادوم قاعدة البيانات بنفس الوقت. مُعامِلات اختبار الحمل (load testing parameters) قابلة للضبط بشكلٍ كلّي ويمكن استخدام نتائج الاختبارات المختلفة بهدف تحسين تصميم قواعد البيانات أو استهلاك موارد العتاد.</p><p>في هذا الدرس، سنشرح كيفيّة تثبيت وإعداد mysqlslap بهدف إجراء اختبار الحِمْل (load test) على قاعدة بيانات MySQL باستخدام بعض عمليات الاستعلام الأساسية ولنرى كيف يمكن لاختبارات الأداء أن تساعدنا على تحسين هذه الاستعلامات لاحقًا. بعد القليل من التوضيحات المبدئية، سنقوم بعمل سيناريو تجريبي مشابه للتجربة الحقيقية حيث سنقوم بإنشاء نسخة من قاعدة بيانات موجودة حاليًا لنقوم بالاختبارات عليها، وسنجمع الاستعلامات من ملفّات السجل ونبدأ بالاختبار بواسطة سكربت.</p><h2>ما هو حجم الخادوم الذي يجب أن أستخدمه؟</h2><p>إذا كنتَ مهتمًا باختبار أداء خادوم قاعدة بياناتٍ معيّن، فيجب عليك أن تقوم بتشغيل اختبارات الأداء على خادوم بنفس المواصفات وبنسخة مطابقة تمامًا لقاعدة البيانات التي قمت بتثبيتها على خادومك الرئيسي.</p><p>إذا كنتَ تريد المضيّ قدمًا بهذا الدرس بهدف التعلّم وتنفيذ كلّ أمر موجودٍ فيه، فإننا ننصحك بخادوم يمتلك 2 جيجابت من الذاكرة العشوائية (RAM) على الأقل. وبما أنّ الأوامر الموجودة في هذا الدرس تهدف إلى إرهاق الخادوم بالطلبات الكثيرة بهدف قياس أدائه، فإنّك قد تلاحظ أنّ الخواديم الأصغر حجمًا قد ينقطع الاتصال بها بسبب ذلك الحِمل.</p><p>تمّ إنتاج الخرج الناتج في هذا الدرس بواسطة عدّة طرق بهدف تحسين الاستفادة من الأمثلة الموجودة هنا.</p><h2>الخطوة الأولى: تثبيت خادوم MySQL على نظام اختباري</h2><p>سنبدأ عبر تثبيت نسخة جديدة من خادوم MySQL المطوّر بواسطة المجتمع أو MySQL Community Server على نظام تشغيل اختباري. <strong>يجب ألّا تقوم بتشغيل </strong>أيّ<strong> أوامر أو استعلامات تجدها في هذا الدرس على خادوم قاعدة بيانات ضمن بيئة إنتاجية بتاتًا</strong>.</p><p>تهدف هذه الاختبارات إلى الضغط على الخادوم التجريبي وقد تسبب تعليقا أو تعطلا لخادوم يعمل ضمن بيئة عمل إنتاجية. تمّ تنفيذ هذا الدرس ضمن بيئة العمل التالية:</p><ul><li>CentOS 7.</li><li>أوامر تمّ تنفيذها بواسطة <a href="https://academy.hsoub.com/devops/linux/%D8%B6%D8%A8%D8%B7-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D9%8A%D9%86-%D9%88%D8%A7%D9%84%D9%85%D8%AC%D9%85%D9%88%D8%B9%D8%A7%D8%AA-%D9%81%D9%8A-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r78/">مستخدم جذر</a>.</li><li>2 جيجابت من الذاكرة العشوائية (RAM); لا تنسى أنّ الاختبارات التي سيتم ذكرها هنا تمّ إنتاجها بهدف التعليم ولا تعني بأيّ شكل من الأشكال أنّها نتيجة اختبارات رسمية صادرة عنّا.</li></ul><p>أولًا، سنقوم بإنشاء مسار ليحوي جميع الملفّات المتعلّقة بهذا الدرس. سيساعدنا هذا على إبقاء المكان نظيفًا. قم بالذهاب إلى هذا المسار:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mkdir /mysqlslap_tutorial
cd /mysqlslap_tutorial</pre><p>بعدها، سنقوم بتحميل مستودع <strong>yum</strong> الخاصّ بنسخة المجتمع من خادوم MySQL. المستودع الذي سنحمّله هو مخصص بشكل اساسي لـRed Hat Enterprise Linux 7 إلّا أنّه يعمل بالطبع مع CentOS 7 كذلك:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm</pre><p>الآن يمكننا تنفيذ <span style="font-family:courier new,courier,monospace;">rpm -Uvh</span> لتثبيت هذا المستودع:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo rpm -Uvh mysql-community-release-el7-5.noarch.rpm</pre><p>تحقق أنّه قد تمّ تثبيت المستودعات عبر تفحّص محتويات المجلّد <span style="font-family:courier new,courier,monospace;">etc/yum.repos.d/</span>:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo ls -l /etc/yum.repos.d</pre><p>يجب أن يبدو الخرج كالتالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">-rw-r--r--. 1 root root 1612 Jul  4 21:00 CentOS-Base.repo
-rw-r--r--. 1 root root  640 Jul  4 21:00 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 1331 Jul  4 21:00 CentOS-Sources.repo
-rw-r--r--. 1 root root  156 Jul  4 21:00 CentOS-Vault.repo
-rw-r--r--. 1 root root 1209 Jan 29  2014 mysql-community.repo
-rw-r--r--. 1 root root 1060 Jan 29  2014 mysql-community-source.repo</pre><p>وفي حالتنا، فإنّ <strong>MySQL 5.6 Community Server</strong> هو ما نريده:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">mysql-connectors-community/x86_64       MySQL Connectors Community           10
mysql-tools-community/x86_64            MySQL Tools Community                 6
mysql56-community/x86_64                MySQL 5.6 Community Server           64</pre><p>والآن قم بتثبيت خادوم MySQL:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo yum install mysql-community-server</pre><p>بمجرّد اكتمال العمليّة، قم بالتحقق من أنّه تمّ تثبيت المكوّنات فعلًا:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo yum list installed | grep mysql</pre><p>يجب أن تبدو القائمة كالتالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">mysql-community-client.x86_64      5.6.20-4.el7      @mysql56-community
mysql-community-common.x86_64      5.6.20-4.el7      @mysql56-community
mysql-community-libs.x86_64        5.6.20-4.el7      @mysql56-community
mysql-community-release.noarch     el7-5             installed
mysql-community-server.x86_64      5.6.20-4.el7      @mysql56-community</pre><p>بعدها، يجب أن نتأكّد أن عفريت MySQL أو MySQL Daemon يعمل بالفعل وأنّه سيبدأ تلقائيًا عند تشغيل الخادوم. يمكنك القيام بذلك عبر الأمر التالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo systemctl status mysqld.service</pre><p>يجب أن ترى خرجًا كهذا:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">mysqld.service - MySQL Community Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; disabled)
   Active: inactive (dead)</pre><p>ابدأ الخدمة عبر:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo systemctl start mysqld.service</pre><p>ولجعلها تبدأ عند بدء تشغيل الخادوم:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo systemctl enable mysqld.service</pre><p>وأخيرًا يجب علينا تأمين خادوم MySQL:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysql_secure_installation</pre><p>سيظهر لك هذا مجموعة من الأسئلة. سنريك بالأسفل جميع الأسئلة مع أجوبتها التي يجب أن تختارها. في البداية لن يكون هناك كلمة مرور للمستخدم root الخاصّ بـMySQL، لذا، قم فقط بالضغط على زرّ <span style="font-family:courier new,courier,monospace;">Enter</span>.</p><p>أثناء الأسئلة، يجب أن تقوم بكتابة كلمة مرور جديدة وآمنة للمستخدم الجذر. يجب أن تقوم بكتابة <strong>y</strong> لإزالة حساب المستخدم المجهول من خادوم قاعدة البيانات، ولتعطيل السماح بالولوج البعيد للمستخدم الجذر وإعادة تحميل جدول الصلاحيات وغيرها:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">...
Enter current password for root (enter for none):
OK, successfully used password, moving on...
...
Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!
...
Remove anonymous users? [Y/n] y
 ... Success!
...
Disallow root login remotely? [Y/n] y
 ... Success!
Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
...
Reload privilege tables now? [Y/n] y
 ... Success!
Cleaning up...</pre><p>يمكننا الآن أن نتّصل بقاعدة البيانات لنتأكّد من أنّ كلّ شيءٍ يعمل بشكلٍ صحيح:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysql -h localhost -u root -p</pre><p>قم بإدخال كلمة مرور MySQL التي كتبتها للتوّ الآن. يجب أن ترى الخرج التالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Enter password:
Welcome to the MySQL monitor....

mysql&gt;</pre><p>في طرفيّة <span style="font-family:courier new,courier,monospace;">&lt;mysql</span> قم بإدخال الأمر الذي سيظهر لك جميع قواعد البيانات:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">show databases;</pre><p>يجب أن ترى خرجًا كالتالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)</pre><p>وأخيرًا، دعنا ننشئ مستخدمًا يدعى "sysadmin"، سيتم استخدام هذا الحساب للولوج إلى MySQL بدلًا من المستخدم الجذر. كن متأكّدًا من استبدال <strong>mypassword</strong> بكلمة المرور التي تريدها لهذا المستخدم. سنقوم أيضًا بمنح جميع الصلاحيات اللازمة لهذا المستخدم. في طرفيّة MySQL، قم بإدخال التالي:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">create user sysadmin identified by 'mypassword';</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Query OK, 0 rows affected (0.00 sec)</pre><p>قم بإعطاء جميع الصلاحيات للمستخدم:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">grant all on *.* to sysadmin;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Query OK, 0 rows affected (0.01 sec)</pre><p>والآن فلنعد إلى طرفيّة نظام التشغيل العادية:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">quit;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">Bye</pre><h2>الخطوة الثانية: تثبيت قاعدة بيانات تجريبية</h2><p>الآن، سنحتاج إلى تثبيت قاعدة بيانات تجريبية بهدف الاختبار. اسم قاعدة البيانات هذه هو "employees" وهي <a rel="external nofollow" href="http://dev.mysql.com/doc/index-other.html">وهي متوفّرة بشكلٍ مجاني من على موقع MySQL</a>، كما أنّه يمكن تحميل قاعدة البيانات من <a rel="external nofollow" href="https://launchpad.net/test-db/">Launchpad</a>.</p><p>اخترنا قاعدة "employees" لأنّها تحتوي على مجموعة كبيرة من البيانات. رغم ذلك، فإنّ بنية قاعدة البيانات بسيطة بدرجة كافية، إنّها تحتوي على 6 جداول فقط، ولكن وفي داخلها، فهي تحتوي على سجلات 3 مليون موظّف (يمتلك جدول الرواتب لوحده حوالي 3 ملايين صفّ)، وسيساعدنا هذا على محاكاة حِمل بيئة عمل إنتاجية بشكل أفضل.</p><p>أوّلًا، دعنا نتأكّد أننا في المسار<span style="font-family:courier new,courier,monospace;"> mysqlslap_tutorial/</span> الخاصّ بنا:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">cd /mysqlslap_tutorial</pre><p>قم بتحميل آخر إصدار من قاعدة البيانات التجريبية:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo wget https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2</pre><p>قم بتثبيت <strong>bzip2</strong> لنتمكّن من استخراج الملفّ:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo yum install bzip2</pre><p>والآن قم بفكّ الضغط عن أرشيف قاعدة البيانات، قد يأخذ هذا وقتًا:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo bzip2 -dfv employees_db-full-1.0.6.tar.bz2
sudo tar -xf employees_db-full-1.0.6.tar</pre><p>سيتم فكّ ضغط المحتويات إلى مسار منفصل جديد يدعى "employees_db"، نحتاج أن نقوم بالذهاب إلى هذا المجلّد لنقوم بتشغيل الأمر الذي يقوم بتثبيت قاعدة البيانات هذه. تتضمّن المحتويات ملفّ <span style="font-family:courier new,courier,monospace;">README</span>، سجل للتغييرات، حِزَم بيانات وملفّات استعلامات SQL مختلفة تشكّل جميعها بنية قاعدة البيانات:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">cd employees_db
ls -l</pre><p>وهذا هو ما يجب أن تراه:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">-rw-r--r--. 1 501 games       752 Mar 30  2009 Changelog
-rw-r--r--. 1 501 games      6460 Oct  9  2008 employees_partitioned2.sql
-rw-r--r--. 1 501 games      7624 Feb  6  2009 employees_partitioned3.sql
-rw-r--r--. 1 501 games      5660 Feb  6  2009 employees_partitioned.sql
-rw-r--r--. 1 501 games      3861 Nov 28  2008 employees.sql
-rw-r--r--. 1 501 games       241 Jul 30  2008 load_departments.dump
-rw-r--r--. 1 501 games  13828291 Mar 30  2009 load_dept_emp.dump
-rw-r--r--. 1 501 games      1043 Jul 30  2008 load_dept_manager.dump
-rw-r--r--. 1 501 games  17422825 Jul 30  2008 load_employees.dump
-rw-r--r--. 1 501 games 115848997 Jul 30  2008 load_salaries.dump
-rw-r--r--. 1 501 games  21265449 Jul 30  2008 load_titles.dump
-rw-r--r--. 1 501 games      3889 Mar 30  2009 objects.sql
-rw-r--r--. 1 501 games      2211 Jul 30  2008 README
-rw-r--r--. 1 501 games      4455 Mar 30  2009 test_employees_md5.sql
-rw-r--r--. 1 501 games      4450 Mar 30  2009 test_employees_sha.sql</pre><p>قم بتشغيل هذا الأمر للاتصال بـMySQL وتشغيل سكربت <span style="font-family:courier new,courier,monospace;">employees.sql</span>، والذي سيقوم بإنشاء قاعدة البيانات وتحميل البيانات إليها:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysql -h localhost -u sysadmin -p -t &lt; employees.sql</pre><p>الآن، يجب عليك إدخال كلمة المرور التي اخترتها للمستخدم "sysadmin" من قبل.</p><p>يجب أن يكون خرج العملية شيئًا كهذا، قد تأخذ وقتًا (حوال الدقيقة) ليكتمل:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+-----------------------------+
| INFO                        |
+-----------------------------+
| CREATING DATABASE STRUCTURE |
+-----------------------------+
+------------------------+
| INFO                   |
+------------------------+
| storage engine: InnoDB |
+------------------------+
+---------------------+
| INFO                |
+---------------------+
| LOADING departments |
+---------------------+
+-------------------+
| INFO              |
+-------------------+
| LOADING employees |
+-------------------+
+------------------+
| INFO             |
+------------------+
| LOADING dept_emp |
+------------------+
+----------------------+
| INFO                 |
+----------------------+
| LOADING dept_manager |
+----------------------+
+----------------+
| INFO           |
+----------------+
| LOADING titles |
+----------------+
+------------------+
| INFO             |
+------------------+
| LOADING salaries |
+------------------+</pre><p>الآن، يمكنك الولوج إلى MySQL وتشغيل بعض الاستعلامات البدائية للتحقق من أنّ البيانات قد تمّ استيرادها بنجاح:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">sudo mysql -h localhost -u sysadmin -p</pre><p>قم بإدخال كلمة المرور الخاصّة بالمستخدم sysadmin.</p><p>تحقق من قائمة قواعد البيانات لرؤية قاعدة البيانات employees الجديدة:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">show databases;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)</pre><p>استخدم قاعدة البيانات "employees" عبر الأمر:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">use employees;</pre><p>وللتحقق من الجداول الموجودة:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">show tables;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+---------------------+
| Tables_in_employees |
+---------------------+
| departments         |
| dept_emp            |
| dept_manager        |
| employees           |
| salaries            |
| titles              |
+---------------------+
6 rows in set (0.01 sec)</pre><p>إذا كنت تريد ذلك، فيمكنك التحقق من تفاصيل كلّ جدول من هذه الجداول. سنتحقق الآن من تفاصيل جدول <strong>titles</strong> فقط:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">describe titles;</pre><p>الخرج:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| emp_no    | int(11)     | NO   | PRI | NULL    |       |
| title     | varchar(50) | NO   | PRI | NULL    |       |
| from_date | date        | NO   | PRI | NULL    |       |
| to_date   | date        | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)</pre><p>وللتحقق من رقم المُدخَلات:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">mysql&gt; select count(*) from titles;</pre><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+----------+
| count(*) |
+----------+
|   443308 |
+----------+
1 row in set (0.14 sec)</pre><p>يمكنك التحقق من أيّ بيانات أخرى تريدها. بعد أن تنتهي، ارجع إلى طرفيّة نظام التشغيل الرئيسية عبر كتابة:</p><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">quit;</pre><p>انتهى درسنا حول تثبيت <strong>mysqlslap</strong> وإعداده، اقرأ <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-mysqlslap-%D9%84%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-mysql-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r109/">الدرس الآخر</a> لمتابعة طريقة استخدامه للقيام بالاختبارات المطلوبة.</p><p>ترجمة -وبتصرف- للمقال: <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-measure-mysql-query-performance-with-mysqlslap">How To Measure MySQL Query Performance with mysqlslap</a> لصاحبه: Sadequl Hussain.</p>
]]></description><guid isPermaLink="false">107</guid><pubDate>Sun, 20 Sep 2015 11:08:04 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x62A;&#x623;&#x645;&#x64A;&#x646; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; MySQL ,MariaDB &#x639;&#x644;&#x649; &#x62E;&#x648;&#x627;&#x62F;&#x64A;&#x645; &#x644;&#x64A;&#x646;&#x643;&#x633;</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-mysql-mariadb-%D8%B9%D9%84%D9%89-%D8%AE%D9%88%D8%A7%D8%AF%D9%8A%D9%85-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r54/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_05/securing-mysql-mariadb.png.527487124df26cf36276eb7432c0114c.png" /></p>

<p dir="rtl">هناك العديد من لغات قواعد البيانات SQL التي تعمل على أنظمة اللينكس واليونكس، ومن أشهر لغات قواعد البيانات العلائقية التي تعمل في بيئات الخوادم هما MySQL وMariaDB.</p><p dir="rtl"><a rel="external nofollow" name="_GoBack"></a> ومع ذلك، مثل أغلب البرامج، هذه الأدوات يمكن أن تكون الاحتياجات الأمنية إذا تم تكوينها بشكل غير صحيح، هذا الشرح التعليمي سوف يرشدك لبعض الخطوات الأساسية التي يمكن اتخاذها لتأمين قاعدة البيانات الخاصة بك سواء MariaDB أو MySQL، والتأكد من أنها ليست بابًا مفتوحًا إلى VPS الخاص بك.</p><p dir="rtl">من أجل البساطة والوضوح، سوف نستخدم MySQL على خادوم Ubuntu كمثال، ومع أن هذه التقنيات يمكن تطبيقها على توزيعات لينكس الأخرى، ويمكن استخدامها مع MariaDB كذلك.</p><h2 dir="rtl">الإعداد الأولي</h2><p dir="rtl">MySQL يمنحك فرصة لاتخاذ الخطوة الأولى نحو تحقيق الأمن أثناء التثبيت، وسوف نطلب منكم وضع كلمة سر root (الجذر).</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ sudo apt-get install mysql-server

Configuring mysql-server-5.5
While not mandatory, it is highly recommended that you set a password for the MySQL administrative "root" user.
If this field is left blank, the password will not be changed.

New password for the MySQL "root" user:</pre><p dir="rtl">يمكنك دائما تعيين كلمة سر root في وقت لاحق، ولكن ليس هناك سبب لتخطي هذه الخطوة، لذلك يجب تأمين حساب المسؤول الخاص بك من البداية.</p><p dir="rtl">بمجرد اكتمال التثبيت، يجب علينا تشغيل عدد قليل من النصوص المدرجة.</p><p dir="rtl">أولاً، سوف نستخدم "<span style="font-family:courier new,courier,monospace;">mysql_install_db</span>" وهو سكريبت نصي لإنشاء تصميم قواعد البيانات الخاصة بنا.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ sudo mysql_install_db</pre><p dir="rtl">بعد ذلك، قم بتشغيل السكريبت الذي يسمى "<span style="font-family:courier new,courier,monospace;">mysql_secure_installation</span>"، وسيرشدنا لبعض الإجراءات التي من شأنها إزالة بعض الافتراضات التي تشكل خطرا على استخدامها في بيئة الإنتاج.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ sudo mysql_secure_installation</pre><p dir="rtl">أولاً سوف يطلب منك إدخال كلمة السر الجذر وستقوم بإدخالها أثناء التثبيت، وبعد ذلك مباشرة ، سوف يطلب منك سلسلة من الأسئلة، بدءا من إذا كنت ترغب في تغيير كلمة سر الجذر.</p><p dir="rtl">هذه هي فرصة أخرى لتغيير كلمة المرور الخاصة بك إلى أي شيء آمن إذا لم تكن قد فعلت ذلك بالفعل.</p><p dir="rtl">يجب أن تكون الإجابة "Y" (نعم) لجميع الأسئلة المتبقية.</p><p dir="rtl">سيؤدي ذلك إلى إزالة قدرة أي شخص لتسجيل الدخول إلى MySQL  افتراضيا، وتعطيل تسجيل الدخول عن بعد على حساب المسؤول، وإزالة بعض قواعد بيانات الاختبار غير الآمنة، وتحديث قاعدة البيانات التي تعمل حاليا لاعتماد هذه التغيرات.</p><h2 dir="rtl">اعتبارات أمنية</h2><p dir="rtl">القاعدة البسيطة لزيادة حماية MySQL (ومعظم الأنظمة الأخرى) هو إعطاء صلاحيات النفاذ فقط عند الضرورة. أحيانا لكي تكون بياناتك آمنة يجب أن توزان بين الراحة والأمان.</p><p dir="rtl">في هذا الدليل، سوف نميل إلى الجانب الأمني، لذا فإن استخدامك الخاص لقاعدة البيانات يمكن أن يدفعك لإنتقاء أحد هذه الخيارات.</p><h3 dir="rtl">زيادة الأمن من خلال ملف My.cnf</h3><p dir="rtl">ملف الإعدادت الرئيسية في MySQL هو ملف يسمى "<span style="font-family:courier new,courier,monospace;">my.cn</span>f" الموجود في  "<span style="font-family:courier new,courier,monospace;">/etc/mysql/</span>" هذا الامتداد على أوبونتو وامتداد "<span style="font-family:courier new,courier,monospace;">/etc/</span>" على بعض الخواديم الأخرى.</p><p dir="rtl">سوف نقوم بتغيير بعض الإعدادات في هذا الملف لتأمين MySQL الخاصة بنا.</p><p dir="rtl">فتح الملف مع صلاحيات الجذر، تغيير مسار الامتداد حسب الحاجة إذا كنت تتبع هذا الشرح التعليمي على نظام مختلف:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ sudo nano /etc/mysql/my.cnf</pre><p dir="rtl">الإعداد الأولي التي يجب علينا أن نتحقق منه "وضع عنوان IP" ضمن قسم "[mysqld]". ويجب تعيين هذا الإعداد على جهاز الشبكة المحلي loopback ، وهو "127.0.0.1".</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint"> $ bind-address = 127.0.0.1</pre><p dir="rtl">هذا يجعل من أن MySQL لا تقبل الاتصالات من أي مكان باستثناء الجهاز المحلي.</p><p dir="rtl">إذا كنت بحاجة للوصول إلى قاعدة البيانات من جهاز آخر، خذ بالاعتبار الاتصال عن طريق SSH للقيام بالاستعلام وادارة قاعدة البيانات الخاصة بك محليا وإرسال النتائج من خلال قناة SSH.</p><p dir="rtl">الفجوة التالية التي سوف نعدلها، هي وظيفة تتيح لك الوصول إلى نظام الملفات من داخل MySQL، يمكن أن يكون لها تداعيات أمنية خطيرة ويجب ايقافها إلا إذا كنت في حاجة شديدة لها.</p><p dir="rtl">في نفس المقطع من الملف، سوف نقوم بإضافة التوجيه لتعطيل هذه القدرة على تحميل الملفات المحلية:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">local-infile=0</pre><p dir="rtl">إذا كان لدينا مساحة كافية ولا تعمل على قاعدة بيانات ضخمة، فإنه يمكن أن يكون مفيدا لتسجيل معلومات إضافية لمراقبة أي نشاط مثير للشبهة.</p><p dir="rtl">تسجيل معلومات أكثر من اللازم يضعف الأداء، لذلك قم بوزن أي شيء تحتاجه بعناية.</p><p dir="rtl">يمكنك وضع تسجيل الأحداث المتغيرة داخل القسم نفسه "[mysqld]" التي قمنا بالإضافة فيها:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">log=/var/log/mysql-logfile</pre><p dir="rtl">تأكد من أن سجل MySQL يعمل، سجل الأخطاء، وسجل MySQL ليس سهل القراءة:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ sudo ls -l /var/log/mysql*

-rw-r----- 1 mysql adm 0 Jul 23 18:06 /var/log/mysql.err
-rw-r----- 1 mysql adm 0 Jul 23 18:06 /var/log/mysql.log
/var/log/mysql:
total 28
-rw-rw---- 1 mysql adm 20694 Jul 23 19:17 error.log</pre><h2 dir="rtl">تأمين MySQL من الداخل</h2><p dir="rtl">هناك عدد من الخطوات التي يمكنك اتخاذها أثناء استخدام MySQL لتحسين الوضع الأمني.</p><p dir="rtl">سوف نقوم بإدخال الأوامر في هذا القسم في بداخل واجهة MySQL ، لذلك نحن بحاجة إلى تسجيل الدخول.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">$ mysql -u root -p</pre><p dir="rtl">سيطلب منك إدخال كلمة سر الجذر التي قمت بإعدادها في وقت سابق.</p><h3 dir="rtl">تأمين كلمات السر والمستخدمين المرتبطين</h3><p dir="rtl">أولاً، تأكد من وجود مستخدمين بدون كلمة مرور أو المضيف المرتبط في MySQL:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">SELECT User,Host,Password FROM mysql.user;
</pre><pre data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint" style="white-space: pre; word-wrap: normal; padding: 13px 17px; line-height: 22.3999996185303px; margin-top: 28px; margin-bottom: 28px; font-family: monospace, serif; box-sizing: border-box; border-radius: 3px; color: rgb(0, 0, 0); overflow: auto !important; background-color: rgb(246, 246, 246);">+------------------+-----------+-------------------------------------------+
| user             | host      | password                                  |
+------------------+-----------+-------------------------------------------+
| root             | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| demo-user        | %         |                                           |
| root             | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| root             | ::1       | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 |
+------------------+-----------+-------------------------------------------+
5 rows in set (0.00 sec)</pre><p dir="rtl">كما ترون في مثالنا هذا "المستخدم التجريبي " ليس لديه كلمة مرور، وهو ساري المفعول بغض النظر عن ما هو عليه في المضيف، ويعتبر هذا آمن جدا.</p><p dir="rtl">يمكننا وضع كلمة سر للمستخدم مع هذا الأمر Change "كلمة المرور الجديدة" أدخل كلمة المرور التي ترغب بها.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">UPDATE mysql.user SET Password=PASSWORD('newPassWord') WHERE User=""demo-user";</pre><p dir="rtl">إذاً علينا التحقق من جدول المستخدم مرة أخرى، وسوف نرى أن المستخدم التجريبي لديه الآن كلمة سر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">SELECT User,Host,Password FROM mysql.user;</pre><pre style="margin-top: 28px; margin-bottom: 28px; font-family: monospace, serif; white-space: pre; word-wrap: normal; box-sizing: border-box; border-radius: 3px; padding: 13px 17px; color: rgb(0, 0, 0); overflow: auto !important; background-color: rgb(246, 246, 246);" data-pbcklang="" data-pbcktabsize="" class="ipsCode prettyprint">+------------------+-----------+-------------------------------------------+
| user             | host      | password                                  |
+------------------+-----------+-------------------------------------------+
| root             | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| demo-user        | %         | *D8DECEC305209EEFEC43008E1D420E1AA06B19E0 |
| root             | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| root             | ::1       | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 |
| debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 |
+------------------+-----------+-------------------------------------------+
5 rows in set (0.00 sec)</pre><p>إذا ما نظرت هذا الحقل"host"، سترى أن لا يزال لدينا "٪"، هي عبارة عن بطاقة بديلة وهذا يعني أي مضيف. وليس هذا ما نريده، دعونا نغيرها إلى " localhost".</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">UPDATE mysql.user SET Host='localhost' WHERE User="demo-user";</pre><p dir="rtl">إذا تحققنا مرة أخرى، يمكننا أن نرى أن جدول المستخدم لديه الآن الحقول المناسبة.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">SELECT User,Host,Password FROM mysql.user;</pre><p dir="rtl">إذا كان لدينا جدول يحتوي على مستخدمين فارغين (لا يجب في هذه المرحلة أن يكونوا "mysql_secure_installation", سنغطي هذه الناحية بأي حال من الأحوال لاحقا)، وينبغي علينا إزالتهم.</p><p dir="rtl">للقيام بذلك، يمكننا استخدام الأمور التالي لحذف المستخدمين الفارغين من جدول الوصول:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">DELETE FROM mysql.user WHERE User="";</pre><p dir="rtl">بعد أن يتم تعديل جدول المستخدم، نحن بحاجة إلى إدخال الأمر التالي لتنفيذ صلاحيات جديدة:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">FLUSH PRIVILEGES;</pre><p dir="rtl">إنشاء مستخدمين محددين لتطبيقات معينة</p><p dir="rtl">طريقة تشغيل العمليات داخل لينكس تكون معزولة لكل مستخدم على حدى، وتستخدم قاعدة بيانات MySQL نفس طريقة العزل.</p><p dir="rtl">كل تطبيق يستخدم MySQL يجب أن يمتلك مستخدم خاص به ولديه صلاحيات محدودة ويستطيع الوصول إلى قواعد البيانات التي يحتاج لتشغيلها فقط.</p><p dir="rtl">عندما نقوم بإعداد تطبيق جديد لاستخدام MySQL، يجب أن ننشئ قواعد البيانات التي يحتاجها هذا التطبيق:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">create database testDB;
Query OK, 1 row affected (0.00 sec)</pre><p dir="rtl">بعد ذلك، يجب علينا إنشاء مستخدم لإدارة قاعدة البيانات، ومنحه الصلاحيات التي يحتاجها فقط، وهذه تختلف من تطبيق لآخر، وبعض الاستخدامات تحتاج لصلاحيات مفتوحة أكثر من غيرها.</p><p dir="rtl">لإنشاء مستخدم جديد، استخدم الأمر التالي:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">CREATE USER 'demo-user'@'localhost' IDENTIFIED BY 'password';</pre><p dir="rtl">يمكننا منح المستخدم الجديد صلاحيات على الجدول الجديد بالأمر التالي. انظر الشرح التعليمي حول كيفية إنشاء مستخدم ومنح صلاحيات جديدة في MySQL لمعرفة المزيد عن الصلاحيات المحددة:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">GRANT SELECT,UPDATE,DELETE ON testDB.* TO 'demo-user'@'localhost';</pre><p dir="rtl">وكمثال على ذلك، إذا كنا بحاجة إلى وقت لاحق لإلغاء الصلاحيات من الحساب، يمكن أن نستخدم الأمر التالي:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">REVOKE UPDATE ON testDB.* FROM 'demo-user'@'localhost';</pre><p dir="rtl">إذا كنا بحاجة إلى كافة الصلاحيات على قاعدة بيانات معينة، يمكننا تحديد ذلك بما يلي:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">GRANT ALL ON testDB.* TO 'demo-user'@'localhost';</pre><p dir="rtl">لإظهار الصلاحيات الحالية للمستخدم، علينا أولا أن ننفذ الصلاحيات حددناه باستخدام أمر "flush privileges"، ثم بعد ذلك يمكننا الاستعلام عن الصلاحيات التي بحوزة المستخدم.</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">FLUSH PRIVILEGES;

show grants for 'demo-user'@'localhost';

Grants for demo-user@localhost
GRANT USAGE ON *.* TO 'demo-user'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' 
GRANT SELECT, UPDATE, DELETE ON `testDB`.* TO 'demo-user'@'localhost'
2 rows in set (0.00 sec)</pre><p dir="rtl">دائما امسح الصلاحيات عندما تنتهي من إجراء التغييرات.</p><h2 dir="rtl">تغيير المستخدم الجذر</h2><p dir="rtl">خطوة إضافية واحدة وهي، ربما تريد تغيير اسم الجذر(root login name )، فإذا كان الهاكر يحاول أن يقوم بتسجيل الدخول باسم الروت في MySQL ، فسوف يحتاج إلى تنفيذ خطوة إضافية هي العثور على اسم المستخدم.</p><p dir="rtl">تستطيع تغيير اسم المستخدم روت باستخدام الأمر التالي:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">rename user 'root'@'localhost' to 'newAdminUser'@'localhost';</pre><p dir="rtl">يمكننا أن نرى التغيير باستخدام نفس الاستعلام الذي استخدمناه لقاعدة بيانات المستخدم:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">select user,host,password from mysql.user;</pre><p dir="rtl">مرة أخرى، يجب علينا مسح الصلاحيات التغيرات التي حدثت:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">FLUSH PRIVILEGES;</pre><p dir="rtl">تذكر أنه سوف تسجل دخول إلى MySQL مثل اسم مستخدم تم إنشاؤه حديثا عندما ترغب في أداء المهام الإدارية:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">mysql -u newAdminUser -p</pre><p dir="rtl">بأي حال من الأحوال هذه قائمة شاملة من الاجراءات الأمنية لقواعد البيانات MySQL, MariaDB، وقد أصبح لديك مقدمة جيدة لأنواع القرارات التي ستتخذها عندما تريد تأمين قواعد البيانات الخاصة بك.</p><p dir="rtl">يمكن الاطلاع على مزيد من المعلومات حول الإعدادت والأمن في قواعد بيانات المواقع MySQL وMariaDB إضافة الى صفحات المختصين، ويمكن للتطبيقات التي اخترت استخدامها أن تقدم المشورة الأمنية.</p><p dir="rtl">ترجمة -وبتصرّف- للمقال: <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-secure-mysql-and-mariadb-databases-in-a-linux-vps">How To Secure MySQL and MariaDB Databases in a Linux VPS</a>.</p>
]]></description><guid isPermaLink="false">54</guid><pubDate>Wed, 27 May 2015 21:18:59 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x64F;&#x62B;&#x628;&#x651;&#x650;&#x62A; &#x648;&#x62A;&#x624;&#x645;&#x651;&#x650;&#x646; phpMyAdmin &#x639;&#x644;&#x649; Ubuntu 14.04</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81-%D8%AA%D9%8F%D8%AB%D8%A8%D9%91%D9%90%D8%AA-%D9%88%D8%AA%D8%A4%D9%85%D9%91%D9%90%D9%86-phpmyadmin-%D8%B9%D9%84%D9%89-ubuntu-1404-r35/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_04/phpmyadmin_480x300.jpg.fa01bb473c0c08998c1d57ac56dc7a78.jpg" /></p>

<h2 id="كيف-تثبت-وتؤمن-phpmyadmin-على-ubuntu-1404">مقدِّمة</h2><p>يحتاج الكثيرُ من المستخدمين إلى نظام إدارة قواعد بيانات Database Managment System, DBMS مثل MySQL، إلّا أنّهم قد لا يكونون مرتاحين للتّفاعل مع النّظام من خلال سطر أوامر MySQL فقط.<br>أُنشئ phpMyAdmin بحيث يتفاعل هؤلاء المستخدمون مع MySQL عن طريق واجهة ويب. سنعرض في هذا الدّرس لكيفيّة تثبيت وتأمين phpMyAdmin بحيث يُمكن استخدامُه بأمان من أجل إدارة قواعد بيانات MySQL على أوبنتو 14.04.</p><h2 id="المتطلبات">المُتطلَّبات</h2><p>نفترض، قبل البدء مع خطوات هذا الدّرس، أنّك تتوفّر على المتطلَّبات التّاليّة:</p><ul><li>حساب بصلاحيّات sudo، غير حساب المستخدِم الجذر Root user كما هوّ موضَّح في الخطوات 1-4 من درس <a href="http://academy.hsoub.com/devops/servers/%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A7%D9%84%D8%A7%D8%A8%D8%AA%D8%AF%D8%A7%D8%A6%D9%8A-%D9%84%D8%AE%D8%A7%D8%AF%D9%88%D9%85-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1404-r4/">الإعداد الابتدائي لخادوم أوبنتو</a>.</li><li>حزم MySQL، Apache، Linux وPHP (المعروفة بLAMP) مُثَبَّتة ومُعدَّة. يُمكن مراجعة درس <a href="http://academy.hsoub.com/devops/servers/%D9%83%D9%8A%D9%81-%D8%AA%D9%8F%D8%AB%D8%A8%D9%91%D9%90%D8%AA-%D8%AD%D9%90%D8%B2%D9%85-mysql%D8%8C-apache%D8%8C-linux-lamp-%D9%88php-%D8%B9%D9%84%D9%89-ubuntu-1404-r27/">كيف تُثبِّت حِزم MySQL، Apache، Linux) LAMP وPHP) على Ubuntu 14.04</a> لهذا الغرض.</li></ul><p>بإكمال الخطوات أعلاه تكون مستعدا لمتابعة هذا الدّرس.</p><h2 id="الخطوة-الأولى-ثبت-phpmyadmin">الخطوة الأولى: ثبِّت phpMyAdmin</h2><p>نبدأ بتنزيل وتثبيت phpMyAdmin من مستودعات أوبنتو عن طريق مدير الحزم apt:</p><pre data-pbcklang="php" data-pbcktabsize="" class="php ipsCode prettyprint">sudo apt-get update
sudo apt-get install phpmyadmin</pre><p>ستُطرَح عليك بعضُ الأسئلة لإعداد التّثبيت بما يُناسِب:</p><ul><li>عند اختيار خادوم الويب اختَر apache2. ملحوظة: إن لم تضغط زر المسافة SPACE على لوحة المفاتيح لاختيّار Apache فلن ينقُل برنامج التّثبيت الملفّات الضّرورية أثناء التّثبيت. اختر زر SPACE على لوحة المفاتيح ثمّ زر TAB ثمّ زرّ ENTER لاختيّار Apache.</li><li>اختَر نعم (YES) عند السّؤال إذا ما كنت تُريد استخدام <span style="font-family:courier new,courier,monospace;">dbconfig-common</span> لضبط قاعدة البيانات.</li><li>أدخِل كلمة سرّ مدير قاعدة البيانات عندما يُطلَب منك ذلك.</li><li>سيُطلب منك أيضًا اختيّار وتأكيد كلمة سرّ تطبيق phpMyAdmin نفسِه.</li></ul><p>تُضيف عمليّة التّثبيت ملفّ إعداد phpMyAdmin إلى المُجلَّد <span style="font-family:courier new,courier,monospace;">/etc/apache2/conf-enabled/</span> حيثُ يقرؤه خادوم ويب Apache أوتوماتيكيًّا.</p><p>كلّ ما علينا فعله يدويًّا هو تفعيل امتداد Extension يحمل الاسم <span style="font-family:courier new,courier,monospace;">php5-mcrypt</span> (واجهة للتّعامل مع مكتبة mcrypt الّتي تضم خوارزميّات للتّعميّة Encryption) عن طريق تنفيذ الأمر:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo php5enmod mcrypt</pre><p>ستحتاج لإعادة تشغيل Apache لكي يتعرَّف على الامتداد الجديد:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo service apache2 restart</pre><p>يُمكنك بعدها الولوج إلى واجهة الويب عن طريق إدخال عنوان IP العمومي لخادومك أو اسم النّطاق في شريط العناوين بمتصفّح الويب متبوعًا ب <span style="font-family:courier new,courier,monospace;">phpmyadmin/</span> كما يلي:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">http://domain_name_or_IP/phpmyadmin</pre><p><strong>ملحوظة</strong>: إن كنت تجرِّب التّثبيت على جهازك المحلّي فيُمكنك الوصول إلى واجهة phpmyadmin عن طريق إدخال العنوان التّالي في شريط العناوين بمتصفّح الويب<br><code><a rel="external nofollow" href="http://127.0.0.1/phpmyadmin">http://127.0.0.1/phpmyadmin</a></code></p><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_04/01_%D8%AA%D8%B3%D8%AC%D9%8A%D9%84_%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84_phpmyadmin.png.295c321e268064c860f85888061d3da7.png"><img data-fileid="1499" class="ipsImage ipsImage_thumbnailed" src="https://academy.hsoub.com/uploads/monthly_2015_04/01_%D8%AA%D8%B3%D8%AC%D9%8A%D9%84_%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84_phpmyadmin.thumb.png.7d8d65acd349126250f0c3dcadfc4227.png"></a></p><p>يُمكنك الآن الولوج إلى واجهة الويب عن طريق حساب المستخدم الجذر الّذي أعددته أثناء تثبيت MySQL.<br>ستظهر عند تسجيل الدّخول واجهة المستخدِم والّتي تُشبه ما يلي:</p><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_04/02_%D9%88%D8%A7%D8%AC%D9%87%D8%A9_%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85_phpmyadmin.png.045caae7c8e699d90068e78539f7ab65.png"><img data-fileid="1500" class="ipsImage ipsImage_thumbnailed" src="https://academy.hsoub.com/uploads/monthly_2015_04/02_%D9%88%D8%A7%D8%AC%D9%87%D8%A9_%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85_phpmyadmin.thumb.png.1a44b9d74590c7249abe1b2ecb9d6e9e.png"></a></p><h2 id="الخطوة-الثانية-تأمين-phpmyadmin">الخطوة الثّانيّة: تأمين phpMyAdmin</h2><p>أكملنا الآن تثبيت phpMyAdmin وسجلنا الدّخول إلى واجهة المستخدِم، لكن بقي أمر آخر. يستهدِف الكثيرُ من المخترقين phpMyAdmin نظرًا لشهرته، في محاولةٍ منهم لنيل طريقة للاتّصال بقاعدة البيانات. نحتاج لتأمين التّطبيق للمساعدة في الحماية من الاستخدام غير المُصرَّح به.<br>إحدى أسهل الطّرق لتأمين phpMyAdmin هيّ وضعُ بوّابة gateway أمام كامل التّطبيق. نستخدم الاستيثاق Authentication والتّصريح Authorization عن طريق ملفّات <span style="font-family:courier new,courier,monospace;">htaccess.</span> المُضمَّنة في Apache.</p><h3 id="1-إعداد-apache-للسماح-بالتجاوز-override-في-ملفات-htaccess">1- إعداد Apache للسّماح بالتّجاوز Override في ملفّات <span style="font-family:courier new,courier,monospace;">htaccess.</span></h3><p>يجب علينا أوّلًا تفعيل استخدام التّجاوز في ملفّات <span style="font-family:courier new,courier,monospace;">htaccess.</span> وذلك بالتّعديل على ملفّ إعداد خاصّ بـ phpMyAdmin في خادوم ويب Apache. يعني تفعيل التّجاوز أنه يُمكن تعريف ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> لمجلَّد مُحدَّد بحيثُ تُنفَّذ تعليمات ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> الموجود في المجلَّد بدلًا من ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> العامّ لخادوم الويب.<br>نُعدِّل على ملف إعداد phpMyAdmin الموجود في مجلّد Apache للإعدادات:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo nano /etc/apache2/conf-available/phpmyadmin.conf</pre><p>نُضيف تعليمة <span style="font-family:courier new,courier,monospace;">AllowOverride All</span> داخل مقطع</p><h3 id="2-أنشئ-ملف-htaccess">2- أنشئ ملفّ <span style="font-family:courier new,courier,monospace;">htaccess.</span></h3><p>نبدأ الآن بعد أن فعَّلنا استخدامَ ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> خاصّ بتطبيقنا، نبدأ بإنشاء هذا الملفّ من أجل إضافة إجراءات أمان إلى phpMyAdmin.<br>يجب أن يُنشَأ ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess. </span>داخل مجلَّد التّطبيق. الأمر التّالي يُنشئ ثمّ يفتح الملفّ (يتطلّب صلاحيّات المستخدم الجذر):</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo nano /usr/share/phpmyadmin/.htaccess</pre><p>نُضيف التّعليمات التّالية داخل هذا الملفّ:</p><pre data-pbcklang="php" data-pbcktabsize="" class="php ipsCode prettyprint">AuthType Basic
AuthName "Restricted Files
AuthUserFile /etc/phpmyadmin/.htpasswd
Require valid-user</pre><p>فلنلقِ نظرة على دلالة كل واحدة من هذه التّعليمات:</p><ul><li><span style="font-family:courier new,courier,monospace;">AuthType Basic</span>: تُحدِّد <span style="font-family:courier new,courier,monospace;">AuthType</span> نوع الاستيثاق الّذي سنطلُب وضعه. <span style="font-family:courier new,courier,monospace;">Basic</span> تعني أنّنا سنستخدم الاستيثاق بكلمة سرّ عن طريق ملفّ يُسمّى ملفّ كلمة السّر.</li><li><span style="font-family:courier new,courier,monospace;">AuthName</span>: هذه التّعليمة تُحدِّد الرّسالة الّتي تظهر في مربّع طلب كلمة السّر عند محاولة الوصول إلى التّطبيق. يجب أن تكون هذه الرّسالة عامّة بحيثُ لا تُعطي أيّ معلومات عن ما تحميه كلمة السّر.</li><li><span style="font-family:courier new,courier,monospace;">AuthUserFile</span>: تُحدّد مكان حفظ ملفّ كلمة السّر المُستخدَمة للاستيثاق. يجب أن يُحفّظ الملفّ خارج المجلّدات الّتي يُقدّم منها خادوم الويب ملفّاتٍ للزوّار. سنُنشئ هذا الملفّ بعد قليل.</li><li><span style="font-family:courier new,courier,monospace;">Require valid-user</span>: تُحدّد نوعيةَ المستخدمين المسموح لهم بالوصول إلى المجلَّد المحمي. هذه التّعلمية أساسيّة من أجل منع وصول المستخدمين غير المُصرَّح لهم بالدّخول إلى التّطبيق.</li></ul><p>احفَظ الملفّ (Ctrl + O) بعد التّعديل ثم أغلقه (Ctrl+ X).</p><h3 id="3-أنشئ-ملف-htpasswd-للاستيثاق">3- أنشئ ملفّ <span style="font-family:courier new,courier,monospace;">htpasswd.</span> للاستيثاق</h3><p>عيّنّا أثناء إنشاء ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> في الفقرة السّابقة طريقة استيثاق تعتمد على ملفّ كلمة سرّ، عبرَ تعليمة <span style="font-family:courier new,courier,monospace;">AuthUserFile</span>. نُنشئ الآن هذا الملفّ.<br>سنحتاج إلى حزمة إضافيّة تعمل مع خادوم الويب لهذا الغرض، نُثبِّتها عبر الأمر:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo apt-get install apache2-utils</pre><p>سنحصُل بعد اكتمال التّثبيت على أداة كلمات السّر في Apache.<br>الأمر التّالي يُنشئ ملفّ كلمة السّر في المسار الّذي عيّنّاه في ملفّ <span style="font-family: 'courier new', courier, monospace; line-height: 17.9200000762939px;">htaccess.</span> ويُحدّد اسمَ مُستخدِم مرفقًا بهذا الملفّ:</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">sudo htpasswd -c /etc/phpmyadmin/.htpasswd username</pre><p>سيُطلَب منك إعطاء ثمّ تأكيد كلمة سرّ المستخدِم الّذي تُنشئه (username في الأمر أعلاه).سيُنشأ بعدها ملفّ يحوي اسم المُستخدم وتلبيد Hash كلمة السّرّ (تُحفَظ كلمة السّرّ بعد تعميّتها Encryption).<br>تُمكن إضافة مُستخدم جديد عن طريق الأمر أعلاه ولكن بدون خيار c- كما يلي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">sudo htpasswd /etc/phpmyadmin/.htpasswd additionaluser</pre><p>عند محاولة الولوج الآن إلى phpMyAdmin فسيُطلَب منك إدخال اسم الحساب الجديد وكلمة السّر المُصاحبة له الّذيْن ضبطتهما للتّو.</p><pre data-pbcklang="php" data-pbcktabsize="4" class="php ipsCode prettyprint">http://domain_name_or_IP/phpmyadmin</pre><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_04/03_%D8%AD%D9%85%D8%A7%D9%8A%D8%A9_phpMyAdmin.png.feda987ea942c3755a7eb6482857a77d.png"><img data-fileid="1501" class="ipsImage ipsImage_thumbnailed" src="https://academy.hsoub.com/uploads/monthly_2015_04/03_%D8%AD%D9%85%D8%A7%D9%8A%D8%A9_phpMyAdmin.thumb.png.fe6a52a2932379e50228ade8b5c98521.png"></a></p><p>بعدَ تخطي استيثاق Apache ستُنقَل إلى واجهة phpMyAdmin حيثُ يجب عليك إدخال اعتمادات واجهة الويب الخاصّة بـ phpMyAdmin.<br>يُضيف هذا الإجراء طبقةً جديدة من الحماية تُساعِد في التّغلّب على أيّ نقاط ضعف قد تكون موجودة في phpMyAdmin.</p><h2 id="خاتمة">خاتمة</h2><p>يجب بعد إكمال هذه الخطوات أن تحصُل على تطبيق phpMyAdmin مضبوط وجاهز للعمل على خادوم أوبنتو 14.04. يُمكن مع phpMyAdmin إنشاء قواعد بيانات، مستخدمين، جداول… إلخ إضافةً إلى الإجراءات الاعتيّاديّة مثل حذف أو تعديل البُنيَات Structures والبيانات بكل سهولة.</p><p>ترجمة - وبتصرّف - لمقال <a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-14-04">How To Install and Secure phpMyAdmin on Ubuntu 14.04</a>.</p>
]]></description><guid isPermaLink="false">35</guid><pubDate>Mon, 27 Apr 2015 09:31:00 +0000</pubDate></item><item><title>&#x645;&#x62F;&#x62E;&#x644; &#x625;&#x644;&#x649; &#x628;&#x631;&#x646;&#x627;&#x645;&#x62C; &#x625;&#x62F;&#x627;&#x631;&#x629; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; MySQL</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D8%AC-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-mysql-r28/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_04/MySQL_480x300.png.8dac228ae8c51c8187d0aa5efe08e587.png" /></p>

<h2 dir="rtl">
	ماهو MySQL؟
</h2>

<p dir="rtl">
	MySQL هو برنامج لإدارة قواعد البيانات Database Management System, DBMS يُساعد مستخدميه في تخزين، تنظيم والعثور على البيانات. ينتشر استخدامُ MySQL في مواقع الويب نظرًا لميزاته والمرونة الّتي يُوفّرها. نهدِف في هذا الدّرس تقديم أساسيّات استخدام MySQL بطريقة مُيَسَّرة وسهلة.
</p>

<p dir="rtl">
	كيف يُثَبَّت برنامج MySQL على توزيعتيْ Ubuntu وCentOS؟
</p>

<p dir="rtl">
	يُمكِن تنزيلُ وتثبيتُ MySQL سريعًا عبر برنامج إدارة الحزم الخاصّ بالتّوزيعة.
</p>

<p dir="rtl">
	1- على Ubuntu:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">sudo apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> install mysql</span><span class="pun">-</span><span class="pln">server</span></pre>

<p dir="rtl">
	2- على CentOS:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">sudo yum install mysql</span><span class="pun">-</span><span class="pln">server
</span><span class="pun">/</span><span class="pln">etc</span><span class="pun">/</span><span class="pln">init</span><span class="pun">.</span><span class="pln">d</span><span class="pun">/</span><span class="pln">mysqld start</span></pre>

<p dir="rtl">
	<strong>ملحوظة</strong>: أثناء تثبيت MySQL سيُطلب منك إدخال ثمّ تأكيد كلمة سرّ للمستخدِم الجذر Root user في MySQL (انتبه إلى أنّ المُستخدم الّذي نتحدّث عنه هنا ليس هو المستخدِم الجذر في الخادوم، بل مستخدم جذر آخر خاصّ بـMySQL).
</p>

<h2 dir="rtl">
	كيف يكون الاتصال بالصدفة Shell الخاصة بـ MySQL؟
</h2>

<p dir="rtl">
	يُمكن - بعد التّثبيت - الاتّصال بMySQL عن طريق صَدَفة ولوج خاصّة عبر تنفيذ الأمر التّالي:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql </span><span class="pun">-</span><span class="pln">u root </span><span class="pun">-</span><span class="pln">p</span></pre>

<p dir="rtl">
	سيُطلب منك إدخال كلمة سر المُستخدم الجذر في MySQL. يُمكنك بعدها البدء في بناء قواعد بيانات في MySQL.
</p>

<p dir="rtl">
	ينبغي الانتباه للنّقطتيْن التّاليّتيْن:
</p>

<ul dir="rtl">
<li>
		تنتهي كلّ أوامر MySQL بنقطة-فاصلة إنجليزيّة (<span style="font-family:courier new,courier,monospace;">;</span>). إن لم تختِم جملةً من أوامر MySQL بنقطة-فاصلة فلن تُتنفّذ هذه الأوامر.
	</li>
	<li>
		تُكتَب أوامرُ MySQL بأحرف كبيرة Uppercase وأسماءُ كلّ من قواعد البيانات، المُستخدمين، الجداول Tables والنّصوص بأحرف صغيرة. هذه النّقطة ليست إجبارية؛ سطرُ أوامر MySQL لا يتأثّر بحالة الأحرف Case insensitive ولكن التّفريق المذكور يجعلُ من التّمييز بين الأوامر وغيرها أكثر سهولة.
	</li>
</ul>
<h2 dir="rtl">
	إنشاء وحذف قاعدة بيانات MySQL
</h2>

<p dir="rtl">
	يُنظِّم MySQL معلوماتِه في قواعد بيانات تتضمّن كلّ واحدة منها جداول ببيانات مُحدَّدة.
</p>

<p dir="rtl">
	يُمكنك عرض قواعد البيانات الموجودة في MySQL عبر الأمر التّالي (يُنفَّذ في صَدَفة MySQL وليس سطر أوامر النّظام):
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">SHOW DATABASES</span><span class="pun">;</span></pre>

<p dir="rtl">
	يجب أن يبدو محتوى الشّاشة لديك مشابِهًا لما يلي:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW DATABASES</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="typ">Database</span><span class="pln">           </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> information_schema </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> mysql              </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> performance_schema </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> test               </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span style="line-height: 1.6;"><span class="lit">4</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.01</span><span class="pln"> sec</span><span class="pun">)</span></span>
</pre>

<p>
	من اليسير إنشاءُ قاعدة بيانات عن طريق الأمر التّالي(حيثُ database name يُمثّل اسمَ قاعدة البيانات):
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">CREATE DATABASE database name</span><span class="pun">;</span></pre>

<p>
	<span style="line-height: 1.6;">لإنشاء قاعدة بيانات باسم <span style="font-family:courier new,courier,monospace;">events</span> مثلًا نُنفّذ الأمر:</span>
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">CREATE DATABASE events</span><span class="pun">;</span></pre>

<p dir="rtl">
	نُعيد عرضَ قواعد البيانات الموجودة في MySQL:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW DATABASES</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="typ">Database</span><span class="pln">           </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> information_schema </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> events             </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> mysql              </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> performance_schema </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> test               </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+--------------------+</span><span class="pln">
</span><span class="lit">5</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.00</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p dir="rtl">
	نُلاحِظ وجود قاعدة البيانات الّتي أنشأناها للتّو.
</p>

<p dir="rtl">
	تُستخدم غالبًا عبارة <span style="font-family:courier new,courier,monospace;">DROP</span> لحذف الكائنات Objects في MySQL. إذا أردتَ حذفَ قاعدة بيانات فالأمر المناسب هو <span style="font-family:courier new,courier,monospace;">DROP DATABASE</span>، كما يلي (حيثُ database name اسم قاعدة البيانات المُراد حذفُها):
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">DROP DATABASE database name</span><span class="pun">;</span></pre>

<h2 dir="rtl">
	استخدام قاعدة بـيانات في MySQL
</h2>

<p dir="rtl">
	نبدأ بملْء قاعدة البيانات بعدَ إنشائها عبر إضافة معلومات إليها.
</p>

<p dir="rtl">
	أولّ خطوة هيّ إنشاء جدول جديد داخل قاعدة البيانات. يتوجّب أوّلًا فتح قاعدة البيانات المُراد استخدامُها عبر الأمر التّالي:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">USE events</span><span class="pun">;</span></pre>

<p dir="rtl">
	يُمكن -كما فعلنا مع قواعد البيانات- عرضُ الجداول الموجودة في قاعدة البيانات الّتي نستخدمُها الآن:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">SHOW tables</span><span class="pun">;</span></pre>

<p dir="rtl">
	تظهر، عندَ تنفيذ الأمر السّابق رسالة <span style="font-family:courier new,courier,monospace;">Empty set</span> (مجموعة خاليّة) دلالةً على عدم وجود جداول في قاعدة البيانات. هذه النّتيجة طبيعيّة جدًّا نظرًا لجِدّة قاعدة البيانات.
</p>

<h2 dir="rtl">
	إنشاء جدول في قاعدة بيانات MySQL
</h2>

<p dir="rtl">
	نفترِض أنّنا نُخطّط لحَدَث يجمع بعضَ الأصدقاء. سنستخدم MySQL لتتبّع تفاصيل هذا الحدث.
</p>

<p dir="rtl">
	نُنشئ جدولًا في MySQL لهذا الغرض (تذكّر أننا نستخدم قاعدة بيانات باسم <span style="font-family:courier new,courier,monospace;">events</span> أي أنّ الجدول الّذي سنُنشئه سيكون ضمن قاعدة البيانات هذه):
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">CREATE TABLE potluck </span><span class="pun">(</span><span class="pln">id INT NOT NULL PRIMARY KEY AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
name VARCHAR</span><span class="pun">(</span><span class="lit">20</span><span class="pun">),</span><span class="pln">
food VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
confirmed CHAR</span><span class="pun">(</span><span class="lit">1</span><span class="pun">),</span><span class="pln">
signup_date DATE</span><span class="pun">);</span></pre>

<p>
	<span style="line-height: 1.6;">نفّذنا عبر الأمر أعلاه الإجراءات التّالية:</span>
</p>

<ul dir="rtl">
<li>
		إنشاء جدول باسم <span style="font-family:courier new,courier,monospace;">potluck</span> ضمن قاعدة البيانات <span style="font-family:courier new,courier,monospace;">events</span>.
	</li>
	<li>
		إنشاء خمسة أعمِدة ضمن الجدول <span style="font-family:courier new,courier,monospace;">potluck</span>. هذه الأعمدة هيّ: <span style="font-family:courier new,courier,monospace;">id</span> (المُعرِِّف)، <span style="font-family:courier new,courier,monospace;">name</span> (الاسم)، <span style="font-family:courier new,courier,monospace;">food</span> (الطّعام)، <span style="font-family:courier new,courier,monospace;">confirmed</span> (حضور مؤكَّد) و <span style="font-family:courier new,courier,monospace;">signup date</span> (تاريخ التّسجيل).
	</li>
	<li>
		تطبيق الأمر <span style="font-family:courier new,courier,monospace;">INT NOT NULL PRIMARY KEY AUTO_INCREMENT</span> للعمود <span style="font-family:courier new,courier,monospace;">id</span> من أجل إعطاء عدد صحيح (<span style="font-family:courier new,courier,monospace;">INT</span> في الأمر) أتوماتيكيًّا لكل صف جديد.
	</li>
	<li>
		قصرُ العمود <span style="font-family:courier new,courier,monospace;">name</span> على عدد محارِف لا يتجاوز العشرين <span style="font-family:courier new,courier,monospace;">(20)VARCHAR</span>.
	</li>
	<li>
		نفس الشيء بالنّسبة للعمود <span style="font-family:courier new,courier,monospace;">food</span> الّذي يُمثِّل متعلّقات الطّعام الّتي سيجلبها كل واحد من الأصدقاء. اسم الطّعام مُكوّن من محارِف لا يتجاوز عددها الثّلاثين<span style="font-family:courier new,courier,monospace;"> (30)VARCHAR</span>.
	</li>
	<li>
		تسجيل تأكيد الحضور عبر العمود <span style="font-family:courier new,courier,monospace;">confirmed</span> المُكوّن من محرف واحد فقط <span style="font-family:courier new,courier,monospace;">(1)CHAR</span>. عند تأكيد الحضور نكتب <span style="font-family:courier new,courier,monospace;">Y</span> وإلّا <span style="font-family:courier new,courier,monospace;">N</span>.
	</li>
	<li>
		حفظ تاريخ التّسجيل عبر العمود <span style="font-family:courier new,courier,monospace;">signup_date</span>. يطلُب MySQL كتابة التّاريخ على الشّكل <span style="font-family:courier new,courier,monospace;">yyyy-mm-dd</span>، حيثُ <span style="font-family:courier new,courier,monospace;">yyyy</span> السّنة مكتوبة على 4 أرقام، و<span style="font-family:courier new,courier,monospace;">mm</span> الشهر في رقمين و<span style="font-family:courier new,courier,monospace;">dd</span> اليوم في رقميْن أيضًا. <span style="font-family:courier new,courier,monospace;">01-01-2015</span> تاريخ بصيغة صحيحة.
	</li>
</ul>
<p dir="rtl">
	<strong>ملحوظة</strong>: كلّ من <span style="font-family:courier new,courier,monospace;">CHAR</span> و <span style="font-family:courier new,courier,monospace;">VARCHAR</span> يُستخدَم للدّلالة على أن العمود يحوي محارف مع تحديد طول المحتوى، ولكن طول المحتوى من نوع <span style="font-family:courier new,courier,monospace;">CHAR</span> ثابت، أي أنّه يجب أن يكون مساويًّا للعدد بين قوسيْن؛ في حين أنّ طول المحتوى من نوع <span style="font-family:courier new,courier,monospace;">VARCHAR</span> متغيِّر والعدد المُذكور هو الطّول الأقصى المسموح به.
</p>

<p dir="rtl">
	نُعيد عرض الجداول الموجودة في قاعدة البيانات <span style="font-family:courier new,courier,monospace;">events</span>:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW TABLES</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="typ">Tables_in_events</span><span class="pln"> </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+------------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> potluck          </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+------------------+</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> row </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.01</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p>
	<span style="line-height: 1.6;">نُلاحِظ ظهور الجدول <span style="font-family:courier new,courier,monospace;">potluck</span>.</span>
</p>

<p dir="rtl">
	إن أردتَ عرض تنظيم الجدول <span style="font-family:courier new,courier,monospace;">potluck</span> فالأمر <span style="font-family:courier new,courier,monospace;">DESCRIBE</span> يؤدّي هذه الوظيفة:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">DESCRIBE potluck</span><span class="pun">;</span></pre>

<p dir="rtl">
	انتبِه إلى أنّ أسماء الجداول وقواعد البيانات في MySQL حسّاسة لحالة الأحرف، رغم أنّ سطر الأوامر ليس كذلك. جدول باسم <span style="font-family:courier new,courier,monospace;">potluck</span> ليس هو نفسُه جدول <span style="font-family:courier new,courier,monospace;">Potluck</span> أو <span style="font-family:courier new,courier,monospace;">POTLUCK</span>.
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln">DESCRIBE potluck</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+-------------+-------------+------+-----+---------+----------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="typ">Field</span><span class="pln">       </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Type</span><span class="pln">        </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Null</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Key</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Default</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Extra</span><span class="pln">          </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+-------------+-------------+------+-----+---------+----------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> id          </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">int</span><span class="pun">(</span><span class="lit">11</span><span class="pun">)</span><span class="pln">     </span><span class="pun">|</span><span class="pln"> NO  </span><span class="pun">|</span><span class="pln"> PRI  </span><span class="pun">|</span><span class="pln"> NULL    </span><span class="pun">|</span><span class="pln"> auto_increment </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> name        </span><span class="pun">|</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> YES </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> NULL    </span><span class="pun">|</span><span class="pln">                </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> food        </span><span class="pun">|</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> YES </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> NULL    </span><span class="pun">|</span><span class="pln">                </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> confirmed   </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">char</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln">     </span><span class="pun">|</span><span class="pln"> YES </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> NULL    </span><span class="pun">|</span><span class="pln">                </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> signup_date </span><span class="pun">|</span><span class="pln"> date        </span><span class="pun">|</span><span class="pln"> YES </span><span class="pun">|</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> NULL    </span><span class="pun">|</span><span class="pln">                </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+-------------+-------------+------+-----+---------+----------------+</span><span class="pln">
</span><span class="lit">5</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.01</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<h2>
	<span style="line-height: 1.6;">إضافة معلومات إلى جدول في MySQL</span>
</h2>

<p dir="rtl">
	لدينا الآن جدول لتنظيم معلومات الحدَث، بقي ملؤه بالبيانات اللّازمة.
</p>

<p dir="rtl">
	استخدِم الأمرَ التّالي لإضافة صف بيانات جديد:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">INSERT INTO </span><span class="str">`potluck`</span><span class="pln"> </span><span class="pun">(</span><span class="str">`id`</span><span class="pun">,</span><span class="str">`name`</span><span class="pun">,</span><span class="str">`food`</span><span class="pun">,</span><span class="str">`confirmed`</span><span class="pun">,</span><span class="str">`signup_date`</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">,</span><span class="pln"> </span><span class="str">"John"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Casserole"</span><span class="pun">,</span><span class="str">"Y"</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2012-04-11'</span><span class="pun">);</span></pre>

<p dir="rtl">
	يُضيف هذا الأمر مُشاركًا جديدًا في الحدث اسمُه <span style="font-family:courier new,courier,monospace;">John</span> وسيأتي بطنجرة (<span style="font-family:courier new,courier,monospace;">Casserole</span>)؛ سجّلَ بتاريخ <span style="font-family:courier new,courier,monospace;">2012-04-11</span> وأكّد حضوره (<span style="font-family:courier new,courier,monospace;">Y</span>). المُعرّف سيُملأ أوتوماتيكيًّا لذا وضعنا <span style="font-family:courier new,courier,monospace;">NULL</span> مكان العمود الأول.
</p>

<p dir="rtl">
	ستظهر بعد تنفيذ الأمر رسالة شبيهة بالتّاليّة:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="typ">Query</span><span class="pln"> OK</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> row affected </span><span class="pun">(</span><span class="lit">0.07</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p dir="rtl">
	نُضيف مشاركين جددًا بتفاصيل مختلفة إلى جدول المُشاركين عبر الأوامر التّاليّة:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">INSERT INTO </span><span class="str">`potluck`</span><span class="pln"> </span><span class="pun">(</span><span class="str">`id`</span><span class="pun">,</span><span class="str">`name`</span><span class="pun">,</span><span class="str">`food`</span><span class="pun">,</span><span class="str">`confirmed`</span><span class="pun">,</span><span class="str">`signup_date`</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Sandy"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Key Lime Tarts"</span><span class="pun">,</span><span class="str">"N"</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2012-04-14'</span><span class="pun">);</span><span class="pln">

INSERT INTO </span><span class="str">`potluck`</span><span class="pln"> </span><span class="pun">(</span><span class="str">`id`</span><span class="pun">,</span><span class="str">`name`</span><span class="pun">,</span><span class="str">`food`</span><span class="pun">,</span><span class="str">`confirmed`</span><span class="pun">,</span><span class="str">`signup_date`</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Tom"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"BBQ"</span><span class="pun">,</span><span class="str">"Y"</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2012-04-18'</span><span class="pun">);</span><span class="pln">

INSERT INTO </span><span class="str">`potluck`</span><span class="pln"> </span><span class="pun">(</span><span class="str">`id`</span><span class="pun">,</span><span class="str">`name`</span><span class="pun">,</span><span class="str">`food`</span><span class="pun">,</span><span class="str">`confirmed`</span><span class="pun">,</span><span class="str">`signup_date`</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Tina"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Salad"</span><span class="pun">,</span><span class="str">"Y"</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2012-04-10'</span><span class="pun">);</span><span class="pln">
</span></pre>

<p>
	<span style="line-height: 1.6;">لعرض جميع البيانات الموجودة في الجدول نستخدم الأمر أدناه. علامة * تعني معلومات جميع الأعمدة.</span>
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM potluck</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+----+-------+----------------+-----------+-------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> id </span><span class="pun">|</span><span class="pln"> name  </span><span class="pun">|</span><span class="pln"> food           </span><span class="pun">|</span><span class="pln"> confirmed </span><span class="pun">|</span><span class="pln"> signup_date </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+----+-------+----------------+-----------+-------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">John</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Casserole</span><span class="pln">      </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">11</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">2</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Sandy</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Key</span><span class="pln"> </span><span class="typ">Lime</span><span class="pln"> </span><span class="typ">Tarts</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> N         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">14</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">3</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Tom</span><span class="pln">   </span><span class="pun">|</span><span class="pln"> BBQ            </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">18</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">4</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Tina</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Salad</span><span class="pln">          </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">10</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+----+-------+----------------+-----------+-------------+</span><span class="pln">
</span><span class="lit">4</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.00</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p>
	<span style="line-height: 1.6;">إن أردنا الاقتصار على المعلومات الموجودة في بعض الأعمدة وليس كلّها نذكر الأعمدة المعنيّة هنا. مثلا إن أردنا فقط الأسماء والأطعمة ننفّذ الأمر:</span>
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">SELECT name</span><span class="pun">,</span><span class="pln"> food FROM potluck</span><span class="pun">;</span></pre>

<h2 dir="rtl">
	تحديث بيانات موجودة في جدول MySQL
</h2>

<p dir="rtl">
	يُتيح MySQL إمكانيّة تغيير بيانات موجودة في جدول. في المثال السّابق أضفنا مشارِكةً باسم Sandy. هذم المُشارِكة لم تؤكّد الحضور (قيمة العمود <span style="font-family:courier new,courier,monospace;">confirmed</span> هي <span style="font-family:courier new,courier,monospace;">N</span>). أبلغتْنا الآن بأنّها تأكّدت من حضورها. لتحديث عمود <span style="font-family:courier new,courier,monospace;">confirmed</span> بالنّسبة لـ<span style="font-family:courier new,courier,monospace;">sandy</span> نُنفذ الأمر:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">UPDATE </span><span class="str">`potluck`</span><span class="pln">
SET
</span><span class="str">`confirmed`</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Y'</span><span class="pln">
WHERE </span><span class="str">`potluck`</span><span class="pun">.</span><span class="str">`name`</span><span class="pln"> </span><span class="pun">=</span><span class="str">'Sandy'</span><span class="pun">;</span></pre>

<p>
	<span style="line-height: 1.6;">يُفهم الأمر أعلاه كما يلي: حدّث بيانات الجدول <span style="font-family:courier new,courier,monospace;">potluck</span> بضبط عمود <span style="font-family:courier new,courier,monospace;">confirmed</span> على القيمة <span style="font-family:courier new,courier,monospace;">Y</span> إذا كانت قيمة العمود <span style="font-family:courier new,courier,monospace;">name</span> تُساوي <span style="font-family:courier new,courier,monospace;">Sandy</span>. كما تُلاحظ يوجد شرط للتّحديث وهو الاسم <span style="font-family:courier new,courier,monospace;">= Sandy</span>.</span>
</p>

<p dir="rtl">
	يُمكن أيضًا استخدامُ هذا الأمر لإضافة بيانات إلى خليّة (تقاطع عمود وصفّ) حتى ولو كانت خاويّة.
</p>

<h2 dir="rtl">
	إضافة أوحذف عمود من جدول في MySQL
</h2>

<p dir="rtl">
	أنشأنا جدولًا ببيانات مُفيدة، ولكن تنقُصُنا معلومة مهمّة: البريد الإلكتروني للمُشترك؛ لذا سنُضيف عمودًا جديدًا نُخزّن فيه هذه المعلومة.
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">ALTER TABLE potluck ADD email VARCHAR</span><span class="pun">(</span><span class="lit">40</span><span class="pun">);</span></pre>

<p>
	<span style="line-height: 1.6;">يقول هذا الأمر "غيّر الجدول <span style="font-family:courier new,courier,monospace;">potluck</span> عن طريق إضافة عمود جديد باسم <span style="font-family:courier new,courier,monospace;">email</span> لا يتجاوز المُحتوى فيه 40 محرفًا".</span>
</p>

<p dir="rtl">
	يُضاف هذا العمود افتراضًا في آخر الجدول، إذا كنتَ تُريد وضعَه في مكان مُعيّن يُمكن ذلك كما يلي:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">ALTER TABLE potluck ADD email VARCHAR</span><span class="pun">(</span><span class="lit">40</span><span class="pun">)</span><span class="pln"> AFTER name</span><span class="pun">;</span></pre>

<p dir="rtl">
	أي أنّ العمود الجديد سيُضاف بعد (<span style="font-family:courier new,courier,monospace;">AFTER</span>) العمود <span style="font-family:courier new,courier,monospace;">name</span>.
</p>

<p dir="rtl">
	بالنّسبة لحذف عمود فهو مُشابه لإضافته:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">ALTER TABLE potluck DROP email</span><span class="pun">;</span></pre>

<p dir="rtl">
	حذف صفّ من جدول
</p>

<p dir="rtl">
	يُمكن إن اقتضت الحاجة حذف صفوف من الجدول عبر الأمر التّالي:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">DELETE </span><span class="kwd">from</span><span class="pln"> </span><span class="pun">[</span><span class="pln">table name</span><span class="pun">]</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> </span><span class="pun">[</span><span class="pln">column name</span><span class="pun">]=[</span><span class="pln">field text</span><span class="pun">];</span></pre>

<p dir="rtl">
	حيثُ <span style="font-family:courier new,courier,monospace;">[table name]</span> اسم الجدوَل ، <span style="font-family:courier new,courier,monospace;">[column name]</span> اسم العمود و<span style="font-family:courier new,courier,monospace;">[field text]</span> هيّ قيمة العمود في الصّف.
</p>

<p dir="rtl">
	نفرض مثلًا أنّنا نُريد حذف <span style="font-family:courier new,courier,monospace;">Sandy</span> من قائمة المُشاركين:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> DELETE </span><span class="kwd">from</span><span class="pln"> potluck </span><span class="kwd">where</span><span class="pln"> name</span><span class="pun">=</span><span class="str">'Sandy'</span><span class="pun">;</span><span class="pln">
</span><span class="typ">Query</span><span class="pln"> OK</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> row affected </span><span class="pun">(</span><span class="lit">0.00</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p>
	<span style="line-height: 1.6;">أي احذَف الصّف الّذي تُساوي فيه قيمةُ عمود الاسم <span style="font-family:courier new,courier,monospace;">Sandy</span>. في حال وجود أكثر من شخص بهذا الاسم فسيُحذف جميع هؤلاء الأشخاص.</span>
</p>

<p dir="rtl">
	نُعيد عرض محتوى الجدول بعد تنفيذ أمر الحذف:
</p>

<pre class="php ipsCode prettyprint prettyprinted" data-pbcklang="php" data-pbcktabsize="4">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM potluck</span><span class="pun">;</span><span class="pln">
</span><span class="pun">+----+------+-----------+-----------+-------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> id </span><span class="pun">|</span><span class="pln"> name </span><span class="pun">|</span><span class="pln"> food      </span><span class="pun">|</span><span class="pln"> confirmed </span><span class="pun">|</span><span class="pln"> signup_date </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+----+------+-----------+-----------+-------------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">John</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Casserole</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">11</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">3</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Tom</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> BBQ       </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">18</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="lit">4</span><span class="pln">  </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Tina</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Salad</span><span class="pln">     </span><span class="pun">|</span><span class="pln"> Y         </span><span class="pun">|</span><span class="pln"> </span><span class="lit">2012</span><span class="pun">-</span><span class="lit">04</span><span class="pun">-</span><span class="lit">10</span><span class="pln">  </span><span class="pun">|</span><span class="pln">
</span><span class="pun">+----+------+-----------+-----------+-------------+</span><span class="pln">
</span><span class="lit">3</span><span class="pln"> rows </span><span class="kwd">in</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">(</span><span class="lit">0.00</span><span class="pln"> sec</span><span class="pun">)</span></pre>

<p>
	<span style="line-height: 1.6;">لاحِظ عدم تغيّر معرّف أي واحد من المُشتركين المتبقّين.</span>
</p>

<p dir="rtl">
	ترجمة -وبتصرّف- للمقال <a href="https://www.digitalocean.com/community/tutorials/a-basic-mysql-tutorial" rel="external nofollow">A Basic MySQL Tutorial</a> لصاحبته Etel Sverdlov.
</p>

<p>
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">28</guid><pubDate>Sun, 12 Apr 2015 09:39:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641;&#x64A;&#x629; &#x625;&#x639;&#x62F;&#x627;&#x62F; &#x642;&#x627;&#x639;&#x62F;&#x629; &#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x628;&#x639;&#x64A;&#x62F;&#x629; &#x644;&#x62A;&#x62D;&#x633;&#x64A;&#x646; &#x623;&#x62F;&#x627;&#x621; &#x645;&#x648;&#x642;&#x639; &#x64A;&#x633;&#x62A;&#x62E;&#x62F;&#x650;&#x645; MySQL</title><link>https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%B9%D9%8A%D8%AF%D8%A9-%D9%84%D8%AA%D8%AD%D8%B3%D9%8A%D9%86-%D8%A3%D8%AF%D8%A7%D8%A1-%D9%85%D9%88%D9%82%D8%B9-%D9%8A%D8%B3%D8%AA%D8%AE%D8%AF%D9%90%D9%85-mysql-r9/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2015_03/mysql-logo.png.a2c2e9899cb700dd75db50663234b265.png" /></p>

<h2 dir="rtl">مقدِّمة</h2><p dir="rtl">يحدُث، مع ازدياد استخدام التطبيق أو موقع الويب الخاص بك، أن يتجاوز الضغط الناتج عن هذا النمو قدرةَ الإعداد الحالي على الاستجابة. في حال كنتَ تستضيف خادوم الويب والنهاية الخلفيةBackend لقاعدة البيانات على نفس الخادوم الافتراضي الخاص Virtual private server, VPS فمن الجيد فصلُ هاتين الوظيفتيْن بحيثُ تنمو كل منهما على جهاز خاص بها.</p><p dir="rtl">سنناقِش في هذا المقال كيفية إعداد خادوم قاعدة بيانات بعيد Remote database server يتّصل به خادوم الويب للحصول على محتوى ديناميكي. سنأخذ ووردبريس مثالا للعمل عليه. سيكون Nginx خادومَ الويب، وسنُعدّه للاتصال بقاعدة بيانات MySQL توجد على حاسوب منفصِل. تجري جميع هذه الإعدادات على خادوم افتراضي خاص يعمل بتوزيعة Ubuntu 12.04.</p><h2 dir="rtl">تثبيت MySQL على خادوم قاعدة البيانات</h2><p dir="rtl">نبدأ بإعداد خادوم افتراضي خاص ليعمل كخادوم MySQL. يُساعِد وجود خادوم قاعدة البيانات على جهاز منفصِل في سهولة التوسّع عند الوصول إلى الحد الأعلى الذي يسمح به إعدادٌ من جهاز واحد، كما أنه يضع أساسا يُمكن استخدامه في ما بعد للجوء إلى توزيع الحِمل Load balancing من أجل توسيع بيئة العمل.</p><p dir="rtl">سنحتاج لتثبيت بعض الحِزم Packages على خادوم قاعدة البيانات قبل بدْء العمل. هذه الحِزم هي نفسها المستخدَمة في تثبيت حِزم LEMP اعتيادية ولكن لن نُثبِّتَها كلَّها هنا (البقية ستتواجد على الخادوم الآخر).</p><p dir="rtl">ابدأ بتحديث النسخ المخبَّأة من الحِزم على النظام لديك، وتثبيت خادوم MySQL:</p><pre class="php ipsCode prettyprint">sudo apt-get update

sudo apt-get install mysql-server </pre><p> </p><p dir="rtl">سيُطلب منك أثناء تثبيت خادوم MySQL إدخالُ كلمة سر لحساب مُدير قاعدة البيانات (الحساب الجذرRoot user) ثم تأكيدُها.</p><p dir="rtl">ستحتاج بعد الانتهاء من تثبيت الحزمة إلى تنفيذ أمر تثبيت قاعدة البيانات والذي سيُنشئ بنية المجلَّدات الضرورية:</p><pre class="php ipsCode prettyprint">sudo mysql_install_db </pre><p dir="rtl">نأتي بعد التثبيت إلى خطوة الرفع من مستوى الأمان عن طريق سكريبت يطلُب تعطيل بعض إعدادات MySQL الافتراضية غير الآمنة:</p><pre class="php ipsCode prettyprint">sudo mysql_secure_installation</pre><p dir="rtl">أدخِل كلمة سر مدير قاعدة بيانات MySQL (ضُبِطت أعلاه). سيطلُب منك ما إذا كنت تريد تغيير كلمة السّر، أدخِل N إن لم ترغَب في ذلك.</p><p dir="rtl">بالنسبة لبقية الأسئلة اضغط زر Enter لترك الخيارات الافتراضية، وهو ما سينتُج عنه حذف بعض قواعد البيانات التجريبية وقفل الولوج Access.</p><h2 dir="rtl">إعداد MySQL للسماح للولوج عن بعد</h2><p dir="rtl">في هذه الفقرة سنضبُط قاعدة البيانات بحيث تسمح بالاتصالات القادمة من حواسيب أخرى.</p><p dir="rtl">افتح ملف إعداد MySQL الرئيس بصلاحيات الجذر في محرّر نصوص (Nano في هذا المثال):</p><pre class="php ipsCode prettyprint">sudo nano /etc/mysql/my.cnf </pre><p dir="rtl">يُقسَّم هذا الملف إلى مقاطِع مُعرَّفة بكلمات بين معكوفَيْن ([ و ]). اعثُر على المقطَع المعرَّف ب mysqld (لاحِظ حرف d في آخر الكلمة):</p><p>[mysqld]</p><p dir="rtl">ابحَث في هذا المقطَع من الملف (بينَه وبين المُعرِّف الموالي) عن مُعطى Parameter باسم bind-address. يُخبِر هذا المُعطى قاعدةَ البيانات بعناوين الشبكة التي تستمع للاتصالات القادمة عبرها. الإعداد الحالي هو الإنصات للاتصالات القادمة من الحاسوب المحلي Local host فقط. سنحتاج لتغيير هذا الإعداد والإشارة إلى عنوان IP خارجي يُمكن الاتصال عن طريقه بالخادوم الآخر.</p><p dir="rtl">استخدِم عنوان IP الخاص لخادومك إن كنتَ تستضيف الخواديم ضمن شبكة داخلية Private network. إن لم تكن لديك شبكة داخلية استخدم عنوان IP العمومي.</p><pre class="php ipsCode prettyprint">bind-address = your_database_IP </pre><p dir="rtl">احفظ الملف (Ctrl + O ثم زر Enter) ثم أغلقه بعد الانتهاء من تحريره (Ctrl + x).</p><p dir="rtl">نُعيد تشغيل قاعدة البيانات لأخذ التغييرات بالاعتبار:</p><pre class="php ipsCode prettyprint">sudo service mysql restart </pre><h2 dir="rtl">إعداد اعتماداتCredentials ووردبريس وقاعدة البيانات</h2><p dir="rtl">ضبطنا في الخطوة السّابقة إعدادات الاتصال عبر عناوين خارجية؛ سنُكمل هذا الإعداد بإنشاء قاعدة بيانات ومستخدِم للأجهزة المتصلة عن بعد. فعلى الرغم من أننا أعددنا خادوم MySQL للإنصات للاتصالات القادمة من عنوان خارجي يُمكن لبقية الأجهزة الاتصال عبره، إلا أنه حتى اللحظة لاتوجد أي قاعدة بيانات للاتصال بها.</p><p dir="rtl">سنغتنم هذه الفرصة أيضًا لاعتماد صلاحيات Privileges تختلف حسب الجهة التي يتصل منها المستخدِم. يُمكن مثلا أن نُنشئ مستخدمَيْن باسم "user" ولكن كل منهما مرتبط بمستضيف Host مختلف. يعني هذا أنه يُمكننا إنشاء مستخدِم مرتبط بخادوم قاعدة البيانات نفسه وتكون لديه صلاحيات واسعة ثم نستعمل نفس اسم المستخدم على خادوم الويب ونعطيه فقط الصلاحيات التي يحتاجها ووردبريس.</p><p dir="rtl">سيمنحنا هذا الإعداد القدرة على القيام بالأعمال الإدارية التي تتطلب صلاحيات واسعة عند الولوج إلى خادوم قاعدة البيانات وفي نفس الوقت نعطي لخادوم الويب الحد الأدنى من الصّلاحيات التي يحتاجها. تُعتبَر هذه السياسة جيدة من ناحية أمنية حيثُ تحمي جزئيًا خادوم قاعدة البيانات في حال تعرض خادوم الويب للاختراق.</p><p dir="rtl">للبدء في الإعداد نتّصل بخادوم قاعدة بيانات MySQL باستعمال الحساب الجذر وكلمة سر المدير عبر الأمر:</p><pre class="php ipsCode prettyprint">mysql -u root -p </pre><p dir="rtl">سيُطلَب منك إدخال كلمة سر المدير بعد تنفيذ هذا الأمر.</p><p dir="rtl">بعد الولوج نُنشئ قاعدة البيانات التي سيتّصل بها ووردبريس. اخترنا إعطاء اسم wordpress لقاعدة البيانات ليسهُل علينا التعرف عليها لاحقا:</p><pre class="php ipsCode prettyprint">CREATE DATABASE wordpress; </pre><p dir="rtl">الآن سننشئ مستخدِما جديدا لديه كامل الصلاحيات على قاعدة البيانات wordpress. سنسميه wordpressuser ثم نحدّد الجهات التي يُمكن منها استعمال هذا المُستخدِم بحيث يقتصر استعماله على الاتصالات من الخادوم نفسه عن طريق استخدام localhost أثناء تنفيذ الأمر، كما يلي:</p><pre class="php ipsCode prettyprint">CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password'; </pre><p dir="rtl">في الأمر السّابق أنشأنا مستخدِما باسم wordpressuser مع كلمة السر password (اكتب كلمة سر خاصة بك مكانها) وحصرنا الجهات التي يُمكنه الاتصال منها بالمستضيف المحلي (localhost)، أي خادوم قاعدة البيانات نفسِه. نُكمل بإعطاء هذا المستخدِم كامل الصّلاحيات على قاعدة البيانات wordpress:</p><pre class="php ipsCode prettyprint">GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'localhost'; </pre><p dir="rtl">يُمكن للمستخدم wordpressuser أن يُجري أي عملية على قاعدة البيانات wordpress بشرطِ أن يكون متصلا من خادوم قاعدة البيانات.</p><p dir="rtl">فلننشئ الآن الحساب المرافق الذي ستستخدمه الاتصالات القادمة من خادوم الويب. سنحتاج لعنوان IP خادوم الويب للقيام بهذا الأمر. يُمكننا اختيار أي اسم نراه مناسبا للمستخدِم، لكن من أجل الحفاظ على تجانس التجربة سنختار نفس الاسم أعلاه، مع تغيير اسم المُستضيف.</p><p dir="rtl">انتبه إلى أنه ينبغي استخدام نفس عناوين الشبكة التي استخدمتَها في ملف my.conf أثناء إعداد MySQL للسماح للولوج عن بعد. يعني هذا أنك يجب أن تستخدم عنوان IP خاص إذا كانت لديك شبكة داخلية أو عنوان IP عمومي في الحالة المغايِرة، مع التوافق مع إعدادات الملف المذكور سابقا.</p><pre class="php ipsCode prettyprint">CREATE USER 'wordpressuser'@'web_server_IP' IDENTIFIED BY 'password'; </pre><p dir="rtl">يُنشِئ هذا الأمر مستخدِما باسم wordpressuser مع كلمة السر password وحصرنا الجهات التي يُمكنه الاتصال منها بخادوم الويب (حيثُ web_server_IP عنوان IP خادوم الويب).</p><p dir="rtl">الهدف هو أن تقتصر صلاحيات هذا المستخدم على صلاحيات يحتاجها ووردبريس للعمل وهي القراءة من قاعدة البيانات (SELECT) ، وحذف سطر من جدول (DELETE)، وإضافة سطر إلى جدول (INSERT) وتحديث البيانات الموجودة سلفا (UPDATE؛ ولكن ليس بإمكاننا تفعيل هذا الإعداد الآن. السبب أن هذه الصلاحيات لا تكفي للقيام ببعض العمليات، مثل تثبيت ووردبريس. وهو ما يعني أننا سنُفعِّل مؤقتا صلاحيات أوسع لهذا المستخدِم ثم نعود لنزعها منه وترك الصلاحيات الأربع التي ذكرناها سابقا فقط، وذلك بعد اكتمال التثبيت.</p><p dir="rtl">للمعلومة، الأمر المُستَخدم لتأمين الحساب والحد من صلاحياته هو التالي (سنعود له في ما بعد):</p><pre class="php ipsCode prettyprint">GRANT SELECT,DELETE,INSERT,UPDATE ON wordpress.* TO 'wordpressuser'@'web_server_ip'; </pre><p dir="rtl">قبل ذلك سننمح هذا المُستخدِم - مؤقتا - كامل الصلاحيات، وهو ما يجعله مطابِقا للمستخدِم السابق:</p><p>GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'web_server_ip';</p><p dir="rtl">سنعود لتغيير هذا الإعداد بعد تثبيت وضبط ووردبريس. إن كنتَ تستخدِم هذا الدّرس لمعرفة كيفية الفصل بين خادوم قادة البيانات وخادوم الويب ولا تحتاج لتثبيت ووردبريس؛ فيُمكنك تفعيل التقييدات على حساب المستخدِم الآن. يعتمِد الأمر على تطبيقك والصلاحيات الدنيا التي يُمكِنه العمل بها.</p><p dir="rtl">نحفظ التغييرات التي أجريناها على الصّلاحيات بكتابتها على القرص الصّلب:</p><pre class="php ipsCode prettyprint">FLUSH PRIVILEGES; </pre><p dir="rtl">يُمكن الآن الخروج من سطر أوامر MySQL عن طريق تنفيذ الأمر:</p><pre class="php ipsCode prettyprint">exit </pre><h2 dir="rtl">اختبِر الاتصالات المحلية والبعيدة</h2><p dir="rtl">سنتأكد قبل المواصلة مع بقية الخطوات من إمكانية الاتصال باستخدام الحساب wordpressuser على كل من خادوم قاعدة البيانات وخادوم الويب.</p><p dir="rtl">جرِّب أولا الاتصال من الجهاز الذي توجد به قاعدة البيانات باستخدام الحساب الجديد:</p><pre class="php ipsCode prettyprint">mysql -u wordpressuser -p </pre><p dir="rtl">ثم أدخِل كلمة السر التي أعددتها أثناء إنشاء الحساب. عند الولوج إلى سطر أوامر MySQL بعد تنفيذ الأمر أعلاه فإن الاتصال تم بنجاح. يُمكنك الخروج عبر الأمر:</p><pre class="php ipsCode prettyprint">exit </pre><p dir="rtl">سجِّل الدخول إلى خادوم الويب لتجربة الاتصال عن بُعد.</p><p dir="rtl">ستحتاج لتثبيت بعض الأدوات على خادوم الويب حتى يُمكنك الولوج إلى قاعدة البيانات عن بعد. حدِّث النسخ المخبَّأة من الحزم ثم ثبّت أدوات عميل MySQL Client:</p><pre class="php ipsCode prettyprint">sudo apt-get update

sudo apt-get install mysql-client </pre><p> </p><p dir="rtl">يُمكننا بعد اكتمال التثبيت تجربة الاتصال بخادوم قاعدة البيانات: </p><pre class="php ipsCode prettyprint">mysql -u wordpressuser -h database_server_IP -p </pre><p dir="rtl">مُجدّدا، تأكد من استخدام نفس عناوين الشبكة التي استخدمتها أثناء إعداد خادوم قاعدة البيانات.</p><p dir="rtl">أدخِل كلمة السر عندما تُطلَب منك. ينبغي أن يظهر سطر أوامر MySQL، وهو ما يدل على نجاح الاختبار؛ يُمكنك بعدها الخروج من سطر أوامر MySQL.</p><p dir="rtl">للمزيد من التحقق يُمكنك تجربة الاتصال من خادوم ثالث للتأكد من عدم سماح خادوم قاعدة البيانات لك بالولوج. يعني هذا أنك تحققتَ من الولوج من الجهاز المحلي (خادوم قاعدة البيانات) ومن خادوم الويب، لكن لا يُسمَح بالولوج من خادوم آخر.</p><p dir="rtl">نُجرّب الولوج إلى قاعدة البيانات من خادوم غير مُصرَّح له بالدخول عن طريق عنوان IP:</p><pre class="php ipsCode prettyprint">mysql -u wordpressuser -h database_server_IP -p </pre><p dir="rtl">لن يُسمَح لك بالدخول، بدلا من ذلك تظهر رسالة خطأ كالتالي:</p><pre class="php ipsCode prettyprint">ERROR 1130 (HY000): Host '11.111.111.111' is not allowed to connect to this MySQL server </pre><p dir="rtl">يعني هذا أن الجهاز الذي تُريد الاتصال منه لا يُسمح له بالولوج إلى قاعدة البيانات، وهو بالضبط ما نريده.</p><h2 dir="rtl">إعداد خادوم الويب</h2><p dir="rtl">نحتاج الآن بعد التأكد من إمكانية الاتصال من خادوم الويب إلى تثبيت البرامج الضرورية لهذا الخادوم ليقوم بعمله (تقديم صفحات الويب). سنضبُط كلًّا من Nginx وPHP وبقية العناصر الضرورية لخادوم الويب.</p><p dir="rtl">حدّثنا قبل قليل النسخ المخبّأة من الحزم على أوبنتو، وهو ما يعني أنه يُمكننا تثبيت الحزم التي نحتاجها مباشرة:</p><pre class="php ipsCode prettyprint">sudo apt-get install nginx php5-fpm php5-mysql </pre><p dir="rtl">بعد انتهاء تثبيت جميع الحزم، يمكن الانتقال إلى إعداد البرامج.</p><h3 dir="rtl">إعداد PHP</h3><p dir="rtl">نبدأ بالأسهل، إعداد PHP.</p><p dir="rtl">افتَح ملف إعداد PHP حيثُ سنضبُط بعض القيم المتعلقة بphp-fpm، وهو المُكوِّن المسؤول عن تقديم المحتوى الديناميكي في PHP:</p><pre class="php ipsCode prettyprint">sudo nano /etc/php5/fpm/php.ini </pre><p dir="rtl">ابحَث عن مُعطى Parameter باسم cgi.fix_pathinfo. غالب الظن أنه سيكون مسبوقا بعلامة ";" (دلالةً على أن السّطر تعليق، أي أنه لا يُؤخذ في الاعتبار) وقيمته تساوي "1". سننزع علامة التعليق ونُعطيه القيمة "0". فيُصبِح السطر كالتالي:</p><pre class="php ipsCode prettyprint">cgi.fix_pathinfo=0 </pre><p dir="rtl">هذا الإجراء أمني، حيثُ أخبرنا PHP بهذه الطريقة ألا يُحاول تخمين الملف الذي يبحث عنه المستخدِم إن لم يجد تطابقا تاما مع طلبه. يُمكِن لمستخدم سيء النية أن يستغل عدم ضبط هذا الإعداد لمحاولة تنفيذ سكربتات لا ترغب في تنفيذها على الخادوم.</p><p dir="rtl">احفَظ ثم أغلِق الملف.</p><p dir="rtl">ننتقل الآن إلى إعداد الطريقة التي يتواصل بها المعالج (Processor) الخاص بPHP مع خادوم الويب:</p><pre class="php ipsCode prettyprint">sudo nano /etc/php5/fpm/pool.d/www.conf </pre><p dir="rtl">ابحَث عن تعليمة Directive الاستماع، التي تأتي افتراضيا مضبوطة على 127.0.0.1:9000. بدلا من منفذ Port، سنستخدم مقبس Unix Socket ، Unix.</p><pre class="php ipsCode prettyprint">listen = /var/run/php5-fpm.sock </pre><p dir="rtl">احفَظ ثم أغلِق الملف بعد الانتهاء من تحريره.</p><p dir="rtl">نُعيد تشغيل معالج PHP لاعتماد القِيم الجديدة:</p><pre class="php ipsCode prettyprint">sudo service php5-fpm restart </pre><h3 dir="rtl">إعداد Nginx<br>ننتقل بعد إعداد PHP إلى إعداد خادوم ويب Nginx. نبدأ بنسخ ملف المستضيفات الافتراضية Virtual hosts الموجود سلفًا إلى ملف جديد سنعمل عليه، ونمنحه اسم نطاق الموقع. اخترنا "example.com" مثالاً للتوضيح هنا:</h3><pre class="php ipsCode prettyprint">sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com </pre><p dir="rtl">الآن افتَح الملف الجديد:</p><pre class="php ipsCode prettyprint">sudo nano /etc/nginx/sites-available/example.com </pre><p dir="rtl">سنُعدّل الجزء الخاص بالخادوم داخل الملف (الأسطُر الموجودة بين الأقواس المعكوفة الموجودة بعد كلمة server). ابدأ بتعليق تعليمة الإنصات للمنفَذ رقم 80. سنغيِّر أيضًا المجلّد الجذر ونطلُب من Nginx تقديم ملف (فهرس) PHP بشكل افتراضي:</p><pre class="php ipsCode prettyprint">server {

listen 80;

root /var/www/example.com;

index index.php index.hmtl index.htm; </pre><p> </p><p dir="rtl">نأتي الآن لتعليمة server_name التي سنُعدّلها حتى تستخدم اسم النطاق الذي نريد. تأكّد من ضبط تعليمة try_files بشكل صحيح (تمرير الطّلبات إلى PHP في حال عدم عثور خادوم ويب Nginx على الملف المطلوب) وكذلك من ضبط صفحات الخطأ.</p><pre class="php ipsCode prettyprint">server {

listen 80;

root /var/www/example.com;

index index.php index.hmtl index.htm;

server_name example.com;

location / {

try_files $uri $uri/ /index.php?q=$uri&amp;$args;

}

error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root /usr/share/nginx/www;

} </pre><p> </p><p dir="rtl">نحتاج قبل الانتهاء من إعداد Nginx لضبط معالجة PHP عن طريق استعمال جزء location لمُطابقة جميع طلبات PHP. في حال تعثر الحصول على الملف المطلوب نُجيب مباشرة بخطأ 404. نستخدم هنا أيضًا نفس المقبس الذي استخدمناه في PHP.</p><pre class="php ipsCode prettyprint">server {

listen 80;

root /var/www/example.com;

index index.php index.hmtl index.htm;

server_name example.com;

location / {

try_files $uri $uri/ /index.php?q=$uri&amp;$args;

}

error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root /usr/share/nginx/www;

}

location ~ \.php$ {

try_files $uri =404;

fastcgi_pass unix:/var/run/php5-fpm.sock;

fastcgi_index index.php;

include fastcgi_params;

}

}

</pre><p> </p><p> </p><p dir="rtl">بهذا ننتهي من إعداد الجزء المتعلّق بالخادوم. احفَظ ثم أغلق الملف.</p><p dir="rtl">تبّقى لنا حذف رابط ملف الإعداد الافتراضي ثم ربط المجلّد المفعَّل حيثُ توجد ملفات الموقع بملف إعدادات الخادوم الذي ضبطناه للتو:</p><pre class="php ipsCode prettyprint">sudo rm /etc/nginx/sites-enabled/default

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ </pre><p> </p><p dir="rtl">أعد تشغيل Nginx لأخذ التعديلات بالاعتبار:</p><pre class="php ipsCode prettyprint">sudo service nginx restart </pre><h2 dir="rtl">ثبِّت ووردبريس</h2><p dir="rtl">بعد إعداد كل من خادوم الويب ومُعالج PHP إضافة لخادوم قاعدة البيانات نأتي لتثبيت تطبيق يعمل على خادوم الويب ويتّصل بقاعدة البيانات. سنثبت ووردبريس لتجربة الإعدادات التي ذكرناها سابقا.</p><p dir="rtl">نزِّل آخر إصدار من ووردبريس (4.1.1 أثناء كتابة هذه السّطور) إلى مجلّدك الشخصي:</p><pre class="php ipsCode prettyprint">cd ~

wget https://ar.wordpress.org/wordpress-4.1.1-ar.tar.gz</pre><p> </p><p dir="rtl">استخرِج المفات عن طريق الأمر التالي الذي سينتُج عنه إنشاء مجلَّد باسم "wordpress" داخل مجلّدك الشخصي:</p><pre class="php ipsCode prettyprint">tar xzvf latest.tar.gz </pre><p dir="rtl">يأتي مع ووردبريس مثال لملف الإعداد ولكنه غير جاهز للاستعمال، سنُعيد تسميَّته حتى يُقرأ بشكل صحيح ثم نفتحه بمحرّر نصوص للتعديل عليه:</p><pre class="php ipsCode prettyprint">cp ~/wordpress/wp-config-sample.php ~/wordpress/wp-config.php

nano ~/wordpress/wp-config.php </pre><p> </p><p dir="rtl">أدخِل القيم الصحيحة للتعليمات التالية، تذكَّر أن تستخدِم نفس عنوان IP الذي استخدمتَه أثناء تجرية الاتصال بقاعدة البيانات.</p><pre class="php ipsCode prettyprint">/** اسم قاعدة بيانات ووردبريس */

define('DB_NAME', 'wordpress');

/** اسم المستخدم لقاعدة البيانات */

define('DB_USER', 'wordpressuser');

/** كلمة المرور لقاعدة البيانات */

define('DB_PASSWORD', 'password');

/** عنوان خادوم قاعدة البيانات */

define('DB_HOST', 'database_server_ip'); </pre><p> </p><p dir="rtl"><br> </p><p dir="rtl">احفَظ الملف بعد الانتهاء من تحريره ثم أغلقه. هذا هو الجزء الوحيد من الإعداد الذي يربط بشكل واضح بين خادوم الويب وخادوم قاعدة البيانات.</p><p dir="rtl">الآن سننشئ بنية المجلَّد التي أدرجناها خلال إعداد خادوم Nginx، في الجزء المعلَّم ب server في ملف الإعداد، حيثُ استخدمنا "exemaple.com" كمثال توضيحي؛ استخدِم اسم النطاق الذي اخترتَه خلال إعداد Nginx:</p><pre class="php ipsCode prettyprint">sudo mkdir -p /var/www/example.com </pre><p dir="rtl">تم ننسَخ الملفات والمجلَّدات الموجودة داخل مجلّد ووردبريس (wordpress/~) إلى المجلّد الجذر الذي أنشأناه للتّو:</p><pre class="php ipsCode prettyprint">sudo cp -r ~/wordpress/* /var/www/example.com </pre><p dir="rtl">كل الملفات الآن في المكان الذي يجب أن تكون فيه، تبقى لنا فقط تغيير أذونات Permissions ومُلكية المجلّد. ننتقل إلى مبدأ المستند Document root في خادوم الويب (المجلّد الأعلى مستوًى Top-level directory الذي سيبحث فيه خادوم الويب عن محتوى الموقع):</p><pre class="php ipsCode prettyprint">cd /var/www/example.com </pre><p dir="rtl">سنجعل من حساب خادوم الويب واسمُه www-data، مالكَ جميع الملفات في هذا المجلّد:</p><pre class="php ipsCode prettyprint">sudo chown -R www-data:www-data * </pre><p dir="rtl">سنحتاج لإذن الكتابة في ملفات الموقع حتى يُمكننا التعديل عليها. لذا سنُضيف الحساب العادي غير الجذر إلى مجموعة Group خادوم الويب ثم نُعطي لهذه المجموعة إذن التعديل على الملفات الموجودة في هذا المجلَّد:</p><pre class="php ipsCode prettyprint">sudo usermod -a -G www-data your_user

sudo chmod -R g+rw /var/www/example.com </pre><p> </p><h2 dir="rtl">إعداد الموقع عبر واجهة الويب</h2><p dir="rtl">كل ما تحتاجه الآن هو استكمال التثبيت عن طريق واجهة الويب. استخدِم المتصفّح للدخول إلى اسم نطاق الموقع (يُمكن أيضا استخدام عنوان IP العمومي):</p><p><a rel="external nofollow" href="http://example.com">http://example.com</a></p><p dir="rtl">يجب أن تظهر شاشة تثبيت ووردبريس والتي يجب أن تملأ حقول النموذج الموجود فيها بالمعلومات الضرورية:</p><p style="text-align:right;"><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_03/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.png.ccdaabc97d9ffdfcadf725b684de2e59.png"><img class="ipsImage ipsImage_thumbnailed" data-fileid="196" alt="_ووردبريس.thumb.png.47db56848b2b" src="https://academy.hsoub.com/uploads/monthly_2015_03/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.thumb.png.47db56848b2bf321a7377933196337e4.png"></a></p><p dir="rtl"> </p><p dir="rtl">استخدِم الحساب الذي أنشأتَه على ووردبريس أثناء ضبط إعداداته للولوج إلى لوحة التحكم:</p><p style="text-align:right;"><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_03/%D8%A7%D9%84%D9%88%D9%84%D9%88%D8%AC_%D8%A5%D9%84%D9%89_%D9%84%D9%88%D8%AD%D8%A9_%D8%AA%D8%AD%D9%83%D9%85_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.png.0a9e1fa3fa7165c7bcd55d8fc23e4fac.png"><img class="ipsImage ipsImage_thumbnailed" data-fileid="197" alt="_إلى_لوحة_تحكم_ووردبري" src="https://academy.hsoub.com/uploads/monthly_2015_03/%D8%A7%D9%84%D9%88%D9%84%D9%88%D8%AC_%D8%A5%D9%84%D9%89_%D9%84%D9%88%D8%AD%D8%A9_%D8%AA%D8%AD%D9%83%D9%85_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.thumb.png.14cc15255b240927fde3635f19f098d7.png"></a></p><p dir="rtl"> </p><p dir="rtl">ستُنقَل بعدها إلى لوحة تحكم ووردبريس حيثُ يمكنك البدء في إعداد موقعك.</p><p><a class="ipsAttachLink ipsAttachLink_image" rel="external nofollow" href="https://academy.hsoub.com/uploads/monthly_2015_03/%D9%84%D9%88%D8%AD%D8%A9_%D8%AA%D8%AD%D9%83%D9%85_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.png.25783f9b28d180efe36838d3a2351b6d.png"><img class="ipsImage ipsImage_thumbnailed" data-fileid="198" alt="_تحكم_ووردبريس.thumb.png.1ee" src="https://academy.hsoub.com/uploads/monthly_2015_03/%D9%84%D9%88%D8%AD%D8%A9_%D8%AA%D8%AD%D9%83%D9%85_%D9%88%D9%88%D8%B1%D8%AF%D8%A8%D8%B1%D9%8A%D8%B3.thumb.png.1eea23e86f7c8ed5379f05ec6776838d.png"></a></p><p dir="rtl"> </p><h2 dir="rtl">قيّد أذون الولوج عن بعد إلى قاعدة البيانات</h2><p dir="rtl">نعود الآن بعد الانتهاء من تثبيت ووردبريس إلى استرجاع بعض الأذونات التي منحناها لمستخدِم قاعدة البيانات البعيد.</p><p dir="rtl">لن يحتاج ووردبريس لصلاحيات إدارية إلا عند التحديث أو أثناء تثبيت الإضافات. انتبِه لهذا الأمر في حال واجهتك رسالة خطأ عند إجراء بعض العمليات الإدارية بعد تقييد أذون الولوج عن بعد إلى قاعدة البيانات.</p><p dir="rtl">انتبه أيضًا إلى أن بعض الإضافات تطلُب أذونا إضافية وابحث في كل إضافة للتأكد من ما تحتاجه مع اختيار الإضافات التي تطلُب أقل قدر من الصّلاحيات.</p><p dir="rtl">ادخُل على خادوم قاعدة البيانات ثم إلى MySQL باستخدام الحساب الجذر :</p><pre class="php ipsCode prettyprint">mysql -u root -p </pre><p dir="rtl">سيُطلب منك إدخال كلمة السر.</p><p dir="rtl">نفّذ الأمر التالي لإظهار أذون المستخدِم البعيد:</p><pre class="php ipsCode prettyprint">show grants for 'wordpressuser'@'web_server_IP';



+---------------------------------------------------------------------------------------------------------------------------+

| Grants for wordpressuser@xxx.xxx.xxx.xxx |

+---------------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'wordpressuser'@'xxx.xxx.xxx.xxx' IDENTIFIED BY PASSWORD '*5FD2B7524254B7F81B32873B1EA6D681503A5CA9' |

| GRANT ALL PRIVILEGES ON `wordpress`.* TO 'wordpressuser'@'xx.xxx.xxx.xxx' |

+---------------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec) </pre><p> </p><p> </p><p dir="rtl">لا يعني إذن الاستعمال Usage في السّطر الأول أي صلاحيات فعلية، لذا لن نهتمّ به هنا. الصّلاحيات الموجودة في السّطر الثاني هي التي أعددناها في خطوة سابقة من هذا الدّليل حيثُ أعطينا المستخدِم wordpressuser كامل الصلاحيات (ALL PRIVILEGES في الجدول أعلاه) على قاعدة البيانات wordpress عند الاتصال عن بعد بخادوم قاعدة البيانات.</p><p dir="rtl">تتكون عملية تقييد الصّلاحيات من خطوتين. أولا ننزع كل الصّلاحيات الممنوحة حاليا للمستخدِم، وذلك عبر الأمر:</p><pre class="php ipsCode prettyprint">REVOKE ALL PRIVILEGES on wordpress.* FROM 'wordpressuser'@'web_server_IP'; </pre><p dir="rtl"><br> </p><p dir="rtl">عند طلب إظهار صلاحيّات المستخدِم الحالية سنُلاحظ اختفاء السّطر الثاني:</p><p dir="rtl"><br> </p><pre class="php ipsCode prettyprint">show grants for 'wordpressuser'@'web_server_IP';



+---------------------------------------------------------------------------------------------------------------------------+

| Grants for wordpressuser@xxx.xxx.xxx.xxx |

+---------------------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'wordpressuser'@'xxx.xxx.xxx.xxx' IDENTIFIED BY PASSWORD '*5FD2B7524254B7F81B32873B1EA6D681503A5CA9' |

+---------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec) </pre><p> </p><p> </p><p dir="rtl">ثانيا، نُحدّد الصلاحيات التي نرغب في منحها لحساب المستخدِم، وهي كما ذكرنا سالفا القراءة من قاعدة البيانات (SELECT) ، وحذف سطر من جدول (DELETE)، وإضافة سطر إلى جدول (INSERT) وتحديث البيانات الموجودة (UPDATE):</p><pre class="php ipsCode prettyprint">GRANT SELECT,DELETE,INSERT,UPDATE ON wordpress.* TO 'wordpressuser'@'web_server_ip'; </pre><p dir="rtl">تحقّق مجدّدا بعد تنفيذ الأمر السابق من صلاحيات المستخدِم وستلحَظ الصّلاحيات الجديدة.</p><p dir="rtl">بقي أن نطلُب من MySQL أخذ التغييرات التي أجريناها في الاعتبار عن طريق الأمر:</p><pre class="php ipsCode prettyprint">FLUSH PRIVILEGES; </pre><p dir="rtl">للخروج من سطر أوامر MySQL:</p><pre class="php ipsCode prettyprint">exit </pre><h2 dir="rtl">خاتمة</h2><p dir="rtl">ينبغي أن يكون لديك بعد متابعة هذا الدرس فهمٌ جيّد لكيفية جعل تطبيقك يتفاعل مع قاعدة بيانات بعيدة. رأينا في الإعدادات أعلاه خطوات خاصة بووردبريس ولكن هذا لا يمنع من فهم الفكرة العامة لإعداد MySQL وضبط صلاحيات المستخدمين ثم تطبيقها حسب حاجة التطبيق الذي تُريد التعامل معه.</p><p dir="rtl">ترجمة -وبتصرّف- للمقال: <span style="line-height:22.3999996185303px;"><a rel="external nofollow" href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-remote-database-to-optimize-site-performance-with-mysql">How To Set Up a Remote Database to Optimize Site Performance with MySQL</a></span></p>
]]></description><guid isPermaLink="false">9</guid><pubDate>Sun, 01 Mar 2015 21:17:14 +0000</pubDate></item></channel></rss>
