RPM অর্কেস্ট্রেটর ব্যবহার করে S3-এর সাথে মানানসই স্টোরেজে AlloyDB Omni-র ব্যাক-আপ নেওয়া ও রিস্টোর করা

১. ভূমিকা

এই কোডল্যাবে, আপনি RPM অর্কেস্ট্রেটর ব্যবহার করে AlloyDB Omni-এর জন্য S3-এর সাথে মানানসই অবজেক্ট স্টোরেজে একটি হাই অ্যাভেলিবিলিটি (HA) ক্লাস্টারের ব্যাক-আপ নেবেন।

এই কোডল্যাব, Compute Engine ভার্চুয়াল মেশিনে (VM) HA ক্লাস্টার তৈরি করতে, RPM Orchestrator ব্যবহার করে GCE VM-এ AlloyDB Omni হাই অ্যাভেলিবিলিটি ক্লাস্টার ডিপ্লয় করুন কোডল্যাবের ক্লাস্টার ব্যবহার করে। এই কোডল্যাবে, আপনি একটি VM-এ S3-এর সাথে মানানসই অবজেক্ট স্টোরেজ সার্ভার যোগ করেন। আপনি HA ক্লাস্টারের জন্য অবজেক্ট স্টোরেজ সার্ভার ব্যবহার করেন যাতে ডেটার ব্যাক-আপ নেওয়া যায় এবং সার্ভার থেকে ক্লাস্টার রিস্টোর করা যায়।

Cloud Shell কন্ট্রোল VM-এর সাথে কানেক্ট করে। কন্ট্রোল VM, Ansible ও MinIO চালায়। psql, HAProxy VM-এর ভার্চুয়াল IP-র মাধ্যমে ক্লাস্টারের সাথে কানেক্ট করে। ডেটাবেস VM পোর্ট 9000-এ MinIO-তে ব্যাক-আপ পাঠায়।

পূর্বশর্ত

  • বিলিং চালু করা আছে এমন একটি Google Cloud প্রোজেক্ট।
  • HA কোডল্যাবে তালিকাভুক্ত IAM ভূমিকা।
  • Linux কমান্ড ও SQL সম্পর্কে প্রাথমিক জ্ঞান।

আপনি কী শিখবেন

  • ব্যাক-আপের জন্য কীভাবে S3-এর সাথে মানানসই অবজেক্ট স্টোরেজ সার্ভার ইনস্টল ও রান করতে হয়।
  • S3-এর সাথে মানানসই স্টোরেজে ব্যাকআপ লেখার জন্য ব্যাকআপ প্ল্যান কীভাবে তৈরি করতে হয়।
  • কীভাবে অন-ডিমান্ড ব্যাক-আপ তৈরি করতে হয়।
  • ব্যাক-আপ থেকে এবং কোনও নির্দিষ্ট সময়ে ক্লাস্টার কীভাবে ফিরিয়ে আনতে হয়।

আপনার কী কী প্রয়োজন

২. সেট-আপ ও প্রয়োজনীয়তা

  1. এই ধাপে, আপনি RPM Orchestrator ব্যবহার করে GCE VM-এ AlloyDB Omni হাই অ্যাভেলিবিলিটি ক্লাস্টার ডিপ্লয় করুন কোডল্যাব ব্যবহার করে HA ক্লাস্টার তৈরি করেন। নিচে উল্লেখ করা ধাপগুলি সম্পূর্ণ করুন। আপনার কাছে যদি আগে থেকেই কোডল্যাব থেকে পাওয়া ক্লাস্টার থাকে, তাহলে পরবর্তী ধাপে এগিয়ে যান।
  2. মনে রাখবেন: এই পর্যায়ে "রিসোর্স ক্লিন-আপ করুন" ধাপটি এক্সিকিউট করবেন না। এই কোডল্যাবের শেষে আপনি সেই ধাপটি সম্পূর্ণ করবেন।
  3. এই কোডল্যাবে ফিরে যান

৩. ক্লাস্টারে কানেক্ট করা এবং স্যাম্পেল ডেটা যোগ করা

