אופטימיזציה של שימוש גבוה ב-CPU במופעים

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

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

זיהוי צווארי בקבוק במעבד

בקטעים הבאים נדון בתרחישי CPU שונים.

שימוש בתובנות לגבי שאילתות כדי לזהות שאילתות עם צריכת CPU גבוהה

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

שימוש בתוסף pg_proctab

משתמשים בתוסף pg_proctab בשילוב עם כלי השירות pg_top כדי לקבל פלט של מערכת ההפעלה שמספק מידע על ניצול המעבד (CPU) לכל תהליך.

שימוש בשאילתות

בקטעים הבאים נדון בשאילתות שונות שאפשר להשתמש בהן.

זיהוי החיבורים הפעילים לפי מצב

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

SELECT
  state,
  usename,
  count(1)
FROM
  pg_stat_activity
WHERE
  pid <> pg_backend_pid()
group by
  state,
  usename
order by
  1;

הפלט אמור להיראות כך:


        state        |    usename    | count
---------------------+---------------+-------
 active              | ltest         |   318
 active              | sbtest        |    95
 active              |               |     2
 idle                | cloudsqladmin |     2
 idle in transaction | ltest         |    32
 idle in transaction | sbtest        |     5
                     | cloudsqladmin |     3
                     |               |     4
(8 rows)

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

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

SELECT
  pg_terminate_backend(pid)
FROM
  pg_stat_activity
WHERE
  usename = 'sbtest'
  and pid <> pg_backend_pid()
  and state in ('idle');

אפשר גם לסיים את החיבורים בנפרד באמצעות pg_terminate_backend על ידי הרצת השאילתה הבאה:

SELECT pg_terminate_backend (<pid>);

כאן אפשר לקבל את ה-PID מ-pg_stat_activity.

זיהוי החיבורים שפועלים לאורך זמן

זוהי דוגמה לשאילתה שמחזירה שאילתות שפועלות במשך זמן רב. במקרה כזה, אפשר לזהות את השאילתות שהיו פעילות במשך יותר מ-5 דקות.

SELECT
  pid,
  query_start,
  xact_start,
  now() - pg_stat_activity.query_start AS duration,
  query,
  state
FROM
  pg_stat_activity
WHERE
  (
    now() - pg_stat_activity.query_start
  ) > interval '5 minutes' order by 4 desc;

בדיקת תוכנית ההסבר כדי לזהות שאילתות שנכתבו בצורה לא טובה

אפשר להשתמש ב-EXPLAIN PLAN כדי לבדוק שאילתה שנכתבה בצורה לא טובה ולשכתב אותה, אם צריך. אפשר לבטל את השאילתה ארוכת הטווח באמצעות הפקודה הבאה, עם האישורים הנדרשים.

SELECT pg_cancel_backend(<pid>);

מעקב אחרי פעילות של VACUUM

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

SELECT
  relid :: regclass,
  pid,
  phase,
  heap_blks_total,
  heap_blks_scanned,
  heap_blks_vacuumed,
  index_vacuum_count,
  max_dead_tuples,
  num_dead_tuples
FROM
  pg_stat_progress_vacuum;

כדי לבדוק אם יש פעילות מתמשכת של VACUUM במופע, משתמשים בשאילתה הבאה:

SELECT
  pid,
  datname,
  usename,
  query
FROM
  pg_stat_activity
WHERE
  query like '%vacuum%';

בנוסף, אפשר לבצע אופטימיזציה של פעולות VACUUM ב-PostgreSQL ולפתור בעיות שקשורות אליהן.

הוספת התוסף pg_stat_statements

כדי לקבל מידע משופר על פעילות המופע, צריך להגדיר את התוסף pg_stat_statements.

נקודות ביקורת תכופות

נקודות בדיקה תכופות פוגעות בביצועים. אם ביומן ההתראות של PostgreSQL מופיעה האזהרה checkpoint occurring too frequently, כדאי לשנות את הדגל checkpoint_timeout.

איסוף נתונים סטטיסטיים

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

SELECT
  relname,
  last_autovacuum,
  last_autoanalyze
FROM
  pg_stat_user_tables;

הגדרות מערכת לא מתאימות

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

SELECT
  datname,
  usename,
  (
    case when usename is not null then state else query end
  ) AS what,
  wait_event_type,
  wait_event,
  backend_type,
  count(*)
FROM
  pg_stat_activity
GROUP BY
  1,
  2,
  3,
  4,
  5,
  6
ORDER BY
  1,
  2,
  3,
  4 nulls first,
  5,
  6;

הפלט אמור להיראות כך:


 ..  | .. | what           | wait_event_type |      wait_event      | ..    | count
-..--+-..-+----------------+-----------------+----------------------+-..----+------
 ..
 ..  | .. | active         | IO              | CommitWaitFlush      | ..    |   750
 ..  | .. | idle           | IO              | CommitWaitFlush      | ..    |   360
 ..  | .. | active         | LWLock          | BufferMapping        | ..    |   191

מעקב אחר סריקות רציפות

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

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

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

SELECT
  relname,
  idx_scan,
  seq_scan,
  n_live_tup
FROM
  pg_stat_user_tables
WHERE
  seq_scan > 0
ORDER BY
  n_live_tup desc;

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

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