מיגרציה מקוונת של סכמת MySQL: היכן פרודקשן נשבר
שינוי מבנה טבלה ללא השבתה נראה כפעולה שגרתית, עד ש-ALTER פוגש עומס חי. MySQL מחזיק את מטא-הנתונים של הטבלה עד לסיום הבנייה מחדש: בזמן שנכתבים מחדש מיליוני שורות, שאילתות נכנסות ממתינות לשחרור הנעילה. הידרדרות השירות תחת עומס מתחילה לפני שהפעולה עצמה מסתיימת.
נעילות טבלאות בפרודקשן הן רק הצד הראשון. בנייה מחדש ארוכה מחזיקה טרנזקציה פתוחה ומנפחת את יומן ה-rollback, ופסקי זמן בבנייה מחדש ארוכה קוטעים את התקשורת עם הרפליקות: הפיגור גדל, וחלק מהתעבורה קורא נתונים מיושנים. המשתמש רואה לא שגיאת מיגרציה, אלא שירות שהאט.
סוג כשל נפרד הוא אי-התאמת נתונים בעותקים. בנייה מחדש דרך טבלת תאום וטריגרים מעבירה שורות במנות, ומנה שאבדה בעת ההחלפה או בהתנגשות של מפתחות ייחודיים נשארת רק בגרסה הישנה של הטבלה. המיגרציה נראית מוצלחת, אך השוואת המונים חושפת אי-התאמה.
הכלי pt-online-schema-change מסיר את רוב הסיכונים הללו: מעתיק את הטבלה במנות, עוקב אחר הפיגור של העותקים ומחליף את הנתונים באמצעות שינוי שם.
אך ההתנהגות נקבעת על ידי הפרמטרים — גודל המנה, ההשהיה בעת פיגור, העומס המותר על הדיסק; כשהם מוגדרים באקראי, הם מפילים את מסד הנתונים חזק יותר מ-ALTER בודד.
מיגרציה מקוונת של סכמת MySQL היא תהליך מנוהל, ולא לחיצה על כפתור: לפניה באים מדידות, חזרה גנרלית על עותק ותוכנית rollback. נבחן היכן בדיוק פרודקשן נשבר וכיצד זה נסגר.
מה נותנת בנייה מחדש מדויקת של טבלאות ללא עצירה
ALTER TABLE רגיל על טבלה גדולה יוצר תור של שאילתות אחר מטא-נתוני הנעילה: בזמן הבנייה מחדש, הקריאות והכתיבות ממתינות, ובשירות עמוס זה נראה כזינוק בפסקי הזמן אצל הלקוחות.
בנייה מחדש של טבלאות ללא עצירת השירות בנויה אחרת: Percona Toolkit יוצר עותק צל עם המבנה הרצוי, מעביר שורות במנות ומסנכרן שינויים דרך טריגרים, בזמן שהאפליקציה ממשיכה לכתוב לטבלה המקורית.
הנעילה נשארת רק בשלב ההחלפה הסופי — שינוי שם קצר שלא מספיק לצבור תור של שאילתות. זהו בדיוק הסרת הכשלים בגלל נעילות: סוג השגיאות שבו האפליקציה ממתינה לשחרור הטבלה זמן רב יותר ממה שפסק הזמן שלה מתיר, כלל לא נוצר. חלון התחזוקה מצטמצם משעות של השבתה מתוכננת לכמה שניות, וגם זאת רק בתנאי שההחלפה עומדת בלוח הזמנים.
זמן עבודה צפוי נותנת מהירות העברה מנוהלת: בין מנות נשמרת השהיה, וכשההשהיה בעותק גדלה, התהליך נעצר אוטומטית.
הפחתת העומס על עותקי מסד הנתונים מושגת באותו מנגנון — הרפליקות לא מפגרות אחרי המאסטר, ולכן הדוחות והאנליטיקה ממשיכים לקרוא נתונים עדכניים, ולא מדביקים את המקור לאחר סיום העבודה.
בסיום הלקוח מקבל טבלה עם המבנה הרצוי, תוכנית rollback שהוכנה לפני ההרצה, ויומן העברה: נפח השורות, נקודות ההשהיה, משך ההחלפה הסופית. לוחות הזמנים לטבלה גדולה מחושבים מראש לפי הנפח ומהירות ההעברה, ולא מתבררים ברגע ההשבתה — זה מה שהופך את המיגרציה מסיכון לעבודה מתוכננת.
דרכים לבנות מחדש טבלה: השוואה של גישות ומגבלות
בחירת הדרך נקבעת על ידי שלושה פרמטרים: נפח הטבלה, הזמן המותר של אי-זמינות לכתיבה ואופי העומס.
בנייה מחדש מקוונת דרך עותק ביניים — זה pt-online-schema-change מ-Percona Toolkit — יוצרת לצד הטבלה טבלה עם המבנה החדש, מעתיקה שורות במנות ותולה טריגרים על המקור, ולכן השינויים מהאפליקציה מגיעים מיד לשתי הטבלאות.
בשלב הסופי השמות מוחלפים, ונעילת הכתיבה מסתכמת באלפיות שנייה — בדרך כלל לא מבחינים בה לא המשתמשים ולא המשימות ברקע.
גם הגבולות של הגישה מוגדרים. טבלה ללא מפתח ראשי או ייחודי אינה מעובדת — זה פוסל חלק מהטבלאות ההיסטוריות. העותק תופס אותו מקום כמו המקור, ובכתיבה צפופה הדבקת השינויים עלולה לפגר אחרי הטריגרים: אז העבודה נפסקת ומועברת לחלון תחזוקה.
| גישה | מתי מתאימה | מגבלות |
|---|---|---|
| בנייה מחדש מקוונת דרך עותק ביניים | יש מפתח ראשי, אסור לעצור את הכתיבה, הטבלה חיה תחת עומס מסביב לשעון | העותק מכפיל את המקום, אין מפתח ייחודי — לא עולה, בכתיבה צפופה ההדבקה מפגרת |
| העברה לטבלה חדשה עם השלמה | משתנה סוג המפתח, סכמת החלוקה למחיצות או שהמבנה נכתב מחדש לעומק | נדרש קוד שקורא משתי הטבלאות וזמן להשוואה; החלפת האפליקציות מתואמת |
| חלון תחזוקה מתוכנן | טבלה קטנה או בינונית, יש זמן השבתה מוסכם | הכתיבה נעצרת, חלק מהשאילתות מקבל שגיאה, נדרש צילום מוכן ל-rollback |
כלל מעשי: עד כמה מיליוני שורות וכתיבה מתונה — השיטה המקוונת; שינוי מבנה עמוק — העברה לטבלה חדשה עם השוואה לאחר מכן; טבלאות קטנות זול יותר וצפוי יותר לבנות מחדש בחלון מתוכנן, כשהכתיבה נעצרת לכמה דקות.
שלבי העבודה: מביקורת עומס ועד מסירת מסד הנתונים
סדר העבודה נבנה מהעומס, ולא מהנוחות של החלון: כל עוד הטבלה פתוחה לכתיבה, השינוי מתחרה על נעילות, מקום וקיבולת של הרפליקות. כל שלב מסתיים בתוצאה ניתנת לבדיקה, ולכן ההחלטה להמשיך מתקבלת לפי מספרים, ולא לפי תחושה.
- ביקורת עומס על מסד הנתונים. מצלמים פרופיל על פני כמה יממות: שעות שיא, שיעור פעולות הכתיבה, השאילתות הכבדות ביותר, הפיגור של הרפליקות, הגודל וקצב הגדילה של טבלאות היעד. בפלט — חלון שבו ההתערבות בטוחה.
- תכנית ביצוע העבודה. קובעים איזה שינוי נדרש, האם הטבלה נבנית מחדש במלואה או משתנה במקום, האם יספיק מקום בדיסק, כיצד יתנהגו המפתחות הזרים והטריגרים. כאן גם מופיעה הערכת משך הזמן.
- הגדרת המיגרציה. הכלי pt-online-schema-change מעביר נתונים במנות, ולכן מגדירים את גודל המנה, הפיגור המותר של הרפליקות, סף העצירה החירומית ובקרת הנעילות. הגדרה שגויה מאטה את מסד הנתונים חזק יותר מהשינוי עצמו.
- הרצת ניסיון. מריצים על עותק של מסד הנתונים הייצורי עם נפח אמיתי: מודדים זמן, התנהגות הטריגרים, ההשפעה על הרפליקות. זה נותן מספרים בפועל במקום חישובים.
- נקודת ה-rollback. קובעים את הדרך ואת הזמן לחזרה: הטבלה המקורית נשארת ללא שינוי, הצילום בוצע, החזרה נכנסת בחלון. את ה-rollback בודקים לפני ההרצה החיה, ולא אחריה.
- בדיקת שלמות הנתונים. משווים את מספר השורות וסכומי הביקורת לפני ואחרי, בודקים אינדקסים ומפתחות זרים. הסכמה החדשה נכנסת לפעולה רק בהתאמה מלאה.
- מסירת מסד הנתונים. מוסרים פרמטרים, סכמה, נוהל לשינויים חוזרים וספי ניטור, שלפיהם התורן יראה את הבעיה לפני המשתמשים.
תארו את מסד הנתונים והמשימה שלכם — נחזור עם הערכה ותוכנית לפי שלבים אלה.
מה נשאר אצל הצוות: הרכב האספקה והתיעוד
העבודה אינה מסתיימת ברגע המיגרציה המוצלחת, אלא כשצוות הלקוח יכול לחזור עליה בלעדינו. לכן באספקה נכללים לא רק ההרצה עצמה, אלא גם קונפיגורציות, סכמות של קשרים בין טבלאות ונוהלים — מה שלפיו המהנדס הבא יעבור את אותו מסלול ויקבל את אותה תוצאה.
- קונפיגורציות עבודה: פרמטרים של העתקת נתונים, ספי העומס המותר על השרת, מגבלות המתנה לנעילות ורשימת טבלאות חריגות — כקבצים שלצד המיגרציות בפרויקט.
- סכמות תלויות בין טבלאות: אילו מפתחות זרים, טריגרים וצירופי "הורה — צאצא" משפיעים על סדר העבודה, מה להעביר ראשון ומה להמתין איתו לאחרון.
- כללי גישה: חשבון נפרד עם הרשאות מינימליות מספיקות, מה בדיוק נדרש ליצירת טריגרים ולהחלפה, ומה נשאר בלתי נגיש כברירת מחדל.
- נוהל לעבודות חוזרות: סדר שלב-אחר-שלב למיגרציה הבאה — מהערכת גודל הטבלה וחלון העבודה ועד בדיקת הרפליקציה ומחיקת אובייקטים שירותיים.
- תיעוד ל-rollback: כיצד להחזיר את הסכמה הקודמת אם ההחלפה לא צלחה, אילו אובייקטים למחוק ובאיזה פרק זמן המצב חוזר למקור.
- דוח על ההרצה: זמן העיבוד של כל טבלה, השהיית הרפליקציה, מספר הניסיונות החוזרים ונקודות שבהן נדרשה התערבות מהנדס.
- סקריפטים לבדיקה: השוואת מספר השורות וסכומי הביקורת לפני ואחרי, כדי שהתוצאה תאושר בנתונים ולא במילים.
מקרה בוחן: העברת טבלה גדולה למבנה חדש ללא השבתה
צוואר הבקבוק: בנייה מחדש תחת נעילה
טבלה בת 180 מיליון שורות קיבלה כמה אלפי פעולות בשנייה, והחלפה רגילה של סוג שדה המפתח עם בנייה מחדש של האינדקסים החזיקה אותה תחת נעילה כולה.
החלון הקרוב נתן כ-40 דקות של אי-זמינות לכתיבה, צוותים סמוכים היו צריכים לעצור משימות רקע, וחלק מהשאילתות בכל זאת נפלו בגלל פסק זמן — כ-0.3% מהפעולות אבדו וטופלו ידנית.
כיצד זה עבר ובמה זה הסתיים
השתמשנו ב-pt-online-schema-change מ-Percona Toolkit: הכלי פותח עותק צל של הטבלה, תולה טריגרים על השינויים ומעביר שורות במנות, וכשההשהיה של הרפליקציה גדלה הוא מאט את הקצב בעצמו.
ההעתקה התנהלה במקביל לתעבורה העובדת, ללא חלון השבתה — שיא הערב עבר ללא הידרדרות, וההחלפה למבנה החדש ארכה חלקיקי שנייה, עם נעילה רק על החלפת הטבלה. לאחר המעבר השווינו סכומי ביקורת על כל המנות שהועברו: אפס אי-התאמות, והחזרה לטבלה המקורית נותרה זמינה עד סוף ההשוואה.
| מדד | לפני | אחרי |
|---|---|---|
| אי-זמינות לכתיבה | ~40 דקות | חלקיקי שנייה |
| פעולות שאבדו | ~0.3% | 0 |
| השוואת נתונים | סלקטיבית, ידנית | סכומי ביקורת על כל המנות |
| התנהגות בשיא | עצירת משימות רקע | המיגרציה האטה את הקצב בעצמה |
| rollback | שחזור מעותק | חזרה לטבלה המקורית |
מה לעשות אם ב-MySQL כבר יש רפליקות וטריגרים?
מתאר פרוס עם רפליקות אינו מפריע למיגרציה, אך משנה את סדר העבודה. הכלי יוצר עותק של הטבלה עם המבנה החדש, ממלא אותו במנות ומסנכרן תיקונים באמצעות טריגרים, ובסוף מחליף את המקור בשינוי שם אטומי — הרפליקות מקבלות את אותה רצף מהיומן.
טריגרים קיימים הם המכשול הראשון: כברירת מחדל הכלי נעצר אם על הטבלה כבר יש טריגרים, כדי לא לשבור לוגיקה זרה. הדגל --preserve-triggers מעביר את גופם לטבלה החדשה, אך בדקו שהם אינם מפנים לשם הישן במפורש — לאחר ההחלפה הפניות כאלה יישברו.
מפתחות זרים קובעים את המחיר ואת חלון הסיכון. המצב rebuild_constraints בונה מחדש את האילוצים של הצאצאים — ארוך יותר, אך ללא פער שבו ההפניות תלויות על טבלה שנעלמה; drop_swap מהיר יותר, אך יוצר פער כזה, ובקשרים עם מחיקה מדורגת דורש בדיקה נפרדת. כשהמפתחות מפנים גם פנימה וגם החוצה, את השינוי מריצים על עותק של המתאר כולו.
סיכון נפרד הוא מסנני הרפליקציה: אם טבלת העותק השירותית נכללת בהם, היא לא תהיה ברפליקה, ההחלפה תעבור "בהצלחה", והמבנים יתפצלו, ולכן את הקונפיגורציה משווים לפני ההתחלה, וסף --max-lag עוצר את ההעתקה בעת פיגור חזק.
כל עוד שינוי המבנה לא הגיע לכל הרפליקות, האפליקציה אסור לה לקרוא את העמודות החדשות — ברפליקה המפגרת הן עדיין לא קיימות, ומכאן קריאה מושהית של נתונים ישנים ושגיאות. עובדים בשינוי אחד לכל מעבר: הרצה, החלפה, השוואת מבנה על המאסטר וכל רפליקה, ואחר כך הבא.
ספקות טכניים: שאלות שנשאלות לפני ההתחלה
לפני בנייה מחדש של טבלה גדולה על מסד נתונים חיה עולה אותו סט שאלות: כמה ייפול על העומס החי, מה יקרה בהפסקה, כיצד יתנהגו המפתחות הזרים והטריגרים, ובמה מאושרת התוצאה. להלן תשובות שבדרך כלל נדרשות לפני תיאום החלון.
האם בנייה מחדש של הטבלה תפיל את מסד הנתונים?
ההעתקה מתנהלת במנות עם השהיות ביניהן. מוגדרים ספים לפי מספר השאילתות הפעילות והפיגור של הרפליקה: כשהם נחצים, ההעתקה נעצרת וממתינה עד שמסד הנתונים יתפנה. הפרודקשן מקבל תוספת לעומס, ולא צניחה בזמן התגובה.
מה יקרה אם מפסיקים את העבודה?
ב-Percona Toolkit, בעת עצירה או שגיאה, הכלי מסיר את הטריגרים שלו ואת הטבלה הזמנית, המקורית נשארת ללא שינוי, ואפשר להמשיך מנקודת העצירה. בלתי הפיכה היא רק ההחלפה הסופית של הטבלאות — אותה מחזיקים קצרה ועושים בחלון מתואם.
מפתחות זרים וטריגרים — מה איתם?
טבלאות הצאצא מוחלפות בשלב נפרד, אחרת המפתחות הזרים ימשיכו להפנות לישנה. טריגרים שתלו על הטבלה המקורית אינם פועלים בזמן ההעתקה — את הלוגיקה שלהם מעבירים מראש, אחרת חלק מהשינויים אובד.
כיצד לוודא שהנתונים לא אבדו?
לאחר ההחלפה משווים את מספר השורות וסכומי הביקורת לפי טווחים, ובנפרד — רשומות שהשתנו בזמן ההעתקה. אי-התאמות מטפלים בהן לפני מחיקת הטבלה הזמנית: כל עוד היא במקום, rollback עוד אפשרי.
ואם יש כמה עותקים של מסד הנתונים?
רפליקות אינן יורשות את הבנייה מחדש — את הסכמה בכל עותק מביאים במעבר משלו. או שאנחנו חוזרים על המיגרציה בכל אחת, או שבונים מחדש את העותק מגיבוי ומדביקים אותו ביומן השינויים, אם הפיגור מותר.
נדון במשימה: נשלח תוכנית עבודה והערכה
כדי לחזור עם תוכנית שלבי עבודה והערכת לוחות זמנים, אנחנו צריכים נתוני קלט על מסד הנתונים שלכם — לא "יש שרת עם MySQL" מופשט, אלא קונקרטיקה: טבלאות היעד והנפח שלהן, מנוע האחסון, קיומם של מפתחות זרים, טריגרים ותצוגות, טופולוגיית הרפליקציה, חלון העומס הנמוך.
ככל שנתוני המוצא מדויקים יותר, כך פחות הפתעות במתאר החיה: לפיהם רואים מראש היכן תידרש בנייה מחדש של הטבלה והיכן די בהחלפה דרך שינוי שם.
מה אתם מקבלים לאחר ניתוח המשימה:
- תוכנית שלבי עבודה עם סדר הפעולות: הכנה, הרצת ניסיון על עותק, מיגרציה, בדיקת שלמות הנתונים, קיבוע נקודת ה-rollback.
- הערכת לוחות זמנים עם פילוח לפי שלבים וסימון היכן נדרש חלון תיאום עם העסק.
- תכנית rollback: אילו מטא-נתונים שומרים וכיצד לחזור לטבלה המקורית אם הבדיקות לא עברו.
- רשימת סיכונים לקונפיגורציה שלכם: נעילות ארוכות, גידול בעומס על הרפליקות, פיגור של צמתי הצאצא.
- סט מדדי ליווי: השהיית הרפליקציה, מספר החיבורים הפעילים, מהירות העיבוד של השורות המועתקות.
- טיוטת נוהל למשמרת התורנית: מה לעשות כשמאותתים ההתראות ומתי לעצור את ההעברה.
את הבדיקה מבצעים על המתאר שלכם — על עותק של מסד הנתונים החיה או על סביבת בדיקה באותה קונפיגורציה, כדי שתוצאת ההרצה תועבר הלאה ללא הנחות וללא חישובים מחדש.
תארו את המשימה: אילו טבלאות נוגעים, מה העומס בשעות השיא, האם יש חלון להחלפה. נחזור עם תוכנית שלבים והערכת לוחות זמנים.