এই ধাপে, আপনি কন্ট্রোল VM-এ ক্লাস্টার সেটিংস লোড করেন। তারপরে আপনি ক্লাস্টারের সাথে কানেক্ট করেন এবং স্যাম্পেল ডেটা সহ একটি টেবিল যোগ করেন।

  1. আপনি কন্ট্রোল VM-এ কানেক্ট না করে থাকলে, Cloud Shell থেকে এতে কানেক্ট করুন:
    gcloud compute ssh "$CLUSTER-control" --zone="$ZONE" --project="$PROJECT"
    
    Deploy AlloyDB Omni high availability cluster on GCE VMs using RPM Orchestrator কোডল্যাবের ডিপ্লয়মেন্টের জন্য VM প্রস্তুত করুন ধাপ থেকে CLUSTER, ZONE ও PROJECT ভেরিয়েবলগুলি এসেছে। Cloud Shell-এ এই ভেরিয়েবল না থাকলে, সেগুলি আবার সেট করুন।
  2. কন্ট্রোল VM-এ, আপনার হোম ডিরেক্টরিতে পরিবর্তন করুন এবং এনভায়রনমেন্ট ভেরিয়েবল লোড করুন। তারপর এনভায়রনমেন্ট ফাইলে ক্লাস্টারের নাম ও SSH ব্যবহারকারীকে যোগ করুন:
    cd ~
    source /tmp/cluster.conf
    cat >> ~/.codelab.env <<EOF
    export CLUSTER="$cluster"
    export SSH_USER="$service_account"
    EOF
    source ~/.codelab.env
    env | grep -E '^(CLUSTER|SSH_USER|VIRTUAL_IP)='
    
    যাচাই করে দেখুন যে আউটপুটে CLUSTER, SSH_USER ও VIRTUAL_IP দেখানো হচ্ছে। মনে রাখবেন: পরে আবার কন্ট্রোল VM-এ কানেক্ট করলে, চালিয়ে যাওয়ার আগে cd ~ ও source ~/.codelab.env রান করান।
  3. এনভায়রনমেন্ট ফাইলে কানেকশন সেটিংস যোগ করুন। read কমান্ড পাসওয়ার্ড চাইলে, postgres ব্যবহারকারীর পাসওয়ার্ড লিখুন। RPM Orchestrator ব্যবহার করে GCE VM-এ AlloyDB Omni হাই অ্যাভেলিবিলিটি ক্লাস্টার ডিপ্লয় করুন কোডল্যাবের AlloyDB Omni ক্লাস্টার বুটস্ট্র্যাপ করুন ধাপে আপনি এই পাসওয়ার্ড সেট করেন
    cat >> ~/.codelab.env <<'EOF'
    export PATH="/usr/pgsql-18/bin:$PATH"
    export PGHOST="$VIRTUAL_IP"
    export PGUSER="postgres"
    EOF
    read -rsp "Password of the postgres user: " PGPASSWORD; echo
    printf 'export PGPASSWORD=%q\n' "$PGPASSWORD" >> ~/.codelab.env
    source ~/.codelab.env
    env | grep -E '^(PGHOST|PGUSER|PGPASSWORD)='
    
  4. একটি টেবিল তৈরি করে ১,০০০টি সারি যোগ করুন:
    psql <<'SQL'
    CREATE TABLE public.orders (
      id integer PRIMARY KEY,
      item text NOT NULL,
      created_at timestamptz NOT NULL DEFAULT pg_catalog.now()
    );
    INSERT INTO public.orders (id, item)
    SELECT g, 'item-' || g FROM pg_catalog.generate_series(1, 1000) AS g;
    SQL
    
  5. সারি গণনা করুন:
    psql -c "SELECT pg_catalog.count(*) FROM public.orders;"
    
    যাচাই করুন যে আউটপুট 1000 রিটার্ন করে।

৪. S3-এর সাথে মানানসই অবজেক্ট স্টোরেজ ইনস্টল ও রান করা

