100500 طريقة تخزين مؤقت في قاعدة بيانات أوراكل

لمعرفة ما هي ذاكرة التخزين المؤقت ، ما هي ذاكرة التخزين المؤقت للنتائج ، وكيف يتم تصنيعها في Oracle وفي قواعد البيانات الأخرى ، فهي ليست مثيرة للاهتمام وجميلة جدًا. لكن كل شيء يأخذ ألوانًا مختلفة تمامًا عندما يتعلق الأمر بأمثلة محددة. ألكسندر توكاريف ( shtock ) بنى تقريره على Highload ++ 2017 بناءً على الحالات. وعلى وجه التحديد ، على أساس الحالات التي أخبرها عندما تكون ذاكرة التخزين المؤقت محلية الصنع مناسبة ، وما هو ألم ذاكرة التخزين المؤقت للنتائج من جانب الخادم وكيفية استبدالها بذاكرة من جانب العميل ، وبشكل عام ، طرح عددًا من النصائح المفيدة لإعداد Result Cache في Oracle.


نبذة عن المتحدث: يعمل ألكسندر توكاريف في DataArt ويتعامل مع القضايا المتعلقة بقواعد البيانات ، سواء من حيث بناء الأنظمة من الصفر أو تحسين الأنظمة الحالية.

لنبدأ ببعض الأسئلة البلاغية. هل عملت مع Oracle Result Cache؟ هل تعتقد أن Oracle قاعدة بيانات مناسبة لجميع المناسبات؟ وفقًا لتجربة ألكسندر ، يجيب معظم الناس على السؤال الأخير بالنفي ، مائة حالم لديه حالم واحد . ولكن بفضل إيمانه ، يتقدم التقدم.

بالمناسبة ، تمتلك Oracle بالفعل 14 قاعدة بيانات - 14 حتى الآن - ما سيحدث في المستقبل غير معروف.

كما سبق ذكره ، سيتم توضيح جميع المشاكل والحلول في حالات محددة. ستكون هاتان حالتان من مشاريع DataArt ، ومثال طرف ثالث.

مخابئ قاعدة البيانات


بادئ ذي بدء ، أي مخابئ في قواعد البيانات. كل شيء واضح هنا:

  • ذاكرة التخزين المؤقت - ذاكرة التخزين المؤقت للبيانات - ذاكرة التخزين المؤقت لصفحات البيانات / كتل البيانات ؛
  • ذاكرة التخزين المؤقت للبيان - ذاكرة التخزين المؤقت للبيانات وخططها - ذاكرة التخزين المؤقت لخطة الاستعلامات ؛
  • ذاكرة التخزين المؤقت للنتائج - ذاكرة التخزين المؤقت لنتائج الصف - صفوف من الاستعلامات ؛
  • ذاكرة التخزين المؤقت لنظام التشغيل - ذاكرة التخزين المؤقت لنظام التشغيل.

علاوة على ذلك ، يتم استخدام ذاكرة التخزين المؤقت للنتيجة بشكل عام فقط في Oracle. كان مرة واحدة في MySQL ، ولكن تم قطعه بشكل بطولي. في PostgreSQL ، لا يوجد هناك ، فهو موجود بشكل أو بآخر في منتج طرف ثالث.

الحالة 1. مخزن التجزئة




أعلاه هو رسم تخطيطي للمنتج الذي أرفقه - المستودع (Oracle 11 ، 20 Tb ، 300 مستخدم) ، ويحتوي على نوع من التقرير الكئيب ، حيث كان هناك 350 منتجًا فريدًا لكل 5000 سطر بيانات. استغرق الأمر حوالي 20 دقيقة ، وكان المستخدمون حزينين.

عرض هذا التقرير ، مثل أي شخص آخر ، متاح على موقع مؤتمر Highload ++.

يحتوي هذا التقرير على SELECT و JOINs ووظيفة. دالة كدالة ، كل شيء سيكون على ما يرام ، إلا أنها تحسب معلمة غامضة تسمى "قيمة تسعير التحويل" ، وتعمل لمدة 0.2 ثانية - يبدو أنها لا شيء ، ولكن يتم استدعاؤها عدة مرات كما توجد صفوف في الجدول. تحتوي هذه الوظيفة على 400 صف من SQL + PL / SQL ، منذ ذلك الحين المنتج في حالة دعم ، من المخيف تغييره.

