نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا

على نحو متزايد، يتم تلقي مثل هذه الطلبات من العملاء: "نريدها مثل Amazon RDS، ولكن أرخص"؛ "نريده مثل RDS، ولكن في كل مكان وفي أي بنية تحتية." لتنفيذ مثل هذا الحل المُدار على Kubernetes، نظرنا إلى الوضع الحالي للمشغلين الأكثر شيوعًا لـ PostgreSQL (Stolon، والمشغلون من Crunchy Data وZalando) وقمنا باختيارنا.

هذه المقالة هي تجربتنا سواء من الناحية النظرية (مراجعة الحلول) أو من الناحية العملية (ما تم اختياره وما خرج به). لكن أولاً، دعونا نحدد ما هي المتطلبات العامة للبديل المحتمل لـ RDS...

ما هو آر دي إس

عندما يتحدث الناس عن RDS، في تجربتنا، فإنهم يقصدون خدمة إدارة قواعد البيانات المُدارة التي:

  1. من السهل اقامة.
  2. لديه القدرة على العمل مع اللقطات والتعافي منها (ويفضل أن يكون ذلك بدعم من بيتر);
  3. يسمح لك بإنشاء طبولوجيا رئيسية وتابعة؛
  4. لديه قائمة غنية من الملحقات.
  5. يوفر التدقيق وإدارة المستخدم / الوصول.

بشكل عام، يمكن أن تكون طرق تنفيذ المهمة مختلفة جدًا، لكن المسار مع Ansible الشرطي ليس قريبًا منا. (توصل زملاء من 2GIS إلى نتيجة مماثلة نتيجة لـ محاولته قم بإنشاء "أداة النشر السريع لنظام مجموعة تجاوز الفشل المستندة إلى Postgres".)

إن المشغلين هم النهج المقبول عمومًا لحل مثل هذه المشكلات في النظام البيئي Kubernetes. بمزيد من التفاصيل عنها فيما يتعلق بقواعد البيانات التي تعمل داخل Kubernetes، قال المدير الفني لـFlant بالفعل، وزعفي أحد تقاريره.

NB: لإنشاء عوامل تشغيل بسيطة بسرعة، نوصي بالانتباه إلى الأداة المساعدة مفتوحة المصدر الخاصة بنا مشغل القشرة. باستخدامه، يمكنك القيام بذلك دون معرفة Go، ولكن بطرق مألوفة أكثر لمسؤولي النظام: في Bash، وPython، وما إلى ذلك.

هناك العديد من مشغلي K8s المشهورين لـ PostgreSQL:

  • ستولون.
  • مشغل PostgreSQL للبيانات المقرمشة؛
  • مشغل زالاندو بوستجرس.

دعونا ننظر إليهم عن كثب.

اختيار المشغل

بالإضافة إلى الميزات المهمة المذكورة أعلاه، نحن - كمهندسي البنية التحتية في Kubernetes - توقعنا أيضًا ما يلي من المشغلين:

  • النشر من Git ومع الموارد المخصصة;
  • دعم مكافحة التقارب ؛
  • تثبيت تقارب العقدة أو محدد العقدة؛
  • تحديد التسامح.
  • توافر خيارات الضبط
  • تقنيات مفهومة وحتى الأوامر.

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

الآن - لمشغلي PostgreSQL أنفسهم.

1. ستولون

ستولون من شركة Sorint.lab الإيطالية التقرير المذكور بالفعل تم اعتباره نوعًا من المعايير بين مشغلي نظام إدارة قواعد البيانات (DBMS). هذا مشروع قديم نوعًا ما: تم إصداره العام الأول في نوفمبر 2015 (!)، ويضم مستودع GitHub ما يقرب من 3000 نجم وأكثر من 40 مساهمًا.

في الواقع، يعد Stolon مثالاً رائعًا للهندسة المعمارية المدروسة:

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا
يمكن العثور على جهاز هذا المشغل بالتفصيل في التقرير أو وثائق المشروع. بشكل عام، يكفي أن نقول أنه يمكنه القيام بكل ما هو موضح: تجاوز الفشل، الوكيل للوصول الشفاف للعميل، النسخ الاحتياطية ... علاوة على ذلك، يوفر الوكلاء الوصول من خلال خدمة نقطة نهاية واحدة - على عكس الحلين الآخرين اللذين تمت مناقشتهما أدناه (لديهم خدمتان للوصول قاعدة).

