הגדרת שכפול לוגי ב-Kubernetes

בחירת גרסת תיעוד:

ב-PostgreSQL, רפליקציה לוגית היא שיטה להעתקת שינויים בנתונים ממסד נתונים של בעל תוכן דיגיטלי למנוי אחד או יותר, שיכולים להיות מסדי נתונים או אפליקציות אחרות. אתם יכולים להפעיל ולהגדיר שכפול לוגי באשכולות שאתם יוצרים באמצעות AlloyDB Omni Kubernetes Operator.

במסמך הזה מובאות דוגמאות שממחישות איך ליצור ולהגדיר אשכול של בעלי תוכן דיגיטלי ואשכול של מנויים. לפני שאתם קוראים את המסמך הזה, כדאי שתכירו את הסקירה הכללית על AlloyDB Omni. חשוב גם להכיר את המגבלות של רפליקציה לוגית ב-PostgreSQL.

קטעי הקוד בדף הזה הם דוגמאות שאפשר להשתמש בהן כמודלים, ולהחליף את הערכים בערכים של משאבי AlloyDB Omni.

יצירת האשכולות

  1. התקנת Omni Operator ב-Kubernetes.

  2. יוצרים אשכול של בעלי תוכן דיגיטלי.

    $ cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-publisher
    type: Opaque
    data:
      publisher: "b2RzcGFzc3dvcmQ=" # Password is odspassword
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: DBCluster
    metadata:
      name: publisher
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-publisher
        databaseVersion: "15.5.4"
        resources:
          memory: 10Gi
          cpu: 1
          disks:
          - name: DataDisk
            size: 40Gi
    EOF
    
  3. יוצרים אשכול מנויים.

    $ cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-subscriber
    type: Opaque
    data:
      subscriber: "b2RzcGFzc3dvcmQ=" # Password is odspassword
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: DBCluster
    metadata:
      name: subscriber
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-subscriber
        databaseVersion: "15.5.4"
        resources:
          memory: 10Gi
          cpu: 1
          disks:
          - name: DataDisk
            size: 40Gi
    EOF
    

הגדרת מסד הנתונים המפרסם

