אופטימיזציה של שימוש גבוה בזיכרון במופעים

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

במאמר שיטות מומלצות לניהול השימוש בזיכרון מוסבר איך להגדיר את השימוש בזיכרון במכונה של Cloud SQL.

זיהוי שימוש גבוה בזיכרון

בקטעים הבאים נתאר תרחישים של שימוש גבוה בזיכרון.

שימוש ב-Metrics Explorer כדי לזהות את השימוש בזיכרון

אתם יכולים לבדוק את השימוש בזיכרון של המכונה באמצעות המדד database/memory/components ב-Metrics Explorer:

  • ‫usage: זיכרון שמשמש באופן פעיל לתהליכי PostgreSQL, כולל shared_buffers ומטמונים אחרים במסד הנתונים.
  • ‫cache: הזיכרון שמשמש את מטמון הדפים של מערכת ההפעלה, שבדרך כלל אפשר להחזיר. ערכים גבוהים של cache לא בהכרח מצביעים על עומס בזיכרון.
  • ‫free: זיכרון לא מנוצל שזמין לתהליכים של מסד הנתונים או למטמון הדפים של מערכת ההפעלה.

שימוש בתובנות לגבי שאילתות כדי לנתח את תוכנית ההסבר של שאילתות שצורכות הרבה משאבים

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

שיטות סריקה נפוצות של PostgreSQL שמשתמשות בזיכרון רב כוללות את השיטות הבאות:

  • סריקת ערימה של מפת סיביות (bitmap)
  • מיון מהיר
  • ‫Hash join או Hash

שימוש גבוה בזיכרון ויומנים רלוונטיים למכונות שמופעל בהן Gemini

אם הפעלתם את Gemini, במקום כשל OOM שמוביל להשבתה של מסד הנתונים, החיבור שמריץ שאילתה עם שימוש גבוה בזיכרון מסתיים, וכך נמנעת ההשבתה של מסד הנתונים. כדי לזהות את השאילתה שגרמה לשגיאה, אפשר לבדוק אם הרשומות הבאות מופיעות ביומני מסד הנתונים:

  (...timestamp….) db=postgres, user=customer FATAL: terminating connection due to administrator command

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

  db=postgres,user=customer LOG:  postgres process with PID 1734 for the query "SELECT COUNT(product) AS item_count FROM test_table WHERE product_type = $1 AND product LIKE $2 AND c6_2 IN ($3,$4,$5,$6,$7)" has been cancelled.

ההתראות מוצגות גם בדף Cloud SQL Instances לאירועים הבאים:

  • ניצול הזיכרון של המכונה ב-24 השעות האחרונות.
  • רשימה של שאילתות מנורמלות שבוטלו ב-24 השעות האחרונות.
  • קישור למסמכי העזרה של Google בנושא אופטימיזציה של השימוש בזיכרון.

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

ההמלצות הבאות מתייחסות לבעיות נפוצות שקשורות לזיכרון. אם המכונה ממשיכה להשתמש בכמות גדולה של זיכרון, סביר להניח שבסופו של דבר תהיה בעיה של out of memory. אם דרישות הזיכרון של PostgreSQL או של תהליך אחר גורמות לכך שהמערכת נתקלת במצב של אין זיכרון פנוי (OOM), מופיעה הודעת ליבה (kernel) של Out of Memory ביומני PostgreSQL, ובסופו של דבר המכונה של PostgreSQL נעצרת. לדוגמה:

Out of Memory: Killed process 12345 (postgres)

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

  • הגדרה של work_mem

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

  • מעקב אחרי הסשנים הפעילים

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

      SELECT
        state,
        usename,
        count(1)
      FROM
        pg_stat_activity
      WHERE
        pid <> pg_backend_pid()
      GROUP BY
        state,
        usename
      ORDER BY
        1;
    

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

  • הגדרה של shared_buffers

    אם הערך של shared_buffers גבוה, כדאי להקטין אותו shared_buffers כדי שאפשר יהיה להשתמש בזיכרון לפעולות אחרות, כמו work_mem, או ליצירת חיבורים חדשים.

    שיעור מציאות במטמון (cache hit)

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

    SELECT
      sum(heap_blks_read) as heap_read,
      sum(heap_blks_hit)  as heap_hit,
      sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio
    FROM
      pg_statio_user_tables;
    

    מריצים את השאילתה הבאה כדי לבדוק את שיעור המציאות במטמון של בקשות האינדקס במכונה של PostgreSQL:

      SELECT
        sum(idx_blks_read) as idx_read,
        sum(idx_blks_hit)  as idx_hit,
        (sum(idx_blks_hit) - sum(idx_blks_read)) / sum(idx_blks_hit) as ratio
      FROM
        pg_statio_user_indexes;
    

    באופן כללי, שיעור מציאות במטמון של 95% עד 99% נחשב לערך טוב.

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

  • הגדרה של max_locks_per_transaction

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

    הערך של max_locks_per_transaction צריך להיות אובייקטים של max_locks_per_transaction * (max_connections + max_prepared_transactions). כלומר, אם יש לכם 300 אלף אובייקטים, והערך של max_connections הוא 200, הערך של max_locks_per_transaction צריך להיות 1,500.

  • הגדרה של max_pred_locks_per_transaction

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

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

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