ومع ذلك، ستولون لا توجد موارد مخصصةولهذا السبب لا يمكن نشره بطريقة تجعل من السهل والسريع - "مثل الكعك الساخن" - إنشاء مثيلات DBMS في Kubernetes. تتم الإدارة من خلال الأداة المساعدة stolonctlوالنشر - من خلال مخطط Helm، ويتم تحديد العناصر المخصصة في ConfigMap.

من ناحية، اتضح أن المشغل ليس مشغلا حقا (لأنه لا يستخدم CRD). ولكن من ناحية أخرى، فهو نظام مرن يسمح لك بتكوين الموارد في K8s بالطريقة التي تريدها.

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

2. مشغل PostgreSQL للبيانات المقرمشة

المشغل من البيانات المقرمشة، وهي شركة أمريكية ناشئة شابة، تبدو كبديل منطقي. يبدأ تاريخها العام بالإصدار الأول في مارس 2017، ومنذ ذلك الحين، استقبل مستودع GitHub ما يقل قليلاً عن 1300 نجم وأكثر من 50 مساهمًا. تم اختبار الإصدار الأخير من شهر سبتمبر للعمل مع Kubernetes 1.15-1.18 وOpenShift 3.11+ و4.4+ وGKE وVMware Enterprise PKS 1.3+.

تلبي بنية مشغل Crunchy Data PostgreSQL أيضًا المتطلبات المذكورة:

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا

الإدارة من خلال الأداة المساعدة pgoومع ذلك، فإنه يقوم بدوره بإنشاء موارد مخصصة لـ Kubernetes. لذلك، أسعدنا المشغل كمستخدمين محتملين:

  • هناك تحكم عبر CRD.
  • إدارة مريحة للمستخدم (أيضًا عبر CRD)؛
  • التكامل مع المكونات الأخرى مجموعة حاوية البيانات المقرمشة - مجموعة متخصصة من صور الحاويات لـ PostgreSQL والأدوات المساعدة للعمل معها (بما في ذلك pgBackRest، وpgAudit، والامتدادات من contrib، وما إلى ذلك).

ومع ذلك، كشفت محاولات البدء في استخدام المشغل من Crunchy Data عن عدة مشاكل:

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

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

ميزة أخرى لهذا المشغل هي تكامله الجاهز مع الأنظمة المساعدة المختلفة. على سبيل المثال، من السهل تثبيت pgAdmin وpgBounce، وفي توثيق تعتبر Grafana و Prometheus التي تم تكوينها مسبقًا. في الآونة الأخيرة الإصدار 4.5.0-beta1 وأشار بشكل منفصل إلى تحسين التكامل مع المشروع com.pgMonitor، وبفضل ذلك يقدم المشغل تصورًا مرئيًا لمقاييس PgSQL خارج الصندوق.

ومع ذلك، أدى الاختيار الغريب للموارد التي أنشأها Kubernetes إلى إيجاد حل مختلف.

3. مشغل زالاندو بوستجرس

إن منتجات زالاندو معروفة لنا منذ فترة طويلة: لدينا خبرة في استخدام زالينيوم وبالطبع قمنا بتجربتها باتروني هو حل HA الشهير الخاص بهم لـ PostgreSQL. حول نهج الشركة في الخلق مشغل PostgreSQL قال أحد مؤلفيه - أليكسي كليوكين - على الهواء بوستجرس-الثلاثاء #5وقد أحببنا ذلك.

هذا هو الحل الأحدث الذي تمت مناقشته في المقالة: تم الإصدار الأول في أغسطس 2018. ومع ذلك، على الرغم من العدد الصغير من الإصدارات الرسمية، فقد قطع المشروع شوطًا طويلًا، وتجاوز بالفعل شعبية الحل من Crunchy Data مع أكثر من 1300 نجمة على GitHub والحد الأقصى لعدد المساهمين (70+).

يتم استخدام الحلول التي تم اختبارها عبر الزمن "تحت غطاء المحرك" لهذا المشغل:

إليك كيفية عرض بنية المشغل من زالاندو:

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا

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

وبما أننا اخترنا الحل من Zalando من بين الخيارات الثلاثة التي تم النظر فيها، فسيتم تقديم وصف إضافي لقدراته أدناه، فورًا إلى جانب ممارسة التطبيق.

تدرب مع مشغل Postgres بواسطة Zalando

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

بعد التثبيت، يجب عليك الاهتمام بالإعدادات تخزين السجلات والنسخ الاحتياطية. يتم ذلك عبر ConfigMap postgres-operator في مساحة الاسم حيث قمت بتعيين عامل التشغيل. بعد تكوين المستودعات، يمكنك نشر أول مجموعة PostgreSQL الخاصة بك.

على سبيل المثال، يبدو النشر القياسي لدينا كما يلي:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

ينشر هذا البيان مجموعة من 3 مثيلات مع عربة جانبية للنموذج postgres_exporter، والتي نجمع منها مقاييس التطبيق. كما ترون، كل شيء بسيط للغاية، وإذا كنت ترغب في ذلك، يمكنك إنشاء عدد غير محدود حرفيا من المجموعات.

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

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا
قائمة مجموعات PostgreSQL

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا
إدارة النسخ الاحتياطي

ميزة أخرى مثيرة للاهتمام هي الدعم واجهة برمجة تطبيقات الفرق. يتم إنشاء هذه الآلية تلقائيًا الأدوار في PostgreSQL، بناءً على قائمة أسماء المستخدمين الناتجة. بعد ذلك، تسمح لك واجهة برمجة التطبيقات (API) بإرجاع قائمة المستخدمين الذين تم إنشاء أدوارهم تلقائيًا.

المشاكل والحلول

ومع ذلك، فإن استخدام المشغل سرعان ما كشف عن عدة عيوب هامة:

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

ولحسن الحظ، يمكن حل الكثير منها. لنبدأ من النهاية - مشاكل توثيق.

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

  1. تحتاج إلى صنع سر.
  2. قم بتمريرها إلى المشغل كمعلمة pod_environment_secret_name في CRD باستخدام إعدادات المشغل أو في ConfigMap (اعتمادًا على الطريقة التي تختارها لتثبيت المشغل).

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

إذا قمت بتمرير المعلمات إلى المشغل للنسخ الاحتياطي، وهي - wal_s3_bucket ومفاتيح الوصول في AWS S3، ثم سوف احتياطية كل شيء: ليس فقط القواعد في الإنتاج، ولكن أيضا التدريج. هذا لا يناسبنا.

في وصف المعلمات لـ Spilo، وهو غلاف Docker الأساسي لـ PgSQL عند استخدام عامل التشغيل، اتضح أنه يمكنك تمرير معلمة WAL_S3_BUCKET فارغة، وبالتالي تعطيل النسخ الاحتياطية. وعلاوة على ذلك، لفرح عظيم، وجدت علاقات عامة جاهزة، والذي قبلناه على الفور في شوكتنا. الآن أصبح من السهل الإضافة enableWALArchiving: false إلى مورد كتلة PostgreSQL.

نعم، كان من الممكن القيام بذلك بشكل مختلف عن طريق تشغيل عاملين: أحدهما للتدريج (بدون نسخ احتياطية)، والثاني للإنتاج. لكننا تمكنا من تدبر الأمر بواحدة.

حسنًا، لقد تعلمنا كيفية نقل الوصول إلى S3 إلى قواعد البيانات وبدأت النسخ الاحتياطية في الوصول إلى وحدة التخزين. كيفية جعل صفحات النسخ الاحتياطي تعمل في واجهة مستخدم المشغل؟

نظرة عامة موجزة عن بيانات PostgreSQL الخاصة بـ Kubernetes ، وخياراتنا وخبراتنا

في واجهة مستخدم المشغل، ستحتاج إلى إضافة 3 متغيرات:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

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

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