ولنفس السبب ، تعذّر استخدام result_cache.



لحل المشكلة ، نستخدم النهج القياسي مع التخزين المؤقت اليدوي : نترك أول 3 كتل من الدائرة ، كما كانت ، ببساطة قم بإعادة تسمية وظيفة SKU_detail () إلى SKU_full () ونعلن عن مجموعة مصاحبة ، حيث على التوالي:

  • المفاتيح هي وحدات SKU الخاصة بنا (سلع السلع) ،
  • القيم هي سعر تحويل التحويل المحسوب.

نجعل وظيفة ذاكرة التخزين المؤقت (SKU) واضحة: إذا لم يكن هناك مثل هذا المعرف في الصفيف النقابي ، فسيتم تشغيل وظيفتنا ، ويتم تخزين النتيجة وتخزينها وإعادتها. وفقًا لذلك ، إذا كان مثل هذا المعرّف ، فلن يحدث كل هذا. في الواقع ، حصلنا على مخبأ عند الطلب .

وبالتالي ، قمنا بتقليل عدد استدعاءات الوظائف إلى المبلغ المطلوب بالفعل. انخفض وقت معالجة التقرير إلى 4 دقائق ، شعر جميع المستخدمين بالارتياح.

ذاكرة التخزين المؤقت المصنوعة يدوياً


إن عيوب ومزايا هذا النظام واضحة من هذه الصورة الذكية الكبيرة ، والتي سنتناولها كثيرًا - هذه هي بنية الذاكرة.



من المهم أن نفهم في أي منطقة ذاكرة توجد فيها المجموعات. يتم وضعها في منطقة ذاكرة تسمى PGA. يتم إنشاء منطقة عامة للبرنامج في كل اتصال بقاعدة البيانات. هذا هو ما يحدد المزايا والعيوب ، حيث أن المزيد من الاتصالات - المزيد من الذاكرة ، والذاكرة الباهظة الثمن ، والخادم ، والمسؤولون هم عطاء.



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

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



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

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

الحالة 2. تجهيز الوثائق المالية


لذا ، قضيتنا الثانية.



هذا هو نظام معالجة الوثائق المالية شبه الآلي - مؤسسة كئيبة ذات بنية كلاسيكية ، والتي تشمل:

  • عميل رقيق
  • 4000 مستخدم يعيشون في مناطق مختلفة من العالم ؛
  • موازن
  • 2 JBoss لحساب منطق الأعمال ؛
  • كتلة في الذاكرة ؛
  • أوراكل الأساسية ؛
  • أوراكل النسخ الاحتياطي

واحدة من المهام العديدة لهذا النظام هي حساب التوصيات .



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

يختار المستخدم القيمة المطلوبة ويكرر العملية لكل سطر فارغ.

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

  1. تعدد اللغات - حوالي 30 لغة. كل لغة لها خصائصها ومرادفاتها وميزاتها الأخرى.
  2. البيانات السابقة لهذا العميل ، أو في حالة عدم وجودها ، بيانات عميل من نفس الصناعة أو عميل مماثل في الربح.

في الواقع ، هذه حوالي 12 قاعدة معقدة للغاية.

الافتراضات الأولية:

  • لا يزيد عن 100 مستخدم في المرة الواحدة ؛
  • 2-3 أعمدة للاعتراف ؛
  • 100 سطر.

لا يوجد حمولة عالية على الإطلاق - كل شيء ممل.

لذا ، حان وقت الإصدار. حدث تجميد التعليمات البرمجية ، وتخشى Java من اللمس ، وتستغرق معالجة المستند 5 دقائق على الأقل.

يأتون إلى فريق تطوير قاعدة البيانات لطلب المساعدة. بالطبع ، لأنه إذا تباطأ شيء ما في JVM ، فعندئذٍ تحتاج إلى تغيير قاعدة البيانات أو إصلاحها .



درسنا الوثائق وأدركنا أنه في كثير من الأحيان تتكرر قيم أزواج القيمة الرئيسية - 5-10 مرات. وفقًا لذلك ، قررنا استخدام قاعدة البيانات للتخزين المؤقت ، لأنه تم اختبارها بالفعل.

