การสำรองข้อมูล postgresql แบบเพิ่มหน่วยด้วย pgbackrest - หลักสูตรสำหรับนักสู้รุ่นเยาว์จากนักพัฒนา

ข้อจำกัดความรับผิดชอบ

ฉันเป็นนักพัฒนา ฉันเขียนโค้ดและโต้ตอบกับฐานข้อมูลในฐานะผู้ใช้เท่านั้น ฉันจะไม่แสร้งทำเป็นผู้ดูแลระบบ แต่อย่างใด แม้แต่ dba ก็ตาม แต่…

มันเกิดขึ้นจนฉันต้องจัดระเบียบการสำรองข้อมูลของฐานข้อมูล postgresql ไม่มีคลาวด์ - เพียงใช้ SSH และตรวจสอบให้แน่ใจว่าทุกอย่างทำงานได้โดยไม่ต้องขอเงิน เราจะทำอย่างไรในกรณีเช่นนี้? ถูกต้อง เราดัน pgdump เข้าไปใน cron สำรองข้อมูลทุกอย่างไปยังไฟล์เก็บถาวรทุกวัน และหากเราสูญหายโดยสิ้นเชิง เราจะส่งไฟล์เก็บถาวรนี้ไปที่ไหนสักแห่งที่ห่างไกล

คราวนี้ความยากคือตามแผน ฐานข้อมูลควรจะเติบโตประมาณ +- 100 MB ต่อวัน แน่นอนว่าหลังจากผ่านไปสองสามสัปดาห์ ความปรารถนาที่จะสำรองข้อมูลทุกอย่างด้วย pgdump จะหายไป นี่คือจุดที่การสำรองข้อมูลส่วนเพิ่มเข้ามาช่วยเหลือ

น่าสนใจ? ยินดีต้อนรับสู่แมว

การสำรองข้อมูลส่วนเพิ่มเป็นการสำรองข้อมูลประเภทหนึ่งเมื่อไม่ได้คัดลอกไฟล์ต้นฉบับทั้งหมด แต่จะมีเพียงไฟล์ใหม่และไฟล์ที่เปลี่ยนแปลงนับตั้งแต่สร้างสำเนาครั้งก่อน

เช่นเดียวกับนักพัฒนารายอื่นๆ ที่ไม่เต็มใจอย่างยิ่ง (ในขณะนั้น) ที่จะเข้าใจความซับซ้อนของ postgres ฉันต้องการค้นหาปุ่มสีเขียว คุณก็รู้ เช่นเดียวกับใน AWS, DigitalOcean: คุณกดปุ่มเดียว - คุณได้รับการจำลอง คุณกดที่สอง - คุณตั้งค่าการสำรองข้อมูล ปุ่มที่สาม - คุณย้อนทุกอย่างกลับไปสองสามชั่วโมง ฉันไม่พบปุ่มหรือเครื่องมือ GUI ที่สวยงาม หากคุณรู้จักสิ่งนั้น (ฟรีหรือถูก) เขียนเกี่ยวกับมันในความคิดเห็น

หลังจาก googling ฉันพบเครื่องมือสองอย่าง พีจีบาร์แมน и pgbackrest. ฉันไม่ประสบความสำเร็จกับอันแรก (เอกสารที่กระจัดกระจายมาก ฉันพยายามคิดทุกอย่างตามคู่มือเก่า) แต่ด้วยอันที่สองเอกสารก็พบว่ามีมาตรฐาน แต่ไม่มีข้อบกพร่อง บทความนี้จึงถูกเขียนขึ้นเพื่อให้การทำงานของผู้ที่ต้องเผชิญกับงานที่คล้ายกันง่ายขึ้น

หลังจากอ่านบทความนี้ คุณจะได้เรียนรู้วิธีการสำรองข้อมูลส่วนเพิ่ม บันทึกลงในเซิร์ฟเวอร์ระยะไกล (พื้นที่เก็บข้อมูลที่มีการสำรองข้อมูล) และกู้คืนในกรณีที่ข้อมูลสูญหายหรือปัญหาอื่น ๆ บนเซิร์ฟเวอร์หลัก

การอบรม

หากต้องการทำซ้ำคู่มือ คุณจะต้องมี VPS สองตัว อันแรกจะเป็นที่เก็บข้อมูล (พื้นที่เก็บข้อมูลที่จะจัดเก็บข้อมูลสำรอง) และอันที่สองในความเป็นจริงคือเซิร์ฟเวอร์ที่มี postgres (ในกรณีของฉันคือ postgres เวอร์ชัน 11)

สันนิษฐานว่าบนเซิร์ฟเวอร์ที่มี postgres คุณมีรูทผู้ใช้ sudo ผู้ใช้ postgres และ postgres เอง (ผู้ใช้ postgres จะถูกสร้างขึ้นโดยอัตโนมัติเมื่อติดตั้ง postgresql) และบนเซิร์ฟเวอร์ที่เก็บจะมีผู้ใช้รูทและ sudo (ในคู่มือ จะใช้ชื่อผู้ใช้ pgbackrest)