لماذا هذا؟ على الرغم من أنه في الكود غير ضروري GRANTلا يتم تطبيقها دائمًا. هناك طريقتان: syncPreparedDatabases и syncDatabases. في syncPreparedDatabases - على الرغم من وجوده في القسم preparedDatabases غير هناك شرط defaultRoles и defaultUsers لإنشاء الأدوار، لا يتم تطبيق الحقوق الافتراضية. نحن بصدد إعداد تصحيح بحيث يتم تطبيق هذه الحقوق تلقائيًا.

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

ماذا حدث؟

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

قائمة المستفيدين الرئيسيين المقبولين في الشوكة:

سيكون أمرًا رائعًا أن يدعم المجتمع هذه العلاقات العامة حتى يتمكنوا من الوصول إلى الإصدار التالي من المشغل (1.6).

علاوة! قصة نجاح هجرة الإنتاج

إذا كنت تستخدم Patroni، فيمكن ترحيل الإنتاج المباشر إلى المشغل بأقل وقت توقف.

يتيح لك Spilo إنشاء مجموعات احتياطية من خلال تخزين S3 باستخدام وول إيعندما يتم تخزين سجل PgSQL الثنائي لأول مرة في S3 ثم يتم ضخه بواسطة النسخة المتماثلة. ولكن ماذا لو كان لديك لا المستخدمة من قبل Wal-E في البنية التحتية القديمة؟ الحل لهذه المشكلة موجود بالفعل تم اقتراحه على المحور.

يأتي النسخ المتماثل المنطقي لـ PostgreSQL للإنقاذ. لكننا لن نخوض في تفاصيل كيفية إنشاء المنشورات والاشتراكات، لأن ... خطتنا فشلت.

الحقيقة هي أن قاعدة البيانات تحتوي على العديد من الجداول المحملة بملايين الصفوف، والتي، علاوة على ذلك، يتم تجديدها وحذفها باستمرار. اشتراك بسيط с copy_data، عندما تنسخ النسخة المتماثلة الجديدة كل المحتوى من النسخة الرئيسية، فإنها لا تستطيع مواكبة النسخة الرئيسية. نجح نسخ المحتوى لمدة أسبوع، لكنه لم يلحق بالسيد أبدًا. وفي النهاية ساعد في حل المشكلة مقالة زملاء من Avito: يمكنك نقل البيانات باستخدام pg_dump. سأصف نسختنا (المعدلة قليلاً) من هذه الخوارزمية.

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

ستستخدم الأوامر اللاحقة التي تصف عملية الترحيل الترميز التالي للمضيفين:

  1. رئيسي — الخادم المصدر؛
  2. نسخة طبق الأصل1 - بث نسخة طبق الأصل من الإنتاج القديم؛
  3. نسخة طبق الأصل2 - نسخة منطقية جديدة.

خطة الهجرة

1. قم بإنشاء اشتراك في كافة الجداول الموجودة في المخطط على المعالج public قاعدة dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. قم بإنشاء فتحة النسخ المتماثل على الشريحة الرئيسية:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. إيقاف النسخ المتماثل على النسخة المتماثلة القديمة:

psql -h replica1 -c "select pg_wal_replay_pause();"

4. الحصول على رقم المعاملة من السيد:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. تفريغ من النسخة المتماثلة القديمة. وسنقوم بذلك في عدة مواضيع مما سيساعد في تسريع العملية:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. قم بتحميل التفريغ إلى الخادم الجديد:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. بعد تنزيل التفريغ، يمكنك بدء النسخ المتماثل على النسخة المتماثلة المتدفقة:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. قم بإنشاء اشتراك على نسخة متماثلة منطقية جديدة:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. احصل على oid الاشتراكات:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. لنفترض أنه تم استلامه oid=1000. لنطبق رقم المعاملة على الاشتراك:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10. لنبدأ بالتكرار:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. التحقق من حالة الاشتراك، يجب أن يعمل النسخ المتماثل:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. بعد بدء النسخ المتماثل ومزامنة قواعد البيانات، يمكنك التبديل.

13. بعد تعطيل النسخ المتماثل، تحتاج إلى إصلاح التسلسل. هذا موصوف بشكل جيد في المقال على wiki.postgresql.org.

وبفضل هذه الخطة، تمت عملية التحول بأقل قدر من التأخير.

اختتام

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

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

PS

اقرأ أيضًا على مدونتنا:

المصدر: www.habr.com

إضافة تعليق