Megosztás a következőn keresztül:


Magas CPU-használattal járó hiba elhárítása rugalmas Azure Database for MySQL-kiszolgálón

A rugalmas Azure Database for MySQL-kiszolgáló számos metrikát biztosít, amelyekkel azonosíthatja a kiszolgálón található erőforrás szűk keresztmetszeteit és teljesítményproblémáit. Annak megállapításához, hogy a kiszolgáló magas cpu-kihasználtságot tapasztal-e, figyelje az olyan metrikákat, mint a "Gazdagép CPU-százaléka", a "Teljes kapcsolatok", a "Gazdagép memória százaléka" és az "IO Percent". A metrikák kombinációjának megtekintése időnként betekintést nyújt abba, hogy mi okozhatja a rugalmas Azure Database for MySQL-kiszolgálópéldány megnövekedett processzorhasználatát.

Vegyük például a kapcsolatok hirtelen megugrását, amely olyan adatbázis-lekérdezések megugrását okozza, amelyek a processzorhasználat felfutását okozzák.

A metrikák rögzítése mellett fontos a számítási feladat nyomon követése is annak megértéséhez, hogy egy vagy több lekérdezés okozza-e a cpu-kihasználtság kiugró emelkedését.

Magas processzorhasználati okok

A CPU-csúcsok különböző okokból fordulhatnak elő, elsősorban a kapcsolatok kiugró száma és a rosszul írt SQL-lekérdezések, vagy a kettő kombinációja miatt:

Kiugróan magas a kapcsolatok száma

A kapcsolatok számának növekedése a szálak számának növekedéséhez vezethet, ami viszont a CPU-használat növekedését okozhatja, mivel a CPU-nak kezelnie kell ezeket a kapcsolatokat a lekérdezésekkel és erőforrásokkal együtt. A kapcsolatok kiugró számának hibaelhárításához ellenőrizze a Total Connections metrikát, és a kapcsolatokról a következő szakaszban talál további információt. A performance_schema segítségével a következő parancsokkal azonosíthatja a kiszolgálóhoz jelenleg csatlakozó állomásokat és felhasználókat:

Jelenlegi csatlakoztatott hosztok

select HOST,CURRENT_CONNECTIONS From performance_schema.hosts
where CURRENT_CONNECTIONS > 0
and host not in ('NULL','localhost');

Jelenlegi csatlakoztatott felhasználók

select USER,CURRENT_CONNECTIONS from performance_schema.users
where CURRENT_CONNECTIONS >0
and USER not in ('NULL','azure_superuser');

Rosszul írt SQL-lekérdezések

Azok a lekérdezések, amelyek végrehajtása drága, és index nélkül nagyszámú sort vizsgálnak, vagy amelyek más nem hatékony tervekkel együtt ideiglenes rendezéseket hajtanak végre, CPU-tüskékhez vezethetnek. Bár egyes lekérdezések gyorsan végrehajthatók egyetlen munkamenetben, több munkamenetben való futtatáskor a processzor kiugróan magas lehet. Ezért fontos, hogy mindig elmagyarázzuk a megjelenítési folyamatlistából rögzített lekérdezéseket, és biztosítsuk, hogy a végrehajtási tervek hatékonyak legyenek. Ez úgy érhető el, hogy a szűrők/hol záradékok használatával minimális számú sort vizsgálnak, indexeket használnak, és elkerülik a nagy ideiglenes rendezést, valamint a többi rossz végrehajtási tervet. A végrehajtási tervekről további információt a EXPLAIN kimeneti formátumában talál.

Az aktuális számítási feladat adatainak rögzítése

A SHOW (FULL) PROCESSLIST parancs megjeleníti a rugalmas Azure Database for MySQL-kiszolgálópéldányhoz jelenleg csatlakozó összes felhasználói munkamenet listáját. Az egyes munkamenetek aktuális állapotával és tevékenységével kapcsolatos részleteket is tartalmaz.

Ez a parancs csak pillanatképet készít az aktuális munkamenet állapotáról, és nem ad információt az előzmény-munkamenet tevékenységéről.

