מדוע נופל צבר PostgreSQL בעל זמינות גבוהה בעת כשל של צומת
צבר של שלושה צמתים נראה עמיד בפני תקלות בדיוק עד לכשל הראשון של הצומת הראשי. זרם השכפול נפסק, אישורי כתיבה סינכרונית מפסיקים להגיע, הרפליקה עוברת למצב קריאה בלבד: בסיס הנתונים פורמלית חי, אך אינו יכול לקלוט נתונים חדשים. שני שרתים מתוך שלושה בריאים, אך הכתיבה מושבתת.
מכאן מתחיל מעבר ידני לפי הנחיות: להעלות את הרפליקה, להעביר אותה לתפקיד הצומת הראשי, לכתוב מחדש את התצורה, להעביר את הכתובת הווירטואלית, ולבנות מחדש את השרת הישן כרפליקה. במצב רגוע מדובר בעשרות דקות, בלילה ללא גישה למסוף — זמן רב יותר, וכל צעד ידני מותיר מקום לטעות.
האפליקציה ממשיכה באותו זמן להחזיק חיבורים לצומת המת. מאגר החיבורים אינו יודע שמאחורי הכתובת אין שרת, וממשיך להקצות חיבורים חדשים לאותה כתובת — הפעלה מחדש של שירותים או עריכת מחרוזות החיבור הופכות למשימה נפרדת. כתוצאה מכך, זמן ההשבתה של בסיס הנתונים מתארך לשעות, אף שהבסיס כבר הועלה עד אז.
מחיר נפרד — המצב שלאחר התקלה. חלק מהטרנזקציות לא הגיעו לרפליקה, ולאחר הבנייה מחדש היא מפגרת ומדביקה את הזרם הראשי במשך שעות. אם הועלה צומת שני ולא כבו את הישן, נוצרים שני צמתים ראשיים, ואת הפערים בנתונים יש לפרק שורה אחר שורה.
הסיבה אינה בחומרה, אלא בהיעדר אוטומציה: ההחלטה על כשל אינה מתקבלת לפי כלל פורמלי, הצומת הראשי החדש אינו נבחר, והכתובת אינה עוברת. בהמשך נסביר כיצד זה נסגר באמצעות שילוב של Patroni עם אחסון מצב מבוזר ונקודת כניסה אחודה לאפליקציות.
מה נותן צבר עמיד בפני תקלות: אפקט מדיד
שחזור ידני לאחר כשל של הצומת הראשי הוא עשרות דקות של השבתה: האפליקציה צוברת שגיאות חיבור, תור המשימות שלא טופלו גדל, והתורן מעלה ידנית את הרפליקה ובודק את שלמות הנתונים. צבר בזמינות גבוהה המבוסס על Patroni עושה זאת בעצמו — אי-זמינות בסיס הנתונים נמדדת בשניות, ולא בדקות.
זמן שחזור. המדד המרכזי — כמה זמן עובר מהיעלמות הצומת הראשי ועד לקליטת כתיבות חדשות. ספי בדיקת הבריאות ומספר הרפליקות המאושרות נכוונים כך שהמעבר האוטומטי יסתיים בתוך שניות בודדות עד עשרות שניות, אך לא יופעל באופן שגוי עקב תקלות רשת קצרות-מועד. טרנזקציות שכבר אושרו ללקוח אינן הולכות לאיבוד בתהליך זה.
מעבר אוטומטי. שיעור הכשלים שהצבר מטפל בהם ללא אדם שואף למאה אחוזים: צומת נפל — תפקיד הראשי עבר לרפליקה, והאפליקציה התחברה מחדש לאותה כתובת. ידי המהנדס נדרשות רק לעבודות מתוכננות: עדכונים, שינויי טופולוגיה ומעבר בין אתרים.
אילו כשלים נמנעים. צבר עמיד בפני תקלות מכסה מחלקה שלמה של תקלות: פיצול (split-brain), שבו הכתיבה מתבצעת לשני צמתים בו-זמנית, וקריאה של נתונים מיושנים מרפליקה מפגרת.
תחת עומס נוצרת צפיות — הקריאה מתחלקת בין הרפליקות, הכתיבה עוברת לצומת הראשי, ונפילה של רפליקה אחת כלל אינה מורגשת על ידי האפליקציה.
אפשרויות ארגון PostgreSQL: השוואת גישות
ההבדל בין הסכמות ניכר לא בעבודה רגועה, אלא ברגע הכשל: כמה טרנזקציות אבדו וכמה זמן בסיס הנתונים אינו קולט כתיבה. להלן ארבע אפשרויות שאנו פורסים בפועל, עם המגבלות שכדאי להכיר לפני ההטמעה, ולא בזמן התקלה.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| שכפול זרימה עם גיבוי חם | קריאה ודוחות עוברים לרפליקות, מותר אובדן של השניות האחרונות של הנתונים | המעבר נעשה ביד, קיים חלון אי-זמינות לכתיבה, והפיגור של הרפליקה מועבר למנהיג החדש |
| גיבוי סינכרוני | הנתונים קריטיים: חישובים, הנהלת חשבונות, החלפה עם מערכות חיצוניות | זמן אישור הכתיבה גדל; בעת נפילת הגיבוי נדרשת מדיניות — להמתין או להמשיך ללא סינכרוניות |
| צבר מנוהל בשליטתנו | נדרש מעבר אוטומטי וכיוונון פרמטרים לפרופיל העומס | דורש ניטור, תרגולי מעבר תקופתיים ומשמעת בעדכונים |
| שירות מנוהל חיצוני | אין צוות תפעול פנימי, העומס סטנדרטי וצפוי | פחות שליטה על פרמטרים והרחבות, מעבר לספק אחר יקר |
הבחירה נקבעת לפי שני מספרים: זמן אי-הזמינות המותר ונפח הטרנזקציות שאבדו שמותר. היכן שאובדן נתונים אינו מתקבל על הדעת, אנו בונים צבר עם מעבר תפקידים אוטומטי (Patroni) וגיבוי סינכרוני, ואת הגיבוי החם משאירים לקריאה ולדיווח.
שלבי ההטמעה: ביקורת, סכמה, כיוונון, בדיקה, מסירה
סדר העבודות נבנה כך שכל החלטה נבדקת לפני הפרודקשן: תחילה מתעדים עובדות על הצבר הנוכחי, לאחר מכן מתכננים את הסכמה המטרה, ורק אז משנים משהו בצמתי הייצור. סדר כזה מסיר את הסיכון המרכזי — ״תיקנו פרמטר, והשלכות ראינו ברגע התקלה״.
- ביקורת תצורה. מתעדים את פרמטרי Patroni, פרמטרי השכפול, פריסת הצמתים לפי אזורי זמינות, והתנהגות מאגר החיבורים והאפליקציות בעת ניתוק הקשר עם המאסטר. התוצר — רשימת נקודות כשל והערכה של זמן אי-הזמינות שהצבר מספק כיום.
- תכנון סכמת המעבר. קובעים את מספר הצמתים והקוורום, מצב השכפול הסינכרוני, סדר בחירת המנהיג החדש, תפקיד הבורר וחלון המעבר המטרה. מתעדים מה קורה לטרנזקציות שלא הספיקו להגיע לרפליקות.
- בניית מתקן בדיקה. פורסים עותק של הטופולוגיה המטרה, מריצים עומס ותרחישי כשל. כאן גם בודקים את התאימות לגרסאות האפליקציות הנוכחיות ואת תקינות מחרוזות החיבור.
- כיוונון בצמתי הייצור. מכניסים את הצמתים בשלבים, מהרפליקות אל המאסטר, כדי שבכל רגע תישאר נקודת חזרה. מגדירים בדיקות חיות, פסקי זמן ושחזור אוטומטי של רפליקה מפגרת.
- בדיקת כשלים. הורגים את המאסטר, מנתקים את הרשת בין האזורים, מאטים את הדיסק, מכבים צומת של אחסון המצב — ובוחנים כיצד הצבר מתנהג ללא התערבות. כל תרחיש חוזרים עליו עד שהתוצאה נעשית צפויה.
- מסירה לתפעול. מוסרים נוהל למעבר מתוכנן, לוחות בקרה והתראות, סדר פעולות בעת איבוד קוורום, והנחיות להחזרת התצורה למצבה הקודם. מקיימים סבב הסבר עם צוות הלקוח על מתקן חי.
לאחר המסירה יש לצוות לא רק צבר עובד, אלא גם הבנה מדוע הוא בנוי דווקא כך — ניתן להעריך כל שינוי בפרמטרים לפני שהוא נכנס לייצור.
תצורות, סכמות מעבר ונוהלי תפעול
לאחר המסירה נשאר לצוות שלכם לא אוסף של הסכמות בעל-פה, אלא ערכת עבודה של תוצרים: תצורות, סכמות, מדיניות ונוהלים. כל מסמך קשור לפעולה קונקרטית של התורן — לפיו ניתן להעלות צבר מאפס, לבצע מעבר מתוכנן או לנתח תקרית בלי שמחבר התצורה יהיה זמין.
- תצורות כל הצמתים — קבצי Patroni, פרמטרי PostgreSQL, הגדרות DCS: במאגר עם היסטוריית שינויים, ולא מפוזרים על השרתים. כל תיקון עובר סקירה ומתבטל ברוויזיה אחת.
- סכמת הטופולוגיה — אילו צמתים, היכן הרפליקה הסינכרונית, אילו נקודות כשל קיימות ומה קורה עם אובדן צומת או אחסון מצב.
- מדיניות גישה — תפקידים והרשאות, הפרדה בין האפליקציה לניהול, סדר מתן גישות לתורנים ורוטציה של פרטי הזדהות.
- גיבוי — לוח זמנים לגיבויים מלאים ואינקרמנטליים, עומק השמירה, ארכוב רציף של יומנים ונקודת שחזור מובטחת.
- נוהל תפעול — מעבר מתוכנן, חלונות תחזוקה, עדכון ברפליקות, פעולות בעת אובדן צומת וקריטריונים להסלמה.
- הנחיות לתורנים — תרחישים שלב-אחר-שלב עם פקודות ובדיקות: מה התורן עושה בעצמו, ובאיזה שלב הוא מזעיק מהנדס.
- תיעוד הצבר — סכמת שחזור לאחר תקלה, תוצאות תרגולים ויומן שינויים עם אחראי לכל אחד.
את הערכה מוסרים יחד עם הדרכות למשמרת התורנים: שניים-שלושה סבבי תרגול במתקן בדיקה, שבהם המהנדסים שלכם מבצעים את המעבר ואנחנו רק צופים.
מקרה בוחן: כיצד הוחלף מעבר ידני באוטומטי
צבר של שלושה צמתים פעל על שכפול זרימה, אך מעבר התפקידים נותר ידני: התורן, לפי הנחיות באורך שני עמודים, העלה את הרפליקה והעביר את התעבורה.
האפליקציה באותו זמן הייתה מושבתת — מהתרעת הניטור ועד חזרת הכתיבה חלפו כארבעים דקות, וברבעון הצטברו חמש-שש תקלות כאלה, מחציתן בלילה ובסופי שבוע.
העברנו את הצבר ל-Patroni: הוא שומר את המצב באחסון מבוזר, עוקב אחר בריאות הצמתים וממנה בעצמו מנהיג חדש אם הנוכחי הפסיק להגיב. האפליקציה פונה לכתובת וירטואלית, ולכן לאחר המעבר אין צורך לשנות את מחרוזת החיבור.
מדדים לפני ואחרי
- מעברים עקב תקלה: 5-6 ברבעון → 2-3, ואף ניתוח לילי אחד.
- זמן שחזור הכתיבה: כארבעים דקות → פחות מדקה.
- הזעקות שווא של התורן: הצטמצמו בערך בחצי.
מה השתנה במשמרת התורנים
העבודה עברה מ״לתקן עכשיו״ ל״לבדוק מה תוקן״: התורן מקבל התראה כבר לאחר מעבר התפקיד ומנתח את הסיבה בשעות העבודה. את הנוהל באורך שני עמודים החליפו בדיקת סטטוס קצרה ורשימת פעולות למקרה שהאוטומציה לא הצליחה.
הסתייגות אחת: לבחירת מנהיג נדרש קוורום, ולכן את צמתי אחסון המצב פיזרו בין אזורי זמינות — אחרת כשל של מקטע אחד מכבה את כל ההיגיון.
במה נבחר מנהיג אוטומטי שונה ממעבר ידני?
ההבדל הוא במי שמקבל את ההחלטה על החלפת התפקיד. בבחירת מנהיג אוטומטית זה נעשה על ידי קוורום של צמתים: הם מאשרים זה לזה את נוכחותם באופן תמידי, וברגע שהצומת הראשי מפסיק להגיב, הרפליקה עולה מדרגה בעצמה. במעבר ידני ההחלטה מתקבלת על ידי המהנדס — לפי התראה, לפי הנוהל, לפי שיחה טלפונית.
מכאן ההבדל המרכזי במחיר ההשבתה. האוטומציה מסתיימת בתוך שניות: הצומת מאבד קשר, הקוורום מתעד זאת ומעביר את התפקיד. התרחיש הידני כולל זמן לתגובת ההתראה, למשמרת התורנים, לגישות ולפקודה עצמה — מדובר בעשרות דקות, שבמהלכן הכתיבה לבסיס הנתונים מושבתת ותור החיבורים גדל.
| פרמטר | בחירת מנהיג אוטומטית | מעבר ידני |
|---|---|---|
| מי מקבל את ההחלטה | קוורום צמתים לפי רוב | מהנדס לפי התראה |
| זמן עד שחזור הכתיבה | שניות, ללא מעורבות אדם | מדקות ומעלה, תלוי במשמרת ובגישות |
| פיצול רשת | ללא קוורום התפקיד אינו עולה מדרגה, ומנהיג שני אינו נוצר | את הרפליקה עלולים להעלות במקטע מנותק — נוצרים שני מנהיגים ופערים בנתונים |
| החזרת הצומת הקודם | משתחזר לפי היומן וחוזר להיות רפליקה בעצמו | נדרש ניתוח והשוואה ידנית |
| התנהגות האפליקציה | חיבור מחדש לפי פסק זמן, וניסיון חוזר אצל המנהיג החדש | שגיאות כתיבה לאורך כל חלון ההשבתה |
פיצול רשת הוא הפרמטר שנשמט לרוב בסכמות ידניות. האוטומציה מתוכננת כך שצומת ללא קוורום לא יהפוך למנהיג: כשל כתיבה קצר עדיף על שני מנהיגים בלתי תלויים ונתונים סותרים, שאותם אחר כך יש לאחות ביד.
התנהגות האפליקציה תלויה ישירות בכמה מהר בסיס הנתונים שוב קולט כתיבה. במעבר אוטומטי הלקוחות מתחברים מחדש לפי פסק זמן ומבצעים את הפעולה שוב אצל המנהיג החדש. במעבר ידני האפליקציה חייבת לשרוד חלון כשל ארוך, אחרת מופיעות הזמנות אבודות וכפילויות.
ספקות טכניים: שכפול, מעבר, תחזוקה
הספקות בשלב זה מצטמצמים לארבע שאלות: האם הטרנזקציות האחרונות הולכות לאיבוד בעת תקלה, לכמה זמן נעצרת האפליקציה, כיצד נבדק השחזור ומה עושים עם צבר שכבר פועל.
האם נאבד את הטרנזקציות האחרונות בעת המעבר?
תלוי במצב כתיבת היומן. בשכפול סינכרוני האישור נשלח ללקוח רק לאחר שהרפליקה קיבלה את היומן — בעת נפילת המנהיג ההפסד הוא אפס. בשכפול א-סינכרוני מתבטלת חלק מהטרנזקציות האחרונות שאושרו. את המצב בוחרים בהתאם לפרופיל העומס: קו תשלומים — סינכרוני, דיווח — א-סינכרוני.
האם האפליקציה תושבת בזמן המעבר?
החלפת המנהיג אורכת שניות בודדות. החיבור מחדש של האפליקציה נמשך יותר: ללא ניסיונות חוזרים במאגר החיבורים, ההשבתה מתארכת עד להתערבות ידנית. לכן, לצד הצבר, אנו מגדירים נקודת חיבור אחודה ופרמטרי ניסיונות חוזרים.
כיצד אתם בודקים גיבויים?
עותק שמעולם לא שוחזר אינו נחשב לעותק. מגדירים ארכוב רציף של יומני טרנזקציות, שחזור לנקודת זמן שרירותית ובדיקה תקופתית: פורסים את הצבר מחדש מהעותק במלואו ומודדים את זמן השחזור בפועל. בנפרד מקפידים שהארכוב לא יפגר בשקט.
יש לנו כבר צבר פרוס — האם לבנות הכול מחדש?
לא. מתחילים מביקורת: צמתים וקוורום, פיגור הרפליקות, מצב הסינכרוניזציה ומצב העותקים. לאחר מכן מתקנים פרמטרים, לפי הצורך מוסיפים צומת עד ובודקים את ההתנהגות בכשל מבוקר. צבר שנבנה בסקריפטים ידניים מועבר לניהול ללא עצירת השירות.
נדון במשימה: נחזור עם הערכה ותוכנית עבודה
כדי שהערכת העבודה תתבסס על עובדות ולא על הנחות, די בכמה נתוני פתיחה: פריסת הצמתים, נפחי מסדי הנתונים ופרופיל העומס, דרישות לזמן השחזור ולאובדן הנתונים המותר. אם חלק מהמידע חסר, המהנדסים יתעדו אותו בעצמם בסבב אבחון ראשוני — מדובר בשיחת ועידה אחת, והיא אינה מעכבת את ההתחלה.
בתגובה נשלח ערכה שלפיה ניתן לקבל החלטה:
- ניתוח הסכמה הנוכחית: נקודות כשל, התנהגות בעת מעבר, צווארי בקבוק בדיסק ובשכפול.
- תוכנית הטמעה לפי שלבים — עם סדר העבודות, התלויות ונקודות התיאום בין השלבים.
- הרכב החומרים הנמסרים: תצורות, סכמת הצבר, נוהלי מעבר ושחזור.
- דרישות לסביבה: צמתים, תת-מערכת דיסקים, רשת, גישות וחשבונות שירות.
- תוכנית בדיקות: תרחישי כשל שמריצים עד המסירה, וקריטריונים לקבלה עבור כל אחד.
- הערכת העבודה בפילוח לפי שלבים, כדי שניתן יהיה להפעיל אותם בחלקים.
תארו את המשימה וצרפו את מה שקיים לגבי התשתית — נחזור עם הערכה ותוכנית עבודה, ואת הנקודות השנויות במחלוקת ננתח בשיחת ועידה.







