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

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

ב-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 מקצה זיכרון מקומי לכל פעולה, כמו מיון וגיבוב (hashing). הכמות המקסימלית שאפשר להקצות לכל פעולה של שאילתה לפני כתיבה לקובצי דיסק זמניים מוגדרת על ידי הדגל work_mem, וערך ברירת המחדל הוא 4MB. אם הערך של work_mem גבוה, כמות הנתונים שאפשר למיין בזיכרון גבוהה.
  • זיכרון לעבודות תחזוקה: פעולות תחזוקה מסוימות כמו VACUUM,‏ CREATE INDEX,‏ ALTER TABLE ו-ADD FOREIGN KEY דורשות זיכרון מקומי נפרד שמוקצה על ידי PostgreSQL. אפשר להגדיר את הכמות המקסימלית של תהליך הקצה העורפי שבו הפעולות האלה משתמשות באמצעות הדגל maintenance_work_mem, וערך ברירת המחדל הוא 64MB. שימו לב שגם תהליכי autovacuum משתמשים בזיכרון של maintenance work, ואפשר לשנות את המקסימום באמצעות הדגל 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 מטרגט רק את תהליכי ה-worker של 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.

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

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