এই ধাপে, আপনি একটি Ansible প্লেবুক লেখেন যা কন্ট্রোল VM-এ একটি MinIO সার্ভার ইনস্টল করে। এছাড়াও, প্লেবুকটি ব্যাক-আপের জন্য বাকেট ও ব্যবহারকারী তৈরি করে এবং এটি নিশ্চিত করে যে ডেটাবেস VM, MinIO-এর সাথে কানেক্ট করতে পারে। কন্ট্রোল VM-এ এই ধাপের সব কমান্ড রান করান।

  1. কন্ট্রোল VM-এ, এনভায়রনমেন্ট ফাইলে স্টোরেজ সেটিংস যোগ করুন। openssl কমান্ড র‍্যান্ডম পাসওয়ার্ড তৈরি করে।
    MD=http://metadata.google.internal/computeMetadata/v1/instance
    S3_IP=$(curl -s -H "Metadata-Flavor: Google" "$MD/network-interfaces/0/ip")
    cat >> ~/.codelab.env <<EOF
    export S3_IP="$S3_IP"
    export S3_HOST="$CLUSTER-control"
    export S3_BUCKET="alloydb-backups"
    export S3_REGION="us-east-1"
    export MINIO_ROOT_USER="s3admin"
    export MINIO_ROOT_PASSWORD="$(openssl rand -hex 16)"
    export S3_ACCESS_KEY_ID="alloydb-backup"
    export S3_SECRET_ACCESS_KEY="$(openssl rand -hex 16)"
    export MINIO_URL="https://github.com/minio/minio/releases/download/RELEASE.2024-05-10T01-41-38Z/minio.linux-amd64.RELEASE.2024-05-10T01-41-38Z"
    export MC_URL="https://github.com/minio/mc/releases/download/RELEASE.2024-05-09T17-04-24Z/mc.linux-amd64.RELEASE.2024-05-09T17-04-24Z"
    EOF
    source ~/.codelab.env
    echo "$S3_HOST $S3_IP"
    
    আউটপুটে কন্ট্রোল VM-এর নাম ও ইন্টার্নাল IP অ্যাড্রেস দেখা যাচ্ছে কিনা তা নিশ্চিত করুন, যেমন my-cluster-control 10.1.0.2। ডেটাবেস VM, MinIO-এর সাথে কানেক্ট করার জন্য এই হোস্ট নেম ও IP অ্যাড্রেস ব্যবহার করে। VM-এর মেটাডেটা সার্ভার IP অ্যাড্রেস দেয়। আরও তথ্যের জন্য, VM মেটাডেটা ডকুমেন্টেশন দেখুন।MINIO_URL এবং MC_URL ভ্যালু হল MinIO সার্ভার এবং MinIO ক্লায়েন্টের (mc) ডাউনলোড URL।
  2. কন্ট্রোল VM-এ প্রয়োজনীয় community.crypto Ansible সংগ্রহ ইনস্টল করুন:
    ansible-galaxy collection install community.crypto
    
  3. s3_server.yaml প্লেবুক তৈরি করুন:
    cat > s3_server.yaml <<EOF
    - name: Install and run MinIO on the control VM
      hosts: localhost
      connection: local
      become: true
      gather_facts: false
      tasks:
        - name: Create MinIO directories
          ansible.builtin.file:
            path: "{{ item }}"
            state: directory
            mode: "0755"
          loop:
            - /var/lib/minio/data
            - /var/lib/minio/certs
    
        - name: Download MinIO server and client
          ansible.builtin.get_url:
            url: "{{ item.url }}"
            dest: "{{ item.dest }}"
            mode: "0755"
          loop:
            - url: "$MINIO_URL"
              dest: /usr/local/bin/minio
            - url: "$MC_URL"
              dest: /usr/local/bin/mc
    
        - name: Generate MinIO TLS private key
          community.crypto.openssl_privatekey:
            path: /var/lib/minio/certs/private.key
            size: 2048
            mode: "0600"
    
        - name: Generate MinIO certificate signing request
          community.crypto.openssl_csr_pipe:
            privatekey_path: /var/lib/minio/certs/private.key
            common_name: "$S3_HOST"
            subject_alt_name:
              - "DNS:$S3_HOST"
              - "DNS:$S3_BUCKET.$S3_HOST"
              - "DNS:localhost"
              - "IP:127.0.0.1"
              - "IP:$S3_IP"
          register: minio_csr
    
        - name: Generate self-signed MinIO TLS certificate
          community.crypto.x509_certificate:
            path: /var/lib/minio/certs/public.crt
            csr_content: "{{ minio_csr.csr }}"
            privatekey_path: /var/lib/minio/certs/private.key
            provider: selfsigned
            selfsigned_not_after: "+365d"
            mode: "0644"
    
        - name: Create MinIO systemd service unit
          ansible.builtin.copy:
            dest: /etc/systemd/system/minio.service
            mode: "0600"
            content: |
              [Unit]
              Description=MinIO Object Storage
              After=network.target
    
              [Service]
              Environment="MINIO_ROOT_USER=$MINIO_ROOT_USER"
              Environment="MINIO_ROOT_PASSWORD=$MINIO_ROOT_PASSWORD"
              Environment="MINIO_DOMAIN=$S3_HOST"
              ExecStart=/usr/local/bin/minio server /var/lib/minio/data --certs-dir /var/lib/minio/certs
              Restart=on-failure
    
              [Install]
              WantedBy=multi-user.target
    
        - name: Start and enable MinIO service
          ansible.builtin.systemd_service:
            name: minio
            daemon_reload: true
            state: started
            enabled: true
    
        - name: Add storage host names to /etc/hosts on the control VM
          ansible.builtin.lineinfile:
            path: /etc/hosts
            line: "$S3_IP $S3_HOST $S3_BUCKET.$S3_HOST"
            state: present
    
        - name: Wait for MinIO health endpoint
          ansible.builtin.uri:
            url: "https://$S3_HOST:9000/minio/health/live"
            ca_path: /var/lib/minio/certs/public.crt
            status_code: 200
          register: minio_health
          until: minio_health.status == 200
          retries: 6
          delay: 5
    
        - name: Create backup bucket and user in MinIO
          ansible.builtin.command:
            argv: "{{ item }}"
          loop:
            - - /usr/local/bin/mc
              - --insecure
              - alias
              - set
              - s3repo
              - "https://$S3_HOST:9000"
              - "$MINIO_ROOT_USER"
              - "$MINIO_ROOT_PASSWORD"
            - - /usr/local/bin/mc
              - --insecure
              - mb
              - --ignore-existing
              - "s3repo/$S3_BUCKET"
            - - /usr/local/bin/mc
              - --insecure
              - admin
              - user
              - add
              - s3repo
              - "$S3_ACCESS_KEY_ID"
              - "$S3_SECRET_ACCESS_KEY"
            - - /usr/local/bin/mc
              - --insecure
              - admin
              - policy
              - attach
              - s3repo
              - readwrite
              - --user
              - "$S3_ACCESS_KEY_ID"
          become: false
          no_log: true
    
    - name: Configure database VMs for MinIO
      hosts: primary_instance_nodes
      become: true
      gather_facts: false
      vars:
        ansible_user: $SSH_USER
        ansible_ssh_private_key_file: $HOME/ssh-key-cluster-sa
      tasks:
        - name: Set SELinux to permissive mode
          ansible.builtin.command:
            cmd: setenforce 0
    
        - name: Add storage host names to /etc/hosts
          ansible.builtin.lineinfile:
            path: /etc/hosts
            line: "$S3_IP $S3_HOST $S3_BUCKET.$S3_HOST"
            state: present
    
        - name: Verify storage host resolution
          ansible.builtin.getent:
            database: hosts
            key: "$S3_BUCKET.$S3_HOST"
    
        - name: Verify connection to MinIO
          ansible.builtin.uri:
            url: "https://$S3_HOST:9000/minio/health/live"
            validate_certs: false
            status_code: 200
    EOF
    
    MINIO_DOMAIN ভেরিয়েবল MinIO-কে ভার্চুয়াল-হোস্ট-স্টাইল অনুরোধ গ্রহণ করতে দেয়। RPM অর্কেস্ট্রেটর ব্যাক-আপ লেখার জন্য alloydb-backup ব্যবহারকারীকে ব্যবহার করে। readwrite নীতি হল MinIO-এর বিল্ট-ইন নীতি।
  4. প্লেবুক চালান:
    ansible-playbook s3_server.yaml -i deployment_spec.yaml
    
    PLAY RECAP আউটপুটে localhost এবং প্রতিটি ডেটাবেস VM-এর জন্য failed=0 দেখাচ্ছে কিনা তা যাচাই করুন।
  5. বাকেট আছে কিনা যাচাই করুন:
    mc --insecure ls s3repo
    
    যাচাই করে দেখুন যে আউটপুটে alloydb-backups/ বাকেট দেখা যাচ্ছে কিনা।