قررنا استخدام ذاكرة التخزين المؤقت لنتائج خادم Oracle لأن:

  1. تم استنفاد فرص تحسين SQL ، لأنها تستخدم محرك بحث النص الكامل من Oracle ؛
  2. سيتم استخدام ذاكرة التخزين المؤقت للمعلمات المكررة ؛
  3. يتم إعادة حساب معظم البيانات الخاصة بالتوصيات مرة واحدة في الساعة ، لأنها تستخدم فهرس النص الكامل ؛
  4. PL / SQL محظور .

مخبأ نتيجة أوراكل


ذاكرة التخزين المؤقت للنتائج - تخزين نتائج Oracle المؤقت - لها الخصائص التالية:

  • هذه هي منطقة الذاكرة التي يتم فيها تفحص جميع نتائج الاستعلام ؛
  • قراءة متسقة ، ويحدث إبطالها التلقائي ؛
  • مطلوب الحد الأدنى من التغييرات على التطبيق. يمكنك جعل التطبيق لا يحتاج إلى تغيير على الإطلاق ؛
  • المكافأة - يمكنك تخزين منطق PL / SQL في ذاكرة التخزين المؤقت ، ولكنه ممنوع هنا.

كيفية تمكينه؟

الطريقة رقم 1




من السهل جدا تحديد عبارة result_cache . تُظهر الشريحة ظهور معرّف النتيجة. وفقًا لذلك ، في المرة الأولى التي يتم فيها تنفيذ الاستعلام ، ستقوم قاعدة البيانات ببعض العمل ؛ أثناء التنفيذ اللاحق ، في هذه الحالة لا يلزم عمل. كل شيء على ما يرام.

الطريقة رقم 2




الطريقة الثانية تسمح لمطوري التطبيقات بعدم القيام بأي شيء - هذه هي ما يسمى التعليقات التوضيحية. نشير إلى علامة اختيار للجدول أن الطلب المقدم له يجب أن يوضع في result_cache. وبناءً على ذلك ، لا يوجد تلميح ، فنحن لا نلمس التطبيق ، وكل شيء موجود بالفعل في المخزن الناتج.

بالمناسبة ، ما رأيك ، إذا كان الاستعلام يشير إلى جدولين ، أحدهما تم وضع علامة على أنه النتيجة_الذاكرة المؤقتة ، والثاني ليس ، هل نتيجة هذا الاستعلام مخبأة؟

الجواب لا ، على الإطلاق.

حتى يتم تخزينها مؤقتًا ، يجب أن تحتوي جميع الجداول المشاركة في الاستعلام على تعليق توضيحي للنتيجة.

تتبع التبعية


هناك طرق عرض ذات صلة يمكنك من خلالها معرفة التبعيات.



في المثال أعلاه ، استعلام JOIN هو جدول يوجد فيه تبعية واحدة. لماذا؟ لأن Oracle تحدد التبعية ليس فقط من خلال التحليل ، ولكنها تنفذها وفقًا لنتائج خطة العمل .

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

لا تتبع أوراكل ما لا يلزم تتبعه .

في PL / SQL ، يتم تشغيل التبعية في وقت التشغيل بحيث يمكنك استخدام SQL الديناميكي والقيام بأشياء أخرى.



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



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



الإعاقة


لذا ، دعنا نرى متى يقوم Oracle بإبطال result_cache. تعرض الحالة المنشورة الحالة الحالية لصلاحية ذاكرة التخزين المؤقت. عندما طلب النتيجة ، ذاكرة التخزين المؤقت ، كما قلت ، لا توجد وظائف في قاعدة البيانات



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

ولكن في الجلسة الحالية سنرى أن الحمل قد انتهى ، حيث يتم تجاهل ذاكرة التخزين المؤقت في هذه الجلسة. هذا أمر معقول تمامًا ، فلنلتزم - ستصبح النتيجة غير صالحة ، كل شيء يعمل من تلقاء نفسه.



