PostgreSQL - كيفية تشغيل VACUUM من التعليمات البرمجية خارج كتلة المعاملات؟

StackOverflow https://stackoverflow.com/questions/1017463

سؤال

أنا أستخدم Python مع psycopg2 وأحاول تشغيل النسخة الكاملة VACUUM بعد عملية يومية يتم فيها إدخال عدة آلاف من الصفوف.المشكلة هي أنه عندما أحاول تشغيل VACUUM الأمر داخل الكود الخاص بي أحصل على الخطأ التالي:

psycopg2.InternalError: VACUUM cannot run inside a transaction block

كيف يمكنني تشغيل هذا من الكود خارج كتلة المعاملة؟

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

class db(object):
    def __init__(dbname, host, port, user, password):
        self.conn = psycopg2.connect("dbname=%s host=%s port=%s \
                                      user=%s password=%s" \
                                      % (dbname, host, port, user, password))

        self.cursor = self.conn.cursor()

    def _doQuery(self, query):
        self.cursor.execute(query)
        self.conn.commit()

    def vacuum(self):
        query = "VACUUM FULL"
        self._doQuery(query)
هل كانت مفيدة؟

المحلول

وبعد مزيد من البحث اكتشفت الممتلكات isolation_level من كائن الاتصال psycopg2. اتضح أن تغيير هذا 0 سوف نقل لكم من كتلة المعاملة. تغيير طريقة فراغ الطبقة المذكورة أعلاه على ما يلي يحل. علما بأنني أيضا تعيين مستوى العزل إلى ما كان عليه سابقا فقط في حالة (ويبدو أن 1 افتراضيا).

def vacuum(self):
    old_isolation_level = self.conn.isolation_level
    self.conn.set_isolation_level(0)
    query = "VACUUM FULL"
    self._doQuery(query)
    self.conn.set_isolation_level(old_isolation_level)

هذه المقالة (قرب نهاية على تلك الصفحة) يقدم شرحا موجزا من العزلة المستويات في هذا السياق.

نصائح أخرى

وبالإضافة إلى ذلك، يمكنك أيضا الحصول على الرسائل المقدمة من فراغ أو تحليل باستخدام:

>> print conn.notices #conn is the connection object

وهذا الأمر طباعة قائمة مع رسالة سجل استفسارات مثل فراغ وتحليل:

INFO:  "usuario": processados 1 de 1 páginas, contendo 7 registros vigentes e 0 registros não vigentes; 7 registros amostrados, 7 registros totais estimados   
INFO:  analisando "public.usuario"

وهذا يمكن أن يكون مفيدا للدباس ^^

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

from django.db import connection
# Much of the proxy is not defined until this is done
force_proxy = connection.cursor()
realconn=connection.connection
old_isolation_level = realconn.isolation_level
realconn.set_isolation_level(0)
cursor = realconn.cursor()
cursor.execute('VACUUM ANALYZE')
realconn.set_isolation_level(old_isolation_level)

ومما يؤسف له أن وكيل اتصال التي تقدمها جانغو لا توفر الوصول إلى set_isolation_level.

ملاحظة إذا كنت تستخدم جانغو مع الجنوب لتنفيذ عملية ترحيل يمكنك استخدام التعليمات البرمجية التالية لتنفيذ VACUUM ANALYZE.

def forwards(self, orm):

    db.commit_transaction()
    db.execute("VACUUM ANALYZE <table>")

    #Optionally start another transaction to do some more work...
    db.start_transaction()

لا أعرف psycopg2 وPostgreSQL، لكن فقط apsw وSQLite، لذلك أعتقد أنني لا أستطيع تقديم مساعدة "psycopg2".

ولكن يبدو لي أن PostgreSQL قد يعمل بشكل مشابه لعمل SQLite، وله وضعان للتشغيل:

  • خارج كتلة المعاملة:وهذا يعادل لغويًا وجود كتلة معاملات حول كل عملية SQL واحدة
  • داخل كتلة المعاملة، التي تم وضع علامة عليها بـ "بدء المعاملة" وتنتهي بـ "إنهاء المعاملة"

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

بالطبع من الممكن أن يكون لـ "psycopg2" طريقة "الفراغ" الخاصة به، أو وضع التشغيل الخاص، حيث لا يتم بدء أي معاملات ضمنية.

عندما لا توجد مثل هذه الاحتمالات، يبقى هناك خيار واحد (بدون تغيير طبقة الوصول ;-) ):

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

لا تفعل ذلك - لا تحتاج فراغ كامل. في الواقع إذا قمت بتشغيل النسخة الأخيرة نوعا من بوستجرس (دعنا نقول> 8.1) لا تحتاج حتى لتشغيل فراغ عادي يدويا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top