৫. ব্যাক-আপ প্ল্যান তৈরি করা

ব্যাক-আপ প্ল্যানে ক্লাস্টারের ব্যাক-আপের স্টোরেজ লোকেশন, শিডিউল ও ডেটা কতদিন রাখা হবে সেই সংক্রান্ত তথ্য থাকে। এই ধাপে, আপনি MinIO বাকেটের জন্য একটি ব্যাক-আপ প্ল্যান তৈরি করেন।

  1. কন্ট্রোল VM-এ, ব্যাকআপ প্লেবুক ও স্ট্যাটাস প্লেবুক তৈরি করুন। আপনি Secret, BackupPlan ও Backup রিসোর্সের জন্য ব্যাক-আপ প্লেবুক ব্যবহার করেন। কোনও রিসোর্সের স্ট্যাটাস দেখাতে আপনি স্ট্যাটাস প্লেবুক ব্যবহার করেন।
    cat > backup.yaml <<EOF
    - name: Manage AlloyDB Omni backups
      hosts: localhost
      roles:
        - role: google.alloydbomni_orchestrator.backup
    EOF
    cat > status.yaml <<EOF
    - name: Get resource status
      hosts: localhost
      roles:
        - role: google.alloydbomni_orchestrator.status
    EOF
    
  2. S3 ক্রেডেনশিয়ালের জন্য Secret রিসোর্স তৈরি করুন। তারপর রিসোর্স প্রয়োগ করুন:
    S3_KEY_ID_B64=$(printf '%s' "$S3_ACCESS_KEY_ID" | base64 -w 0)
    S3_KEY_B64=$(printf '%s' "$S3_SECRET_ACCESS_KEY" | base64 -w 0)
    cat > s3_secret.yaml <<EOF
    Secret:
      metadata:
        name: s3-backup-secret
      spec:
        type: Opaque
        data:
          access-key-id: "$S3_KEY_ID_B64"
          access-key: "$S3_KEY_B64"
    EOF
    ansible-playbook backup.yaml -i deployment_spec.yaml \
        -e resource_spec=s3_secret.yaml
    
    data বিভাগে কী নামের মান access-key-id ও access-key হতে হবে। BackupPlan রিসোর্স প্রয়োগ করার আগে আপনাকে অবশ্যই Secret রিসোর্স প্রয়োগ করতে হবে।
  3. BackupPlan রিসোর্স তৈরি করে সেটি প্রয়োগ করুন:
    cat > backup_plan.yaml <<EOF
    BackupPlan:
      metadata:
        name: s3-backup-plan
      spec:
        dbclusterRef: $CLUSTER
        backupLocation:
          type: S3
          s3Options:
            bucket: $S3_BUCKET
            key: /backups
            endpoint: https://$S3_HOST:9000
            region: $S3_REGION
            secretRef:
              name: s3-backup-secret
            caBundle:
              - |
    $(sed 's/^/            /' /var/lib/minio/certs/public.crt)
    EOF
    ansible-playbook backup.yaml -i deployment_spec.yaml \
        -e resource_spec=backup_plan.yaml
    
    key ভ্যালু হল, বাকের্টের মধ্যে ব্যাক-আপের পাথ। এই পাথটি অবশ্যই একটি স্ল্যাশ (/) দিয়ে শুরু হতে হবে। caBundle ফিল্ডে PEM-এনকোড করা CA সার্টিফিকেট থাকে যা S3 স্টোরেজ সার্ভারের সার্টিফিকেট যাচাই করে।
  4. ব্যাক-আপ প্ল্যান রেডি আছে কিনা তা যাচাই করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=BackupPlan -e resource_name=s3-backup-plan
    
    যাচাই করে দেখুন যে phase ফিল্ডে Ready দেখা যাচ্ছে কিনা। ফেজ Ready না হলে, এক মিনিট অপেক্ষা করে আবার কমান্ড চালান।
  5. ব্যাক-আপ প্ল্যান তৈরি করা হলে, RPM অর্কেস্ট্রেটর অটোমেটিক প্রাথমিক সম্পূর্ণ ব্যাক-আপ নেওয়া শুরু করে। আপনি অন-ডিমান্ড ব্যাক-আপ তৈরি করার আগে এই প্রাথমিক ব্যাক-আপ সম্পূর্ণ হয়েছে কিনা তা যাচাই করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=Backup
    
    প্রাথমিক ব্যাক-আপ ফেজ সম্পূর্ণ হয়েছে কিনা তা যাচাই করুন।