يبدو - حلم! تعتبر التبعية صحيحة - فقط حسب الطلب. ولكن لا ، تم الكشف عن عدد من الفروق الدقيقة. تنتج أوراكل إعاقات وفي عدد من الحالات غير الواضحة :

  1. مع أي تحديد للتحديث ، تطير التبعيات.
  2. إذا كان الجدول يحتوي على مفاتيح خارجية غير مفهرسة ، وحدث تحديث على الجدول الذي يحمل علامة result_cache ، والتي لم تؤثر على أي شيء على الإطلاق ، ولكن شيئًا ما تغير في الجدول الأصلي ، فستصبح ذاكرة التخزين المؤقت أيضًا غير صالحة.
  3. هذا هو الشيء الأكثر إثارة للاهتمام الذي يفسد الحياة قدر الإمكان - إذا كان هناك تحديث غير ناجح على الجدول تم وضع علامة عليه كملف ذاكرة التخزين المؤقت ، لم ينجح شيء ، ولكن في نفس المعاملة تم تطبيق أي تغييرات أخرى أثرت بطريقة ما على الجدول الأول ، ثم على أي حال سيتم إعادة تعيين النتيجة المخبأة.

لا يزال هناك مثل هذا الضجيج حول النتيجة_الذاكرة المخبأة ، عندما يسمع المطورون ، بعد أن سمعوا أن هناك شيئًا رائعًا ، يفكرون: "أوه ، هناك تخزين! الآن سنأخذ بعض الطلبات التي تعمل على 2-3 أقسام - في التاريخ الحالي وفي السابق ، ضع علامة على ذلك على أنه المخرجات الناتجة ، وسيتم دائمًا أخذها من الذاكرة! "

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

لقد فكرنا وقررنا أن نذهب إلى إنتاج نظام التوصية بهذه الأشياء:

  • لن نقوم بتخزين جميع طاولاتنا ، سنأخذ فقط الطاولات الضرورية.
  • قم بتعيين result_cache لاستعلام طويل المدى.

فحصنا كل شيء ، أجرينا اختبارات الأداء ، ووقت المعالجة - 30 ثانية . كل شيء رائع ، اذهب إلى الإنتاج!

متقطع - ذهب للنوم. نصل في الصباح. نرى رسالة: "الاعتراف يستغرق 20 دقيقة على الأقل ، تجميد الجلسات". لماذا يتجمدون؟ كيف تحولت 30 ثانية إلى 20 دقيقة ؟

بدأوا في فهم وإلقاء نظرة على قاعدة البيانات:

  • الجلسات النشطة - 400 ؛
  • على متوسط ​​الأسطر في وثيقة الاعتراف - 500 ؛
  • أعمدة الحد الأدنى - 5-8 ؛
  • عدد الجلسات في قاعدة البيانات يساوي دائمًا عدد تطبيقات المستخدم مضروبًا في 3! و result_cache لا يحب الوصول إليها بشكل متكرر.

بعد إجراء تحقيق داخلي ، اكتشفنا أن مطوري Java يعترفون في 3 سلاسل رسائل.

لقد انزعجنا - حمولة 5 أضعاف ، وإسقاط ، وتدهور ، وحتى مع هذه المعلمات لم يكن ينبغي أن يحدث مثل هذا الهبوط.

من الواضح أنك بحاجة إلى الفهم.

المراقبة




للمراقبة ، لدينا شيئان رئيسيان:

  1. V $ RESULT_CACHE_OBJECTS - قائمة بجميع الكائنات ؛
  2. V $ RESULT_CACHE_STATISTICS - إحصائيات مجمعة عن result_cache ككل.

MEMORY_REPORT هي اختلافات في موضوع ما ، ولن نحتاجها.

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



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



لذلك ، باستخدام طريقة عرض v $ result_cache_objects ، اكتشفنا أن هناك الآلاف من الإدخالات في قائمة الكائنات المخزنة مؤقتًا - أكثر بكثير مما توقعنا. علاوة على ذلك ، كانت هذه كائنات من بعض استعلاماتنا على جداول غريبة - أقراص صغيرة ، واستعلامات تاريخ التعديل الأخير. من الواضح أن شخصًا ما وضع ETL على قاعدتنا .

