יצירה של חריץ שכפול ופרסום

בחירת גרסה של מאמר העזרה:

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

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

מידע נוסף על רפליקציה לוגית ב-PostgreSQL זמין במאמר רפליקציה לוגית.

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

לפני שמתחילים

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

לפני שיוצרים את מיקומי השכפול, צריך ליצור את אשכול השרתים המפרסם עם שכפול לוגי מופעל. צריך להגדיר את הפרמטר wal_level לערך logical במניפסט של DBCluster.

כדי ליצור אשכול של מסד נתונים של בעל תוכן דיגיטלי עם רפליקציה לוגית מופעלת, צריך להחיל את מניפסט:

  apiVersion: v1
  kind: Secret
  metadata:
    name: db-pw-DB_CLUSTER_NAME
    namespace: DB_CLUSTER_NAMESPACE
  type: Opaque
  data:
    DB_CLUSTER_NAME: "ENCODED_PASSWORD"
  ---
  apiVersion: alloydbomni.dbadmin.goog/v1
  kind: DBCluster
  metadata:
    name: DB_CLUSTER_NAME
    namespace: DB_CLUSTER_NAMESPACE
  spec:
    databaseVersion: "ALLOYDB_OMNI_VERSION"
    spec:
    availability:
      numberOfStandbys: 1
    primarySpec:
      parameters:
        wal_level: "logical"
      adminUser:
        passwordRef:
          name: db-pw-DB_CLUSTER_NAME
      resources:
        cpu: CPU_COUNT
        memory: MEMORY_SIZE
        disks:
        - name: DataDisk
          size: DISK_SIZE

מחליפים את מה שכתוב בשדות הבאים:

  • ‫DB_CLUSTER_NAME: השם של אשכול מסד הנתונים הזה, לדוגמה publisher.

  • ‫DB_CLUSTER_NAMESPACE (אופציונלי): מרחב השמות שבו רוצים ליצור את אשכול מסד הנתונים, למשל publisher-namespace.

  • ‫ENCODED_PASSWORD: סיסמת ההתחברות למסד הנתונים של תפקיד המשתמש postgres שמוגדר כברירת מחדל, מקודדת כמחרוזת base64. לדוגמה, Q2hhbmdlTWUxMjM= בשביל ChangeMe123.

  • ‫ALLOYDB_OMNI_VERSION: גרסת AlloyDB Omni, ‏ 15.7.0 ומעלה.

  • ‫CPU_COUNT: מספר המעבדים שזמינים לכל מכונה של מסד נתונים באשכול מסדי הנתונים הזה.

  • ‫MEMORY_SIZE: כמות הזיכרון לכל מופע של מסד נתונים באשכול מסדי הנתונים הזה. מומלץ להגדיר את הערך הזה ל-8GB לכל מעבד (CPU). לדוגמה, אם הגדרתם את cpu ל-2 קודם במניפסט הזה, מומלץ להגדיר את memory ל-16Gi.

  • ‫DISK_SIZE: גודל הדיסק לכל מכונה של מסד נתונים, לדוגמה 10Gi.

יצירת משבצת רפליקציה

אחרי שיוצרים את אשכול המפרסם, אפשר ליצור משבצת רפליקציה לוגית באמצעות המשאב Replication באשכול המפרסם. כל משאב של Replication משויך למשאב של אשכול מסד נתונים תואם. לאשכול מסד נתונים יכולים להיות כמה משאבי רפליקציה לוגית שמשויכים אליו.

כדי להגדיר משבצת שכפול באשכול של השרת הראשי, צריך להחיל את המניפסט הבא:

$ cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: USER_PASSWORD_SECRET_NAME
  namespace: USER_PASSWORD_SECRET_NAMESPACE
type: Opaque
---
apiVersion: alloydbomni.dbadmin.goog/v1
kind: Replication
metadata:
  name: REPLICATION_NAME
  namespace: NAMESPACE
spec:
  dbcluster:
    name: DB_CLUSTER_NAME
  upstream:
    logicalReplication:
      pluginName: DECODER_PLUGIN
      databaseName: DATABASE_NAME
    applicationName: APPLICATION_NAME
    replicationSlotName: REPLICATION_SLOT_NAME
    synchronous: "REPLICATION_MODE"
    username: APPLICATION_USER
    password:
      name: USER_PASSWORD_SECRET_NAME
      namespace: USER_PASSWORD_SECRET_NAMESPACE
EOF

