העברה מ-PostgreSQL אל Spanner (ניב PostgreSQL)

בדף הזה מוסבר איך להעביר מסד נתונים של PostgreSQL בקוד פתוח (מעכשיו נתייחס אליו כאל PostgreSQL) למסד נתונים של Spanner עם ניב PostgreSQL (מעכשיו נתייחס אליו כאל Spanner).

למידע על מעבר ל-Spanner ולניב GoogleSQL, אפשר לעיין במאמר העברה מ-PostgreSQL ל-Spanner (ניב GoogleSQL).

מגבלות על העברה

ב-Spanner יש מושגים מסוימים ששונים מאלה שבכלים אחרים לניהול מסדי נתונים ברמת הארגון, ולכן יכול להיות שתצטרכו לשנות את הארכיטקטורה של האפליקציה כדי למצות את היכולות של Spanner. יכול להיות שתצטרכו גם להשתמש בשירותים אחרים מ-Google Cloud בנוסף ל-Spanner כדי לענות על הצרכים שלכם.

תהליכים מאוחסנים וטריגרים

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

רצפים

‫Spanner ממליץ להשתמש בגרסה 4 של UUID כשיטת ברירת המחדל ליצירת ערכים של מפתח ראשי. הפונקציה GENERATE_UUID() (GoogleSQL, PostgreSQL) מחזירה ערכים של מזהה ייחודי אוניברסלי (UUID) בגרסה 4 שמיוצגים כסוג STRING.

אם אתם צריכים ליצור ערכים של מספרים שלמים, Spanner תומך ברצפים חיוביים עם היפוך סיביות (GoogleSQL,‏ PostgreSQL), שמפיקים ערכים שמפוזרים באופן שווה על פני מרחב המספרים החיוביים של 64 ביט. אפשר להשתמש במספרים האלה כדי למנוע בעיות בשימוש בנקודה חמה.

מידע נוסף מופיע במאמר בנושא אסטרטגיות של ערכי ברירת מחדל למפתח ראשי.

בקרות גישה

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

תהליך ההעברה

ההעברה כוללת את המשימות הבאות:

  1. מיפוי סכימת PostgreSQL ל-Spanner.
  2. תרגום של שאילתות SQL.
  3. יצירת מכונה, מסד נתונים וסכימה ב-Spanner.
  4. הגדרת רמת הבידוד של הטרנזקציה ובקרת בו-זמניות.
  5. שינוי מבנה האפליקציה כדי שתפעל עם מסד הנתונים של Spanner.
  6. העברת הנתונים.
  7. אימות המערכת החדשה והעברתה לסטטוס של סביבת ייצור.

שלב 1: מיפוי של סכימת PostgreSQL ל-Spanner

השלב הראשון בהעברת מסד נתונים מ-PostgreSQL בקוד פתוח ל-Spanner הוא לקבוע אילו שינויים בסכימה צריך לבצע.

מקש במקלדת הראשית

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

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

מדדים

‫PostgreSQL b-tree indexes דומים לsecondary indexes ב-Spanner. במסד נתונים של Spanner, משתמשים באינדקסים משניים כדי ליצור אינדקס לעמודות שמתבצע בהן חיפוש לעיתים קרובות, וכדי להחליף אילוצים של UNIQUE שצוינו בטבלאות. לדוגמה, אם ב-PostgreSQL DDL מופיעה ההצהרה הבאה:

     CREATE TABLE customer (
        id CHAR (5) PRIMARY KEY,
        first_name VARCHAR (50),
        last_name VARCHAR (50),
        email VARCHAR (50) UNIQUE
     );

You can use the following statement in your Spanner DDL:

    CREATE TABLE customer (
       id VARCHAR(5) PRIMARY KEY,
       first_name VARCHAR(50),
       last_name VARCHAR(50),
       email VARCHAR(50)
       );

    CREATE UNIQUE INDEX customer_emails ON customer(email);

כדי למצוא את האינדקסים של אחת מהטבלאות שלכם ב-PostgreSQL, מריצים את פקודת המטא \di ב-psql.

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

מערכת Spanner מטמיעה אינדקסים כטבלאות, ולכן יצירת אינדקס לעמודות עם ערכים שעולים באופן מונוטוני (כמו אלה שמכילות נתוני TIMESTAMP) עלולה לגרום לנקודה חמה. מידע נוסף על שיטות למניעת נקודות חמות זמין במאמר What DBAs need to know about Spanner, part 1: Keys and indexes.

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

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

יש סיכוי גבוה יותר שאופטימיזציית השאילתות של Spanner תשתמש באינדקס משני אם האינדקס עצמו מאחסן את כל העמודות שנכללות בשאילתה (שאילתה מכוסה). כדי לאלץ שימוש באינדקס כששולחים שאילתות לגבי עמודות שלא מאוחסנות באינדקס, צריך להשתמש בהוראה FORCE INDEX בהצהרת ה-SQL, לדוגמה:

SELECT *
FROM MyTable /*@ FORCE_INDEX=MyTableIndex */
WHERE IndexedColumn=$1;

הנה דוגמה להצהרת DDL שיוצרת אינדקס משני לטבלה Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

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

תצוגות

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

עמודות שנוצרו

‫Spanner תומך בעמודות שנוצרו. במאמר יצירה וניהול של עמודות שנוצרו על ידי מערכת מפורטים הבדלים בתחביר והגבלות.

שילוב טבלאות

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

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

אתם יכולים להגדיר ON DELETE פעולות לטבלאות צאצא כדי לקבוע מה יקרה כששורת האב תימחק: כל שורות הצאצא יימחקו, או שמחיקת שורת האב תיחסם אם קיימות שורות צאצא.

הנה דוגמה ליצירת טבלת אלבומים שמשולבת בטבלת האבות Singers שהוגדרה קודם:

CREATE TABLE Albums (
 SingerID      bigint,
 AlbumID       bigint,
 AlbumTitle    varchar,
 PRIMARY KEY (SingerID, AlbumID)
 )
 INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

מידע נוסף זמין במאמר בנושא יצירת טבלאות משולבות.

סוגי הנתונים

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

סוג נתונים שימוש במקום זאת
bigserial,serial8 bigint, int8
ביט [ (n) ] -
bit varying [ (n) ], varbit [ (n) ] -
תיבה -
‫character [ (n) ], char [ (n) ] character varying
cidr טקסט
מעגל -
inet טקסט
מספר שלם, int4 bigint, int8
‫interval [fields] [ (p) ] bigint
json jsonb
שורה -
lseg -
macaddr טקסט
כסף מספרי, עשרוני
נתיב -
pg_lsn -
נקודה -
פוליגון -
realfloat4 דיוק כפול, float8
smallint, int2 bigint, int8
smallserial, serial2 bigint, int8
‫serial, ‏ serial4 bigint, int8
שעה [ (p) ] [ בלי אזור זמן ] טקסט, בפורמט HH:MM:SS.sss
‫time [ (p) ] with time zonetimetz טקסט, בסימון HH:MM:SS.sss+ZZZZ. אפשר גם להשתמש בשתי עמודות.
חותמת זמן [ (p) ] [ בלי אזור זמן ] text או timestamptz
tsquery -
tsvector -
txid_snapshot -
uuid text או bytea
xml טקסט

שלב 2: תרגום של שאילתות SQL

ב-Spanner יש הרבה פונקציות של PostgreSQL בקוד פתוח שזמינות כדי להקל על המעבר.

אפשר ליצור פרופיל של שאילתות SQL באמצעות הדף Spanner Studio במסוף Google Cloud כדי להריץ את השאילתה. באופן כללי, שאילתות שמבצעות סריקות מלאות של טבלאות גדולות הן יקרות מאוד, ולכן מומלץ להשתמש בהן במשורה. מידע נוסף על אופטימיזציה של שאילתות SQL זמין במאמר שיטות מומלצות לשימוש ב-SQL.

שלב 3: יוצרים את מכונת Spanner, מסד הנתונים והסכימה

יוצרים את המכונה ויוצרים מסד נתונים בניב PostgreSQL. לאחר מכן יוצרים את הסכימה באמצעות שפת הגדרת הנתונים (DDL) של PostgreSQL.

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

למידע נוסף:

שלב 4: הגדרת רמת בידוד של טרנזקציה ובקרת בו-זמניות

רמת הבידוד שמוגדרת כברירת מחדל בעסקאות ב-Spanner היא בידוד ניתן לסידור, שמבטיח עקביות חיצונית של הנתונים. ‫Spanner מציע גם בידוד קריאה חוזרת. מומלץ להגדיר את רמת הבידוד ל-repeatable read ואת בקרת בו-זמניות ל-pessimistic concurrency כחלק מתהליך העברת האפליקציה, כדי שהסמנטיקה של העסקאות ב-Spanner תתאים באופן הדוק לסמנטיקה של עסקאות ברירת המחדל ב-PostgreSQL. הוראות להגדרת רמת הבידוד ובקרת הגישה בו-זמנית באפליקציה מופיעות במאמרים שימוש ברמת הבידוד 'קריאה חוזרת' והגדרת בקרת גישה בו-זמנית.

שלב 5: שינוי מבנה האפליקציה

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

שלב 6: העברת הנתונים

יש שתי דרכים להעביר את הנתונים:

  • שימוש בכלי ההעברה של Spanner.

    כלי ההעברה של Spanner תומך בהעברת סכימות ונתונים. אפשר לייבא קובץ pg_dump או קובץ CSV, או לייבא נתונים באמצעות חיבור ישיר למסד הנתונים של PostgreSQL בקוד פתוח.

  • באמצעות הפקודה COPY FROM STDIN.

    פרטים נוספים זמינים במאמר בנושא פקודת COPY לייבוא נתונים.