النسخ الاحتياطية المتزايدة لـ PostgreSQL مع pgBackRest. الجزء 2. التشفير ، التمهيد إلى S3 ، الاستعادة إلى خادم جديد ، PITR

هذه المقالة هي استمرار لمقال "النسخ الاحتياطية المتزايدة Postgresql مع pgbackrest - مسار جندي شاب من المطور".



في الجزء الأول ، تعلمنا كيفية عمل نسخ احتياطية تزايدي ، وتحميلها على خادم بعيد (مستودع مع نسخ احتياطية) والعودة إلى آخر نسخة احتياطية.

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


لحظة



لا يتظاهر المؤلف بأنه DBA ، لكنه في بعض الأحيان يحب الإعداد ورؤية كل شيء بنفسه.



تدريب



لإعادة إنتاج هذا الدليل ، نحتاج إلى:



  1. خادم مع قاعدة بيانات (سنقوم بتثبيت pgbackrest عليه) ؛
  2. تخزين S3 (يمكنك استخدام Amazon أو أي جهاز متوافق مع S3 ، وسأستخدم Amazon S3) ؛
  3. الخادم الثالث. اختياري. على ذلك ، سنتدرب على نشر postgresql و pgbackrest من البداية ، ونشر نسخة احتياطية موجودة من تخزين S3 (تم حرق الخادم ، ونقله ، وما إلى ذلك) ؛


من المفترض أنك قمت بالفعل بتثبيت postgresql ، وبالتالي فإن مستخدم postgres موجود أيضًا.



لقد وصفت عملية التثبيت لـ pgbackrest في المقالة السابقة ، ولكن فقط في حالة تكرارها مرة أخرى (أذكرك: قبل التثبيت ، قم بإنشاء مستخدم sudo لنفسك - سأستخدم مستخدم sudo مع اسم مستخدم pgbackrest).



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



سنتبع هذا المسار:



تكوين postgresql و pgbackrest تكوين

تشفير النسخ الاحتياطية (سطرين)

تعلم النسخ الاحتياطي والإرسال إلى وحدة تخزين S3 (خمسة أسطر)

عمل نسخة احتياطية

دعنا نتخيل أننا كسرنا الكتلة ، ونشرنا على خادم جديد ، وقمنا بتوصيل مستودع S3 الحالي

وقمنا بلف النسخة الاحتياطية. عندما كانت العلامة لا تزال موجودة)



لنذهب!



تثبيت pgBackRest



مستخدم sudo أو الجذر:



1. قم بتنزيل الأرشيف من pgbackrest وانقل محتوياته إلى مجلد / build:



sudo mkdir /build
sudo wget -q -O - \
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | \
       sudo tar zx -C /build


2. قم بتثبيت التبعيات اللازمة للبناء:



sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev \
       libpq-dev


3. وضع pgbackrest معًا:



cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src


4. انسخ الملف القابل للتنفيذ إلى الدليل / usr / bin:



sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest


5.pgBackRest يتطلب بيرل. تثبيت:



sudo apt-get install perl


6. إنشاء أدلة للسجلات ، ومنحها حقوقًا معينة:



sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown postgres:postgres /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf


7. تحقق:



pgbackrest version


إعداد Postgresql و pgBackRest



مستخدم sudo أو الجذر:



1. قم بإجراء الإعدادات اللازمة في postgresql.conf (وهو موجود في المجلد / etc / postgresql / 11 / main) لكي يعمل pgBackRest:



archive_command = 'pgbackrest --stanza=main archive-push %p' #  main -  .   postgres    main.
archive_mode = on
max_wal_senders = 3
wal_level = replica


2. لنقم بإجراء الإعدادات اللازمة في ملف تكوين pgbackrest (/etc/pgbackrest/pgbackrest.conf):