מחליפים את מה שכתוב בשדות הבאים:

  • ‫REPLICATION_NAME: שם למשאב Replication, לדוגמה replication-1.
  • ‫NAMESPACE: מרחב השמות של Kubernetes למשאב Replication הזה. הוא חייב להיות זהה למרחב השמות של אשכול מסד הנתונים.
  • ‫DB_CLUSTER_NAME: השם של אשכול מסד הנתונים שהקציתם כשיצרתם אותו.
  • ‫DECODER_PLUGIN: הגדרה לפלאגין הפענוח, כמו pgoutput, שבו רוצים להשתמש לרפליקציה לוגית. מידע נוסף על פלאגינים שונים של פענוח זמין במאמר בנושא פלאגינים של פלט.
  • ‫DATABASE_NAME: מוגדר לשם של מסד הנתונים שאת השינויים בו רוצים להזרים אל משבצת השכפול. מוודאים שמסד הנתונים כבר נוצר באשכול של בעל התוכן הדיגיטלי.
  • ‫APPLICATION_NAME (אופציונלי): מגדירים את שם האפליקציה שתתחבר למשבצת הרפליקציה. חובה למלא את השדה הזה כשמצב הסטרימינג מוגדר כסינכרוני.
  • ‫REPLICATION_MODE (אופציונלי): מגדירים ל-false לשכפול אסינכרוני. אם רוצים להפעיל שכפול סינכרוני, אבל על חשבון המהירות, מגדירים את הערך הזה כ-true. ערך ברירת המחדל הוא false, אם לא הוגדר במפורש.
  • ‫REPLICATION_SLOT_NAME: השם של משבצת השכפול שתיצור המערכת ושמשתמש המינוי ישתמש בה – לדוגמה, logicalrepltestslot.
  • ‫REPLICATION_USER (אופציונלי): שם המשתמש שמתחבר למקום השכפול. אם מגדירים את משתמש השכפול, צריך להגדיר את שם הסוד, מרחב השמות והסיסמה.
  • ‫USER_PASSWORD_SECRET_NAME (אופציונלי): שם הסוד של Kubernetes של משתמש האפליקציה. חובה, אם משתמש האפליקציה מוגדר.
  • ‫USER_PASSWORD_SECRET_NAMESPACE (אופציונלי): מרחב השמות שבו נמצא הסוד של Kubernetes למשתמש באפליקציה. חובה, אם מוגדר משתמש באפליקציה.

צפייה בסטטוס של משבצת רפליקציה

כדי לראות את הסטטוס של משבצות השכפול, מריצים את הפקודה הבאה:

kubectl get replication.alloydbomni.dbadmin.goog REPLICATION_NAME -n NAMESPACE -oyaml

השדה status ופרטים נוספים נכללים בתשובה:

apiVersion: alloydbomni.dbadmin.goog/v1
kind: Replication
metadata:
  name: REPLICATION_NAME
  namespace: NAMESPACE
...
...
status:
  conditions:
  - lastTransitionTime: "2025-01-25T06:49:25Z"
    message: Ready for replication
    reason: Ready
    status: "True"
    type: Ready
  - lastTransitionTime: "2025-01-25T06:49:25Z"
    message: Replication slot is not being used
    reason: Unhealthy
    status: "False"
    type: Healthy
  observedGeneration: 2
  upstream:
    host: DATABASE_ENDPOINT
    password:
      name: USER_PASSWORD_SECRET_NAME
      namespace: USER_PASSWORD_SECRET_NAMESPACE
    port: DATABASE_PORT
    replicationSlotName: REPLICATION_SLOT_NAME
    username: APPLICATION_USER

השדה DATABASE_ENDPOINT מציג את כתובת ה-IP שבה אתם משתמשים כדי להתחבר למסד הנתונים. הסטטוס TRUE בעמודה READY מציין שהמשבצת מוכנה לסטרימינג. כשהאפליקציה או ה-DBCluster של המנוי מתחברים למשבצת הרפליקציה, הסטטוס בעמודה HEALTHY משתנה ל-TRUE.

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

  1. מוצאים את הפוד הרצוי.

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  2. מתחברים לפוד הראשי באשכול של בעל התוכן הדיגיטלי באמצעות psql:

    psql -h IP_ADDRESS -U USERNAME -d DATABASE_NAME

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫IP_ADDRESS: כתובת ה-IP של הפוד הראשי של אשכול השרתים של בעל התוכן הדיגיטלי.
    • ‫USERNAME: משתמש postgres של מסד הנתונים.
    • ‫DATABASE_NAME: מסד הנתונים שאליו המנוי רוצה להירשם.
  3. אם ה-DATABASE_NAME שצוין במשאב הרפליקציה לא קיים, יוצרים מסד נתונים.

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

    $ psql -h localhost -U postgres DATABASE_NAME
    customer=# CREATE TABLE TABLE_NAME(
    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 TABLE_NAME (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 TABLE_NAME;
    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)
    

    מחליפים את TABLE_NAME בטבלה שבה רוצים לאחסן את הנתונים, והמנוי נרשם אליה.

  5. נותנים את ההרשאות:

    GRANT SELECT ON ALL TABLES IN SCHEMA public TO REPLICATION_USER;
    GRANT USAGE ON SCHEMA public TO REPLICATION_USER;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO REPLICATION_USER;
    
  6. מריצים את הפקודה הבאה כדי ליצור פרסום:

    CREATE PUBLICATION PUBLICATION_NAME;
    ALTER PUBLICATION PUBLICATION_NAME ADD TABLE TABLE_NAME;
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫PUBLICATION_NAME: שם הפרסום שבו המנוי ישתמש כדי להירשם.

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

מגבלות

  • אי אפשר לעדכן את ההגדרות של משבצת הרפליקציה. כדי לעדכן את ההגדרות, צריך למחוק את משבצת הרפליקציה וליצור אותה מחדש עם ההגדרות המעודכנות.

    כדי להסיר את משבצת הרפליקציה, מריצים את הפקודה הבאה:

    kubectl delete replication.alloydbomni.dbadmin.goog REPLICATION_NAME -n NAMESPACE
    
  • אפשר להגדיר את משבצת השכפול הלוגי רק במסד הנתונים של בעל התוכן הדיגיטלי. ה-API לשכפול לא תומך ב-DBCluster או באפליקציות של מנויים לשכפול לוגי.

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

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