৬. চাহিদা মতো ব্যাক-আপ তৈরি করা

এই ধাপে, আপনি ক্লাস্টারের একটি অন-ডিমান্ড ব্যাক-আপ তৈরি করেন।

  1. কন্ট্রোল VM-এ, Backup রিসোর্স তৈরি করুন। তারপর রিসোর্স প্রয়োগ করুন:
    cat > create_backup.yaml <<EOF
    Backup:
      metadata:
        name: s3-backup-1
      spec:
        backupPlanRef: s3-backup-plan
        dbclusterRef: $CLUSTER
    EOF
    ansible-playbook backup.yaml -i deployment_spec.yaml \
        -e resource_spec=create_backup.yaml
    
    backupPlanRef ফিল্ডে ব্যাক-আপ প্ল্যানের নাম লিখতে হবে। dbclusterRef ফিল্ড হল ক্লাস্টারের নাম।
  2. ব্যাক-আপ সম্পূর্ণ হয়েছে কিনা তা যাচাই করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=Backup -e resource_name=s3-backup-1
    
    যাচাই করে দেখুন যে phase ফিল্ডে Succeeded দেখা যাচ্ছে কিনা। ফেজ Succeeded না হলে, এক মিনিট অপেক্ষা করে আবার কমান্ড চালান।
  3. ব্যাক-আপ ফাইলগুলি বাকেটে আছে কিনা তা যাচাই করুন:
    mc --insecure tree "s3repo/$S3_BUCKET"
    
    যাচাই করে দেখুন যে আউটপুটে একটি backup ফোল্ডার দেখা যাচ্ছে যার মধ্যে একটি db ফোল্ডার আছে।