Tekintsük át a parancs futtatásának mintakimenetét.

SHOW FULL PROCESSLIST;
+-------+------------------+--------------------+---------------+-------------+--------+-----------------------------+------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
| +-------+------------------+--------------------+---------------+-------------+--------+-----------------------------+------------------------------------------+ |
| 1 | event_scheduler | localhost | NULL | Daemon | 13 | Waiting for next activation | NULL |
| 6 | azure_superuser | 127.0.0.1:33571 | NULL | Sleep | 115 | | NULL |
|
| 24835 | adminuser | 10.1.1.4:39296 | classicmodels | Query | 7 | Sending data | select * from classicmodels.orderdetails; |
| 24837 | adminuser | 10.1.1.4:38208 | NULL | Query | 0 | starting | SHOW FULL PROCESSLIST |
| +-------+------------------+--------------------+---------------+-------------+--------+-----------------------------+------------------------------------------+ |
| 5 rows in set (0.00 sec) |

Az ügyfél tulajdonában lévő "adminuser" felhasználónak két munkamenete van, mindkettő ugyanabból az IP-címből:

  • A 24835-ös munkamenet egy SELECT utasítást futtat az elmúlt hét másodpercben.
  • A 24837- munkamenet a "teljes folyamatlista megjelenítése" utasítást hajtja végre.

Szükség esetén előfordulhat, hogy le kell mondania egy lekérdezést, például egy jelentéskészítési vagy HTAP-lekérdezést, amely miatt az éles számítási feladatok processzorhasználata megugrott. A cpu-kihasználtság csökkentése érdekében azonban mindig vegye figyelembe a lekérdezés megszüntetésének lehetséges következményeit. Máskor, ha vannak olyan hosszú ideig futó lekérdezések, amelyek cpu-csúcsokhoz vezetnek, hangolja ezeket a lekérdezéseket, hogy az erőforrások optimálisan legyenek kihasználva.

Részletes aktuális számítási feladatok elemzése

A munkamenetek, tranzakciók és lekérdezések állapotáról legalább két információforrást kell használnia:

  • A kiszolgáló folyamatlistája a INFORMATION_SCHEMA. PROCESSLIST-tábla, amelyhez a SHOW [FULL] PROCESSLIST parancs futtatásával is hozzáférhet.
  • Az InnoDB tranzakciós metaadatai a INFORMATION_SCHEMA. INNODB_TRX táblázat.

A kapcsolat és a tranzakció állapota nem írható le egyetlen forrásból származó információval. A folyamatlista például nem tájékoztatja arról, hogy van-e nyitott tranzakció a munkamenetekhez társítva. Másrészt a tranzakció metaadatai nem jelenítik meg a munkamenet állapotát és az adott állapotban töltött időt.

Az alábbi példa lekérdezés, amely a folyamatlista adatait egyesíti az InnoDB-tranzakció metaadatainak néhány fontos részével:

mysql> select p.id as session_id, p.user, p.host, p.db, p.command, p.time, p.state, substring(p.info, 1, 50) as info, t.trx_started, unix_timestamp(now()) - unix_timestamp(t.trx_started) as trx_age_seconds, t.trx_rows_modified, t.trx_isolation_level   from information_schema.processlist p left join information_schema.innodb_trx t on p.id = t.trx_mysql_thread_id \G

Az alábbi példa a lekérdezés kimenetét mutatja be:

****************** 1. row ******************
        session_id: 11
               user: adminuser
               host: 172.31.19.159:53624
                 db: NULL
            command: Sleep
               time: 636
              state: cleaned up
               info: NULL
        trx_started: 2019-08-01 15:25:07
    trx_age_seconds: 2908
  trx_rows_modified: 17825792
trx_isolation_level: REPEATABLE READ
****************** 2. row ******************
         session_id: 12
               user: adminuser
               host: 172.31.19.159:53622
                 db: NULL
            command: Query
               time: 15
              state: executing
               info: select * from classicmodels.orders
        trx_started: NULL
    trx_age_seconds: NULL
  trx_rows_modified: NULL