เพื่อให้คุณมีปัญหาน้อยลงเมื่อทำซ้ำคำแนะนำ ฉันจึงเขียนเป็นตัวเอียง ฉันรันคำสั่งกับผู้ใช้คนไหนและมีสิทธิ์อะไร ในขณะที่เขียนและตรวจสอบบทความ

การติดตั้ง pgbackrest

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

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 ต้องใช้ Perl ติดตั้ง:

sudo apt-get install perl

6. สร้างไดเร็กทอรีสำหรับบันทึกโดยให้สิทธิ์บางประการ:

sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /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 pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

7. ตรวจสอบ:

pgbackrest version

เซิร์ฟเวอร์ Postgres (ผู้ใช้ sudo หรือรูท):

กระบวนการติดตั้ง pgbackrest บนเซิร์ฟเวอร์ที่มี postgres นั้นคล้ายคลึงกับกระบวนการติดตั้งบนที่เก็บ (ใช่ ต้องติดตั้ง pgbackrest บนเซิร์ฟเวอร์ทั้งสอง) แต่ในย่อหน้าที่ 6 คำสั่งที่สองและสุดท้าย:

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

แทนที่ด้วย:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

การตั้งค่าการโต้ตอบระหว่างเซิร์ฟเวอร์ผ่าน SSH ที่ไม่มีรหัสผ่าน

เพื่อให้ pgbackrest ทำงานได้อย่างถูกต้อง จำเป็นต้องกำหนดค่าการโต้ตอบระหว่างเซิร์ฟเวอร์ postgres และที่เก็บโดยใช้ไฟล์คีย์

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

สร้างคู่คีย์:

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

คำเตือน! เรารันคำสั่งข้างต้นโดยไม่มี sudo

เซิร์ฟเวอร์ Postgres (ผู้ใช้ sudo หรือรูท):

สร้างคู่คีย์:

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

พื้นที่เก็บข้อมูล (ผู้ใช้ sudo):

คัดลอกคีย์สาธารณะของเซิร์ฟเวอร์ postgres ไปยังเซิร์ฟเวอร์ที่เก็บ:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<postgres_server_ip> cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

ในขั้นตอนนี้ คุณจะถูกถามรหัสผ่านสำหรับผู้ใช้รูท คุณต้องป้อนรหัสผ่านของผู้ใช้รูทของเซิร์ฟเวอร์ postgres!

เซิร์ฟเวอร์ Postgres (ผู้ใช้ sudo):

คัดลอกพับลิกคีย์ของที่เก็บไปยังเซิร์ฟเวอร์ด้วย postgres:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<repository_server_ip> cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

ในขั้นตอนนี้ คุณจะถูกถามรหัสผ่านสำหรับผู้ใช้รูท คุณต้องป้อนรหัสผ่านของผู้ใช้รูทของที่เก็บให้ตรงกันทุกประการ!

เราตรวจสอบ:

พื้นที่เก็บข้อมูล (ผู้ใช้รูท เพื่อความบริสุทธิ์ของการทดลอง):

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

เซิร์ฟเวอร์ Postgres (ผู้ใช้รูท เพื่อความบริสุทธิ์ของการทดสอบ):

sudo -u postgres ssh pgbackrest@<repository_server_ip>

เราตรวจสอบให้แน่ใจว่าเราสามารถเข้าถึงได้โดยไม่มีปัญหา

การตั้งค่าเซิร์ฟเวอร์ postgres

เซิร์ฟเวอร์ Postgres (ผู้ใช้ sudo หรือรูท):

1. อนุญาตให้ทำการเคาะเซิร์ฟเวอร์ postgres จาก IP ภายนอก เมื่อต้องการทำเช่นนี้ ให้แก้ไขไฟล์ postgresql.conf (อยู่ในโฟลเดอร์ /etc/postgresql/11/main) โดยเพิ่มบรรทัดลงไป:

listen_addresses = '*'

หากมีบรรทัดดังกล่าวอยู่แล้ว ให้ยกเลิกหมายเหตุหรือตั้งค่าพารามิเตอร์เป็น '*'

ในไฟล์ pg_hba.conf (อยู่ในโฟลเดอร์ด้วย /etc/postgresql/11/main) เพิ่มบรรทัดต่อไปนี้:

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

ที่ไหน:

hostssl/host - подключаемся через SSL (или нет)
all - разрешаем подключение ко всем базам
all - имя пользователя, которому разрешаем подключение (всем)
0.0.0.0/0 - маска сети с которой можно подключаться
md5 - способ шифрования пароля

2. มาทำการตั้งค่าที่จำเป็นกันเถอะ 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