৭. ব্যাক-আপ থেকে ক্লাস্টার ফিরিয়ে আনা

RPM অর্কেস্ট্রেটর ক্লাস্টারকে আগের অবস্থায় ফিরিয়ে আনে। এই ধাপে, আপনি একটি টেবিল মুছে দেন এবং ব্যাক-আপ থেকে এটি ফিরিয়ে আনেন। তারপরে, আপনি চাইলে ক্লাস্টারকে কোনও নির্দিষ্ট সময়ে ফিরিয়ে আনতে পারবেন।

সতর্কতা: রিস্টোর অপারেশন ডেটাবেস ক্লাস্টারের সব ডেটা ওভাররাইট করে।

ব্যাক-আপ থেকে ফিরিয়ে আনুন

  1. কন্ট্রোল VM-এ, orders টেবিলটি মুছে দিন। তারপর সারিগুলি গণনা করুন:
    psql -c "DROP TABLE public.orders;"
    psql -c "SELECT pg_catalog.count(*) FROM public.orders;"
    
    যাচাই করুন যে দ্বিতীয় কমান্ডটি কোনও সমস্যার কারণে কাজ করছে না। সমস্যার মেসেজে দেখানো হয়েছে যে রিলেশনটি নেই। যেমন, ‘ERROR: table "orders" does not exist'
  2. রিস্টোর প্লেবুক তৈরি করুন:
    cat > restore.yaml <<EOF
    - name: Restore AlloyDB Omni cluster
      hosts: localhost
      roles:
        - role: google.alloydbomni_orchestrator.restore
    EOF
    
  3. s3-backup-1 ব্যাক-আপের জন্য Restore রিসোর্স তৈরি করো। তারপর রিসোর্স প্রয়োগ করুন:
    cat > restore_backup.yaml <<EOF
    Restore:
      metadata:
        name: s3-restore-1
      spec:
        sourceDBCluster: $CLUSTER
        backup: s3-backup-1
    EOF
    ansible-playbook restore.yaml -i deployment_spec.yaml \
        -e resource_spec=restore_backup.yaml
    
  4. রিস্টোর করার প্রসেস সম্পূর্ণ হয়েছে কিনা তা যাচাই করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=Restore -e resource_name=s3-restore-1
    
    যাচাই করে দেখুন যে phase ফিল্ডে ProvisionSucceeded দেখা যাচ্ছে কিনা। ফেজ ProvisionSucceeded না হলে, এক মিনিট অপেক্ষা করে আবার কমান্ড চালান।
  5. ফিরিয়ে আনা টেবিলের সারি গণনা করুন:
    psql -c "SELECT pg_catalog.count(*) FROM public.orders;"
    
    যাচাই করে দেখুন যে আউটপুটে 1000 দেখা যাচ্ছে কিনা।

(ঐচ্ছিক) কোনও নির্দিষ্ট সময়ে ফিরিয়ে আনা

কোনও নির্দিষ্ট সময়ে রিস্টোর করার জন্য ব্যাক-আপ ও আর্কাইভ করা রাইট-অহেড লগ (WAL) ব্যবহার করা হয়। ব্যাক-আপ প্ল্যানের রিকভারি উইন্ডোতে যেকোনও সময়ে আপনি ক্লাস্টার রিস্টোর করতে পারবেন।

টার্গেট সময়ের নিয়ম

