2013-02-01

مشاكل بطئ الأداء فى قواعد بيانات أوراكل - الجزء الاول

مشاكل بطئ قواعد البيانات

قواعد البياناتدائماً ما يطمح مستخدموا أنظمة الأوراكل إلى معدلات أداء ذات سرعة عالية High Performance، وقد يصاب الموظفين بنوع من الأحباط وخيبة الامل عندما لا يجدون هذه المعدلات العالية للأداء فى قواعد بيانات أوراكل. فعندما تتلقى اتصالا هاتفيا من أحد الموظفين يخبرك فيه أن الأوراكل بطئ، وتجده مستاءً جدا من ذلك. عندئذ يجب عليك التدخل لمعرفة سبب هذا البطئ فى الأداء ثم محاولة حل الموقف. فماذا تفعل؟



قبل أن تبدأ فى معرفة السبب الحقيقى وراء بطئ أداء قاعدة البيانات، يجب أن تعرف أنت شخصياً أن قاعدة البيانات لا تبطئ ولا تسرع فى عملها، فهى تعمل بنفس الطريقة طوال الوقت. ولكن جلسات العمل Sessions المتصلة بقاعدة البيانات قد تواجه بعض الصعوبات فى تنفيذ العملية التى تريدها على قاعدة البيانات مما يؤدى إلى بطئ فى المخرجات Output وهذا ما يشعر به المستخدم.

ويكون دورك هنا هو معرفة المشكلة التى أدت إلى بطئ التنفيذ ومحاولة ازالة أسباب هذه المشكلة وضمان عدم تكرارها مرة أخرى إن أمكن ذلك.

الخطوة الأولى لحل مشكلة بطئ جلسات العمل Sessions Performance هو تحديد جلسة العمل التى يشكو المستخدم من بطئها، ثم تحديد ما الذى كانت تفعله جلسة العمل فى هذه اللحظة تحديداً، وبعد ذلك نبدأ فى أتخاذ الخطوات اللازمة للاصلاح.

قواعد البيانات أوراكل مجهزة لتقوم بتسجيل العديد من المعلومات حول جلسات العمل المتصلة مع قاعدة البيانات، وكذلك تسجل العديد من التفاصيل التى سنتسخدمها لمعرفة ما الذى أدى الى بطئ جلسة عمل محددة. يمكن الحصول على هذه البيانات من خلال الأستعلام  V$SESSION View  

حالات جلسة العمل Session State:
1-      Idle: جلسة العمل فى حالة سكون أو خمول. هى لا تؤدى أى شيء الآن.
2-      Processing: هى فى مرحلة أداء الأعمال المطلوبة منها.
3-      Waiting: جلسة العمل كانت تؤدى بعض الأعمال، ولكن علمها يتطلب إحضار بعض البيانات من مصدر أخر (كالقرص الصلب مثلا)، وهى فى حالة انتظار وصول هذه البيانات من المصدر الأخر.

الحالة Idle هذه الحالة لا تسبب أى بطئ لجلسة العمل، فهى قد أنهت الاعمال المطلوبة منها وفى انتظار وصول المزيد من الاعمال المطلوبة. كذلك الحالة Processing فهى منهمكة الآن فى تأدية ما هو مطلوب منها وهذا لا يعتبر تأخير أو بطئ منها.

أما الحالة Waiting فهى فى انتظار وصول بيانات من مصدر أخر. إذا وصلت البيانات المطلوبة من ذلك المصدر الأخر فأن جلسة العمل ستكمل عملها ومن ثم تتغير حالتها إلى Processing ثم بعد ذلك تتحول إلى Idle حين تنتهى من عملها.

أما إذا لم ترد البيانات المطلوبة من المصدر الأخر فستظل جلسة العمل فى حالة الانتظار هذه حتى تأتيها البيانات التى تريدها وإلا فانها لن تكمل عملها وستظل فى حالة انتظار. أوقات الانتظار هذه التى تنتظر فيها جلسة العمل البيانات من المصادر الأخرى، إذا طالت عن زمن محدد سيؤدى هذا إلى ما يسميه المستخدم ببطئ قاعدة البيانات. ودورنا هنا أن نعرف أسباب زيادة فترات الأنتظار التى تتوقف فيها جلسة العمل انتظاراً لقدوم البيانات من المصادر الأخرى ونحاول تقليلها.

كما قلنا سابقاً فإن قواعد البيانات أوراكل مجهزة لتسجيل كل ما يختص بجلسات العمل فى الاستعلام المسمى بـ V$SESSION View وفيه نجد كل ما يهمنا ان نعرفه لكى نقوم بتحليل أسباب بطئ جلسة العمل ومعرفة كيفية العلاج.

لمعرفة كيفية استخدام هذا الاستعلام سنقوم باجراء أحد السيناريوهات الشائعة وهو "غلق السجل" Row locking بمعنى أنه يوجد لدينا سجل Record or row يحتوى على بيانات معينة، ويوجد اثنين من المستخدمين يريدون تعديل هذا السجل فى نفس الوقت، الطبيعى هنا أن تقوم قاعدة البيانات بأغلاق السجل lock أمام أحد المستخدمين، لحين ينتهى المستخدم الأول من أجراء التعديلات عليه، قبل ان تسمح للمستخدم الثانى بالكتابة على نفس السجل.

