שיטות מומלצות לניהול השימוש בזיכרון

בדף הזה מוסבר איך להגדיר את השימוש בזיכרון במופע Cloud SQL.

מבוא

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

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

באופן כללי, רכיבי הזיכרון של PostgreSQL מחולקים לשני חלקים:

  • זיכרון גלובלי: הזיכרון הזה משותף לכל התהליכים להפעלת שאילתות, למשל shared_buffers ו-max_connections.
  • זיכרון מקומי: זיכרון ייעודי שמוקצה לכל חיבור, למשל work_mem,‏ maintenance_work_mem ו-temp_buffers.

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

שימוש בזיכרון ודגלים

כאשר יש שימוש גבוה בזיכרון על ידי מכונות Cloud SQL, יכול להיות שתעלו את השאלות הבאות:

  • איזו שאילתה או איזה תהליך משתמשים בזיכרון רב?
  • האם הגדרות הזיכרון מתאימות לפעילות במסד הנתונים?
  • איך משנים את הגדרות הזיכרון?

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

  • מאגר משותף: זהו הזיכרון המשותף ש-PostgreSQL מקצה כדי להכיל נתוני טבלה לפעולות read ו-write. בפעולה read, כל נתון שמבוקש מהדיסק נשלף קודם ל-RAM ואז מועבר ללקוח. באופן דומה, ב-PostgreSQL, כשמתבצעת בקשה לנתונים (לדוגמה, SELECT * from emp), הנתונים נשלפים קודם מהדיסק אל shared_buffers לצורך שמירה במטמון, ואז הם מועברים ללקוח. אותו דבר קורה בפעולה write.

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

  • זיכרון עבודה של שאילתה: כשמריצים שאילתה, PostgreSQL מקצה זיכרון מקומי לכל פעולה, כמו מיון וגיבוב. הגודל המקסימלי שאפשר להקצות לכל פעולה של שאילתה לפני כתיבה לקבצים זמניים בדיסק מוגדר באמצעות הדגל work_mem, וערך ברירת המחדל הוא 4MB. אם הערך של work_mem גבוה, כמות הנתונים שאפשר למיין בזיכרון גבוהה.
  • זיכרון עבודה לתחזוקה: חלק מפעולות התחזוקה, כמו VACUUM,‏ CREATE INDEX,‏ ALTER TABLE ו-ADD FOREIGN KEY, דורשות זיכרון מקומי נפרד שמוקצה על ידי PostgreSQL. אפשר להגדיר את הכמות המקסימלית לתהליך העורפי שבו הפעולות האלה משתמשות באמצעות הדגל maintenance_work_mem. ערך ברירת המחדל הוא 64MB. חשוב לציין שגם תהליכי העבודה של autovacuum משתמשים בזיכרון של עבודות תחזוקה, ואפשר לבטל את המקסימום באמצעות הדגל autovacuum_work_mem. אם הערך של maintenance_work_mem גבוה, מהירות הביצועים של הפעולה VACUUM גבוהה.
  • מאגרי נתונים זמניים: כשמשתמשים בטבלה זמנית בסשן של מסד נתונים, PostgreSQL מקצה מאגרי נתונים זמניים כדי להחזיק את הטבלה הזמנית המקומית של הסשן. אפשר לציין את הסכום המקסימלי באמצעות הדגל temp_buffers, וערך ברירת המחדל הוא 8MB.
  • חיבור למסד נתונים: כשלקוח מתחבר למסד הנתונים,‏ PostgreSQL יוצר תהליך בקצה העורפי כדי לשרת את סשן הלקוח. בנוסף לזיכרון שנדרש להפעלת השאילתה, מערכת PostgreSQL מקצה זיכרון נוסף כדי לשמור מידע כמו מטמון של קטלוג המערכת ותוכניות מוכנות של שאילתות. אפשר להגדיר את המספר המקסימלי של חיבורים בו-זמניים שמותרים לשרת מסד הנתונים באמצעות הדגל max_connections. כל חיבור בלי פעילות צורך בערך 2MB עד 3MB של זיכרון משותף. אם הערך של max_connections גבוה, המופע יכול ליצור יותר חיבורים, אבל זה יבוא על חשבון הזיכרון.

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

מעקב אחרי השימוש בזיכרון

עוקבים באופן קבוע אחרי הזיכרון של המכונה ב-Cloud Monitoring ומוודאים שהשימוש בו לא חורג ממגבלת הזיכרון. מומלץ להגדיר התראה ב-Cloud Monitoring שתתקבל אם השימוש יעלה על 90% מהמגבלה למשך 6 שעות. ההתראה הזו יכולה להזהיר אתכם באופן קבוע כשהשימוש בזיכרון קרוב למגבלה.

