প্রোডাকশন ডাটাবেস ব্যাকআপ কৌশল যা আসলে কাজ করে: MySQL এবং PostgreSQL
উৎপাদনে MySQL এবং PostgreSQL এর জন্য প্রমাণিত ব্যাকআপ এবং পুনরুদ্ধারের কৌশল
উৎপাদন ডেটা হারানো এমন একটি ঘটনা যা ক্যারিয়ার শেষ করে, কোম্পানি বন্ধ করে দেয় এবং সব ভুল কারণে হ্যাকার নিউজের প্রথম পাতা তৈরি করে। তবুও বেশিরভাগ দল ডাটাবেস ব্যাকআপগুলিকে একটি চিন্তাভাবনা হিসাবে বিবেচনা করে — একটি ক্রোন জব যেটি কেউ দুই বছর আগে সেট করেছিল যেটি কেউ যাচাই করেনি। এই নিবন্ধটি MySQL এবং PostgreSQL-এর জন্য যুদ্ধ-পরীক্ষিত ব্যাকআপ কৌশলগুলি তৈরি করে যা একক-নোড k3s ক্লাস্টার থেকে মাল্টি-রিজিওন ক্লাউড ডিপ্লোয়মেন্ট পর্যন্ত উত্পাদন পরিবেশে প্রমাণিত হয়েছে যা প্রতিদিন লক্ষ লক্ষ লেনদেন প্রক্রিয়া করে।
আমরা সম্পূর্ণ স্পেকট্রাম কভার করব: যৌক্তিক এবং শারীরিক ব্যাকআপ পদ্ধতি, পয়েন্ট-ইন-টাইম পুনরুদ্ধার, স্বয়ংক্রিয় সময়সূচী, ক্লাউড স্টোরেজ লক্ষ্য, এনক্রিপশন, যাচাইকরণ, Kubernetes-নেটিভ পন্থা, এবং দুর্যোগ পুনরুদ্ধারের পরিকল্পনা যা এটিকে একত্রিত করে। প্রতিটি সুপারিশ কংক্রিট কনফিগারেশন এবং কোড সহ আসে যা আপনি আপনার পরিবেশের সাথে মানিয়ে নিতে পারেন।
ব্যাকআপের ধরন বোঝা
নির্দিষ্ট সরঞ্জামগুলিতে ডুব দেওয়ার আগে, আপনার চারটি মৌলিক ব্যাকআপ কৌশলগুলির একটি পরিষ্কার মানসিক মডেল এবং তারা কীভাবে পুনরুদ্ধারের উদ্দেশ্যগুলির সাথে যোগাযোগ করে তা প্রয়োজন। প্রতিটি কৌশল ব্যাকআপ গতি, স্টোরেজ খরচ এবং পুনরুদ্ধারের সময়ের মধ্যে আলাদা ট্রেড-অফ করে।
একটিসম্পূর্ণ ব্যাকআপসময়ে একক সময়ে সমগ্র ডাটাবেস ক্যাপচার করে। এটি সম্পর্কে যুক্তি দেওয়া সবচেয়ে সহজ এবং পুনরুদ্ধার করা দ্রুততম, তবে সঞ্চয়স্থানে সবচেয়ে ব্যয়বহুল এবং তৈরি করা সবচেয়ে ধীর। একটিক্রমবর্ধমান ব্যাকআপশুধুমাত্র সেই ডেটাই ক্যাপচার করে যা যেকোনো ধরনের শেষ ব্যাকআপের পর থেকে পরিবর্তিত হয়েছে। সঞ্চয়স্থানে এটি তৈরি করা এবং কমপ্যাক্ট করা দ্রুত, কিন্তু পুনরুদ্ধারের জন্য সম্পূর্ণ চেইনটি পুনরায় চালানোর প্রয়োজন: শেষ পূর্ণ ব্যাকআপ এবং পরবর্তী প্রতিটি বৃদ্ধি। একটিডিফারেনশিয়াল ব্যাকআপশেষ সম্পূর্ণ ব্যাকআপের পর থেকে পরিবর্তিত সমস্ত কিছু ক্যাপচার করে৷ এটি একটি মাঝামাঝি জায়গা দখল করে — একটি বৃদ্ধির চেয়ে বড় কিন্তু পুনরুদ্ধার করা সহজ কারণ আপনার শুধুমাত্র শেষ পূর্ণ এবং সর্বশেষ ডিফারেনশিয়াল প্রয়োজন। অবশেষে,ক্রমাগত আর্কাইভিং(PostgreSQL-এ WAL আর্কাইভিং, MySQL-এ বাইনারি লগ স্ট্রিমিং) প্রতিটি ব্যক্তিগত লেনদেনকে ক্যাপচার করে, ব্যাকআপগুলির মধ্যে যেকোনো মুহূর্তে পয়েন্ট-ইন-টাইম পুনরুদ্ধার সক্ষম করে৷
বেশিরভাগ উত্পাদন সিস্টেমের জন্য সর্বোত্তম কৌশল হল একটি সংমিশ্রণ: সাপ্তাহিক পূর্ণ ব্যাকআপ, দৈনিক বৃদ্ধি বা ডিফারেনশিয়াল, এবং অবিচ্ছিন্ন WAL/বিনলগ সংরক্ষণাগার। এটি আপনাকে সাম্প্রতিক পূর্ণ ব্যাকআপগুলি থেকে দ্রুত পুনরুদ্ধার এবং আপনার প্রয়োজনের সময় যে কোনও সময়ে পুনরুদ্ধার করার ক্ষমতা উভয়ই দেয়৷
MySQL ব্যাকআপ পদ্ধতি
MySQL বেশ কয়েকটি ব্যাকআপ টুল অফার করে, প্রতিটি বিভিন্ন ডাটাবেসের আকার এবং পুনরুদ্ধারের প্রয়োজনীয়তার জন্য উপযুক্ত। সঠিক পছন্দ আপনার ডেটা ভলিউম, গ্রহণযোগ্য ব্যাকআপ উইন্ডো এবং RTO/RPO লক্ষ্যগুলির উপর নির্ভর করে।
mysqldump — ইউনিভার্সাল লজিক্যাল ব্যাকআপ
mysqldumpSQL বিবৃতি তৈরি করে যা স্কিমা এবং ডেটা পুনরায় তৈরি করে। এটি প্রতিটি MySQL সংস্করণ এবং স্টোরেজ ইঞ্জিনে কাজ করে, এটিকে সর্বজনীন ফলব্যাক করে তোলে। যাইহোক, এটি ডাম্পের সময় টেবিল লক করে (InnoDB এর সাথে--single-transactionব্যবহার না করলে), এবং পুনরুদ্ধারের গতি 50-100 GB এর বেশি ডাটাবেসের জন্য উল্লেখযোগ্যভাবে হ্রাস পায় কারণ এটি পৃথক INSERT বিবৃতিগুলি পুনরায় প্লে করে।
# Full logical backup with consistent snapshot for InnoDB
mysqldump --single-transaction --routines --triggers --events \
--set-gtid-purged=ON --all-databases \
| gzip > /backups/mysql-full-$(date +%Y%m%d-%H%M%S).sql.gz
# Single database backup with compression
mysqldump --single-transaction --routines --triggers \
--databases production_db \
| pigz -p4 > /backups/production_db-$(date +%Y%m%d).sql.gz
# Schema-only backup for migration planning
mysqldump --no-data --routines --triggers --events \
--all-databases > /backups/schema-only-$(date +%Y%m%d).sqlmysqlpump — সমান্তরাল লজিক্যাল ব্যাকআপ
mysqlpumpসমান্তরাল টেবিল ডাম্পিং এবং বিল্ট-ইন কম্প্রেশন সহmysqldump-এ উন্নতি করে। এটি অনেকগুলি স্বাধীন টেবিলের সাথে ডেটাবেসের জন্য ব্যাকআপ সময়কে উল্লেখযোগ্যভাবে কমাতে পারে।
# Parallel logical backup with 4 threads and zstd compression
mysqlpump --default-parallelism=4 --compress-output=ZSTD \
--include-databases=production_db,analytics_db \
--set-gtid-purged=ON \
> /backups/mysql-pump-$(date +%Y%m%d).sql.zstPercona XtraBackup — InnoDB
এর জন্য শারীরিক ব্যাকআপ50 GB-এর থেকে বড় ডেটাবেসের জন্য, যৌক্তিক ব্যাকআপগুলি অব্যবহারিক হয়ে ওঠে — ব্যাকআপ উইন্ডো এবং পুনরুদ্ধারের সময় উভয়ই ডেটা আকারের সাথে রৈখিকভাবে বৃদ্ধি পায়। Percona XtraBackup ডাটাবেস লক না করে InnoDB ডেটা ফাইলের ফিজিক্যাল-লেভেল কপি নেয়, এটি মাল্টি-টেরাবাইট স্থাপনার জন্য উপযুক্ত করে তোলে।
# Full physical backup with streaming to compressed archive
xtrabackup --backup --target-dir=/backups/full-$(date +%Y%m%d) \
--user=backup_user --password=secure_pass \
--parallel=4 --compress --compress-threads=4
# Incremental backup based on last full
xtrabackup --backup --target-dir=/backups/incr-$(date +%Y%m%d) \
--incremental-basedir=/backups/full-20260412 \
--user=backup_user --password=secure_pass \
--parallel=4
# Stream full backup directly to S3 via xbstream
xtrabackup --backup --stream=xbstream --compress \
--user=backup_user --password=secure_pass | \
aws s3 cp - s3://db-backups/mysql/full-$(date +%Y%m%d).xbstream
# Prepare for restore (apply redo log)
xtrabackup --prepare --target-dir=/backups/full-20260412
# Prepare incremental on top of full
xtrabackup --prepare --apply-log-only --target-dir=/backups/full-20260412
xtrabackup --prepare --target-dir=/backups/full-20260412 \
--incremental-dir=/backups/incr-20260412
# Restore
systemctl stop mysqld
xtrabackup --copy-back --target-dir=/backups/full-20260412
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqldMySQL বাইনারি লগ — পয়েন্ট-ইন-টাইম রিকভারি
MySQL বাইনারি লগ প্রতিটি ডেটা-সংশোধনকারী বিবৃতি বা সারি পরিবর্তন রেকর্ড করে। একটি সম্পূর্ণ বা শারীরিক ব্যাকআপের সাথে মিলিত হলে, তারা ব্যাকআপ নেওয়ার পরে যেকোনো মুহূর্তে পয়েন্ট-ইন-টাইম পুনরুদ্ধার সক্ষম করে।
# Enable binary logging in my.cnf
[mysqld]
server-id = 1
log-bin = /var/log/mysql/mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800 # 7 days
sync_binlog = 1
gtid_mode = ON
enforce_gtid_consistency = ON
# Flush and archive binary logs
mysqladmin flush-logs
mysqlbinlog --read-from-remote-server --host=db-primary \
--raw --stop-never --result-file=/backup/binlogs/ \
mysql-bin.000042
# Point-in-time recovery: replay binlog up to specific timestamp
mysqlbinlog --stop-datetime="2026-04-12 14:30:00" \
/backup/binlogs/mysql-bin.000042 \
/backup/binlogs/mysql-bin.000043 | mysql -u rootPostgreSQL ব্যাকআপ পদ্ধতি
PostgreSQL-এর ব্যাকআপ ইকোসিস্টেম MySQL-এর চেয়ে তর্কযোগ্যভাবে সমৃদ্ধ, প্রথম পক্ষের সরঞ্জাম এবং বৃহৎ-স্কেল উত্পাদন পরিবেশের জন্য নির্মিত সম্প্রদায় সমাধানগুলির একটি পরিপক্ক সেট সহ।
pg_dump এবং pg_dumpall — লজিক্যাল ব্যাকআপ
mysqldumpএর মত,pg_dumpলজিক্যাল ব্যাকআপ তৈরি করে। কাস্টম ফরম্যাট (-Fc) প্রস্তাবিত ডিফল্ট কারণ এটি সমান্তরাল পুনরুদ্ধার, নির্বাচনী টেবিল পুনরুদ্ধার এবং অন্তর্নির্মিত সংকোচন সমর্থন করে।
# Custom format with parallel dump (4 worker jobs)
pg_dump -Fc -j4 -f /backups/production-$(date +%Y%m%d).dump production_db
# Directory format for maximum parallelism on large databases
pg_dump -Fd -j8 -f /backups/production-$(date +%Y%m%d)/ production_db
# All databases including globals (roles, tablespaces)
pg_dumpall > /backups/pg-all-$(date +%Y%m%d).sql
# Parallel restore from custom format
pg_restore -j4 -d production_db_restored /backups/production-20260412.dump
# Selective restore: single table
pg_restore -j4 -d production_db -t orders /backups/production-20260412.dumppg_basebackup — শারীরিক ব্যাকআপ ফাউন্ডেশন
pg_basebackupসম্পূর্ণ PostgreSQL ডেটা ডিরেক্টরির একটি ফিজিক্যাল কপি নেয়। এটি স্বতন্ত্র পুনরুদ্ধার এবং স্ট্রিমিং প্রতিলিপি সেটআপ উভয়ের জন্য ভিত্তি। WAL সংরক্ষণাগারের সাথে মিলিত, এটি পয়েন্ট-ইন-টাইম পুনরুদ্ধার সক্ষম করে।
# Physical backup with WAL files included
pg_basebackup -D /backups/base-$(date +%Y%m%d) \
-Ft -z -Xs -P -c fast \
-U replication_user -h db-primary
# Stream backup directly to a tar archive with checksums
pg_basebackup -D - -Ft -Xs -c fast \
-U replication_user -h db-primary | \
gzip > /backups/pg-base-$(date +%Y%m%d).tar.gzpgBackRest — এন্টারপ্রাইজ-গ্রেড ব্যাকআপ ম্যানেজমেন্ট
pgBackRest হল PostgreSQL ব্যাকআপ পরিচালনার জন্য সোনার মান। এটি সম্পূর্ণ, ক্রমবর্ধমান এবং ডিফারেনশিয়াল ব্যাকআপ, সমান্তরাল ব্যাকআপ এবং পুনরুদ্ধার, এনক্রিপশন, মাল্টি-রিপোজিটরি টার্গেট (স্থানীয় ডিস্ক, S3, GCS, Azure ব্লব), এবং স্বয়ংক্রিয় WAL সংরক্ষণাগার সমর্থন করে — সমস্ত একটি একক, সমন্বিত কনফিগারেশনের মাধ্যমে।
# /etc/pgbackrest/pgbackrest.conf
[global]
repo1-type=s3
repo1-s3-bucket=pg-backups-production
repo1-s3-endpoint=s3.eu-west-1.amazonaws.com
repo1-s3-region=eu-west-1
repo1-s3-key=AKIAIOSFODNN7EXAMPLE
repo1-s3-key-secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
repo1-path=/pgbackrest
repo1-retention-full=4
repo1-retention-diff=14
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=a_very_secure_encryption_passphrase
# Second repository for geographic redundancy
repo2-type=azure
repo2-azure-container=pg-backups-dr
repo2-azure-account=prodbackupstorage
repo2-azure-key=base64encodedkeyhere
repo2-path=/pgbackrest
repo2-retention-full=2
process-max=4
compress-type=zst
compress-level=6
log-level-console=info
log-level-file=detail
start-fast=y
[production]
pg1-path=/var/lib/postgresql/16/main
pg1-port=5432
# PostgreSQL WAL archive configuration (postgresql.conf)
# archive_mode = on
# archive_command = 'pgbackrest --stanza=production archive-push %p'
# Create the stanza
pgbackrest --stanza=production stanza-create
# Verify the stanza configuration
pgbackrest --stanza=production check
# Full backup
pgbackrest --stanza=production --type=full backup
# Differential backup
pgbackrest --stanza=production --type=diff backup
# Incremental backup
pgbackrest --stanza=production --type=incr backup
# List backups
pgbackrest --stanza=production infoWAL-G — ক্লাউড স্টোরেজ
-এ লাইটওয়েট ওয়াল সংরক্ষণাগারWAL-G হল pgBackRest এর একটি সহজ বিকল্প যা ক্লাউড অবজেক্ট স্টোরেজে WAL সেগমেন্ট এবং বেস ব্যাকআপ স্ট্রিমিং এর উপর ফোকাস করে। এটি কনটেইনারাইজড পরিবেশে জনপ্রিয় যেখানে আপনি ন্যূনতম কনফিগারেশন সহ একটি একক বাইনারি চান।
# Environment variables for WAL-G with S3
export WALG_S3_PREFIX=s3://pg-wal-archive/production
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_REGION=eu-west-1
export WALG_COMPRESSION_METHOD=lz4
export PGHOST=/var/run/postgresql
# Configure WAL archiving in postgresql.conf
# archive_mode = on
# archive_command = 'wal-g wal-push %p'
# restore_command = 'wal-g wal-fetch %f %p'
# Take a base backup
wal-g backup-push /var/lib/postgresql/16/main
# List backups
wal-g backup-list
# Restore from latest backup
wal-g backup-fetch /var/lib/postgresql/16/main LATEST
# Delete old backups (retain last 4)
wal-g delete retain FULL 4 --confirmবর্মন — কেন্দ্রীভূত ব্যাকআপ সার্ভার
বর্মন (ব্যাকআপ এবং রিকভারি ম্যানেজার) এমন পরিবেশের জন্য ডিজাইন করা হয়েছে যেখানে একটি ডেডিকেটেড ব্যাকআপ সার্ভার একাধিক PostgreSQL দৃষ্টান্তের জন্য ব্যাকআপ পরিচালনা করে। এটি ব্যাকআপ পরিবহনের জন্য rsync/SSH এবং স্ট্রিমিং রেপ্লিকেশন প্রোটোকল উভয় সমর্থন করে।
# /etc/barman.d/production.conf
[production]
description = "Production PostgreSQL 16"
ssh_command = ssh postgres@db-primary
conninfo = host=db-primary user=barman dbname=postgres
streaming_conninfo = host=db-primary user=streaming_barman
backup_method = postgres
streaming_archiver = on
slot_name = barman
retention_policy = RECOVERY WINDOW OF 14 DAYS
# Create replication slot and start streaming
barman receive-wal --create-slot production
barman switch-wal --force --archive production
# Take a backup
barman backup production
# List backups
barman list-backup production
# Restore to point in time
barman recover --target-time "2026-04-12 14:30:00" \
production 20260412T120000 /var/lib/postgresql/16/mainপয়েন্ট-ইন-টাইম রিকভারি (PITR)
পয়েন্ট-ইন-টাইম পুনরুদ্ধার হল আপনার ব্যাকআপ টুলকিটের সবচেয়ে গুরুত্বপূর্ণ ক্ষমতা। এটি আপনাকে একটি ডাটাবেসকে সঠিক অবস্থায় পুনরুদ্ধার করতে দেয় যে কোন নির্দিষ্ট মুহুর্তে এটি ছিল - শুধুমাত্র যখন ব্যাকআপ নেওয়া হয়েছিল তখন নয়, ব্যাকআপগুলির মধ্যে যেকোনো সেকেন্ড। দুর্ঘটনাজনিত ডেটা মুছে ফেলা, অ্যাপ্লিকেশন বাগগুলি যা ডেটা নষ্ট করে এবং নিরাপত্তার ঘটনাগুলি থেকে পুনরুদ্ধার করার জন্য এটি গুরুত্বপূর্ণ যেখানে আপনাকে সমঝোতার সঠিক মুহূর্তটি সনাক্ত করতে হবে।
PostgreSQLএর জন্যPITR
PostgreSQL PITR একটি বেস ব্যাকআপ পুনরুদ্ধার করে এবং টার্গেট টাইমস্ট্যাম্প পর্যন্ত WAL সেগমেন্ট রিপ্লে করে কাজ করে। pgBackRest এর সাথে, পুরো প্রক্রিয়াটি একটি একক কমান্ড।
# Restore to specific point in time with pgBackRest
pgbackrest --stanza=production \
--type=time --target="2026-04-12 16:42:30" \
--target-action=promote \
restore
# Manual PITR using pg_basebackup + WAL archive
# 1. Stop PostgreSQL
systemctl stop postgresql
# 2. Clear the data directory and restore base backup
rm -rf /var/lib/postgresql/16/main/*
tar xzf /backups/pg-base-20260412.tar.gz -C /var/lib/postgresql/16/main/
# 3. Create recovery signal and configure restore
cat > /var/lib/postgresql/16/main/postgresql.auto.conf << 'CONF'
restore_command = 'cp /backup/wal_archive/%f %p'
recovery_target_time = '2026-04-12 16:42:30'
recovery_target_action = 'promote'
CONF
touch /var/lib/postgresql/16/main/recovery.signal
# 4. Start PostgreSQL — it will replay WAL and stop at target
systemctl start postgresqlMySQLএর জন্যPITR
MySQL PITR বাইনারি লগ রিপ্লে সহ একটি XtraBackup ফিজিক্যাল রিস্টোরকে একত্রিত করে।
# 1. Restore the XtraBackup
systemctl stop mysqld
rm -rf /var/lib/mysql/*
xtrabackup --prepare --target-dir=/backups/full-20260412
xtrabackup --copy-back --target-dir=/backups/full-20260412
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
# 2. Identify the binlog position from XtraBackup metadata
cat /backups/full-20260412/xtrabackup_binlog_info
# Output: mysql-bin.000042 154 3E11FA47-1111-1111-1111-AAAAAAAAAAAA:1-1234
# 3. Replay binlogs up to target time
mysqlbinlog --start-position=154 \
--stop-datetime="2026-04-12 16:42:30" \
/backup/binlogs/mysql-bin.000042 \
/backup/binlogs/mysql-bin.000043 | mysql -u rootমাল্টি-ক্লাউড ব্যাকআপ আর্কিটেকচার
কোনো একক ক্লাউড প্রদানকারী বা অঞ্চলের ব্যর্থতার জন্যউত্পাদন ব্যাকআপ কৌশলগুলি অবশ্যই দায়ী। আপনার প্রোডাকশন ডাটাবেসের মতো একই ক্লাউড অ্যাকাউন্ট এবং অঞ্চলে একচেটিয়াভাবে ব্যাকআপগুলি সঞ্চয় করার অর্থ হল একটি একক অ্যাকাউন্ট আপস, বিলিং সমস্যা বা আঞ্চলিক বিভ্রাট আপনার ডেটা এবং আপনার ব্যাকআপগুলি একই সাথে নিয়ে যেতে পারে। একটি শক্তিশালী আর্কিটেকচার ক্রস-অঞ্চল প্রতিলিপি সহ কমপক্ষে দুটি স্বাধীন স্টোরেজ লক্ষ্যে ব্যাকআপ পাঠায়।
লাইফসাইকেল নীতির সাথেক্লাউড স্টোরেজ কনফিগারেশন
# AWS S3 lifecycle policy (Terraform)
resource "aws_s3_bucket_lifecycle_configuration" "backup_lifecycle" {
bucket = aws_s3_bucket.db_backups.id
rule {
id = "backup-tiering"
status = "Enabled"
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
transition {
days = 365
storage_class = "DEEP_ARCHIVE"
}
expiration {
days = 2555 # 7 years for compliance
}
}
rule {
id = "wal-segments"
status = "Enabled"
filter {
prefix = "wal-archive/"
}
expiration {
days = 30
}
}
}
# Enable cross-region replication
resource "aws_s3_bucket_replication_configuration" "backup_replication" {
bucket = aws_s3_bucket.db_backups.id
role = aws_iam_role.replication.arn
rule {
id = "cross-region-dr"
status = "Enabled"
destination {
bucket = aws_s3_bucket.db_backups_dr.arn
storage_class = "STANDARD_IA"
encryption_configuration {
replica_kms_key_id = aws_kms_key.dr_key.arn
}
}
source_selection_criteria {
sse_kms_encrypted_objects {
status = "Enabled"
}
}
}
}# Azure Blob immutability policy (Azure CLI)
az storage container immutability-policy create \
--account-name prodbackupstorage \
--container-name pg-backups \
--period 365 \
--allow-protected-append-writes true
# GCS lifecycle with nearline transition
gsutil lifecycle set /dev/stdin gs://pg-backups-production << 'JSON'
{
"rule": [
{"action": {"type": "SetStorageClass", "storageClass": "NEARLINE"}, "condition": {"age": 30}},
{"action": {"type": "SetStorageClass", "storageClass": "COLDLINE"}, "condition": {"age": 90}},
{"action": {"type": "Delete"}, "condition": {"age": 2555}}
]
}
JSONব্যাকআপ এনক্রিপশন এবং নিরাপত্তা
ব্যাকআপ আক্রমণকারীদের জন্য একটি উচ্চ-মূল্যের লক্ষ্য। একটি চুরি করা আনএনক্রিপ্ট করা ব্যাকআপ আক্রমণকারীকে আপনার চলমান সিস্টেমগুলি লঙ্ঘন করার প্রয়োজন ছাড়াই আপনার উত্পাদন ডেটার একটি সম্পূর্ণ অনুলিপি দেয়৷ প্রতিটি ব্যাকআপ, ট্রানজিট এবং বিশ্রামে, এনক্রিপ্ট করা আবশ্যক।
ট্রানজিটে এনক্রিপশনমানে ডাটাবেস সার্ভার এবং ব্যাকআপ গন্তব্যের মধ্যে সমস্ত সংযোগের জন্য TLS ব্যবহার করা৷ TLS-এর সাথে কনফিগার করা হলে এনক্রিপ্ট করা চ্যানেলের উপর pgBackRest এবং XtraBackup উভয়ই স্ট্রিম। S3, Azure Blob, বা GCS-এ শিপিং করার সময়, ক্লায়েন্ট SDKগুলি ডিফল্টরূপে HTTPS ব্যবহার করে৷
এনক্রিপশন বাকিএর দুটি স্তর রয়েছে৷ সার্ভার-সাইড এনক্রিপশন (SSE) স্টোরেজ টার্গেটে পৌঁছানোর পরে ডেটা এনক্রিপ্ট করে — S3 SSE-KMS, Azure স্টোরেজ সার্ভিস এনক্রিপশন, বা GCS ডিফল্ট এনক্রিপশন। ক্লায়েন্ট-সাইড এনক্রিপশন ডেটাবেস সার্ভার ছেড়ে যাওয়ার আগে ডেটা এনক্রিপ্ট করে, ক্লাউড প্রদানকারী কখনই প্লেইনটেক্সট ডেটা দেখতে না পায় তা নিশ্চিত করে। pgBackRest এবং WAL-G উভয়ই স্থানীয়ভাবে ক্লায়েন্ট-সাইড এনক্রিপশন সমর্থন করে।
# pgBackRest client-side encryption config
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=long_random_passphrase_stored_in_vault
# WAL-G client-side encryption
export WALG_LIBSODIUM_KEY=$(cat /etc/wal-g/encryption.key)
# Or GPG-based
export WALG_GPG_KEY_ID=backup@example.com
# MySQL XtraBackup with encryption
xtrabackup --backup --encrypt=AES256 \
--encrypt-key-file=/etc/mysql/backup-encryption.key \
--target-dir=/backups/full-encrypted-$(date +%Y%m%d)ব্যাকআপ থেকে আলাদাভাবে এনক্রিপশন কী স্টোর করে। HashiCorp ভল্ট, AWS সিক্রেটস ম্যানেজার, বা Azure কী ভল্টের মতো একটি গোপন ব্যবস্থাপক হল প্রস্তাবিত পদ্ধতি। আপনি যদি ব্যাকআপের সাথে চাবিটি সংরক্ষণ করেন, তাহলে একজন আক্রমণকারী যে আপনার ব্যাকআপ সঞ্চয়স্থানে অ্যাক্সেস লাভ করে তার কাছে তাদের প্রয়োজনীয় সবকিছু থাকে।
স্বয়ংক্রিয় ব্যাকআপ শিডিউলিং
ম্যানুয়াল ব্যাকআপগুলি ব্যাকআপ নয় - সেগুলি উচ্চাকাঙ্ক্ষা৷ ব্যাকআপ সময়সূচী অবশ্যই স্বয়ংক্রিয়, নিরীক্ষণ এবং ব্যর্থতার বিষয়ে সতর্কতামূলক হতে হবে।
বেয়ার মেটাল এবং VMsএর জন্যসিস্টেম ক্রন# /etc/cron.d/database-backups
# PostgreSQL — pgBackRest
# Full backup every Sunday at 01:00
0 1 * * 0 postgres pgbackrest --stanza=production --type=full backup 2>&1 | logger -t pgbackrest-full
# Differential backup every day at 01:00 (except Sunday)
0 1 * * 1-6 postgres pgbackrest --stanza=production --type=diff backup 2>&1 | logger -t pgbackrest-diff
# MySQL — XtraBackup
# Full backup every Sunday at 02:00
0 2 * * 0 root /usr/local/bin/mysql-backup.sh full 2>&1 | logger -t xtrabackup-full
# Incremental backup every day at 02:00 (except Sunday)
0 2 * * 1-6 root /usr/local/bin/mysql-backup.sh incremental 2>&1 | logger -t xtrabackup-incr
# Backup verification — restore test every Wednesday at 04:00
0 4 * * 3 root /usr/local/bin/verify-backup.sh 2>&1 | logger -t backup-verify
Kubernetes ক্রোনজবস
# /etc/cron.d/database-backups
# PostgreSQL — pgBackRest
# Full backup every Sunday at 01:00
0 1 * * 0 postgres pgbackrest --stanza=production --type=full backup 2>&1 | logger -t pgbackrest-full
# Differential backup every day at 01:00 (except Sunday)
0 1 * * 1-6 postgres pgbackrest --stanza=production --type=diff backup 2>&1 | logger -t pgbackrest-diff
# MySQL — XtraBackup
# Full backup every Sunday at 02:00
0 2 * * 0 root /usr/local/bin/mysql-backup.sh full 2>&1 | logger -t xtrabackup-full
# Incremental backup every day at 02:00 (except Sunday)
0 2 * * 1-6 root /usr/local/bin/mysql-backup.sh incremental 2>&1 | logger -t xtrabackup-incr
# Backup verification — restore test every Wednesday at 04:00
0 4 * * 3 root /usr/local/bin/verify-backup.sh 2>&1 | logger -t backup-verifyKubernetes পরিবেশে, CronJobs সিস্টেম ক্রন প্রতিস্থাপন করে। তারা বিল্ট-ইন রিট্রাই লজিক, কনকারেন্সি কন্ট্রোল এবং ক্লাস্টারের RBAC এবং সিক্রেট ম্যানেজমেন্টের সাথে ইন্টিগ্রেশন অফার করে।
apiVersion: batch/v1
kind: CronJob
metadata:
name: pg-backup-full
namespace: database
spec:
schedule: "0 1 * * 0" # Sunday 01:00 UTC
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 4
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 7200 # 2 hour timeout
template:
spec:
serviceAccountName: db-backup
restartPolicy: OnFailure
containers:
- name: pgbackrest
image: pgbackrest/pgbackrest:2.50
command:
- /bin/bash
- -c
- |
pgbackrest --stanza=production --type=full backup
RESULT=$?
if [ $RESULT -eq 0 ]; then
curl -s -X POST "$SLACK_WEBHOOK" \
-d '{"text":"PostgreSQL full backup completed successfully"}'
else
curl -s -X POST "$SLACK_WEBHOOK" \
-d '{"text":"ALERT: PostgreSQL full backup FAILED"}'
fi
exit $RESULT
envFrom:
- secretRef:
name: pgbackrest-credentials
- secretRef:
name: slack-webhook
resources:
requests:
memory: 512Mi
cpu: 500m
limits:
memory: 2Gi
cpu: "2"
volumeMounts:
- name: pgbackrest-config
mountPath: /etc/pgbackrest
volumes:
- name: pgbackrest-config
configMap:
name: pgbackrest-conf
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: pg-backup-diff
namespace: database
spec:
schedule: "0 1 * * 1-6" # Mon-Sat 01:00 UTC
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 7
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 3600
template:
spec:
serviceAccountName: db-backup
restartPolicy: OnFailure
containers:
- name: pgbackrest
image: pgbackrest/pgbackrest:2.50
command:
- /bin/bash
- -c
- |
pgbackrest --stanza=production --type=diff backup
envFrom:
- secretRef:
name: pgbackrest-credentials
resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 1Gi
cpu: "1"
volumeMounts:
- name: pgbackrest-config
mountPath: /etc/pgbackrest
volumes:
- name: pgbackrest-config
configMap:
name: pgbackrest-conf
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-backup-full
namespace: database
spec:
schedule: "0 2 * * 0"
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 7200
template:
spec:
serviceAccountName: db-backup
restartPolicy: OnFailure
containers:
- name: xtrabackup
image: percona/percona-xtrabackup:8.0
command:
- /bin/bash
- -c
- |
xtrabackup --backup --stream=xbstream --compress \
--user=$MYSQL_BACKUP_USER \
--password=$MYSQL_BACKUP_PASS \
--host=mysql-primary.database.svc | \
aws s3 cp - s3://$S3_BUCKET/mysql/full-$(date +%Y%m%d).xbstream
envFrom:
- secretRef:
name: mysql-backup-credentials
- secretRef:
name: aws-credentials
resources:
requests:
memory: 512Mi
cpu: 500m
limits:
memory: 2Gi
cpu: "2"Kubernetes-নেটিভ ব্যাকআপ অ্যাপ্রোচ
৷ Kubernetes-এচলমান ডাটাবেসগুলি ব্যাকআপ কৌশলের একটি নতুন মাত্রা প্রবর্তন করে৷ অ্যাপ্লিকেশন-স্তরের ডাটাবেস ব্যাকআপগুলি ছাড়াও, আপনাকে ক্লাস্টার-লেভেল ব্যাকআপ (ইত্যাদি), ক্রমাগত ভলিউম স্ন্যাপশট এবং অপারেটর-পরিচালিত ব্যাকআপগুলি বিবেচনা করতে হবে।
ক্লাস্টার-লেভেল ব্যাকআপএর জন্যভেলেরো
Velero Kubernetes রিসোর্স (ডিপ্লয়মেন্ট, সার্ভিস, কনফিগম্যাপ, সিক্রেটস) এবং ক্রমাগত ভলিউম ব্যাক আপ করে। এটি অ্যাপ্লিকেশন-স্তরের ডাটাবেস ব্যাকআপের প্রতিস্থাপন নয় — এটি PV-এর ক্র্যাশ-সামঞ্জস্যপূর্ণ স্ন্যাপশট ক্যাপচার করে, যা ডাটাবেসের জন্য লেনদেনগতভাবে সামঞ্জস্যপূর্ণ নাও হতে পারে। ডাটাবেস পুনরুদ্ধারের জন্য ক্লাস্টার পুনরুদ্ধার এবং অ্যাপ্লিকেশন-স্তরের সরঞ্জামগুলির (pgBackRest, XtraBackup) জন্য Velero ব্যবহার করুন।
# Install Velero with S3 backend
velero install \
--provider aws \
--bucket velero-backups \
--secret-file ./credentials-velero \
--backup-location-config region=eu-west-1 \
--snapshot-location-config region=eu-west-1 \
--use-volume-snapshots=true \
--plugins velero/velero-plugin-for-aws:v1.9.0
# Create a scheduled backup of the database namespace
velero schedule create db-namespace-backup \
--schedule="0 3 * * *" \
--include-namespaces database \
--ttl 720h \
--storage-location default \
--volume-snapshot-locations default
# On-demand backup before maintenance
velero backup create pre-maintenance-$(date +%Y%m%d) \
--include-namespaces database,monitoring \
--wait
# Restore a namespace from backup
velero restore create --from-backup pre-maintenance-20260412 \
--include-namespaces databasek3s-এলংহর্ন স্ন্যাপশট
k3s স্থাপনাগুলি সাধারণত লংহর্নকে তাদের CSI স্টোরেজ প্রদানকারী হিসাবে ব্যবহার করে। লংহর্ন ভলিউম-স্তরের স্ন্যাপশট এবং S3-সামঞ্জস্যপূর্ণ অবজেক্ট স্টোরেজে স্ন্যাপশট প্রতিলিপি করার ক্ষমতা প্রদান করে। ডেটাবেসের জন্য, গভীরভাবে প্রতিরক্ষার জন্য অ্যাপ্লিকেশন-স্তরের ব্যাকআপগুলির সাথে লংহর্ন স্ন্যাপশটগুলিকে একত্রিত করুন৷
# Longhorn recurring snapshot job via CRD
apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
name: pg-data-snapshot
namespace: longhorn-system
spec:
cron: "0 */4 * * *" # every 4 hours
task: snapshot
retain: 6
concurrency: 1
groups:
- pg-data
labels:
app: postgresql
---
# Longhorn recurring backup to S3
apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
name: pg-data-s3-backup
namespace: longhorn-system
spec:
cron: "0 2 * * *" # daily at 02:00
task: backup
retain: 14
concurrency: 1
groups:
- pg-data
labels:
app: postgresql
---
# VolumeSnapshot using Longhorn CSI
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: pg-data-snap-$(date +%Y%m%d)
namespace: database
spec:
volumeSnapshotClassName: longhorn-snapshot-vsc
source:
persistentVolumeClaimName: pg-data-postgresql-0অপারেটর-পরিচালিত ব্যাকআপগুলি
৷ডাটাবেস অপারেটর যেমন CloudNativePG (PostgreSQL-এর জন্য) এবং Percona অপারেটর (MySQL-এর জন্য) ডাটাবেস লাইফসাইকেলে সরাসরি ব্যাকআপ ব্যবস্থাপনাকে একীভূত করে। অপারেটর কাস্টম সংস্থানগুলির মাধ্যমে স্বয়ংক্রিয়ভাবে সময়সূচী, WAL সংরক্ষণাগার এবং ধারণ পরিচালনা করে।
# CloudNativePG cluster with integrated backup
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: production-pg
namespace: database
spec:
instances: 3
storage:
size: 100Gi
storageClass: longhorn
backup:
barmanObjectStore:
destinationPath: s3://pg-backups/cnpg/
endpointURL: https://s3.eu-west-1.amazonaws.com
s3Credentials:
accessKeyId:
name: aws-creds
key: ACCESS_KEY_ID
secretAccessKey:
name: aws-creds
key: SECRET_ACCESS_KEY
wal:
compression: gzip
maxParallel: 4
data:
compression: gzip
retentionPolicy: "30d"
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: production-pg-weekly
namespace: database
spec:
schedule: "0 1 * * 0"
backupOwnerReference: self
cluster:
name: production-pgক্লাউড প্রদানকারী-নির্দিষ্ট কৌশল
AWS — RDS এবং অরোরা
AWS RDS কনফিগারযোগ্য ধারণ (35 দিন পর্যন্ত) সহ স্বয়ংক্রিয় দৈনিক স্ন্যাপশট প্রদান করে এবং পয়েন্ট-ইন-টাইম পুনরুদ্ধারের জন্য লেনদেন লগ সংরক্ষণাগারের মাধ্যমে ক্রমাগত ব্যাকআপ প্রদান করে। অরোরা ব্যাকট্র্যাক যোগ করে, যা পুনরুদ্ধারের প্রয়োজন ছাড়াই ব্যাকট্র্যাক উইন্ডোর মধ্যে যে কোনও পয়েন্টে ক্লাস্টারটিকে রিওয়াইন্ড করতে পারে — এটি কেবল ডাটাবেসের অভ্যন্তরীণ অবস্থাকে বিপরীত করে।
# Enable automated backups with maximum retention (Terraform)
resource "aws_db_instance" "production" {
identifier = "production-pg"
engine = "postgres"
engine_version = "16.2"
instance_class = "db.r6g.xlarge"
allocated_storage = 500
backup_retention_period = 35 # maximum
backup_window = "03:00-04:00"
copy_tags_to_snapshot = true
deletion_protection = true
storage_encrypted = true
kms_key_id = aws_kms_key.rds.arn
# Enable PITR
enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"]
}
# Cross-region automated backup replication
resource "aws_db_instance_automated_backups_replication" "dr" {
source_db_instance_arn = aws_db_instance.production.arn
kms_key_id = aws_kms_key.dr_rds.arn
retention_period = 14
}
# Aurora Backtrack (MySQL-compatible Aurora only)
resource "aws_rds_cluster" "aurora_production" {
cluster_identifier = "aurora-production"
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.05.2"
backtrack_window = 86400 # 24 hours of backtrack
backup_retention_period = 35
preferred_backup_window = "03:00-04:00"
storage_encrypted = true
}
# Manual snapshot with cross-region copy
aws rds create-db-snapshot \
--db-instance-identifier production-pg \
--db-snapshot-identifier pre-migration-$(date +%Y%m%d)
aws rds copy-db-snapshot \
--source-db-snapshot-identifier arn:aws:rds:eu-west-1:123456789:snapshot:pre-migration-20260412 \
--target-db-snapshot-identifier pre-migration-20260412-dr \
--source-region eu-west-1 \
--region us-east-1 \
--kms-key-id arn:aws:kms:us-east-1:123456789:key/dr-key-idAzure — নমনীয় সার্ভার
PostgreSQL এবং MySQL নমনীয় সার্ভারের জন্যAzure ডেটাবেস স্থানীয়ভাবে অপ্রয়োজনীয় বা জিও-অপ্রয়োজনীয় স্টোরেজ সহ স্বয়ংক্রিয় ব্যাকআপ অন্তর্ভুক্ত করে। ভূ-অপ্রয়োজনীয় ব্যাকআপ দুর্যোগ পুনরুদ্ধারের জন্য ক্রস-অঞ্চল পুনরুদ্ধারের অনুমতি দেয়।
# Azure Flexible Server with geo-redundant backup (Terraform)
resource "azurerm_postgresql_flexible_server" "production" {
name = "production-pg"
location = "westeurope"
resource_group_name = azurerm_resource_group.db.name
sku_name = "GP_Standard_D4s_v3"
version = "16"
storage_mb = 524288 # 512 GB
backup_retention_days = 35
geo_redundant_backup_enabled = true
authentication {
active_directory_auth_enabled = true
password_auth_enabled = false
}
}
# Azure Blob immutability for self-managed backups
resource "azurerm_storage_management_policy" "backup_lifecycle" {
storage_account_id = azurerm_storage_account.backups.id
rule {
name = "backup-tiering"
enabled = true
filters {
blob_types = ["blockBlob"]
prefix_match = ["pg-backups/"]
}
actions {
base_blob {
tier_to_cool_after_days_since_modification_greater_than = 30
tier_to_archive_after_days_since_modification_greater_than = 90
delete_after_days_since_modification_greater_than = 2555
}
}
}
}GCP — ক্লাউড SQL
ক্লাউড SQL বাক্সের বাইরে স্বয়ংক্রিয় ব্যাকআপ এবং পয়েন্ট-ইন-টাইম পুনরুদ্ধার প্রদান করে। GCE বা GKE-তে স্ব-পরিচালিত ডাটাবেসের জন্য, নিয়ারলাইন এবং কোল্ডলাইন স্টোরেজ ক্লাস সহ GCS খরচ-কার্যকর দীর্ঘমেয়াদী ব্যাকআপ স্টোরেজ প্রদান করে।
# Cloud SQL with automated backups and PITR (Terraform)
resource "google_sql_database_instance" "production" {
name = "production-pg"
database_version = "POSTGRES_16"
region = "europe-west1"
settings {
tier = "db-custom-4-16384"
backup_configuration {
enabled = true
start_time = "03:00"
point_in_time_recovery_enabled = true
transaction_log_retention_days = 7
backup_retention_settings {
retained_backups = 30
retention_unit = "COUNT"
}
}
ip_configuration {
ssl_mode = "ENCRYPTED_ONLY"
}
}
}
# Export to GCS for long-term retention
gcloud sql export sql production-pg \
gs://pg-backups-longterm/export-$(date +%Y%m%d).sql.gz \
--database=production_db \
--offloadব্যাকআপ যাচাইকরণ এবং পুনরুদ্ধার পরীক্ষা
একটি ব্যাকআপ যা কখনও পরীক্ষা করা হয়নি তা ব্যাকআপ নয় - এটি একটি আশা৷ স্বয়ংক্রিয় পুনরুদ্ধার পরীক্ষা একটি নিয়মিত সময়সূচীতে চালানো উচিত, আদর্শভাবে সাপ্তাহিক, একটি বিচ্ছিন্ন পরিবেশে। পরীক্ষাটি অবশ্যই যাচাই করতে হবে যে পুনরুদ্ধার ত্রুটি ছাড়াই সম্পূর্ণ হয়, তবে পুনরুদ্ধার করা ডেটা সামঞ্জস্যপূর্ণ এবং অ্যাপ্লিকেশনটি এটিকে সংযুক্ত করতে এবং জিজ্ঞাসা করতে পারে।
#!/bin/bash
# verify-backup.sh — Automated backup verification script
set -euo pipefail
RESTORE_DIR="/tmp/backup-verify-$(date +%Y%m%d-%H%M%S)"
LOG_FILE="/var/log/backup-verify.log"
SLACK_WEBHOOK="${SLACK_WEBHOOK_URL}"
DB_TYPE="${1:-postgresql}" # postgresql or mysql
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }
alert() {
log "ALERT: $*"
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"text\":\"BACKUP VERIFY FAILED: $*\"}"
}
cleanup() {
log "Cleaning up $RESTORE_DIR"
rm -rf "$RESTORE_DIR"
if [ "$DB_TYPE" = "postgresql" ]; then
pg_ctlcluster 16 verify stop 2>/dev/null || true
else
mysqladmin -S /tmp/mysql-verify.sock shutdown 2>/dev/null || true
fi
}
trap cleanup EXIT
mkdir -p "$RESTORE_DIR"
if [ "$DB_TYPE" = "postgresql" ]; then
log "Starting PostgreSQL backup verification"
# Restore latest pgBackRest backup to temporary directory
pgbackrest --stanza=production \
--pg1-path="$RESTORE_DIR/pgdata" \
--type=immediate \
--target-action=promote \
restore 2>&1 | tee -a "$LOG_FILE"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
alert "pgBackRest restore failed"
exit 1
fi
# Start PostgreSQL on a different port
pg_ctlcluster 16 verify start -- \
-D "$RESTORE_DIR/pgdata" \
-o "-p 5433" \
-o "-c listen_addresses=127.0.0.1"
sleep 5
# Verify data integrity
TABLES=$(psql -p 5433 -d production_db -t -c \
"SELECT count(*) FROM information_schema.tables WHERE table_schema='public';")
log "Verified $TABLES tables exist"
ROW_CHECK=$(psql -p 5433 -d production_db -t -c \
"SELECT count(*) FROM orders WHERE created_at > now() - interval '7 days';")
log "Recent orders count: $ROW_CHECK"
if [ "$ROW_CHECK" -lt 1 ]; then
alert "PostgreSQL restore has no recent data — possible stale backup"
exit 1
fi
# Run pg_amcheck for corruption detection (PostgreSQL 14+)
pg_amcheck -p 5433 -d production_db --heapallindexed 2>&1 | tee -a "$LOG_FILE"
log "PostgreSQL backup verification PASSED"
else
log "Starting MySQL backup verification"
# Prepare and restore latest XtraBackup
LATEST_FULL=$(ls -td /backups/full-* | head -1)
cp -r "$LATEST_FULL" "$RESTORE_DIR/mysql-data"
xtrabackup --prepare --target-dir="$RESTORE_DIR/mysql-data"
# Start MySQL on a different socket and port
mysqld --datadir="$RESTORE_DIR/mysql-data" \
--socket=/tmp/mysql-verify.sock \
--port=3307 \
--skip-networking=0 \
--bind-address=127.0.0.1 &
sleep 10
# Verify data
TABLES=$(mysql -S /tmp/mysql-verify.sock -e \
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='production_db';" -sN)
log "Verified $TABLES tables exist"
mysqlcheck -S /tmp/mysql-verify.sock --all-databases --check 2>&1 | tee -a "$LOG_FILE"
log "MySQL backup verification PASSED"
fi
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"text\":\"Backup verification PASSED for $DB_TYPE at $(date)\"}"
log "Verification complete"দুর্যোগ পুনরুদ্ধার পরিকল্পনা: RTO এবং RPO
প্রতিটি ব্যাকআপ কৌশল দুটি মেট্রিক্সের আশেপাশে ডিজাইন করা আবশ্যক:রিকভারি টাইম অবজেক্টিভ (RTO)— আপনি কতক্ষণ ডাউন থাকতে পারবেন — এবংরিকভারি পয়েন্ট অবজেক্টিভ (RPO)— আপনি কতটা ডেটা হারাতে পারবেন৷ এই সংখ্যাগুলি ব্যাকআপ ফ্রিকোয়েন্সি, পদ্ধতি এবং আর্কিটেকচার সম্পর্কে প্রতিটি সিদ্ধান্তকে চালিত করে।
| দৃশ্যকল্প | RTO | RPO | কৌশল |
|---|---|---|---|
| ই-কমার্স চেকআউট | < 5 মিনিট | 0 (শূন্য ডেটা ক্ষতি) | সিঙ্ক্রোনাস প্রতিলিপি + অবিচ্ছিন্ন WAL সংরক্ষণাগার + হট স্ট্যান্ডবাই ফেইলওভার |
| SaaS অ্যাপ্লিকেশন | < 30 মিনিট | < 1 মিনিট | স্ট্রিমিং প্রতিলিপি + WAL-G ক্রমাগত সংরক্ষণাগার + স্বয়ংক্রিয় ব্যর্থতা |
| অভ্যন্তরীণ সরঞ্জাম | < 4 ঘন্টা | < 1 ঘন্টা | দৈনিক ডিফারেনশিয়াল + ঘন্টায় ক্রমবর্ধমান + WAL সংরক্ষণাগার |
| বিশ্লেষণ / ডেটা গুদাম | < 24 ঘন্টা | < 24 ঘন্টা | ক্লাউড স্টোরেজ |
| দেব / স্টেজিং | < 48 ঘন্টা | < 1 সপ্তাহ | সাপ্তাহিক পূর্ণ ব্যাকআপ |
শূন্য RPO-এর জন্য, আপনার অন্তত একটি স্ট্যান্ডবাইতে সিঙ্ক্রোনাস প্রতিলিপি প্রয়োজন। এটি প্রতিটি লেখার লেনদেনে বিলম্ব যোগ করে কিন্তু কোনো প্রতিশ্রুতিবদ্ধ লেনদেন হারিয়ে না যাওয়ার গ্যারান্টি দেয়। বেশিরভাগ উত্পাদন সিস্টেম অবিচ্ছিন্ন WAL/বিনলগ সংরক্ষণাগারের সাথে অ্যাসিঙ্ক্রোনাস স্ট্রিমিং প্রতিলিপি ব্যবহার করে কাছাকাছি-শূন্য RPO (সম্ভাব্য ক্ষতির সেকেন্ড) গ্রহণ করে, যা লিখতে-বিলম্বিত শাস্তি এড়ায়।
দুর্যোগ পুনরুদ্ধার রানবুক টেমপ্লেট
# DR Runbook: Database Recovery
## Severity Levels
- P1: Complete data loss / corruption — all hands, CEO notified
- P2: Partial data loss / single region down — on-call team + escalation
- P3: Replica failure / backup failure — on-call investigation
## Recovery Procedures
### Scenario A: Primary DB failure, replicas healthy
1. Promote replica to primary (automated via Patroni / orchestrator)
2. Verify application connectivity
3. Re-establish replication from new primary
4. Investigate root cause
### Scenario B: Complete cluster failure, backups intact
1. Provision new database infrastructure
2. Restore latest full backup
3. Apply WAL/binlog to reach latest consistent point
4. Verify data integrity with checksums
5. Update DNS / connection strings
6. Resume application traffic
7. Re-establish backup schedule immediately
### Scenario C: Data corruption (bad migration / SQL injection)
1. Identify exact timestamp of corruption
2. Restore to point-in-time just before corruption
3. Export affected tables from restored copy
4. Merge clean data into production
5. OR: full PITR restore if corruption is widespread
## Contacts
- DBA on-call: [PagerDuty rotation]
- Infrastructure: [PagerDuty rotation]
- VP Engineering: [phone number]
## Validation Checklist
- [ ] Application health checks pass
- [ ] Row counts match expected ranges
- [ ] Recent transactions are present
- [ ] Replication re-established
- [ ] Backup schedule resumed
- [ ] Post-incident review scheduledব্যাকআপ মনিটরিং এবং সতর্কতা
ব্যাকআপ সিস্টেমগুলি নীরবে ব্যর্থ হয়৷ ডাটাবেস চলতে থাকে, অ্যাপ্লিকেশনটি ট্র্যাফিক পরিবেশন করতে থাকে, এবং কেউ লক্ষ্য করে না যে ব্যাকআপগুলি তিন সপ্তাহ আগে কাজ করা বন্ধ করে দিয়েছে — যতক্ষণ না তাদের প্রয়োজন হয়। সক্রিয় পর্যবেক্ষণ অপরিহার্য।
# Prometheus alerting rules for backup monitoring
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: backup-alerts
namespace: monitoring
spec:
groups:
- name: database-backups
rules:
- alert: BackupTooOld
expr: |
(time() - backup_last_successful_timestamp_seconds) > 90000
for: 10m
labels:
severity: critical
annotations:
summary: "Database backup is older than 25 hours"
description: "Last successful backup for {{ $labels.database }} was {{ $value | humanizeDuration }} ago"
- alert: BackupJobFailed
expr: |
kube_job_status_failed{job_name=~".*backup.*"} > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Backup CronJob failed: {{ $labels.job_name }}"
- alert: WALArchivingLagging
expr: |
pg_stat_archiver_failed_count > 0
for: 5m
labels:
severity: warning
annotations:
summary: "PostgreSQL WAL archiving has failures"
- alert: BackupStorageQuotaNearing
expr: |
(backup_storage_used_bytes / backup_storage_quota_bytes) > 0.85
for: 30m
labels:
severity: warning
annotations:
summary: "Backup storage at {{ $value | humanizePercentage }} capacity"
- alert: BinlogSpaceCritical
expr: |
mysql_binlog_size_bytes > 53687091200
for: 10m
labels:
severity: warning
annotations:
summary: "MySQL binlog space exceeds 50GB — check archiving"# Custom Prometheus exporter for pgBackRest metrics
#!/usr/bin/env python3
"""pgBackRest Prometheus exporter — exposes backup age and size metrics."""
import json
import subprocess
import time
from prometheus_client import start_http_server, Gauge
BACKUP_AGE = Gauge('pgbackrest_last_backup_age_seconds', 'Seconds since last backup', ['stanza', 'type'])
BACKUP_SIZE = Gauge('pgbackrest_last_backup_size_bytes', 'Size of last backup', ['stanza', 'type'])
BACKUP_REPO_SIZE = Gauge('pgbackrest_repo_size_bytes', 'Total repository size', ['stanza'])
def collect():
result = subprocess.run(
['pgbackrest', '--output=json', 'info'],
capture_output=True, text=True
)
info = json.loads(result.stdout)
for stanza_info in info:
stanza = stanza_info['name']
for backup in stanza_info.get('backup', []):
backup_type = backup['type']
stop_time = backup['timestamp']['stop']
age = time.time() - stop_time
BACKUP_AGE.labels(stanza=stanza, type=backup_type).set(age)
size = backup['info']['size']
BACKUP_SIZE.labels(stanza=stanza, type=backup_type).set(size)
if __name__ == '__main__':
start_http_server(9854)
while True:
collect()
time.sleep(300)সাধারণ ভুল এবং অ্যান্টি-প্যাটার্ন
কয়েক ডজন উত্পাদন পরিবেশে ডাটাবেস ব্যাকআপ পরিচালনা করার পরে, এই ভুলগুলি সবচেয়ে বেশি ক্ষতি করে।
1. ডাটাবেসের মতো একই ডিস্কে ব্যাক আপ করা হচ্ছে।ডিস্ক ব্যর্থ হলে, আপনি ডাটাবেস এবং ব্যাকআপ উভয়ই হারাবেন। সর্বদা একটি পৃথক স্টোরেজ লক্ষ্যে ব্যাকআপ লিখুন - আদর্শভাবে অফ-হোস্ট এবং অফ-অঞ্চল৷
2. কখনই পুনরুদ্ধারের পরীক্ষা করে না৷একটি ব্যাকআপ যা পুনরুদ্ধার করা যায় না তা ব্যাকআপ নয়৷ সাপ্তাহিক স্বয়ংক্রিয় পুনরুদ্ধার পরীক্ষার সময়সূচী করুন এবং প্রকৌশলীদের ত্রৈমাসিক ম্যানুয়াল পুনরুদ্ধার ড্রিলগুলি সম্পাদন করতে দিন।
3. ব্যাকআপ হিসাবে প্রতিলিপির উপর সম্পূর্ণ নির্ভর করা।প্রতিলিপি ব্যাকআপ নয়। প্রাথমিকে একটিDROP TABLEঅবিলম্বে সমস্ত প্রতিলিপিতে প্রতিলিপি করা হয়৷ প্রতিলিপি হার্ডওয়্যার ব্যর্থতা থেকে রক্ষা করে, যৌক্তিক ত্রুটি নয়।
4. ব্যাকআপ কাজগুলি পর্যবেক্ষণ করছে না৷ক্রোন কাজগুলি নীরবে ব্যর্থ হয়৷ Kubernetes CronJobs স্থগিত করা হয়. S3 শংসাপত্রের মেয়াদ শেষ। প্রতিটি ব্যাকআপ কাজ অবশ্যই একটি মনিটরিং সিস্টেমে সাফল্য বা ব্যর্থতার রিপোর্ট করতে হবে এবং সাম্প্রতিক সফল ব্যাকআপটি আপনার RPO-এর থেকে পুরানো হলে সতর্ক করুন৷
5. ব্যাকআপের পাশাপাশি এনক্রিপশন কী সংরক্ষণ করা।যদি কোনো আক্রমণকারী আপনার ব্যাকআপ সঞ্চয়স্থানে অ্যাক্সেস লাভ করে, তবে তাদের ডিক্রিপশন কী থাকা উচিত নয়। একটি ডেডিকেটেড সিক্রেটস ম্যানেজারে কী সংরক্ষণ করুন।
6. কোন ধারণ নীতি নেই।জীবনচক্র নীতি ছাড়া, ব্যাকআপ সঞ্চয়স্থান সীমাহীন বৃদ্ধি পায়। ক্লিয়ার রিটেনশন উইন্ডোস সংজ্ঞায়িত করুন: WAL সেগমেন্টের জন্য 7 দিন, দৈনিক ব্যাকআপের জন্য 30 দিন, মাসিক ব্যাকআপের জন্য 12 মাস, এবং তাদের মুছে ফেলা স্বয়ংক্রিয়ভাবে।
7. ব্যাকআপ কর্মক্ষমতা প্রভাব উপেক্ষা করা।পিক আওয়ারের সময় একটি প্রাথমিক ডাটাবেসে একটি সম্পূর্ণ ব্যাকআপ চালানো অ্যাপ্লিকেশনের কর্মক্ষমতা হ্রাস করে। কম ট্রাফিক উইন্ডোর সময় ব্যাকআপের সময়সূচী করুন, বা একটি ডেডিকেটেড প্রতিরূপ থেকে ব্যাক আপ করুন৷
8.--single-transactionছাড়া বড় ডাটাবেসের জন্যmysqldumpব্যবহার করা।এই পতাকা ব্যতীত,mysqldumpটেবিল লক করে, ডাম্পের সময়কালের জন্য রাইট ব্লক করে। বড় ডাটাবেসের জন্য এর অর্থ মিনিট বা ঘন্টার ডাউনটাইম হতে পারে।
9. ডাটাবেস কনফিগারেশন ব্যাক আপ করতে ভুলে যাওয়া।ডেটা পুনরুদ্ধার করা মাত্র অর্ধেক যুদ্ধ। আপনি যদিpostgresql.conf,pg_hba.conf,my.cnf, প্রতিলিপি সেটিংস এবং ব্যবহারকারী অনুদান হারান, আপনি ডাটাবেসটিকে ব্যবহারযোগ্য অবস্থায় ফিরিয়ে আনতে পারবেন না৷ আপনার ব্যাকআপ প্রক্রিয়ায় কনফিগারেশন ফাইল অন্তর্ভুক্ত করুন।
10. পুনরুদ্ধার পদ্ধতির নথিভুক্ত নয়৷একটি বিভ্রাটের সময়, ডাটাবেস পুনরুদ্ধারকারী ব্যক্তি ব্যাকআপ সেট আপকারী ব্যক্তি নাও হতে পারে৷ একটি লিখিত, পরীক্ষিত রানবুক গুরুত্বপূর্ণ।
ব্যাকআপ স্টোরেজের জন্যখরচ অপ্টিমাইজেশান
৷ব্যাকআপ স্টোরেজ খরচ দ্রুত বৃদ্ধি পেতে পারে, বিশেষ করে বড় ডাটাবেসের ঘন ঘন সম্পূর্ণ ব্যাকআপের সাথে। এই কৌশলগুলি পুনরুদ্ধারযোগ্যতার সাথে আপস না করে খরচ নিয়ন্ত্রণে রাখে।
ইনক্রিমেন্টাল/ডিফারেনশিয়াল ব্যাকআপ ব্যবহার করুন।একটি সাপ্তাহিক পূর্ণ প্লাস দৈনিক পার্থক্য প্রতিদিনের সম্পূর্ণ ব্যাকআপের তুলনায় স্টোরেজের একটি ভগ্নাংশ ব্যবহার করে। pgBackRest এর ডেল্টা পুনরুদ্ধার ক্ষমতা মানে ক্রমবর্ধমান ব্যাকআপগুলি সম্পূর্ণ ব্যাকআপের মতোই দ্রুত পুনরুদ্ধার করে।
কম্প্রেশন সক্ষম করুন৷আধুনিক কম্প্রেশন অ্যালগরিদম যেমন zstd ন্যূনতম CPU ওভারহেড সহ চমৎকার কম্প্রেশন অনুপাত (সাধারণ ডেটাবেস ডেটার জন্য 5:1 থেকে 10:1) অফার করে। pgBackRest এবং XtraBackup উভয়ই স্থানীয়ভাবে zstd সমর্থন করে।
সঞ্চয়স্থান টিয়ারিং প্রয়োগ করুন৷ বয়সের সাথে সাথেব্যাকআপগুলিকে ধীরে ধীরে সস্তা স্টোরেজ স্তরগুলিতে নিয়ে যান৷ আগে দেখানো জীবনচক্র নীতিগুলি (S3 স্ট্যান্ডার্ড → IA → Glacier, GCS Standard → Nearline → Coldline) দীর্ঘমেয়াদী স্টোরেজ খরচ 70-90% কমাতে পারে।
যেখানে সম্ভব ডিডুপ্লিকেট করুন।pgBackRest তার সংগ্রহস্থলে ব্লক-স্তরের অনুলিপি ব্যবহার করে, ব্যাকআপ জুড়ে শুধুমাত্র পরিবর্তিত ব্লক সংরক্ষণ করে। এটি নাটকীয়ভাবে ডাটাবেসের জন্য স্টোরেজ হ্রাস করে যেখানে বেশিরভাগ ডেটা স্থির থাকে।
ডান-আকারের রিটেনশন উইন্ডো।অনেক দলই সতর্কতার বাইরে চিরকালের জন্য ব্যাকআপ রাখতে ডিফল্ট। আপনার প্রকৃত পুনরুদ্ধারের ধরণ এবং সম্মতির প্রয়োজনীয়তাগুলি বিশ্লেষণ করুন, তারপরে মেলে ধরে রাখা সেট করুন। একটি 7-বছর ধরে রাখার প্রয়োজনীয়তা বেশিরভাগ ক্লাউড প্রদানকারীর জন্য $1/TB/মাস এর চেয়ে কম ডিপ আর্কাইভ স্টোরেজ ব্যবহার করতে পারে।
# Cost comparison: Full vs Incremental backup storage
# Assuming 500 GB database, 5% daily change rate, 30-day retention
# Strategy A: Daily full backups
# 500 GB × 30 days = 15,000 GB = 15 TB
# S3 Standard: 15 TB × $0.023/GB = $345/month
# Strategy B: Weekly full + daily incremental
# 4 full × 500 GB = 2,000 GB
# 26 incremental × 25 GB = 650 GB
# Total: 2,650 GB ≈ 2.6 TB
# S3 Standard: 2.6 TB × $0.023/GB = $59.80/month
# Strategy C: Strategy B + lifecycle tiering
# Current week: 525 GB Standard = $12.08
# Weeks 2-4: 2,125 GB Standard-IA = $26.56
# Total: $38.64/month
# Savings: Strategy C is 89% cheaper than Strategy Aসবকিছু একসাথে রাখা: একটি সম্পূর্ণ ব্যাকআপ আর্কিটেকচার
এখানে MySQL এবং PostgreSQL উভয়ই চলমান উৎপাদন পরিবেশের জন্য প্রস্তাবিত ব্যাকআপ আর্কিটেকচার রয়েছে, মাল্টি-ক্লাউড বিপর্যয় পুনরুদ্ধারের সাথে Kubernetes-এ স্থাপন করা হয়েছে।
PostgreSQL এর জন্য:
- দুটি সংগ্রহস্থল (S3 + Azure ব্লব)সহ প্রাথমিক ব্যাকআপ টুল হিসাবে
- pgBackRest
- উভয় রিপোজিটরিতে ক্রমাগত WAL সংরক্ষণাগার
- সাপ্তাহিক পূর্ণ ব্যাকআপ + দৈনিক পার্থক্য (K8s CronJob এর মাধ্যমে) দ্রুত রোলব্যাকের জন্য প্রতি 4 ঘন্টায়
- লংহর্ন ভলিউম স্ন্যাপশট প্রতি বুধবার
- স্বয়ংক্রিয় পুনরুদ্ধার যাচাইকরণ ৷ ব্যাকআপ বয়স, ব্যর্থতা এবং স্টোরেজসম্পর্কে সতর্কতা সহ
- Prometheus পর্যবেক্ষণ
MySQL এর জন্য:
- শারীরিক ব্যাকআপের জন্য
- Percona XtraBackup S3 এ স্ট্রিম করা হয়েছে
- আলাদা সঞ্চয়স্থানে অবিচ্ছিন্ন বাইনারি লগ শিপিং ৷
- সাপ্তাহিক পূর্ণ + দৈনিক বৃদ্ধি (K8s CronJob এর মাধ্যমে) পোর্টেবল লজিক্যাল ব্যাকআপের জন্য ক্রিটিক্যাল স্কিমাগুলির
- দৈনিক
mysqldump - লংহর্ন ভলিউম স্ন্যাপশট প্রতি 4 ঘন্টা ৷ প্রতি বৃহস্পতিবার
- স্বয়ংক্রিয় পুনরুদ্ধার যাচাইকরণ ৷
Kubernetes ক্লাস্টারের জন্য:
- ভেলেরো পিভি স্ন্যাপশট সহ ডাটাবেস নেমস্পেসের দৈনিক ব্যাকআপ
- RKE2/k3s etcd স্ন্যাপশট প্রতি 6 ঘন্টা অফ-ক্লাস্টার স্টোরেজে
- GitOps রিপোজিটরি সমস্ত প্রকাশের জন্য সত্যের উত্স হিসাবে
দুর্যোগ পুনরুদ্ধারের জন্য:
- S3 ক্রস-অঞ্চল প্রতিলিপি DR অঞ্চলে জিও-অপ্রয়োজনীয় ব্যাকআপ কপিএর জন্য
- Azure GRS
- মাসিক DR ড্রিল: DR অঞ্চলে ব্যাকআপ থেকে সম্পূর্ণ ক্লাস্টার পুনর্নির্মাণ
- প্রতিটি ব্যর্থতার দৃশ্যের জন্য ডিসিশন ট্রি সহ ডকুমেন্টেড রানবুক
উপসংহার
ডেটাবেস ব্যাকআপ হল আপনার ব্যবসা এবং বিপর্যয়মূলক ডেটা ক্ষতির মধ্যে প্রতিরক্ষার শেষ লাইন। এই নিবন্ধে বর্ণিত কৌশলগুলি — শারীরিক এবং যৌক্তিক ব্যাকআপ, অবিচ্ছিন্ন WAL এবং বিনলগ সংরক্ষণাগার, লাইফসাইকেল নীতি সহ মাল্টি-ক্লাউড স্টোরেজ, প্রতিটি স্তরে এনক্রিপশন, Kubernetes ক্রোনজবসের মাধ্যমে স্বয়ংক্রিয় সময়সূচী, এবং পদ্ধতিগত পুনরুদ্ধার যাচাইকরণ — উৎপাদন PostgreSQL এবং পরিবেশের জন্য শিল্পের বর্তমান অবস্থার প্রতিনিধিত্ব করে৷
সবচেয়ে গুরুত্বপূর্ণ উপায় হল:একটি ব্যাকআপ কৌশল তার শেষ সফল পুনরুদ্ধার পরীক্ষাএর মতোই ভাল। এই নিবন্ধে প্রতিটি টুল, স্ক্রিপ্ট এবং আর্কিটেকচার প্যাটার্ন একটি উদ্দেশ্য পূরণ করার জন্য বিদ্যমান — নিশ্চিত করে যে যখন সবচেয়ে খারাপ ঘটবে, আপনি আপনার ডেটা পুনরুদ্ধার করতে পারবেন, আপনার RTO এবং RPO প্রতিশ্রুতি পূরণ করতে পারবেন এবং আপনার ব্যবসা চালু রাখতে পারবেন। আপনার ব্যাকআপ সিস্টেম তৈরি করুন, এটি স্বয়ংক্রিয় করুন, এটি নিরীক্ষণ করুন, এটি পরীক্ষা করুন এবং তারপরে এটি আবার পরীক্ষা করুন। আপনার ভবিষ্যত স্ব আপনাকে ধন্যবাদ হবে.