টার্গেট সময়ের ভ্যালু ও ফর্ম্যাট বেছে নেওয়ার জন্য আপনাকে অবশ্যই এইসব নিয়ম মেনে চলতে হবে:

  • UTC-তে RFC 3339 ফর্ম্যাট ব্যবহার করুন: YYYY-MM-DDThh:mm:ssZ. যেমন, 2026-06-19T14:30:00Z হল ১৯ জুন, ২০২৬-এ ১৪:৩০:০০ UTC। T অক্ষরটি তারিখ ও সময়কে আলাদা করে। Z অক্ষরটি UTC সময় দেখায়।
  • অতীতের কোনও সময় ব্যবহার করুন।
  • BackupPlan CRD-এর recoveryWindow ফিল্ডের begin ভ্যালুর পরের কোনও সময় ব্যবহার করুন।

RFC 3339 ফর্ম্যাটে বর্তমান সময় দেখতে, এই কমান্ডটি রান করুন:

date -u +%Y-%m-%dT%H:%M:%SZ

স্থানীয় সময়কে এই ফর্ম্যাটে পরিবর্তন করতে, date কমান্ডে স্থানীয় সময়ের UTC অফসেট যোগ করুন। যেমন, নিম্নলিখিত কমান্ডটি UTC+02:00-এ 19 June 2026-এর 16:30:00 পরিবর্তন করে:

date -u -d "2026-06-19 16:30:00 +0200" +%Y-%m-%dT%H:%M:%SZ

কমান্ডটি 2026-06-19T14:30:00Z রিটার্ন করে।

রেকর্ড করা সময়ে ফিরিয়ে আনা

এই পদ্ধতিতে, আপনি টেবিলে সারি যোগ করেন এবং একটি সময় রেকর্ড করেন। আপনি যখন কোনও সময় রেকর্ড করেন, তখন আপনি সেই নির্দিষ্ট মুহূর্তটি বুকমার্ক করেন যখন ডেটাবেস সম্পূর্ণ অক্ষত থাকে (ঠিক ১৫০০টি সারি থাকে)। তারপর আপনি সারি মুছে দেন এবং রেকর্ড করা সময়ে ক্লাস্টার ফিরিয়ে আনেন।

  1. টেবিলে ৫০০টি সারি যোগ করুন:
    psql <<'SQL'
    INSERT INTO public.orders (id, item)
    SELECT g, 'item-' || g FROM pg_catalog.generate_series(1001, 1500) AS g;
    SQL
    
  2. সময় রেকর্ড করুন। এই মুহূর্তে টেবিলটিতে ১,৫০০টি সারি আছে।
    sleep 5
    PITR_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    echo "export PITR_TIME=$PITR_TIME" >> ~/.codelab.env
    echo "$PITR_TIME"
    sleep 5
    
    আউটপুটে YYYY-MM-DDThh:mm:ssZ ফর্ম্যাটে সময় দেখাচ্ছে কিনা তা যাচাই করুন, যেমন 2026-10-05T11:16:02Z।
  3. অনিচ্ছাকৃত ডেটা মুছে যাওয়ার ঘটনাকে সিমুলেট করতে টেবিল থেকে সারি মুছে দিন। তারপর নতুন WAL ফাইল শুরু করুন:
    psql -c "DELETE FROM public.orders WHERE id > 1000;"
    psql -c "SELECT pg_catalog.count(*) FROM public.orders;"
    psql -c "SELECT pg_catalog.pg_switch_wal();"
    
    যাচাই করে দেখুন যে count কোয়েরিতে 1000 দেখা যাচ্ছে কিনা। pg_switch_wal ফাংশনটি সার্ভারকে একটি নতুন WAL ফাইল শুরু করতে সাহায্য করে। তারপরে, সার্ভার আপনার করা পরিবর্তন সহ WAL ফাইলটি আর্কাইভ করতে পারে।
  4. ব্যাক-আপ প্ল্যানের রিকভারি উইন্ডোতে রেকর্ড করা সময় আছে কিনা তা যাচাই করুন:
    test -n "$PITR_TIME" || { echo "PITR_TIME is not set. Run step 2 again."; exit 1; }
    echo "$PITR_TIME"
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=BackupPlan -e resource_name=s3-backup-plan
    
    recoveryWindow ফিল্ডের begin ভ্যালুর পরে PITR_TIME ভ্যালু আছে কিনা তা যাচাই করুন।
  5. রেকর্ড করা সময়ের জন্য Restore রিসোর্স তৈরি করো। তারপর রিসোর্স প্রয়োগ করুন:
    cat > restore_pitr.yaml <<EOF
    Restore:
      metadata:
        name: s3-restore-pitr
      spec:
        sourceDBCluster: $CLUSTER
        pointInTime: "$PITR_TIME"
    EOF
    ansible-playbook restore.yaml -i deployment_spec.yaml \
        -e resource_spec=restore_pitr.yaml
    
  6. রিস্টোর করার প্রসেস সম্পূর্ণ হয়েছে কিনা তা যাচাই করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml \
        -e resource_type=Restore -e resource_name=s3-restore-pitr
    
    যাচাই করে দেখুন যে phase ফিল্ডে ProvisionSucceeded দেখা যাচ্ছে কিনা। ফেজ ProvisionSucceeded না হলে, এক মিনিট অপেক্ষা করে আবার কমান্ড চালান।
  7. সারি গণনা করুন:
    psql -c "SELECT pg_catalog.count(*) FROM public.orders;"
    
    যাচাই করে দেখুন যে আউটপুটে 1500 দেখা যাচ্ছে কিনা।

