WEBA

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

מנוע ה-pg-delta החדש סוגר שנים של חורים בסנכרון הרשאות ו-RLS, אבל סטטוס האלפא ומחיקת עמודות בשינוי שם דורשים בדיקה ידנית של כל קובץ.

551 מילים29 עובדות אומתו

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

זהירות נדרשת כאן.

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

סוף לטלאים הידניים של ההרשאות

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

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

במקום לנסות לפרש קובצי טקסט מבחוץ, המנוע החדש מעלה שתי סביבות שרת זמניות בתוך Docker, טוען אליהן את הסכמה וההיסטוריה, וקורא ישירות מקטלוג המערכת של מנוע Postgres חי בגרסאות 14 עד 18. הגישה הזו מייצרת גרף תלויות אמיתי ומפרידה בין אובייקטים פנימיים כמו auth לבין טריגרים ששייכים למשתמש, כך שפקודות grant ומדיניות RLS נכנסות סוף סוף לקובץ המיגרציה בצורה סדורה.

מנגנון חכם אבל מסוכן לדאטה

למרות ההתקדמות הטכנולוגית, pg-delta נשאר כלי בגרסת אלפא מוקדמת שמסוכן להריץ באוטומציה מלאה. הבעיה הבולטת ביותר היא הטיפול בשינוי שמות: המנוע אינו יודע לזהות שעמודה קיימת קיבלה שם חדש. במקום להפיק פקודת rename בטוחה, הוא מייצר פקודת drop ואחריה פקודת add חדשה. אם תדחפו שינוי כזה לפרויקט חי, כל המידע שהיה באותה עמודה יימחק לחלוטין ברגע שהקובץ ירוץ.

בנוסף, הכלי מגדיר גבולות ברורים ומסרב לטפל בשינויי נתונים. הוא לא מייצר פקודות לעדכון או הוספת שורות, למעט במקרים חריגים של הרחבות כמו pg_cron ו-pgmq שבהם הגדרות המערכת נשמרות כרשומות בטבלאות פנימיות. הגדרות של Storage buckets נותרו כרגע מחוץ לתחום הדקלרטיבי, ומי שמקים תיקיית אחסון חדשה בלוח הניהול יצטרך להמשיך להגדיר אותה בקובצי seed או במיגרציה ידנית.

השוואת יכולות הליבה בין מנוע migra הישן ל-pg-delta
תכונהmigra (המנוע הישן)pg-delta (המנוע החדש)
קריאת סכמההשוואת שני בסיסי נתונים חייםקטלוג מערכת מתוך Postgres חי
מדיניות RLSיצירה ומחיקה בלבדיצירה, מחיקה ועדכון (Alter)
הגדרת security_invoker בתצוגותנשמטת מההגדרהנשמרת במלואה
הרשאות עמודות ותפקידיםלא נבדקים בקובץנסרקים ומתווספים לפלט
התנהגות עם אובייקטים לא נתמכיםהשמטה שקטההתרעה ואפשרות להכשיל CI
סידור קבצים דקלרטיבייםסדר אלפביתי או הגדרה ידניתגרף תלויות אוטומטי מהקטלוג

איך מדליקים ומתי להיזהר

כדי להתחיל לעבוד עם המנוע יש צורך בגרסה 2.119 של ה-CLI ומעלה. פרויקטים חדשים מקבלים אותו מוגדר מראש, אבל פרויקטים קיימים צריכים להוסיף את המקטע experimental.pgdelta לקובץ config.toml ולהפעיל את הדגל. בפעם הראשונה שתבצעו משיכה מול פרויקט פעיל תיווצר מיגרציית יישור קו שתתפוס את כל ההערות והתפקידים שהמנוע הקודם החמיץ. לפי הדוקומנטציה של Supabase, פקודת הסנכרון הדקלרטיבית החדשה מחליפה את ה-diff הישן בכל מקום שבו מייצרים מיגרציות מקובצי סכמה.

אם אתם מריצים בדיקות אוטומטיות בצינורות CI, מומלץ להצמיד לפקודה את הדגל strict-coverage. הדגל גורם לתהליך להיכשל מיד אם קיים במסד הנתונים אובייקט שהמנוע אינו תומך בו, במקום להדפיס אזהרה בלבד בקונסול. במידה ונוצר קובץ שגוי או שהסביבה אינה מתנהגת כמצופה, אפשר תמיד לחזור אחורה באופן נקודתי באמצעות הדגל use-migra בפקודת ההשוואה.

לא הייתי ממהר.

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

מה לעשות עכשיולהפעיל את המנוע החדש כדי ללכוד הרשאות ו-RLS, אך לבדוק ידנית כל קובץ כדי למנוע מחיקת עמודות בשינוי שם.

מקורות

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

מה שואלים על זה

האם המנוע החדש מוחק מידע קיים אם רק שיניתי שם של עמודה?

כן. המנוע מתרגם כרגע שינוי שם של עמודה בתור מחיקה (Drop) של העמודה הישנה ויצירה (Add) של עמודה חדשה. הרצה של המיגרציה הזו בייצור ללא תיקון ידני לפקודת Rename תמחק את כל המידע שהיה קיים באותה עמודה.

איך מונעים מ-CI להיכשל אם יש אובייקטים שהמנוע עדיין לא מכיר?

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

האם חובה להשתמש ב-Docker כדי לייצר מיגרציות ב-pg-delta?

כברירת מחדל ה-CLI מריץ שני מסדי נתונים זמניים בתוך Docker או Podman. עם זאת, קיימת אפשרות להשתמש בסביבת ריצה טבעית (native runtime) ללא מנוע קונטיינרים במערכות לינוקס או macOS מבוססות Apple silicon.

מה קורה להגדרות ה-Storage buckets כשמייצרים סכמה דקלרטיבית?

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