עדכון הסכימה

ב-Spanner אפשר לעדכן את הסכימה ללא זמן השבתה. יש כמה דרכים לעדכן את הסכימה של מסד נתונים קיים:

  • במסוף Google Cloud

    שולחים פקודת ALTER TABLE בדף Spanner Studio.

    כדי לגשת לדף Spanner Studio, לוחצים על Spanner Studio בדף Database overview (סקירה כללית של מסד הנתונים) או בדף Table overview (סקירה כללית של הטבלה).

  • שימוש בכלי שורת הפקודה gcloud spanner

    מריצים את הפקודה ALTER TABLE באמצעות הפקודה gcloud spanner databases ddl update.

  • שימוש בספריות לקוח

  • שימוש ב-REST API של projects.instances.databases.updateDdl

  • שימוש ב-RPC API‏ UpdateDatabaseDdl

עדכוני סכימה נתמכים

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

  • מוסיפים או מסירים סכימה עם שם.
  • ליצור טבלה חדשה. העמודות בטבלאות החדשות יכולות להיות NOT NULL.
  • למחוק טבלה, אם אין בתוכה טבלאות אחרות שמשולבות בה, ואין לה אינדקסים משניים.
  • יצירה או מחיקה של טבלה עם מפתח זר.
  • הוספה או הסרה של מפתח זר מטבלה קיימת.
  • הוספה של עמודה שאינה עמודת מפתח לכל טבלה. אי אפשר NOT NULL עמודות חדשות שהן לא עמודות מפתח.
    • אפשר להסיר עמודה שאינה עמודת מפתח מכל טבלה, אלא אם היא משמשת אינדקס משני, מפתח זר, עמודה וירטואלית מאוחסנת או אילוץ בדיקה.
  • הוספה של NOT NULL לעמודה שהיא לא עמודת מפתח, לא כולל עמודות ARRAY.
  • הסרת NOT NULL מעמודה שאינה עמודת מפתח.
  • שינוי עמודה מסוג STRING לעמודה מסוג BYTES או עמודה מסוג BYTES לעמודה מסוג STRING.
  • שינוי עמודה מסוג PROTO לעמודה מסוג BYTES או עמודה מסוג BYTES לעמודה מסוג PROTO
  • שינוי סוג הודעת הפרוטו של עמודה מסוג PROTO.
  • כדי להוסיף ערכים חדשים להגדרה של ENUM ולשנות את השם של ערכים קיימים, משתמשים ב-ALTER PROTO BUNDLE.
  • לשנות הודעות שמוגדרות ב-PROTO BUNDLE בדרכים שרירותיות, בתנאי שהשדות ששונו בהודעות האלה לא משמשים כמפתחות באף טבלה, ושהנתונים הקיימים עומדים באילוצים החדשים.
  • להגדיל או להקטין את מגבלת האורך של סוג STRING או BYTES (כולל MAX), אלא אם מדובר בעמודה של מפתח ראשי שעברה בירושה מטבלה אחת או יותר של צאצאים.
  • מגדילים או מקטינים את מגבלת האורך של עמודה מסוג ARRAY<STRING>,‏ ARRAY<BYTES> או ARRAY<PROTO> למקסימום המותר.
  • הפעלה או השבתה של חותמות זמן של ביצוע פעולות (commit) בעמודות של ערכים ומפתחות ראשיים.
  • להוסיף או להסיר אינדקס משני.
  • הוספה או הסרה של אילוץ מסוג check מטבלה קיימת.
  • הוספה או הסרה של עמודה וירטואלית מאוחסנת מטבלה קיימת.
  • יוצרים חבילת נתונים סטטיסטיים חדשה לאופטימיזציה.
  • יצירה וניהול של תצוגות.
  • ליצור רצפים ולנהל אותם.
  • ליצור תפקידים במסד הנתונים ולהעניק הרשאות.
  • הגדרת ערך ברירת מחדל של עמודה, שינוי שלו או הסרה שלו.
  • לשנות את האפשרויות של מסד הנתונים (לדוגמה, default_leader או version_retention_period).
  • יצירה וניהול של סנכרון שינויים בזרמי נתונים.
  • יצירה וניהול של מודלים של למידת מכונה.

עדכוני סכימה שלא נתמכים

‫Spanner לא תומך בעדכוני הסכימה הבאים של מסד נתונים קיים:

  • אם יש שדה PROTO מסוג ENUM שהפניה אליו מופיעה בטבלה או במפתח אינדקס, אי אפשר להסיר ערכים של ENUM מ-proto enums. (הסרה של ערכי ENUM מ-enums שמשמשים עמודות ENUM<> נתמכת, כולל כשמשתמשים בעמודות האלה כמפתחות).

  • שינוי עמודה מסוג STRING(36) לעמודה מסוג UUID או עמודה מסוג UUID לעמודה מסוג STRING(36).