[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-cipher-pass=tr5+BXdfdoxeyUqfo6AzLTrW+c+Jfd/1QbQj2CDMMBwtB0YGH3EJajry4+Eeen6D
repo1-cipher-type=aes-256-cbc
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # ,     . ..           ,      .    "     " -     .
repo1-type=s3
repo1-s3-bucket=pgbackrest-part2-tutorial
repo1-s3-endpoint=s3.us-east-1.amazonaws.com
repo1-s3-region=us-east-1
repo1-s3-key=9wdS3G8U5wz7kNsFWVGck7DDZ7DtVDtbM
repo1-s3-key-secret=A9zRmW16zXKt2vVA8mmNsFWy2mUAPYHa
start-fast=y

[global:archive-push]
compress-level=3


كما تعلم ، قمنا هنا على الفور بتكوين التشفير وتكوين الدعم للتخزين S3.



ملاحظة: لا ينبغي أن يكون هناك أي تعليقات في ملف التكوين.

ملاحظة لإنشاء مفتاح تشفير قوي ، يمكنك استخدام الأمر:



openssl rand -base64 48


إنشاء المستودع



مستخدم sudo أو الجذر:



sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R postgres /var/lib/pgbackrest/
sudo -u postgres pgbackrest --stanza=main stanza-create


إذا نجح كل شيء ، فسترى في دلو S3 الملفات التي أنشأها pgbackrest.



عمل نسخة احتياطية:



مستخدم sudo أو الجذر:



sudo -u postgres pgbackrest --log-level-console=info --stanza=main backup


سيقوم pgBackRest بإنشاء أول نسخة احتياطية كاملة. إذا كنت ترغب في ذلك ، يمكنك تشغيل أمر النسخ الاحتياطي مرة أخرى والتأكد من قيام النظام بإنشاء نسخة احتياطية تزايدي.



إذا كنت تريد عمل نسخة احتياطية كاملة مرة أخرى ، فحدد علامة إضافية:



sudo -u postgres pgbackrest --log-level-console=info --stanza=main --type=full backup


يمكنك عرض قائمة النسخ الاحتياطية باستخدام الأمر:



sudo -u postgres pgbackrest --stanza=main info




استعادة النسخة الاحتياطية:



مستخدم sudo أو الجذر:



1. أوقف تشغيل الكتلة:



sudo pg_ctlcluster 11 main stop


2. الاسترداد من نسخة احتياطية:



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore


لاستعادة قاعدة البيانات إلى حالة آخر نسخة احتياطية كاملة ، استخدم الأمر دون تحديد recovery_target:



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta restore


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



sudo -u postgres psql -c "select pg_wal_replay_resume()"


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



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate --target-action=promote --type=immediate restore


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



3. ابدأ المجموعة:



sudo pg_ctlcluster 11 main start


بعد استعادة النسخة الاحتياطية ، سنقوم بعمل نسخة احتياطية ثانية:

sudo -u postgres pgbackrest --log-level-console=info --stanza=main backup


استعادة النسخة الاحتياطية إلى مجموعة نظيفة:



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



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



sudo user or root:



1. أوقف الكتلة قيد التشغيل:



sudo pg_ctlcluster 11 main stop


2. الاسترداد من نسخة احتياطية:



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate  --target-action=promote --type=immediate restore


وصفت PS الفروق الدقيقة والخواص الدقيقة لهذا الأمر أعلاه. 



3. ابدأ المجموعة:



sudo pg_ctlcluster 11 main start


بعد استعادة النسخة الاحتياطية ، نحتاج إلى إجراء نسخة احتياطية ثانية:



sudo -u postgres pgbackrest --log-level-console=info --stanza=main backup


هذا ، في الواقع ، كل شيء. انطفأت النار.



نقطة في الوقت الاسترداد (PITR)



دعنا نتخيل مثل هذا الموقف حيث تم إنشاء نسخة احتياطية في الساعة 16:00 ، وفي الساعة 18:05 قمنا بمسح لوحة مهمة عن طريق الخطأ حيث تمكنت من الحصول على الكثير من البيانات المهمة التي لا نريد أن نفقدها في غضون ساعتين. يوفر لنا PgBackRest على حساب PostgreSQL مثل هذه الفرصة: يمكننا التراجع إلى نقطة زمنية محددة ، بشرط أن يكون لدينا معلومات كافية لاستردادها.



يعمل مثل هذا:



  1. نقول إننا نريد العودة إلى الساعة 18:04 ؛
  2. يبحث pgBackRest عن آخر نسخة احتياطية حالية (16:00) ؛
  3. يستعيدها ، ولكن ليس كل شيء يتدحرج ، ولكن فقط ما تمكنا من القيام به قبل 18.04 ؛


ملاحظة: هذه الآلية مبنية على سجلات WAL. يمكنك قراءتها هنا .



يمكنك إجراء الاسترداد إلى نقطة زمنية محددة (بعد إيقاف الكتلة) باستخدام هذا الأمر:



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --type=time "--target=2020-09-06 18:27:24.561458+02" --target-action=promote restore


ملاحظة مهمة - يمكن لـ PostgreSQL تشغيل سجلات WAL للأمام فقط وليس للخلف. ماذا يعني هذا في الممارسة العملية؟



لنفترض أنه تم إنشاء نسخة احتياطية في الساعة 16:00. في الساعة 18:05 ، قمنا بحذف الجدول عن طريق الخطأ ، وفي الساعة 18:10 ، تم إنشاء نسخة احتياطية مرة أخرى بالجدول المحذوف بالفعل. عندما تحاول إنشاء PITR ، ستأخذ pgBackRest النسخة الاحتياطية التي تم إنشاؤها في الساعة 16:00 وستقوم بتدوير كل ما كان قبل الساعة 18:05 ، ولن تأخذ النسخة الاحتياطية التي تم إنشاؤها في الساعة 18:10 وستسترجع كل شيء. هذا أمر مهم لتفهمه. يتم وصف هذه الآلية بمزيد من التفصيل هنا .



لنفترض أنك قمت بعمل نسخة احتياطية تحتوي بالفعل على معلومات حول حذف جدول. باستخدام علامة --set ، دعنا نقول أي نسخة احتياطية يجب استخدامها للقاعدة (تلك التي كان الجدول لا يزال فيها). سيأخذ pgBackRest هذه النسخة الاحتياطية ويمرر كل ما كان قبل حذف الجدول.



sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --type=time --set=20200905-183838F_20200906-182612I "--target=2020-09-06 18:27:24.561458+02" --target-action=promote restore


لقد عرضت أمر الحصول على قائمة بالنسخ الاحتياطية أعلاه.



لنبدأ الكتلة. بعد البدء ، دعونا نفحص الملف /var/log/postgresql/postgresql-11-main.log. في ذلك ، نحن مهتمون بالأسطر التالية ، التي توضح أن الاسترداد إلى النقطة الزمنية المحددة كان ناجحًا:



starting point-in-time recovery to 2020-09-07 11:26:52.493127+02
...
recovery stopping before commit of transaction 576, time 2020-09-07 11:27:14.584496+02
...
last completed transaction was at log time 2020-09-07 11:24:09.583761+02


هذا كل شئ. أنصحك بشدة بتجربة هذه الأداة قبل استخدامها في القتال.



All Articles