ניצול גבוה של המעבד במופע יכול להיגרם מסיבות שונות, כמו עלייה בעומסי העבודה, עסקאות כבדות, שאילתות איטיות ועסקאות שפועלות לאורך זמן.
ההמלצות לגבי מכונות מופעלות עם הקצאת משאבים נמוכה מדי מבוססות על ניתוח של ניצול המעבד (CPU). אם רמות השימוש במעבד הן 95% ומעלה במשך פרק זמן משמעותי ב-30 הימים האחרונים, כלי ההמלצות יתריע על כך ויספק תובנות נוספות שיעזרו לפתור את הבעיה.
במאמר הזה מוסבר איך לבדוק ולבצע אופטימיזציה של מופע Cloud SQL ל-MySQL אם הכלי להמלצות על מופעים עם הקצאת יתר מזהה במופע הזה ניצול גבוה של המעבד.
שימוש בתובנות לגבי שאילתות כדי לזהות שאילתות עם צריכת CPU גבוהה
תובנות לגבי שאילתות עוזרות לכם לזהות, לאבחן ולמנוע בעיות בביצועי שאילתות שעלולות לגרום לצריכת CPU גבוהה במסדי נתונים של Cloud SQL.
שימוש בבקרת גישה למסד נתונים של MySQL
אפשר להשתמש בביקורת על מסד נתונים של MySQL כדי לראות את הזיכרון ואת צריכת המשאבים של המכונה.
המלצות
ניצול המעבד עולה באופן יחסי לעומס העבודה. כדי להפחית את ניצול המעבד, כדאי לבדוק את השאילתות שפועלות ולבצע בהן אופטימיזציה. כדי לבדוק את צריכת המעבד, אפשר לבצע את השלבים הבאים.
כדאי לעיין במאמרים בנושא
Threads_runningוThreads_connectedכדי לראות את מספר השרשורים הפעילים, משתמשים בשאילתה הבאה:
> SHOW STATUS like 'Threads_%';
Threads_runningהיא תת-קבוצה שלThreads_connected. שאר השרשורים לא פעילים. עלייה בערך שלThreads_runningתגרום לעלייה בשימוש במעבד. מומלץ לבדוק מה פועל בשרשורים האלה.בדיקת מצבי השאילתה
מריצים את הפקודה
SHOW PROCESSLISTכדי לראות את השאילתות שפועלות. הפונקציה מחזירה את כל השרשורים המחוברים לפי הסדר ואת הצהרת ה-SQL שפועלת באופן פעיל.mysql> SHOW [FULL] PROCESSLIST;שימו לב לעמודות 'מצב' ו'משך'. בודקים אם יש הרבה שאילתות שנתקעו באותו מצב.
- אם הרבה שרשורים מציגים את הסמל
Updating, יכול להיות שיש מחלוקת על נעילת רשומות. הסבר מופיע בשלב הבא. - אם בהרבה שרשורים מופיע
Waitingלנעילת מטא-נתונים של טבלה, צריך לבדוק את השאילתה כדי לדעת איזו טבלה זו, ואז לחפש DDL (כמוALTER TABLE) שיכול להיות שמונע את נעילת המטא-נתונים. יכול להיות ש-DDL ימתין גם לנעילת מטא-נתונים של טבלה אם שאילתה מוקדמת, כמוSELECT queryשפועלת במשך זמן רב, מעכבת אותו.
- אם הרבה שרשורים מציגים את הסמל
בדיקה של התנגשות נעילה של רשומות
כשטרנזקציות מחזיקות נעילות ברשומות פופולריות של אינדקסים, הן חוסמות טרנזקציות אחרות שמבקשות את אותן נעילות. יכול להיות שזה יוביל לשרשור של בעיות, ולכך שמספר בקשות יישארו תקועות וערך המדד
Threads_runningיעלה. כדי לאבחן את הבעיה של התנגשות נעילות, משתמשים בטבלהinformation_schema.innodb_lock_waits.השאילתה הבאה מפרטת כל עסקה חוסמת ואת מספר העסקאות החסומות שמשויכות אליה.
SELECT t.trx_id, t.trx_state, t.trx_started, COUNT(distinct w.requesting_trx_id) AS blocked_trxs FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx t ON t.trx_id = w.blocking_trx_id GROUP BY t.trx_id,t.trx_state, t.trx_started ORDER BY t.trx_id;גם פקודת DML גדולה אחת וגם פקודות DML קטנות רבות שמופעלות בו-זמנית עלולות לגרום למחלוקות על נעילת שורות. כדי לבצע אופטימיזציה בצד האפליקציה, פועלים לפי השלבים הבאים:
- מומלץ להימנע מעסקאות ארוכות כי נעילות השורות נשמרות עד שהעסקה מסתיימת.
- פיצול של פקודת DML גדולה אחת לפקודות DML קטנות יותר.
- מבצעים DML של שורה אחת בקבוצות קטנות.
- צמצום התחרות בין השרשורים. לדוגמה, אם קוד האפליקציה משתמש במאגר חיבורים, צריך להקצות טווח מזהים לאותו שרשור.
איתור עסקאות ממושכות
שימוש ב-
SHOW ENGINE INNODB STATUSבקטע TRANSACTIONS (עסקאות), אפשר לראות את כל העסקאות הפתוחות, מהמוקדמת ביותר ועד המאוחרת ביותר.
mysql> SHOW ENGINE INNODB STATUS\G …… ------------ TRANSACTIONS ------------ … ---TRANSACTION 245762, ACTIVE 262 sec 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1 MySQL thread id 9210, OS thread handle 140262286128896, query id 202218 localhost rootמתחילים עם העסקאות הכי ישנות ומחפשים תשובות לשאלות הבאות:
- כמה זמן העסקאות האלה פועלות?
- כמה מבני נעילה(lock) ונעילות שורות קיימים?
- כמה רשומות יש ביומן הביטול?
- מי המארחים והמשתמשים שהצטרפו לפגישה?
- מהי הצהרת ה-SQL המתמשכת?
שימוש ב-
information_schema.innodb_trxאם
SHOW ENGINE INNODB STATUSקוצץ, אפשר לבדוק את כל העסקאות הפתוחות בדרך אחרת – באמצעות הטבלהinformation_schema.innodb_trx:SELECT trx_id, trx_state, timestampdiff(second, trx_started, now()) AS active_secs, timestampdiff(second, trx_wait_started, now()) AS wait_secs, trx_tables_in_use, trx_tables_locked, trx_lock_structs, trx_rows_locked, trx_rows_modified, trx_query FROM information_schema.innodb_trx
אם העסקאות מופיעות בדוחות הנוכחיים של תהליכים ארוכים, אפשר להחליט אם לעצור את העסקאות האלה כדי להפחית את העומס על השרת או להמתין עד שהעסקאות הקריטיות יושלמו. אם לא מוצגת פעילות בעסקאות ישנות יותר, עוברים לשלב הבא כדי למצוא את היסטוריית העסקאות.
בדיקת הצהרות SQL של עסקאות שפועלות במשך זמן רב
שימוש ב-
performance_schemaכדי להשתמש ב-
performance_schema, צריך להפעיל אותו קודם. זהו שינוי שמחייב הפעלה מחדש של המופע. אחרי שמפעילים אתperformance_schema, בודקים שהכלים והצרכנים מופעלים:SELECT * FROM setup_consumers where name like 'events_statements_history'; SELECT * FROM setup_instruments where name like 'statement/sql/%';אם הם לא מופעלים, צריך להפעיל אותם:
UPDATE setup_instruments SET ENABLED = 'YES', timed = 'YES' WHERE NAME LIKE 'statement/%'; UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_statements%';כברירת מחדל, כל שרשור ישמור את 10 האירועים האחרונים שמוגדרים על ידי
performance_schema_events_statements_history_size. בדרך כלל, הפרטים האלה מספיקים כדי לאתר את העסקה בקוד האפליקציה. הפרמטר הזה לא דינמי.בעזרת
mysql thread id, שהואprocesslist_id, שולחים שאילתה לגבי אירועים בהיסטוריה:SELECT t.thread_id, event_name, sql_text, rows_affected, rows_examined, processlist_id, processlist_time, processlist_state FROM events_statements_history h INNER JOIN threads t ON h.thread_id = t.thread_id WHERE processlist_id = <mysql thread id> ORDER BY event_id;שימוש ביומן של שאילתות איטיות
לצורך ניפוי באגים, אפשר לתעד ביומן השאילתות האיטיות את כל השאילתות שנמשכו יותר מ-
Nשניות. אפשר להפעיל את יומני השאילתות האיטיות על ידי עריכת הגדרות המופע בדף המופע במסוףGoogle Cloud או ב-gcloud CLI, ואז לראות את היומנים באמצעות כלי הצגת היומנים במסוףGoogle Cloud או ב-gloud CLI.
בדיקת התחרות על סמפור
בסביבה מקבילית, יכול להיות שנקודת המחלוקת היא mutex ו-read/write latch במשאבים משותפים, מה שמאט את ביצועי השרת. בנוסף, אם זמן ההמתנה של הסמפור הוא יותר מ-600 שניות, המערכת עלולה לקרוס כדי לצאת מהמצב הזה.
כדי לראות את התחרות על הסמפור, משתמשים בפקודה הבאה:
mysql> SHOW ENGINE INNODB STATUS\G ---------- SEMAPHORES ---------- ... --Thread 140396021667584 has waited at row0purge.cc line 862 for 241.00 seconds the semaphore: S-lock on RW-latch at 0x30c03e8 created in file dict0dict.cc line 1183 a writer (thread id 140395996489472) has reserved it in mode exclusive number of readers 0, waiters flag 1, lock_word: 0 Last time read locked in file row0purge.cc line 862 Last time write locked in file /build/mysql-5.7-FFKPr6/mysql-5.7-5.7.22/storage/innobase/dict/dict0stats.cc line 2376 ...בכל המתנה של סמפור, השורה הראשונה מציגה את השרשור שממתין, את הסמפור הספציפי ואת משך הזמן שהוא ממתין. אם יש המתנות תכופות לסמפור כשמריצים את
SHOW ENGINE INNODB STATUSשוב ושוב, במיוחד המתנות שנמשכות יותר מכמה שניות, זה אומר שהמערכת נתקלת בצווארי בקבוק של פעולות בו-זמניות.יש נקודות מחלוקת שונות בעומסי עבודה ובהגדרות שונות.
אם הסמפורים מופיעים לעיתים קרובות ב-btr0sea.c, יכול להיות שהאינדקס של הגיבוב הדינמי הוא מקור המחלוקת. אפשר לנסות להשבית אותו באמצעות Google Cloud המסוף או
gcloud CLI.אופטימיזציה של שאילתות ארוכות
SELECTקודם כל, בודקים את השאילתה. לזהות את המטרה של השאילתה ואת הדרך הכי טובה להשיג את התוצאות. תוכנית השאילתה הטובה ביותר היא זו שמצמצמת את הגישה לנתונים.
- בדיקת תוכנית הביצוע של השאילתה:
mysql> EXPLAIN <the query>;אפשר לעיין בתיעוד של MySQL כדי להבין איך לפרש את הפלט ולהעריך את יעילות השאילתה.
- שימוש באינדקס הנכון
בודקים את עמודת המפתח כדי לראות אם נעשה שימוש באינדקס הצפוי. אם לא, מעדכנים את נתוני האינדקס:
mysql> analyze table <table_name>הגדלת מספר הדפים לדוגמה שמשמשים לחישוב נתוני האינדקס. מידע נוסף זמין במאמרי העזרה בנושא MySQL.
- ניצול מלא של האינדקס
כשמשתמשים באינדקס עם כמה עמודות, בודקים את העמודות
key_lenכדי לראות אם נעשה שימוש מלא באינדקס לסינון הרשומות. העמודות הכי שמאליות צריכות להיות השוואות שוות, ואפשר להשתמש באינדקס עד לתנאי הטווח הראשון כולל.- שימוש ברמזים לאופטימיזציה
דרך נוספת לוודא שנעשה שימוש באינדקס הנכון היא להחיל רמז לאינדקס ורמז לסדר של צירוף טבלאות.
איך להימנע מרשימת היסטוריה ארוכה באמצעות READ COMMITTED
רשימת ההיסטוריה היא רשימת העסקאות שלא נמחקו במרחב הטבלאות של ביטול הפעולה. רמת הבידוד שמוגדרת כברירת מחדל לטרנזקציה היא
REPEATABLE READ, שדורשת מהטרנזקציה לקרוא את אותה תמונת מצב לאורך משך הזמן שלה. לכן, שאילתתSELECTחוסמת את המחיקה של רשומות ביומן הפעולות שבוצעו מאז שהשאילתה (או הטרנזקציה) התחילה. לכן, רשימה ארוכה של היסטוריה מאטה את הביצועים של השאילתה. אחת הדרכים להימנע מיצירת רשימה ארוכה של היסטוריה היא לשנות את רמת הבידוד של הטרנזקציה ל-READ COMMITTED. עםREAD COMMITTED, כבר לא צריך לשמור את רשימת ההיסטוריה כדי להציג את הקריאה באופן עקבי. אפשר לשנות את רמת הבידוד של טרנזקציות באופן גלובלי לכל הסשנים, לסשן יחיד או לטרנזקציה יחידה הבאה. מידע נוסף זמין במאמרי העזרה בנושא MySQL.שינוי הגדרות השרת
יש הרבה מה לומר על הגדרת השרת. הסיפור המלא הוא מעבר להיקף של המסמך הזה, אבל כדאי לציין שהשרת גם מדווח על משתני סטטוס שונים שנותנים רמזים לגבי איכות ההגדרות הקשורות. לדוגמה:
- אם
Threads_created/Connectionsגדול, צריך לשנות אתthread_cache_size. מטמון תקין של threads יקצר את זמן יצירת ה-thread ויעזור לעומס עבודה עם רמת מקביליות גבוהה. - אם
Table_open_cache_misses/Table_open_cache_hitsלא טריוויאלי, משנים אתtable_open_cache. אם יש טבלאות במטמון הטבלאות, זמן הביצוע של השאילתות מתקצר, ויכול להיות הבדל משמעותי בסביבה עם מספר גבוה של פעולות שמתבצעות בו-זמנית.
- אם
איך מסיימים חיבור לא רצוי
אפשר לעצור את השאילתה אם היא נראית לא תקינה או אם היא כבר לא נדרשת. הוראות לזיהוי ולסיום של השרשור ב-MySQL מופיעות במאמר ניהול חיבורים למסד נתונים.
לבסוף, אם השימוש במעבד עדיין גבוה והשאילתות יוצרות תנועה נחוצה, כדאי להגדיל את משאבי המעבד במופע כדי למנוע קריסה של מסד הנתונים או השבתה.