trx_isolation_level: NULL

Ennek az információnak a munkamenet szerinti elemzése az alábbi táblázatban található.

Terület Elemzés
11. munkamenet Ez a munkamenet jelenleg tétlen (alvó), és nem futnak lekérdezések, és 636 másodpercig tart. A munkameneten belül egy 2908 másodpercig megnyitott tranzakció 17 825 792 sort módosított, és ISMÉTLŐDŐ OLVASÁSi elkülönítést használ.
12. munkamenet A munkamenet jelenleg egy SELECT utasítást hajt végre, amely 15 másodpercen át fut. A munkameneten belül nem fut lekérdezés, ahogy azt a trx_started és trx_age_seconds NULL értékei jelzik. A munkamenet továbbra is a szemétgyűjtés határát fogja tartani mindaddig, amíg fut, kivéve, ha a lazább READ COMMITTED elkülönítést használja.

Ha egy munkamenet tétlenként van bejelentve, az már nem hajt végre semmilyen utasítást. Ezen a ponton a munkamenet befejezett minden korábbi munkát, és az ügyféltől érkező új utasításokra vár. Az inaktív munkamenetek azonban továbbra is felelősek a processzorhasználatért és a memóriahasználatért.

Nyitott tranzakciók listázása

A következő lekérdezés kimenete felsorolja az adatbázis-kiszolgálón jelenleg futó összes tranzakciót a tranzakció kezdési ideje szerint, így könnyen azonosítható, hogy vannak-e hosszú ideig futó és a várt futásidejüket meghaladó tranzakciók.

SELECT trx_id, trx_mysql_thread_id, trx_state, Unix_timestamp() - ( To_seconds(trx_started) - To_seconds('1970-01-01 00:00:00') ) AS trx_age_seconds, trx_weight, trx_query, trx_tables_in_use, trx_tables_locked, trx_lock_structs, trx_rows_locked, trx_rows_modified, trx_isolation_level, trx_unique_checks, trx_is_read_only FROM information_schema.innodb_trx ORDER BY trx_started ASC;

A szálállapotok ismertetése

Azok a tranzakciók, amelyek a végrehajtás során nagyobb processzorkihasználtságot eredményeznek, különböző állapotokban lehetnek szálak, az alábbi szakaszokban leírtak szerint. Ezen információk segítségével jobban megismerheti a lekérdezés életciklusát és a különböző szálállapotokat.

Engedélyek ellenőrzése/Táblák megnyitása

Ez az állapot általában azt jelenti, hogy a megnyitott táblaművelet hosszú időt vesz igénybe. A probléma javítása érdekében általában növelheti a táblagyorsítótár méretét. A lassan megnyíló táblák azonban más problémákra is utalhatnak, például túl sok tábla van ugyanabban az adatbázisban.

Adatok küldése

Bár ez az állapot azt jelentheti, hogy a szál adatokat küld a hálózaton keresztül, azt is jelezheti, hogy a lekérdezés adatokat olvas a lemezről vagy a memóriából. Ezt az állapotot szekvenciális táblavizsgálat okozhatja. Ellenőrizze a innodb_buffer_pool_reads és a innodb_buffer_pool_read_requests értékeit annak megállapításához, hogy a lemezről nagy számú lap van-e kézbesítve a memóriába. További információ: A rugalmas Azure Database for MySQL-kiszolgáló alacsony memóriaproblémáinak elhárítása.

Frissítés

Ez az állapot általában azt jelenti, hogy a szál írási műveletet hajt végre. A teljesítményfigyelőben az IO-hoz kapcsolódó metrikával jobban megismerheti az aktuális munkamenetek működését.

Várakozás lock_type> zárolásra <

Ez az állapot azt jelzi, hogy a szál egy második zárolásra vár. A legtöbb esetben metaadat-zárolás lehet. Tekintse át az összes többi szálat, és ellenőrizze, hogy ki veszi át a zárolást.

Várakozási események ismertetése és elemzése

