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

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

ב-PostgreSQL, ‏ logical replication היא שיטה להעתקת שינויים בנתונים ממסד נתונים של מפרסם למנוי אחד או יותר, שיכולים להיות מסדי נתונים או אפליקציות אחרות. אתם יכולים להפעיל ולהגדיר שכפול לוגי באשכולות שאתם יוצרים באמצעות 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.5"
        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.5"
        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 של ה-pod של בעל האתר, כמו 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)
    

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