الآن نقوم بالدخول على الـ SQL plus وفتح شاشتين Two Sessions، ونقوم بعمل التالى:
فى جلسة العمل الأولى نكتب الامر التالى:
Update <Table1>
Set <Col2> = 'x'
Where <col1> = 1 ;
ستقوم قاعدة البيانات بتنفيذ الأمر، وتظهر لنا رسالة بعدد السجلات التى تم تعديلها
"
1 row updated"، لا تقم بأصدار أمر commit وأترك الوضع فى كما هو عليه فى جلسة العمل هذه. وبهذا نكون قد قمنا بعمل اغلاق لهذا السجل row lock.

الآن ننتقل إلى الشاشة الثانية، ونقوم بتنفيذ الأمر التالى خلال جلسة العمل الأخرى:
Update t1
Set Col2 ='Y'
Where Col1 = 1 ;
هذه الجملة لن يكتمل تنفيذها حيث أنها ستتعلق عن العمل hang، والسبب هو ان الجملة الأولى التى نفذناها من خلال جلسة العمل الأولى Session 1 قد قامت بغلق lock للسجل الذى نتعامل معه وبالتالى سيشكو المستخدم من بطئ أداء قاعدة البيانات.
لمعرفة ما الذى تقوم جلسة العمل الأولى Session 1 بعمله، يجب أن نفحص حالة عمود State فى الأستعلام V$SESSION:
Select sid, state
From V$Session
Where username = '<User Name>' ;
حيث أن User Name هو اسم المستخدم الذى قمت بتسجيله للدخول إلى Session 1. ستكون المخرجات كالتالى:
SID                STATE
-------             ---------------------
xxx                WAITING
yyy                WAITED KNOWN TIME

جلسة العمل التى تحمل رقم yyy تشير حالتها إلى أنها كانت فى وضع أنتظار لوقت محدد من الزمن، ولكنها الآن ليست فى وضع أنتظار مما يعنى أنها تعمل بصورة طبيعية.

جلسة العمل التى تحمل رقم xxx تشير حالتها إلى أنها فى وضع أنتظار الآن، أى أنها لا تعمل. وهذا هو الدليل على على أنها تواجهة مشكلة ما.

الآن يجب أن نعرف ما الذى تنتظره session xxx، ولمعرفه هذا يجب علينا فحص عمود EVENT من نفس الأستعلام، حيث أن هذا العمود لا يحتوى فقط على سبب الأنتظار لأحدى جلسات العمل، ولكنه أيضاً يحتوى على سبب أنتظار جلسة العمل فى الماضى أيضاً (لو كانت دخلت فى مرحلة أنتظار).
Select sid, state, event
From V$SESSION
Where username = '<User Name>' ;
SID   STATE                          EVENT
----    ------------------------      ----------
xxx    WAITING                     eng: TX – row lock contention
yyy    WAITED KNOWN TIME  SQL*Net message from client

النتائج الظاهرة على الشاشة تشير إلى أن :
جلسة العمل التى تحمل رقم yyy هى فى حالة Idle، وذلك لأن الرسالة SQL*Net message from client تعنى أنها فى أنتظار وصول أوامر أخرى لها من العميل. وبما أنه من غير المعروف متى تصل هذه الأوامر، لذا فهى تدخل فى مرحلة سكون Idle حتى تصل لها هذه الأوامر.
لاحظ أن الـ Sessions التى فى حالة سكون Idle تظهر الحالة الخاصه بها state على أنها waiting أيضاً. لذا يجب مراجعة قيمة عمود event لتحديد هل هى فى حالة سكون فعلاً أم لا؟
""SQL*Net message from client وكذلك rdbms ipc message"" تعنى أن الـ session  فى حالة سكون idle.
جلسة العمل التى تحمل رقم xxx فى حالة أنتظار وسبب الأنتظار هو أن جلسة العمل هذه تريد أن تقوم بعمل غلق lock لأحد السجلات، ولكن هذا السجل توجد جلسة عمل اخرى another session قد قامت بعمل غلق عليه هى الأخرى، ولهذا فأن هذا السجل متنازع عليه Contention بين جلستى العمل. لفض هذا النزاع على السجل، يجب أن تقوم جلسة العمل ألأولى بأصدار أمر commit او أمر Roll back لكى تقوم بفك الغلق lock الحادث لهذا السجل. وفى هذه الحالة ستتمكن جلسة العمل الثانية session 2 من تنفيذ الأمر الذى تريده على هذا السجل.

من السابق نستنتج أنه، يجب أولاً النظر إلى عمود State لمعرفه حالة الـ session هل هى تعمل أم فى وضع أنتظار، ثم بعد ذلك ننظر إلى العمود Event لمعرفة سبب أنتظار الـ session.