בנוסף, כדאי לעקוב אחרי מקרים של חוסר זיכרון. כדי לעשות זאת, מגדירים מדד מבוסס-יומן עבור ההודעה server process .* was terminated by signal 9: Killed ב-Cloud Monitoring כדי לספור את האירועים של חוסר זיכרון, ואז מקבלים התראה בכל פעם שאירוע כזה קורה.

אם המופע פועל באופן קבוע מעל 90% ממגבלת הזיכרון או מתרחש אירוע של חוסר זיכרון, אפשר להגדיל את הזיכרון של המופע. אפשרות אחרת היא לצמצם את השימוש בזיכרון על ידי הגבלת מספר החיבורים למסד הנתונים או על ידי הפחתת ערכי הדגלים של מסד הנתונים, כמו shared_buffers,‏ work_mem או max_connections. הורדה של הערכים האלה עלולה להגביל את הביצועים של המופע.

אין מספיק זיכרון

אם אין מספיק זיכרון כדי לטפל בעומס העבודה של מסד הנתונים, מערכת ההפעלה הבסיסית של Linux משתמשת ב-out-of-memory (OOM) killer כמוצא אחרון כדי לסיים תהליך ולפנות זיכרון. ‫Cloud SQL מוגדר כך שהיעד OOM killer הוא רק תהליכי העבודה של PostgreSQL. תהליך ה-postmaster נשמר במצב הזה, כך שהוא צריך רק לסיים את כל החיבורים הקיימים למסד הנתונים ולהפעיל שחזור כדי להגן על שלמות מסד הנתונים. במקרה כזה, יהיו רגעים של הפרעה בשירות והשבתה של מסד הנתונים. ביומן מסד הנתונים של PostgreSQL, מופיעות הודעות כמו הבאות:

2021-10-24 23:34:22.265 UTC [7]: [663-1] db=,user= LOG: server process (PID 1255039) was terminated by signal 9: Killed
2021-10-24 23:34:22.265 UTC [7]: [664-1] db=,user= DETAIL: Failed process was running: SELECT * FROM tab ORDER BY col
2021-10-24 23:34:22.277 UTC [7]: [665-1] db=,user= LOG: terminating any other active server processes
2021-10-24 23:34:22.278 UTC [1255458]: [1-1] db=postgres,user=postgres WARNING: terminating connection because of crash of another server process
2021-10-24 23:34:22.278 UTC [1255458]: [2-1] db=postgres,user=postgres DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2021-10-24 23:34:22.278 UTC [1255458]: [3-1] db=postgres,user=postgres HINT: In a moment you should be able to reconnect to the database and repeat your command.
2021-10-24 23:34:22.278 UTC [1255458]: [4-1] db=postgres,user=postgres CONTEXT: while updating tuple (27,18) in relation "tab"
...
2021-10-24 23:34:22.558 UTC [1255477]: [1-1] db=postgres,user=postgres FATAL: the database system is in recovery mode
...
2021-10-24 23:34:25.579 UTC [7]: [666-1] db=,user= LOG: all server processes terminated; reinitializing
...
2021-10-24 23:34:25.691 UTC [1255482]: [1-1] db=,user= LOG: database system was interrupted; last known up at 2021-10-24 23:31:53 UTC
2021-10-24 23:34:25.776 UTC [1255482]: [2-1] db=,user= LOG: database system was not properly shut down; automatic recovery in progress
2021-10-24 23:34:25.789 UTC [1255482]: [3-1] db=,user= LOG: redo starts at 227/AB359400
2021-10-24 23:34:38.957 UTC [1255482]: [4-1] db=,user= LOG: redo done at 229/4621F508
2021-10-24 23:34:38.959 UTC [1255482]: [5-1] db=,user= LOG: last completed transaction was at log time 2021-10-24 23:34:18.5535+00
2021-10-24 23:34:39.290 UTC [7]: [667-1] db=,user= LOG: database system is ready to accept connections

שאילתות שבוטלו בגלל שימוש גבוה בזיכרון

כששאילתה במסד נתונים של Cloud SQL משתמשת בהרבה זיכרון, Cloud SQL מזהה באופן יזום שימוש גבוה בזיכרון ופועל לסיום החיבור שמריץ את השאילתה הזו כדי למנוע כשל של חוסר זיכרון (OOM). כך נמנעת השבתה של מסד הנתונים בגלל שימוש גבוה בזיכרון.

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

(...timestamp….) [PID]:  db=postgres,user=$user_id LOG: Process [PID] received SIGTERM
(...timestamp….) [PID]:  db=postgres,user=$user_id DETAIL: Cloud SQL cancelled this query owing to its excessive memory usage which can cause the PostgreSQL instance to crash.
(...timestamp….) [PID]:  db=postgres,user=$user_id HINT:  To avoid future interruptions, consider increasing instance memory or optimizing this query.

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

המאמרים הבאים