ביצועים של עדכון סכימה

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

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

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

עדכוני סכימה שאומתו מול הגדרות התצוגה

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

עדכוני סכימה שדורשים אימות נתונים

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

לדוגמה, נניח שהגדרתם את הקובץ music.proto הבא עם ספירה (enum) של RecordLabel והודעת פרוטוקול של Songwriter:

  enum RecordLabel {
    COOL_MUSIC_INC = 0;
    PACIFIC_ENTERTAINMENT = 1;
    XYZ_RECORDS = 2;
  }

  message Songwriter {
    required string nationality   = 1;
    optional int64  year_of_birth = 2;
  }

כדי להוסיף טבלת Songwriters לסכימה:

GoogleSQL

CREATE PROTO BUNDLE (
  googlesql.example.music.Songwriter,
  googlesql.example.music.RecordLabel,
);

CREATE TABLE Songwriters (
  Id         INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  Nickname   STRING(MAX),
  OpaqueData BYTES(MAX),
  SongWriter googlesql.example.music.Songwriter
) PRIMARY KEY (Id);

CREATE TABLE Albums (
  SongwriterId     INT64 NOT NULL,
  AlbumId          INT64 NOT NULL,
  AlbumTitle       STRING(MAX),
  Label            INT32
) PRIMARY KEY (SongwriterId, AlbumId);

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

  • הוספת ההערה NOT NULL לעמודה שאינה עמודת מפתח. לדוגמה:

    ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL;
    
  • הקטנת האורך של עמודה. לדוגמה:

    ALTER TABLE Songwriters ALTER COLUMN FirstName STRING(10);
    
  • השינוי מ-BYTES ל-STRING. לדוגמה:

    ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);
    
  • השינוי מ-INT64/INT32 ל-ENUM. לדוגמה:

    ALTER TABLE Albums ALTER COLUMN Label googlesql.example.music.RecordLabel;
    
  • הסרת ערכים קיימים מהגדרת ה-enum של RecordLabel.

  • הפעלת חותמות זמן של ביצועים בעמודה קיימת של TIMESTAMP. לדוגמה:

    ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);
    
  • הוספת אילוץ מסוג CHECK לטבלה קיימת.

  • הוספת עמודה וירטואלית מאוחסנת לטבלה קיימת.

  • יצירת טבלה חדשה עם מפתח זר.

  • הוספת מפתח זר לטבלה קיימת.

עדכוני הסכימה האלה ייכשלו אם נתוני הבסיס לא יעמדו באילוצים החדשים. לדוגמה, ההצהרה ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL תיכשל אם ערך כלשהו בעמודה Nickname הוא NULL, כי הנתונים הקיימים לא עומדים במגבלת NOT NULL של ההגדרה החדשה.

תהליך אימות הנתונים יכול להימשך כמה דקות עד כמה שעות. הזמן שיידרש להשלמת אימות הנתונים תלוי בגורמים הבאים:

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

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

אפשר לבטל פעולה ממושכת של אימות נתונים באמצעות ה-method‏ projects.instances.databases.operations.cancel או באמצעות gcloud spanner operations.

גרסאות סכימה שנוצרו במהלך עדכוני סכימה

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

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

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

פעולת סכימה משך משוער
CREATE TABLE דקות
CREATE INDEX

דקות עד שעות, אם טבלת הבסיס נוצרת לפני האינדקס.

דקות, אם ההצהרה מופעלת באותו זמן כמו ההצהרה CREATE TABLE עבור טבלת הבסיס.

DROP TABLE דקות
DROP INDEX דקות
ALTER TABLE ... ADD COLUMN דקות
ALTER TABLE ... ALTER COLUMN

דקות עד שעות, אם נדרש אימות ברקע.

דקות, אם לא נדרש אימות ברקע.

ALTER TABLE ... DROP COLUMN דקות
ANALYZE

בין דקות לשעות, בהתאם לגודל מסד הנתונים.

שינויים בסוגי נתונים וסנכרון שינויים בזרמי נתונים

אם משנים את סוג הנתונים של עמודה שזרם שינויים עוקב אחריה, השדה column_types של רשומות רלוונטיות של זרם השינויים ישקף את הסוג החדש, וכך גם נתוני ה-JSON old_values בשדה mods של הרשומות.

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

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