قبل أن نقسم على مطوري ETL ، تحققنا من تمكين خيار force_cache في هذه الجداول ، وتذكر أننا قمنا بتشغيله لأننا كنا بحاجة إلى بعض هذه البيانات غالبًا من قبل التطبيق وكان التخزين المؤقت مناسبًا.



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

هل تعتقد أنه أسهل؟ - لا تشعر بتحسن! انخفض عدد العناصر المخزنة مؤقتًا ، ثم ارتفع مرة أخرى إلى 12000. وواصلنا دراسة ما هو آخر مخبأ مؤقتًا ، نظرًا لأن السرعة لم تتغير.



نحن ننظر - مجموعة من الطلبات ، وذكية للغاية ، ولكن جميعها غير مفهومة. على الرغم من أن أي شخص عمل مع Oracle 12 يعرف أن DS SVC عبارة عن إحصائيات قابلة للتكيف. هناك حاجة لتحسين الأداء ، ولكن عندما تكون هناك النتيجة المخبأة ، يتبين أنها تقتله لأن المنافسة تحدث. هذا بالطبع مكتوب فقط للدعم .

كنا نعلم كيف يتم ترتيب عبء العمل وفهم أنه في حالتنا ، فإن الإحصاءات التكيفية لن تحسن بشكل جذري خططنا. لذلك ، قمنا بإيقاف تشغيله بشكل كبير - والنتيجة ، كما هو مكتوب في الدليل السري ، هي 10 دقائق لكل مستند. ليس سيئًا ، لكن ليس كافيًا.

المزالج


يرجع التنافس بين result_cache و DS SVC إلى حقيقة أن Oracle لديها مزاليج - أقفال صغيرة وخفيفة الوزن.



دون الخوض في تفاصيل حول كيفية عملها ، نحاول وضع مزلاج مسمى عدة مرات - لم ينجح - تلتقط Oracle وتغفو

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

1. قفل الفترة أثناء كتابة البيانات في result_cache.



بمعنى ، إذا كان طلبك يعمل لمدة 8 ثوانٍ ، خلال هذه الثواني الثماني ، فلن تتمكن الطلبات نفسها الأخرى (الكلمة الرئيسية "نفس") من فعل أي شيء ، لأنها تنتظر حتى تتم كتابة البيانات إلى النتيجة_الذاكرة المؤقتة. سيتم تسجيل الطلبات الأخرى ، لكنها ستنتظر القفل على السطر الأول فقط. المدة التي سيضطرون إلى انتظارها غير معروفة ؛ هذه هي المعلمة غير الموثقة result_cache_timeout. بعد ذلك ، يبدأون في تجاهل النتيجة المخبأة ، كما كانت ، ويعملون ببطء. ومع ذلك ، بمجرد تحرير القفل من السطر الأخير عند الباب ، يبدأون تلقائيًا في العمل مع result_cache مرة أخرى.

2. النوع الثاني من الأقفال - لتلقيه من result_cache أيضًا من السطر الأول إلى الأخير.
ولكن نظرًا لأن الجلب يأتي من الذاكرة الفورية ، تتم إزالتها بسرعة كبيرة.



تأكد من مراعاة أنه عندما يرى DBA المزالج في قاعدة البيانات ، فإنه يبدأ بالقول: "Latches! وقت الانتظار - ذهب كل شيء! »وهنا تبدأ اللعبة الأكثر إثارة للاهتمام: إقناع DBA بأن وقت الانتظار من المزالج أقصر بالفعل من وقت إعادة محاولة الاستعلام .



كما تظهر تجربتنا ، تشغل قياساتنا ، ومزالجنا على result_cache 10٪ من الطلبات نفسها .



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



support 2 , , result_cache . .

, . , , , workload 5 . , , .

?

: . , .



4 :

  • RESULT_CACHE_MAX_SIZE;
  • RESULT_CACHE_MAX_RESULT;
  • RESULT_CACHE_MODE;
  • _RESULT_CACHE_MAX_TIMEOUT.



— . , 100 512, 6 .

, - . , Invalidation Count = 10000.

, . , job , . , . job , , .



, invalid , . 40 .

, . , , Oracle. !



SHELFLIVE — , read-consistent , 10 , . . , , .

SNAPSHOT . , , read-consistent — .

