38. النسخ الاحتياطي والاستعادة في PostgreSQL¶
هناك طرق كثيرة لإجراء النسخ الاحتياطي لقاعدة بيانات PostgreSQL، وتعتمد الطريقة التي تختارها إلى حد كبير على طريقة استخدامك لقاعدة البيانات.
بالنسبة لقواعد البيانات الثابتة نسبيًا، يمكن استخدام الأداتين الأساسيتين pg_dump/pg_restore لأخذ لقطات دورية من البيانات.
أما البيانات التي تتغير كثيرًا، فإن استخدام نظام "النسخ الاحتياطي المباشر" (online backup) يتيح أرشفة التحديثات باستمرار إلى موقع آمن.
النسخ الاحتياطي المباشر هو أساس أنظمة النسخ المتماثل (replication) والأنظمة الاحتياطية لتحقيق التوافر العالي، ولا سيما في إصدارات PostgreSQL >= 9.0.
38.1. تنظيم بياناتك¶
كما ناقشنا في مخططات PostgreSQL، يُعدّ ضمان تخزين بيانات الإنتاج دائمًا في مخططات (schemas) منفصلة من أفضل الممارسات المهمة جدًا في إدارة البيانات. وهناك سببان لذلك:
النسخ الاحتياطي للبيانات واستعادتها في المخططات أبسط بكثير من إدارة قوائم من الجداول يجب نسخها احتياطيًا كلًّا على حدة.
إبقاء جداول البيانات خارج المخطط "public" يجعل الترقيات أسهل بكثير، كما نناقش في ترقية البرمجيات.
38.2. النسخ الاحتياطي والاستعادة الأساسيان¶
النسخ الاحتياطي لقاعدة بيانات كاملة سهل باستخدام الأداة pg_dump . وهي أداة سطر أوامر، مما يسهّل أتمتتها بالسكربتات، ويمكن أيضًا استدعاؤها عبر الواجهة الرسومية في أداة PgAdmin.
لإجراء نسخة احتياطية لقاعدة البيانات nyc، يمكننا استخدام الواجهة الرسومية، فقط انقر بزر الفأرة الأيمن على قاعدة البيانات التي تريد نسخها احتياطيًا:
أدخل اسم ملف النسخة الاحتياطية الذي تريد إنشاءه.
لاحظ أن هناك ثلاثة خيارات لتنسيق النسخة الاحتياطية: compress و tar و plain.
التنسيق Plain مجرد ملف SQL نصي. وهو أبسط التنسيقات وأكثرها مرونة من نواحٍ عديدة، إذ يمكن تحريره أو تعديله بسهولة ثم تحميله مجددًا إلى قاعدة بيانات، مما يتيح إجراء تغييرات دون اتصال على أمور مثل الملكية أو غيرها من المعلومات العامة.
التنسيق Tar يستخدم تنسيق أرشيف UNIX لحفظ مكونات النسخة في ملفات منفصلة. ويتيح استخدام تنسيق tar للأداة pg_restore استعادة أجزاء من النسخة بشكل انتقائي.
التنسيق Compress يشبه تنسيق Tar، لكنه يضغط المكونات الداخلية كلًّا على حدة، مما يتيح استعادتها انتقائيًا دون فك ضغط الأرشيف بأكمله.
سنختار الخيار Compress ونبدأ، فنحفظ ملف النسخة الاحتياطية.
يمكن تنفيذ العملية نفسها من سطر الأوامر هكذا:
pg_dump --file=nyc.backup --format=c --port=54321 --username=postgres nyc
بما أن ملف النسخة الاحتياطية بتنسيق Compress، يمكننا عرض محتوياته باستخدام الأمر pg_restore لسرد قائمة المحتويات (manifest). وفي الواجهة الرسومية PgAdmin، يتوفر الخيار "View" في اللوحة.
عند النظر إلى قائمة المحتويات، قد تلاحظ وجود الكثير من تواقيع "FUNCTION" فيها.
وذلك لأن الأداة pg_dump تفرّغ كل كائن غير تابع للنظام في قاعدة البيانات، ويشمل ذلك تعريفات دوال PostGIS.
ملاحظة
يتضمن PostgreSQL 9.1+ ميزة "EXTENSION" التي تتيح تثبيت الحزم الإضافية مثل PostGIS كمكونات نظام مسجّلة، وبالتالي استبعادها من مُخرجات pg_dump . ويدعم PostGIS 2.0 وما بعده التثبيت باستخدام نظام الامتدادات هذا.
يمكننا رؤية قائمة المحتويات نفسها من سطر الأوامر باستخدام pg_restore مباشرة:
pg_restore --list nyc.backup
المشكلة في ملف تفريغ مليء بتواقيع دوال PostGIS أننا أردنا في الواقع تفريغ بياناتنا، لا دوال النظام.
بما أن كل كائن موجود في ملف التفريغ، يمكننا الاستعادة إلى قاعدة بيانات فارغة والحصول على الوظائف كاملة. لكننا بذلك نفترض أن النظام الذي نستعيد إليه يحتوي على الإصدار نفسه تمامًا من PostGIS الذي فرّغنا منه (لأن تعريفات تواقيع الدوال تشير إلى إصدار معيّن من مكتبة PostGIS المشتركة).
من سطر الأوامر تبدو الاستعادة هكذا:
createdb --port 54321 nyc2
pg_restore --dbname=nyc2 --port 54321 --username=postgres nyc.backup
عند تفريغ البيانات فقط، دون تواقيع الدوال، تظهر فائدة وضع البيانات في مخططات، لأن هناك خيارًا في سطر الأوامر لتفريغ مخطط معيّن فقط:
pg_dump --port=54321 -format=c --schema=census --file=census.backup
والآن عند سرد محتويات التفريغ، نرى فقط جداول البيانات التي أردناها:
pg_restore --list census.backup
;
; Archive created at Thu Aug 9 11:02:49 2012
; dbname: nyc
; TOC Entries: 11
; Compression: -1
; Dump Version: 1.11-0
; Format: CUSTOM
; Integer: 4 bytes
; Offset: 8 bytes
; Dumped from database version: 8.4.9
; Dumped by pg_dump version: 8.4.9
;
;
; Selected TOC Entries:
;
6; 2615 20091 SCHEMA - census postgres
146; 1259 19845 TABLE census nyc_census_blocks postgres
145; 1259 19843 SEQUENCE census nyc_census_blocks_gid_seq postgres
2691; 0 0 SEQUENCE OWNED BY census nyc_census_blocks_gid_seq postgres
2692; 0 0 SEQUENCE SET census nyc_census_blocks_gid_seq postgres
2681; 2604 19848 DEFAULT census gid postgres
2688; 0 19845 TABLE DATA census nyc_census_blocks postgres
2686; 2606 19853 CONSTRAINT census nyc_census_blocks_pkey postgres
2687; 1259 20078 INDEX census nyc_census_blocks_geom_gist postgres
وجود جداول البيانات فقط مفيد، لأنه يعني أنه يمكننا الاستعادة إلى قاعدة بيانات مثبّت عليها أي إصدار من PostGIS، كما نتحدث في ترقية البرمجيات.
38.2.1. النسخ الاحتياطي للمستخدمين¶
تعمل الأداة pg_dump على قاعدة بيانات واحدة في كل مرة (أو مخطط أو جدول واحد في كل مرة، إذا قيّدتها). لكن معلومات المستخدمين مخزّنة على مستوى العنقود (cluster) بأكمله، ولا تُخزَّن في أي قاعدة بيانات بعينها!
لإجراء نسخة احتياطية لمعلومات المستخدمين، استخدم الأداة pg_dumpall مع الخيار "--globals-only".
pg_dumpall --globals-only --port 54321
يمكنك أيضًا استخدام pg_dumpall في وضعها الافتراضي لإجراء نسخة احتياطية لعنقود كامل، لكن انتبه إلى أنك، كما مع pg_dump ، ستنسخ احتياطيًا تواقيع دوال PostGIS أيضًا، لذا يجب استعادة التفريغ على تثبيت برمجي مطابق، ولا يمكن استخدامه ضمن عملية ترقية.
38.3. النسخ الاحتياطي والاستعادة المباشران¶
يتيح النسخ الاحتياطي والاستعادة المباشران للمسؤول الاحتفاظ بمجموعة محدّثة جدًا من ملفات النسخ الاحتياطي دون عبء تفريغ قاعدة البيانات بأكملها مرارًا. وإذا كانت قاعدة البيانات تتعرض لأحمال إدراج وتحديث متكررة، فقد يكون النسخ الاحتياطي المباشر أفضل من النسخ الاحتياطي الأساسي.
ملاحظة
أفضل طريقة للتعرف على النسخ الاحتياطي المباشر هي قراءة الأقسام ذات الصلة من دليل PostgreSQL حول الأرشفة المستمرة والاستعادة إلى نقطة زمنية. أما هذا القسم من ورشة PostGIS فسيقدّم فقط لمحة موجزة عن إعداد النسخ الاحتياطي المباشر.
38.3.1. كيف يعمل¶
بدلًا من الكتابة المستمرة إلى جداول البيانات الرئيسية، يخزّن PostgreSQL التغييرات مبدئيًا في "سجلات الكتابة المسبقة" (WAL). وتشكّل هذه السجلات مجتمعةً سجلًا كاملًا لجميع التغييرات التي أُجريت على قاعدة البيانات. ويتمثل النسخ الاحتياطي المباشر في أخذ نسخة من جدول البيانات الرئيسي لقاعدة البيانات، ثم أخذ نسخة من كل ملف WAL يُولَّد بعد ذلك.
عندما يحين وقت الاستعادة إلى قاعدة بيانات جديدة، يبدأ النظام من نسخة البيانات الرئيسية، ثم يعيد تشغيل جميع ملفات WAL داخل قاعدة البيانات. والنتيجة النهائية قاعدة بيانات مستعادة في الحالة نفسها التي كانت عليها الأصلية وقت آخر ملف WAL مُستلَم.
بما أن ملفات WAL تُكتب على أي حال، وأن نقل نسخ منها إلى خادم أرشفة قليل الكلفة حسابيًا، فإن النسخ الاحتياطي المباشر وسيلة فعالة للاحتفاظ بنسخة احتياطية محدّثة جدًا من النظام دون اللجوء إلى عمليات تفريغ كاملة منتظمة ومكثفة.
38.3.2. أرشفة ملفات WAL¶
أول ما ينبغي فعله عند إعداد النسخ الاحتياطي المباشر هو إنشاء طريقة للأرشفة. وتتمتع طرق الأرشفة في PostgreSQL بأقصى درجات المرونة: إذ يستدعي خادم PostgreSQL ببساطة سكربتًا محددًا في معامل الإعداد archive_command.
وهذا يعني أن الأرشفة قد تكون بسيطة كنسخ الملف إلى محرك أقراص موصول عبر الشبكة، أو معقدة كتشفير الملفات وإرسالها بالبريد الإلكتروني إلى الأرشيف البعيد. ويمكنك استخدام أي عملية يمكنك كتابتها بسكربت لأرشفة الملفات.
لتفعيل الأرشفة سنحرّر الملف postgresql.conf، فنفعّل أولًا أرشفة WAL:
wal_level = archive
archive_mode = on
ثم نضبط archive_command لنسخ ملفات الأرشيف إلى موقع آمن (مع تغيير مسارات الوجهة حسب الحاجة):
# Unix
archive_command = 'test ! -f /archivedir/%f && cp %p /archivedir/%f'
# Windows
archive_command = 'copy "%p" "C:\\archivedir\\%f"'
من المهم ألا يكتب أمر الأرشفة فوق الملفات الموجودة، لذا يتضمن أمر unix اختبارًا أوليًا للتأكد من أن الملفات غير موجودة مسبقًا. ومن المهم أيضًا أن يُعيد الأمر حالة غير صفرية إذا فشلت عملية النسخ.
بعد إجراء التغييرات، يمكنك إعادة تشغيل PostgreSQL لتصبح سارية.
38.3.3. أخذ النسخة الاحتياطية الأساسية¶
بعد تجهيز عملية الأرشفة، عليك أخذ نسخة احتياطية أساسية.
ضع قاعدة البيانات في وضع النسخ الاحتياطي (لا يغيّر هذا شيئًا في تشغيل الاستعلامات أو تحديثات البيانات، بل يفرض فقط نقطة تفتيش (checkpoint) ويكتب ملف تسمية يبيّن وقت أخذ النسخة الاحتياطية).
SELECT pg_start_backup('/archivedir/basebackup.tgz');
من الممارسات الجيدة استخدام مسار ملف النسخة الاحتياطية كتسمية، لأنه يساعدك على تتبع مكان تخزين النسخة الاحتياطية.
انسخ قاعدة البيانات إلى موقع الأرشفة:
# Unix
tar cvfz /archivedir/basebackup.tgz ${PGDATA}
ثم أبلغ قاعدة البيانات بأن عملية النسخ الاحتياطي اكتملت.
SELECT pg_stop_backup();
يمكن بالطبع كتابة جميع هذه الخطوات في سكربت لإجراء نسخ احتياطية أساسية منتظمة.
38.3.4. الاستعادة من الأرشيف¶
هذه الخطوات مأخوذة من دليل PostgreSQL حول الأرشفة المستمرة والاستعادة إلى نقطة زمنية.
أوقف الخادم إذا كان قيد التشغيل.
إذا كانت لديك المساحة الكافية، فانسخ دليل بيانات العنقود بالكامل وأي مساحات جداول (tablespaces) إلى موقع مؤقت تحسبًا لاحتياجك إليها لاحقًا. لاحظ أن هذا الاحتياط يتطلب أن تتوفر على نظامك مساحة حرة كافية لحفظ نسختين من قاعدة بياناتك الحالية. وإذا لم تكن لديك مساحة كافية، فعليك على الأقل حفظ محتويات الدليل الفرعي pg_xlog للعنقود، لأنه قد يحتوي على سجلات لم تُؤرشف قبل توقف النظام.
احذف جميع الملفات والأدلة الفرعية الموجودة تحت دليل بيانات العنقود وتحت الأدلة الجذرية لأي مساحات جداول تستخدمها.
استعد ملفات قاعدة البيانات من النسخة الاحتياطية لنظام الملفات. تأكد من استعادتها بالملكية الصحيحة (مستخدم نظام قاعدة البيانات، وليس root!) وبالأذونات الصحيحة. وإذا كنت تستخدم مساحات جداول، فعليك التحقق من استعادة الروابط الرمزية في pg_tblspc/ بشكل صحيح.
احذف أي ملفات موجودة في pg_xlog/؛ فهذه جاءت من النسخة الاحتياطية لنظام الملفات، ولذلك فهي على الأرجح قديمة لا حالية. وإذا لم تكن قد أرشفت pg_xlog/ إطلاقًا، فأعد إنشاءه بالأذونات الصحيحة، مع الحرص على إعادته كرابط رمزي إذا كان مُعدًّا بهذه الطريقة من قبل.
إذا كانت لديك ملفات مقاطع WAL غير مؤرشفة حفظتها في الخطوة 2، فانسخها إلى pg_xlog/. (من الأفضل نسخها لا نقلها، حتى تبقى لديك الملفات دون تعديل إذا حدثت مشكلة واضطررت إلى البدء من جديد.)
أنشئ ملف أوامر الاستعادة recovery.conf في دليل بيانات العنقود (انظر الفصل 26). وقد ترغب أيضًا في تعديل pg_hba.conf مؤقتًا لمنع المستخدمين العاديين من الاتصال حتى تتأكد من نجاح الاستعادة.
شغّل الخادم. سيدخل الخادم في وضع الاستعادة ويبدأ بقراءة ملفات WAL المؤرشفة التي يحتاجها. وإذا توقفت الاستعادة بسبب خطأ خارجي، يمكن ببساطة إعادة تشغيل الخادم وسيواصل الاستعادة. وعند اكتمال عملية الاستعادة، سيعيد الخادم تسمية recovery.conf إلى recovery.done (لمنع الدخول في وضع الاستعادة مجددًا عن طريق الخطأ لاحقًا) ثم يبدأ عمليات قاعدة البيانات العادية.
افحص محتويات قاعدة البيانات للتأكد من أنك استعدتها إلى الحالة المطلوبة. وإن لم يكن كذلك، فارجع إلى الخطوة 1. وإذا كان كل شيء على ما يرام، فاسمح لمستخدميك بالاتصال بإعادة pg_hba.conf إلى وضعه الطبيعي.