بعد ذلك يجب معرفة الزمن المستغرق فى عملية الأنتظار هذه، أو الزمن الذى أستغرقته جلسة العمل سابقاً عندما كانت فى وضع الأنتظار. لمعرفه هذا من نفس الأستعلام الذى نستخدمه يوجد عمودين هما:

Seconds_In_Wait: وهو يوضح عدد الثوانى منذ بدء الدخول فى وضع الانتظار. بالطبع كلما زاد هذا الوقت يدل هذا على أن جلسة العمل تعانى من مشكلة ما.

Wait_Time: عدد الثوانى التى أستمر عليها وضع الانتظار حتى انتهى. وهذا بالنسبة لجلسات العمل التى دخلت فى وضع الانتظار فى السابق وليس الآن. هذا العمود يقاس بجزء من مائة من الثانية hundredths ، أى انه لمعرفه عدد الثوانى يتم قسمة الرقم فى هذا العمود على 100.

الآن وقد عرفنا معلومات عن حالة جلسة العمل Session وهل هى تعمل أم فى وضع انتظار، وما هو السبب فى هذا الانتظار. وعرفنا كيفية تحديد الوقت المستغرق فى وضع الانتظار. دعونا نضع هذا كله فى جملة استعلام واحدة:

col "Description" format a50
select sid,
        decode(state, 'WAITING','Waiting',
                'Working') state,
        decode(state,
                'WAITING',
                'So far '||seconds_in_wait,
                'Last waited '||
                wait_time/100)||
        ' secs for '||event
        "Description"
from v$session

الآن وقد عرفنا أن جلسة العمل session رقم xxx قد دخلت فى وضع الانتظار وأن لديها مشكلة بسبب التنازع على حق الكتابة على أحد السجلات row lock contention وهذا النزاع بالطبع مع جلسة عمل أخرى.

السؤال الذى يطرح نفسه الآن من هى جلسة العمل الاخرى هذه؟ ومن هو السجل row محل النزاع؟ ومن هو الجدول table الذى يحتوى هذا السجل؟ من الذى أصدر الامر الذى تسبب فى هذا النزاع؟ ومن اى جهاز أصدر هذا الأمر؟ ما هو الأمر الذى تسبب فى كل هذا النزاع؟

من هى جلسة العمل الاخرى هذه؟ بالطبع يمكنك إيجاد الاجابة عن هذا السؤال عن طريق تنفيذ الأستعلام التالى:
Select
  blocking_session B_SID,
  blocking_instance B_Inst
From v$session
Where sid = <xxx> ;
حيث أن blocking_session هو رقم الـ Session التى أصدرت الأمر الذى تسبب فى حالة التنازع على غلق السجل.

من هو السجل row محل النزاع؟ ومن هو الجدول table الذى يحتوى هذا السجل؟ أجابة هذين السؤالين فى تنفيذ الأستعلام التالى:

Select row_wait_obj#,   row_wait_file#,    row_wait_block#,     row_wait_row#
From v$session
Where sid = <xxx> ;

حيث أن row_wait_obj# هو رقم الجدول table الذى يحتوى السجل محل النزاع. يمكن معرفه اسم الـ table وبيانات تفصيلية اخرى عنه، عن طريق تنفيذ أستعلام أخر على Dba_Objects.
Select owner, object_type, object_name, data_object_id
From dba_objects
Where object_id = < row_wait_obj# >;

row_wait_file#,    row_wait_block#,     row_wait_row# معلومات عن الملف، والبلوك، والسجل الذى نبحث عنه.

من الذى أصدر الامر الذى تسبب فى هذا النزاع؟ ومن اى جهاز أصدر هذا الأمر؟ عن طريق الأمر التالى يمكن الحصول على أجابات هذين السؤالين وأكثر من ذلك:
Select SID, osuser, machine, terminal, service_name, logon_time, last_call_et ,program
From v$session
Where username = < 'User Name'> ;
OsUser: اسم المستخدم المعرف على نظام التشغيل على الجهاز الذى دخل منه المستخدم.
Machine: إسم الجهاز الذى دخل منه المستخدم.
Terminal: إسم الجهاز لو كان المستخدم يستخدم نظام التشغيل Unix.
Logon_Time: وقت الدخول.
last_call_et: الزمن الذى مضى منذ اصدار أخر أمر.


ما هو الأمر الذى تسبب فى كل هذا النزاع؟ نفذ الامر التالى لتعرف أجابة هذا السؤال:
Select sql_id
From v$session
Where sid = xxx;
sql_id: هو رقم تعريف ID خاص بجملة الأستعلام Query التى يتم تنفيذها حالياً.


ثم بعد ذلك نفذ الامر التالى، لتحصل على النص الكامل لجملة الأستعلام التى يتم تنفيذها:
Select sql_fulltext
From v$sql
Where sql_id = < 'sql_id' >;


بعد معرفتك لكل هذه المعلومات عن جلسات العمل sessions العاملة على قاعدة البيانات، يمكنك تشخيص أى أعطال، وكذلك علاجها بالطريقة المناسبة لكل حالة.





هناك تعليق واحد:

  1. ماشا الله معلومات جدا جدا جدا رااائعة
    والله يوفقك

    وأمل المزيد..

    ردحذف