:



  1. — SYS.
  2. . , , Oracle , , . , Oracle , , 12.2 . , external - support, .
  3. sql pl/sql : current_date, current_time . , current_time, .
  4. .
  5. , CLOB, BLOB .

Result cache inside Oracle


Result_cache — Oracle Core. , , job result_cache (, hint, ) , APEX.



, Dynamic sampling , , , result_cache.



Oracle internals for result cache


result_cache:

  1. (storage) ;
  2. result_cache;
  3. result_cache shared pool.



:

  • .
  • read-consistent.
  • Result_cache, , .

:

  • .
  • , .

!


, . support Oracle, , 29 2017 .: Oracle E-Business suite result_cache, .



, , . support , , .



:

  1. - ;
  2. , , , , v$result_cache_memory dbms_result_cache.memory_report, .

, , , v_result_cache_objects .

, support note — support , .



, , : - . , , :

  1. hint result_cache;
  2. hint no result_cache;
  3. black_list, , , -.

?

  • , - , , ;
  • , , . , - , , .

, . Oracle , .

Client side result cache




يظهر الرسم البياني لجهازه في أعلاه ، وهذه هي المكونات الرئيسية لقاعدة البيانات والسائق.

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

السؤال المثير للاهتمام هو ، كيف تحدث الإعاقة؟

هناك وضعان للإبطال ، يتم تحسينهما بواسطة معلمة Invalidation lag. هذا هو مقدار ما تسمح به أوراكل لذاكرة التخزين المؤقت لبرنامج التشغيل لتكون غير متناسقة.

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



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

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

تكوين ذاكرة التخزين المؤقت للنتائج من جانب العميل أمر بسيط للغاية . هناك خياران:

  1. CLIENT_RESULT_CACHE_LAG - قيمة تأخر ذاكرة التخزين المؤقت ؛
  2. CLIENT_RESULT_CACHE_SIZE - الحجم (الحد الأدنى 32 كيلوبايت ، الحد الأقصى - 2 جيجابايت).



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



بعد أن قمت بـ 10 تكرارات من الاستعلام ، حصلت على ما يلي.



النداء الأول هو إنشاء ، ثم 9 مخبأ الوصول. يشير الجدول إلى أن الذاكرة مخصصة أيضًا في كتل. انتبه أيضًا إلى SELECT - فهي ليست بديهية للغاية. لنكون صادقين ، قبل أن أبدأ في التعامل مع هذا ، لم أكن أعلم حتى أنه كان هناك مثل هذا التمثيل لـ GV$SESSION_CONNECT_INFO . لماذا لم تأخذ Oracle ذلك مباشرة إلى هذا الجدول (وهذه طاولة وليست طريقة عرض) ، لم أتمكن من فهمها. ولكن هذا هو السبب في أنني أعتقد أن هذه الوظيفة ليست شائعة جدًا ، على الرغم من أنها ، كما يبدو لي ، مفيدة جدًا.

مزايا التخزين المؤقت للعميل:

  • ذاكرة العميل رخيصة.
  • أي برنامج تشغيل متاح - JDBC ، .NET ، وما إلى ذلك ؛
  • الحد الأدنى من التأثير في رمز التطبيق.
  • تقليل الحمل على وحدة المعالجة المركزية ، الإدخال / الإخراج وعمومًا قاعدة البيانات ؛
  • لا حاجة لتعلم واستخدام جميع أنواع طبقات التخزين المؤقت الذكية وواجهات برمجة التطبيقات ؛
  • لا المزالج.

العيوب:

  • الاتساق في القراءة بتأخير - من حيث المبدأ ، الآن هذا هو الاتجاه ؛
  • تحتاج إلى عميل Oracle OCI ؛
  • الحد من 2 غيغابايت لكل عميل ، ولكن بشكل عام 2 غيغابايت الكثير ؛
  • بالنسبة لي شخصياً ، فإن القيد الرئيسي هو القليل من المعلومات حول الإنتاج.

في الدعم ، الذي نستخدمه دائمًا عند العمل مع result_cache ، وجدت 5 أخطاء فقط. هذا يشير إلى أنه على الأرجح ، قلة من الناس يحتاجون إليها.

لذا ، فإننا نجمع كل ما قيل أعلاه.

مخبأ يدوي