מגדירים את אשכול השרתים של האתר ויוצרים טבלה. אפשר גם לפרסם נתונים כבדיקה כדי לוודא שהם משוכפלים למנוי.

  1. עדכון הפרמטר wal_level ל-logical.

    $ kubectl patch dbclusters.al publisher  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. מוצאים את הפוד הרצוי.

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=publisher, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  3. נכנסים ל-Pod של מסד הנתונים של אשכול בעלי התוכן הדיגיטלי.

    NAME                                          READY   STATUS    RESTARTS   AGE
    al-2bce-publisher-0                           3/3     Running   0          36m
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    
  4. יוצרים מסד נתונים בשם customer.

    CREATE DATABASE customer;
    
  5. אופציונלי: למטרות בדיקה, מוסיפים טבלה למסד הנתונים ומזינים בה נתונים. אתם יכולים להשתמש בנתונים האלה כדי לצפות בשכפול הנתונים מהמפרסם למנוי.

    $ psql -h localhost -U postgres customer
    customer=# CREATE TABLE COMPANY(
    customer(#    ID INT PRIMARY KEY     NOT NULL,
    customer(#    NAME           TEXT    NOT NULL,
    customer(#    AGE            INT     NOT NULL,
    customer(#    SALARY         REAL
    customer(# );
    CREATE TABLE
    customer=# INSERT INTO COMPANY (ID,NAME,AGE,SALARY) VALUES
    customer-# (1, 'Quinn', 25, 65000.00),
    customer-# (2, 'Kim', 22, 72250.00),
    customer-# (3, 'Bola', 31, 53000.00),
    customer-# (4, 'Sasha', 33, 105000.00),
    customer-# (5, 'Yuri', 27, 85000.00);
    INSERT 0 5
    customer=# \dt
              List of relations
    Schema |  Name   | Type  |  Owner
    --------+---------+-------+----------
    public | company | table | postgres
    (1 row)
    
    customer=# select * from company;
    id | name  | age | salary
    ----+-------+-----+--------
      1 | Quinn  |  25 |  65000
      2 | Kim  |  22 |  72250
      3 | Bola   |  31 |  53000
      4 | Sasha |  33 | 105000
      5 | Yuri |  27 |  85000
    (5 rows)
    
  6. יוצרים משתמש logicalreplica לשכפול ולמתן הרשאות.

    CREATE USER logicalreplica WITH REPLICATION LOGIN PASSWORD '123';
    
  7. נותנים הרשאות. בדוגמה הזו נעשה שימוש בסכימה ציבורית.

    GRANT SELECT ON ALL TABLES IN SCHEMA public TO logicalreplica;
    GRANT USAGE ON SCHEMA public TO logicalreplica;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public
        GRANT SELECT ON TABLES TO logicalreplica;
    
  8. יוצרים פרסום במסד הנתונים customer.

    CREATE PUBLICATION pub_customer;
    ALTER PUBLICATION pub_customer ADD TABLE company;
    

הגדרת אשכול המנויים

מפעילים את אשכול המנויים כדי לקבל עדכוני נתונים מאשכול המפרסמים.

  1. מגדירים את הפרמטר wal_level לערך logical במסד הנתונים של המנויים.

    $ kubectl patch dbclusters.al subscriber  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. מוצאים את הפוד הרצוי.

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=subscriber, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  3. מתחברים ל-pod של מסד הנתונים של אשכול המנויים.

    $ kubectl get pod
    NAME                                          READY   STATUS    RESTARTS   AGE
    al-2bce-publisher-0                           3/3     Running   0          20h
    
    $ kubectl exec -ti al-3513-subscriber-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-3513-subscriber-0:/$
    
  4. מחפשים את כתובת ה-IP של פוד בעלי האתרים, כמו 10.116.14.190

    $ kubectl get service
    NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
    al-publisher-rw-ilb      ClusterIP      10.116.14.190   <none>         5432/TCP         21h
    
  5. מבצעים גיבוי של הסכימה מהמוציא לאור כעותק ראשוני של הנתונים שפורסמו במסד הנתונים של המוציא לאור. רפליקציה לוגית לא תומכת ברפליקציה של DDL. לפני שמתחילים ברפליקציה לוגית, הסכימה או הטבלה שרוצים לשכפל צריכה להיות קיימת ביעד (אשכול המנויים).

    postgres@al-3513-subscriber-0:/$ pg_dump -h 10.116.14.190 -U postgres --create --schema-only customer > /tmp/customer.schema-only.sql
    
  6. מחילים את הגיבוי במסד הנתונים של המנויים.

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres < /tmp/customer.schema-only.sql
    
  7. אופציונלי: מוודאים שאין נתונים בטבלה.

    # There is no data in table company
    customer=# select * from company;
    id | name | age | salary
    ----+------+-----+--------
    (0 rows)
    
  8. יוצרים מינוי למסד הנתונים customer.

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# CREATE SUBSCRIPTION sub_customer CONNECTION 'host=10.116.14.190 port=5432 user=logicalreplica dbname=customer password=123' PUBLICATION pub_customer;
    
  9. אופציונלי: מאמתים את הרפליקציה באשכול המנויים.

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# select * from public.company;
    id | name  | age | salary
    ----+-------+-----+--------
      1 | Quinn |  25 |  65000
      2 | Kim   |  22 |  72250
      3 | Bola  |  31 |  53000
      4 | Sasha |  33 | 105000
      5 | Yuri  |  27 |  85000
    (5 rows)
    
  10. באשכול של בעל האפליקציה, מוסיפים שורה לטבלה.

    # On the publisher database
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-2bce-publisher-0:/$ psql -h localhost -U postgres customer
    customer=# insert into company(id, name, age, salary) values (6, 'Alex', 39, 100000);
    
  11. באשכול המנויים, מוודאים שהשורה שנוספה לטבלה באשכול המפרסמים שוכפלה לטבלה באשכול המנויים.

    # On the subscriber database, data is synced.
    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# select * from company;
    id | name  | age | salary
    ----+-------+-----+--------
      1 | Quinn |  25 |  65000
      2 | Kim   |  22 |  72250
      3 | Bola  |  31 |  53000
      4 | Sasha |  33 | 105000
      5 | Yuri  |  27 |  85000
      6 | Alex  |  39 | 100000
    (6 rows)
    

יצירת טבלאות נוספות באופן ידני

רפליקציה לוגית לא מסנכרנת באופן אוטומטי שינויים ב-DDL, בניגוד ל-replicate_ddl_command ב-pglogical. הכלי pgl_ddl_deploy בקוד פתוח מציע פתרון, אבל אפשר גם להריץ פקודות DDL באופן ידני במנוי.

  1. כדי להמחיש את זה, יוצרים טבלה חדשה בשם finance בcustomerמסד הנתונים באשכול של בעל התוכן הדיגיטלי.

    # On the publisher database
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-2bce-publisher-0:/$ psql -h localhost -U postgres customer
    customer=# create table finance (row text);
    CREATE TABLE
    customer=# insert into finance values ('critical data');
    INSERT 0 1
    customer=# ALTER PUBLICATION pub_customer ADD TABLE finance;
    ALTER PUBLICATION
    
  2. כשמוסיפים טבלה חדשה לאשכול המפרסמים, צריך להחיל ידנית את ה-DDL (יצירת טבלה) במנוי, ואז לאמת את הרפליקציה על ידי הפעלת הפקודה הבאה באשכול המנויים.

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# create table finance (row text);
    CREATE TABLE
    customer=# ALTER SUBSCRIPTION sub_customer REFRESH PUBLICATION;
    ALTER SUBSCRIPTION
    customer=# select * from finance;
          row
    ---------------
    critical data
    (1 row)
    

המאמרים הבאים