Fontos megérteni a MySQL-motor mögöttes várakozási eseményeit, mert a hosszú várakozások vagy az adatbázisokban lévő nagy számú várakozás megnövelheti a processzorhasználatot. Az alábbi példa a megfelelő parancsot és mintakimenetet mutatja be.

SELECT event_name AS wait_event,
count_star AS all_occurrences,
Concat(Round(sum_timer_wait / 1000000000000, 2), ' s') AS total_wait_time,
 Concat(Round(avg_timer_wait / 1000000000, 2), ' ms') AS
avg_wait_time
FROM performance_schema.events_waits_summary_global_by_event_name
WHERE count_star > 0 AND event_name <> 'idle'
ORDER BY sum_timer_wait DESC LIMIT 10;
+--------------------------------------+-----------------+-----------------+---------------+
| wait_event | all_occurrences | total_wait_time | avg_wait_time |
| +--------------------------------------+-----------------+-----------------+---------------+ |
| wait/io/file/sql/binlog | 7090 | 255.54 s | 36.04 ms |
| wait/io/file/innodb/innodb_log_file | 17798 | 55.43 s | 3.11 ms |
| wait/io/file/innodb/innodb_data_file | 260227 | 39.67 s | 0.15 ms |
| wait/io/table/sql/handler | 5548985 | 11.73 s | 0.00 ms |
| wait/io/file/sql/FRM | 1237 | 7.61 s | 6.15 ms |
| wait/io/file/sql/dbopt | 28 | 1.89 s | 67.38 ms |
| wait/io/file/myisam/kfile | 92 | 0.76 s | 8.30 ms |
| wait/io/file/myisam/dfile | 271 | 0.53 s | 1.95 ms |
| wait/io/file/sql/file_parser | 18 | 0.32 s | 17.75 ms |
| wait/io/file/sql/slow_log | 2 | 0.05 s | 25.79 ms |
| +--------------------------------------+-----------------+-----------------+---------------+ |
| 10 rows in set (0.00 sec) |

SELECT Utasítások végrehajtási idejének korlátozása

Ha nem ismeri a SELECT lekérdezéseket tartalmazó adatbázis-műveletek végrehajtási költségét és végrehajtási idejét, a hosszú ideig futó SELECT-k kiszámíthatatlansághoz vagy volatilitáshoz vezethetnek az adatbázis-kiszolgálón. Az utasítások és tranzakciók mérete, valamint a kapcsolódó erőforrás-kihasználtság az alapul szolgáló adatkészlet növekedésétől függően tovább nő. A kötetlen növekedés miatt a végfelhasználói utasítások és tranzakciók hosszabb ideig tarthatnak, és egyre több erőforrást használnak fel, amíg túlterhelik az adatbázis-kiszolgálót. Kötetlen SELECT-lekérdezések használatakor ajánlott konfigurálni a max_execution_time paramétert, hogy az ezt az időtartamot meghaladó lekérdezések megszakadjanak.

Ajánlások

  • Győződjön meg arról, hogy az adatbázis elegendő erőforrással rendelkezik a lekérdezések futtatásához. Előfordulhat, hogy időnként fel kell skáláznia a példány méretét, hogy több processzormagot kapjon a számítási feladatokhoz.
  • Kerülje a nagy vagy hosszú ideig futó tranzakciókat, ha kisebb tranzakciókra bontja őket.
  • Ha lehetséges, futtassa a SELECT utasításokat az olvasási replikakiszolgálókon.
  • A "Gazdagép CPU-százaléka" riasztások használatával értesítéseket kaphat, ha a rendszer túllépi a megadott küszöbértékeket.
  • A Lekérdezési teljesítményelemzések vagy az Azure-munkafüzetek segítségével azonosíthatja a problémás vagy lassan futó lekérdezéseket, majd optimalizálhatja őket.
  • Éles adatbázis-kiszolgálók esetén rendszeres időközönként gyűjtse össze a diagnosztikát, hogy minden zökkenőmentesen fusson. Ha nem, elháríthatja és megoldhatja az ön által azonosított problémákat.

Stack Overflow