3. มาทำการตั้งค่าที่จำเป็นในไฟล์การกำหนดค่า pgbackrest (/etc/pgbackrest/pgbackrest.conf):

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

[global]
log-level-file=detail
repo1-host=<repository_server_ip>

4. โหลด postgresql ใหม่:

sudo service postgresql restart

การตั้งค่าเซิร์ฟเวอร์ที่เก็บ

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

มาทำการตั้งค่าที่จำเป็นในไฟล์กำหนดค่ากัน pgbackrest
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=<postgres_server_ip>
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

การสร้างพื้นที่เก็บข้อมูล

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

สร้างที่เก็บข้อมูลใหม่สำหรับคลัสเตอร์ หลัก:

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

ตรวจสอบ

เซิร์ฟเวอร์ Postgres (ผู้ใช้ sudo หรือรูท):

เราตรวจสอบบนเซิร์ฟเวอร์ postgres:

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

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

เราตรวจสอบเซิร์ฟเวอร์ที่เก็บ:

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

เราตรวจสอบให้แน่ใจว่าในผลลัพธ์เราจะเห็นบรรทัด “ตรวจสอบคำสั่งสิ้นสุด: เสร็จสมบูรณ์แล้ว”

เหนื่อย? เรามาดูส่วนที่น่าสนใจที่สุดกันดีกว่า

กำลังทำการสำรองข้อมูล

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

1. ทำการสำรองข้อมูล:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. ตรวจสอบให้แน่ใจว่าได้สร้างการสำรองข้อมูลแล้ว:

ls /var/lib/pgbackrest/backup/main/

Pgbackrest จะสร้างการสำรองข้อมูลเต็มรูปแบบครั้งแรก หากต้องการ คุณสามารถรันคำสั่ง backup อีกครั้ง และตรวจสอบให้แน่ใจว่าระบบสร้างการสำรองข้อมูลส่วนเพิ่ม

หากคุณต้องการสำรองข้อมูลทั้งหมดอีกครั้ง ให้ระบุแฟล็กเพิ่มเติม:

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

หากคุณต้องการเอาต์พุตคอนโซลโดยละเอียด ให้ระบุด้วย:

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

การกู้คืนข้อมูลสำรอง

เซิร์ฟเวอร์ Postgres (ผู้ใช้ 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()"

ในความเป็นจริง คุณสามารถกู้คืนข้อมูลสำรองเฉพาะตามชื่อได้ ฉันอยู่ตรงนี้เท่านั้น ฉันจะให้ลิงก์ไปยังคำอธิบายของคุณลักษณะนี้ในเอกสารประกอบ. นักพัฒนาแนะนำให้ใช้ตัวเลือกนี้ด้วยความระมัดระวังและอธิบายเหตุผล ฉันสามารถเสริมจากตัวเองว่าฉันใช้มัน หากคุณต้องการจริงๆ ตรวจสอบให้แน่ใจว่าหลังจากการกู้คืนแล้ว ฐานข้อมูลจะออกจากโหมดการกู้คืน (เลือก pg_is_in_recovery() ควรแสดงเป็น “f”) และในกรณีดังกล่าว ให้ทำการสำรองข้อมูลทั้งหมดหลังการกู้คืน

3. เริ่มต้นคลัสเตอร์:

sudo pg_ctlcluster 11 main start

หลังจากกู้คืนข้อมูลสำรองแล้ว เราจำเป็นต้องทำการสำรองข้อมูลครั้งที่สอง:

พื้นที่เก็บข้อมูล (ผู้ใช้ pgbackrest):

sudo pgbackrest --stanza=main backup

นั่นคือทั้งหมดที่ โดยสรุป ฉันอยากจะเตือนคุณว่าฉันไม่ได้พยายามแสร้งทำเป็นผู้อาวุโส dba แต่อย่างใด และจะใช้คลาวด์ในโอกาสที่น้อยที่สุด ปัจจุบันผมเองกำลังเริ่มศึกษาหัวข้อต่างๆ เช่น การสำรองข้อมูล การจำลองแบบ การตรวจสอบ ฯลฯ และฉันเขียนรายงานเล็กๆ น้อยๆ เกี่ยวกับผลลัพธ์เพื่อช่วยเหลือชุมชนเล็กๆ น้อยๆ และทิ้งเอกสารสรุปเล็กๆ น้อยๆ ไว้สำหรับตัวฉันเอง

ในบทความต่อไปนี้ ฉันจะพยายามพูดถึงคุณสมบัติเพิ่มเติม - การกู้คืนข้อมูลไปยังคลัสเตอร์ที่ปลอดภัย การเข้ารหัสการสำรองข้อมูลและการเผยแพร่ไปยัง S3 การสำรองข้อมูลผ่าน rsync

ที่มา: will.com

เพิ่มความคิดเห็น