৮. মুছুন

আপনার Google Cloud অ্যাকাউন্টে চার্জ হওয়া আটকাতে, এই কোডল্যাবের রিসোর্স এবং RPM Orchestrator ব্যবহার করে GCE VM-এ AlloyDB Omni হাই অ্যাভেলিবিলিটি ক্লাস্টার ডিপ্লয় করুন কোডল্যাব মুছে দিন। প্রথমে ব্যাক-আপ রিসোর্স মুছে দিন, তারপর ক্লাস্টার ও কম্পিউট এনভায়র্নমেন্ট মুছে দিন।

  1. কন্ট্রোল VM-এ, মুছে ফেলার প্লেবুক তৈরি করুন:
    cat > delete.yaml <<EOF
    - name: Delete AlloyDB Omni resources
      hosts: localhost
      roles:
        - role: google.alloydbomni_orchestrator.delete
    EOF
    
  2. ব্যাক-আপের তালিকা তৈরি করুন:
    ansible-playbook status.yaml -i deployment_spec.yaml -e resource_type=Backup
    
    আউটপুটে s3-backup-1 ব্যাক-আপ দেখা যাচ্ছে কিনা তা যাচাই করুন।
  3. s3-backup-1 ব্যাক-আপ মুছে দিন:
    ansible-playbook delete.yaml -i deployment_spec.yaml \
        -e resource_type=Backup -e resource_name=s3-backup-1
    
  4. ব্যাক-আপ প্ল্যান মুছে দিন:
    ansible-playbook delete.yaml -i deployment_spec.yaml \
        -e resource_type=BackupPlan -e resource_name=s3-backup-plan
    
  5. RPM Orchestrator ব্যবহার করে GCE VM-এ AlloyDB Omni হাই অ্যাভেলিবিলিটি ক্লাস্টার ডিপ্লয় করুন কোডল্যাবের রিসোর্স ক্লিন-আপ করুন ধাপ ব্যবহার করে ক্লাস্টার ও কম্পিউট এনভায়রনমেন্ট মুছে দিন। MinIO সার্ভার এবং এতে থাকা ব্যাক-আপ কন্ট্রোল VM-এ থাকে। আপনি কম্পিউট এনভায়রনমেন্ট মুছে দিলে, সার্ভার ও ব্যাক-আপ, দুটিই মুছে যায়।

৯. অভিনন্দন

অভিনন্দন। আপনি RPM অর্কেস্ট্রেটর ব্যবহার করে AlloyDB Omni-এর জন্য S3-এর সাথে মানানসই অবজেক্ট স্টোরেজে হাই অ্যাভেলিবিলিটি (HA) ক্লাস্টার ব্যাক-আপ নিয়েছেন। তারপরে, আপনি ব্যাক-আপ থেকে ক্লাস্টার রিস্টোর করেছেন।

আমরা কী কী কভার করেছি

  • S3-এর সাথে মানানসই অবজেক্ট স্টোরেজ হিসেবে MinIO কীভাবে ইনস্টল ও রান করতে হয়।
  • কীভাবে ব্যাক-আপ প্ল্যান ও অন-ডিমান্ড ব্যাক-আপ তৈরি করতে হয়।
  • ব্যাক-আপ থেকে এবং কোনও নির্দিষ্ট সময়ে ক্লাস্টার কীভাবে ফিরিয়ে আনতে হয়।

আরও তথ্যের জন্য, নিম্নলিখিত পৃষ্ঠাগুলি দেখুন:

১০. সমীক্ষা

আপনি এই টিউটোরিয়াল কীভাবে ব্যবহার করবেন?

শুধু এটি পড়ে দেখুন এটি পড়ুন এবং অনুশীলন সম্পূর্ণ করুন