سيناريوهات سيئة:

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

سيناريوهات جيدة:

  • هناك فريق تطوير قاعدة بيانات قوي.
  • تنفيذ منطق PL / SQL.
  • هناك قيود تمنع استخدام تقنيات التخزين المؤقت الأخرى.

ذاكرة التخزين المؤقت للنتائج من جانب الخادم


سيناريوهات سيئة:

  • الكثير من النتائج المختلفة التي تغسل ذاكرة التخزين المؤقت بالكامل ؛
  • تستغرق الطلبات وقتًا أطول من _RESULT_CACHE_TIMEOUT أو تم تكوين هذه المعلمة بشكل غير صحيح.
  • يتم تحميل نتائج الجلسات الكبيرة جدًا في ذاكرة التخزين المؤقت في سلاسل متوازية.

سيناريوهات جيدة:

  • كمية معقولة من النتائج المخبأة.
  • مجموعات بيانات صغيرة نسبيًا (200-300 صف).
  • SQL باهظة الثمن للغاية ، وإلا فسيذهب كل الوقت إلى المزالج.
  • جداول ثابتة أكثر أو أقل.
  • هناك DBA ، والذي في حالة حدوث شيء ما سينقذ الجميع.

ذاكرة التخزين المؤقت للنتائج من جانب العميل


سيناريوهات سيئة:

  • عندما تنشأ مشكلة الإعاقة الفورية.
  • مطلوب محركات رقيقة.

سيناريوهات جيدة:

  • يوجد فريق تطوير عادي للطبقة الوسطى.
  • يتم استخدام الكثير من SQL بالفعل دون استخدام طبقة تخزين مؤقت خارجية يمكن توصيلها بسهولة.
  • هناك قيود على الغدد.


الاستنتاجات


أعتقد أن قصتي تدور حول ألم ذاكرة التخزين المؤقت لنتيجة جانب الخادم ، لذا فإن الاستنتاجات هي كما يلي:

  1. احرص دائمًا على تقييم حجم الذاكرة بشكل صحيح مع مراعاة عدد الاستعلامات ، وليس عدد النتائج ، أي: الكتل ، APEX ، الوظيفة ، الإحصائيات التكيفية ، إلخ.
  2. لا تخف من استخدام خيارات مسح ذاكرة التخزين المؤقت التلقائية (لقطة + مدة الصلاحية).
  3. لا تفرط في تحميل ذاكرة التخزين المؤقت بالطلبات أثناء تحميل كميات كبيرة من البيانات ؛ قم بتعطيل result_cache قبل ذلك. قم بتدفئة ذاكرة التخزين المؤقت.
  4. تأكد من أن _result_cache_timeout يلبي توقعاتك.
  5. لا تستخدم أبدًا FORCE لقاعدة البيانات بأكملها. تحتاج إلى قاعدة بيانات في الذاكرة - استخدم حلًا متخصصًا في الذاكرة.
  6. تحقق مما إذا كان خيار FORCE مستخدمًا بشكل مناسب للجداول الفردية بحيث لا يعمل كما نفعل مع ETL من جهة خارجية.
  7. حدد ما إذا كانت الإحصائيات التكيفية جيدة كما وصفتها Oracle (_optimizer_ads_use_result_cache = false).

Highload ++ سيبيريا الاثنين المقبل ، الجدول الزمني جاهز ونشره على الموقع. هناك العديد من التقارير في موضوع هذه المقالة:

  • سيعرض ألكسندر ماكاروف (CFT GC) طريقة لتحديد الاختناقات في جانب الخادم من البرنامج باستخدام قاعدة بيانات أوراكل كمثال.
  • سيخبرك Ivan Sharov و Konstantin Poluektov بالمشكلات التي تظهر عند ترحيل المنتج إلى إصدارات جديدة من قاعدة بيانات Oracle ، كما يعدان بتقديم توصيات حول تنظيم مثل هذا العمل وإدارته .
  • سيخبرك Nikolay Golov بكيفية ضمان تكامل البيانات في بنية الخدمات الدقيقة دون المعاملات الموزعة والاتصال الضيق.

قابلني في نوفوسيبيرسك!

Source: https://habr.com/ru/post/ar414401/


All Articles