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


A blokkolási problémák ismertetése és megoldása

A következőkre vonatkozik:Azure SQL-adatbázisFabric SQL-adatbázis

A cikk az Azure SQL Database és a Fabric SQL Database blokkolását ismerteti, és bemutatja, hogyan háríthatja el és oldhatja meg a blokkolást.

Célkitűzés

Ebben a cikkben a kapcsolat kifejezés az adatbázis egyetlen bejelentkezett munkamenetére hivatkozik. Minden kapcsolat munkamenet-azonosítóként vagy session_id számos DMV-ben jelenik meg. Ezeket a munkamenet-azonosítókat gyakran folyamatnak nevezik, bár ez nem egy külön folyamatkörnyezet a szokásos értelemben. Ehelyett minden munkamenet-azonosító az adott ügyféltől származó egyetlen kapcsolat kéréseinek kiszolgálásához szükséges kiszolgálói erőforrásokból és adatstruktúrákból áll. Előfordulhat, hogy egyetlen ügyfélalkalmazás egy vagy több kapcsolattal rendelkezik. Az Azure SQL Database szempontjából nincs különbség az egyetlen ügyfélszámítógépen található egyetlen ügyfélalkalmazásból származó több kapcsolat és a több ügyfélalkalmazásból vagy több ügyfélszámítógépről származó több kapcsolat között; Atomiak. Az egyik kapcsolat blokkolhat egy másik kapcsolatot, függetlenül a forrásügyféltől.

További információ a holtpontok hibaelhárításáról: Holtpontok elemzése és megakadályozása az Azure SQL Database-ben és a Fabric SQL Database-.

Jegyzet

Ez a tartalom az Azure SQL Database-re összpontosít. Az Azure SQL Database a Microsoft SQL Server adatbázismotor legújabb stabil verzióján alapul, így a tartalom nagy része hasonló, bár a hibaelhárítási lehetőségek és az eszközök eltérőek lehetnek. További információ az SQL Server blokkolásáról: Az SQL Server blokkolási problémáinak ismertetése és megoldása. A Fabric SQL Database számos funkciót oszt meg az Azure SQL Database-zel. A teljesítménymonitorozással kapcsolatos további információkért lásd: SQL-adatbázis monitorozása a Microsoft Fabric.

A blokkolás ismertetése

A blokkolás minden relációsadatbázis-kezelő rendszer (RDBMS) megkerülhetetlen és tervezett jellemzője, zárolásalapú egyidejűséggel. Az Azure SQL Database adatbázisban történő blokkolás akkor következik be, amikor egy munkamenet egy adott erőforráson zárolást tart, és egy második munkamenet azonosítója megpróbál ugyanezen az erőforráson konfliktusos típusú zárolást szerezni. Általában az az időkeret, amelyre az első munkamenet-azonosító az erőforrást zárolja, kicsi. Amikor a tulajdonosi munkamenet feloldja a zárolást, a második kapcsolat ezután szabadon beszerezhet saját zárolást az erőforráson, és folytathatja a feldolgozást. Ez a viselkedés normális, és egy nap során sokszor előfordulhat, és nincs észrevehető hatása a rendszer teljesítményére.

Az Azure SQL Database minden új adatbázisában alapértelmezés szerint engedélyezve van az leolvasott véglegesített pillanatkép- (RCSI) adatbázis-beállítás. Az adatokat olvasó munkamenetek és a munkamenetek adatírása közötti blokkolás az RCSI-ben minimálisra csökken, amely sorverziók használatával növeli az egyidejűséget. A blokkolás és a holtpontok azonban továbbra is előfordulhatnak az Azure SQL Database adatbázisaiban, mert:

  • Az adatokat módosító lekérdezések blokkolhatják egymást.
  • A lekérdezések olyan elkülönítési szinteken futhatnak, amelyek növelik a blokkolást. Az elkülönítési szintek megadhatók alkalmazáskapcsolati sztringekben, lekérdezési tippekbenvagy SET utasításban a Transact-SQL-ben.
  • RCSI le van tiltva, ezért az adatbázis megosztott (S) zárolásokat használ az olvasási véglegesített elkülönítési szinten futó SELECT-utasítások védelméhez. Ez növelheti a blokkolást és a holtpontokat.

Pillanatkép-elkülönítési szint alapértelmezés szerint engedélyezve van az Azure SQL Database-ben lévő új adatbázisok esetében is. A pillanatkép-elkülönítés egy további soralapú elkülönítési szint, amely tranzakciószintű konzisztenciát biztosít az adatok számára, és amely sorverziókkal választja ki a frissítendő sorokat. A pillanatkép-elkülönítés használatához a lekérdezéseknek vagy kapcsolatoknak explicit módon SNAPSHOTkell beállítaniuk a tranzakcióelkülönítési szintet. Ez csak akkor végezhető el, ha az adatbázis pillanatkép-elkülönítése engedélyezve van.

Megállapíthatja, hogy az RCSI és/vagy a pillanatkép-elkülönítés engedélyezve van-e a Transact-SQL-ben. Csatlakozzon az adatbázishoz az Azure SQL Database-ben, és futtassa a következő lekérdezést:

SELECT name, is_read_committed_snapshot_on, snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO

Ha az RCSI engedélyezve van, a oszlop az 1értéket adja vissza. Ha a pillanatkép-elkülönítés engedélyezve van, a snapshot_isolation_state_desc oszlop a ONértéket adja vissza.

A lekérdezések időtartama és tranzakciós környezete határozza meg a zárolások időtartamát, valamint a többi lekérdezésre gyakorolt hatásukat. A SELECT utasítások RCSI-ben futnak, nem szereznek be megosztott (S) zárolásokat az olvasandó adatokhoz, ezért nem tiltják le az adatokat módosító tranzakciókat. AZ INSERT, UPDATE és DELETE utasítások esetén a zárolások a lekérdezés során is megtarthatók, mind az adatkonzisztenciáért, mind a lekérdezés szükség esetén történő visszaállításának engedélyezéséhez.

A explicit tranzakciósbelül végrehajtott lekérdezések esetében a zárolások típusát és időtartamát a lekérdezés típusa, a tranzakcióelkülönítési szint és a zárolási tippek használata határozza meg a lekérdezésben. A zárolási, zárolási tippek és tranzakcióelkülönítési szintek leírását a következő cikkekben talál:

Ha a zárolás és a blokkolás olyan mértékben fennáll, hogy káros hatással van a rendszer teljesítményére, az alábbi okok egyikének köszönhető:

  • A munkamenet-azonosítók hosszabb ideig zárolják az erőforrásokat, mielőtt felszabadítanák őket. Az ilyen típusú blokkolás idővel feloldja önmagát, de teljesítménycsökkenést okozhat.

  • A munkamenet-azonosító zárolja az erőforrások egy készletét, és soha nem oldja fel őket. Ez a típusú blokkolás nem oldja fel önmagát, és megakadályozza az érintett erőforrásokhoz való hozzáférést határozatlan ideig.

Az első forgatókönyvben a helyzet nagyon folyékony lehet, mivel a különböző munkamenet-azonosítók idővel blokkolják a különböző erőforrásokat, és mozgó célt hoznak létre. Ezeket a helyzeteket nehéz elhárítani SQL Server Management Studio használatával, hogy az egyes lekérdezésekre szűkítse a problémát. Ezzel szemben a második helyzet konzisztens állapotot eredményez, amely könnyebben diagnosztizálható.

Optimalizált zárolás

Az optimalizált zárolás egy új adatbázismotor-funkció, amely drasztikusan csökkenti a zárolási memóriát és az íráshoz egyidejűleg szükséges zárolások számát. Az optimalizált zárolás két elsődleges összetevőt használ: tranzakcióazonosító (TID) zárolást (más sorverziós tulajdonságokban is használják), és minősítés utáni zárolást (LAQ). Nincs szükség további konfigurációra.

Ez a cikk jelenleg az adatbázismotor viselkedésére vonatkozik optimalizált zárolás nélkül.

További információkért és az optimalizált zárolás elérhetőségének megismeréséhez tekintse meg optimalizált zárolásicímű témakört.

Alkalmazások és blokkolás

Előfordulhat, hogy a kiszolgálóoldali hangolással és a platformmal kapcsolatos problémákra kell összpontosítania, amikor blokkolási problémával szembesül. Előfordulhat azonban, hogy csak az adatbázisra való odafigyelés nem vezet megoldáshoz, és jobban elnyeli az ügyfélalkalmazás és az általa küldött lekérdezések vizsgálatára fordított időt és energiát. Függetlenül attól, hogy az alkalmazás milyen szintű láthatóságot tesz elérhetővé a folyamatban lévő adatbázis-hívások tekintetében, a blokkolási probléma gyakran megköveteli az alkalmazás által küldött pontos SQL-utasítások ellenőrzését, valamint az alkalmazás pontos viselkedését a lekérdezések megszakításával, a kapcsolatkezeléssel, az összes eredménysor lekérésével stb. kapcsolatban. Ha a fejlesztőeszköz nem teszi lehetővé a kapcsolatkezelés, a lekérdezések megszakítása, a lekérdezés időtúllépése, az eredmények beolvasása stb. explicit vezérlését, előfordulhat, hogy a blokkolási problémák nem oldhatók meg. Ezt a potenciált alaposan meg kell vizsgálni az Azure SQL Database alkalmazásfejlesztési eszközének kiválasztása előtt, különösen a teljesítményérzékeny OLTP-környezetek esetében.

Az adatbázis és az alkalmazás tervezési és építési fázisában ügyeljen az adatbázis teljesítményére. Különösen az erőforrás-felhasználást, az elkülönítési szintet és a tranzakciós útvonal hosszát kell kiértékelni az egyes lekérdezések esetében. Minden lekérdezésnek és tranzakciónak a lehető legkönnyűsnek kell lennie. Jó kapcsolatkezelési szemléletet kell gyakorolni. Nélküle úgy tűnhet, hogy az alkalmazás alacsony számú felhasználónál elfogadható teljesítménnyel rendelkezik, de a teljesítmény jelentősen csökkenhet, mivel a felhasználók száma felfelé skálázható.

A megfelelő alkalmazás- és lekérdezéstervezéssel az Azure SQL Database több ezer egyidejű felhasználót képes támogatni egyetlen kiszolgálón, kevés blokkolással.

Jegyzet

További alkalmazásfejlesztési útmutató: Csatlakozási problémák és egyéb hibák elhárítása és átmeneti hibakezelési.

Blokkolás hibaelhárítása

Függetlenül attól, hogy milyen blokkoló helyzetben vagyunk, a zárolás hibaelhárításának módszertana ugyanaz. Ezek a logikai elválasztások határozzák meg a cikk további összetételét. A koncepció az, hogy megkeressük a fő blokkoló elemet, és azonosítsuk, hogy mit csinál a lekérdezés és miért blokkol. Miután azonosította a problémás lekérdezést (vagyis azt, hogy mi tartja a zárolásokat a hosszabb ideig), a következő lépés a blokkolás okának elemzése és meghatározása. Miután megértettük az okokat, a lekérdezés és a tranzakció újratervezésével módosíthatjuk a módosításokat.

A hibaelhárítás lépései:

  1. A fő blokkoló munkamenet azonosítása (fejblokkoló)

  2. Keresse meg a blokkolást okozó lekérdezést és tranzakciót (mi tartja a zárolásokat hosszabb ideig)

  3. Annak elemzése/megértése, hogy miért fordul elő a hosszan tartó blokkolás

  4. A blokkolási probléma megoldása lekérdezés és tranzakció újratervezésével

Merüljünk bele, hogy megvitassuk, hogyan azonosíthatja a fő blokkoló munkamenetet egy megfelelő adatrögzítéssel.

Blokkoló információk gyűjtése

A blokkolási problémák elhárításának nehézségeinek elhárítása érdekében az adatbázisgazdák olyan SQL-szkripteket használhatnak, amelyek folyamatosan figyelik a zárolás és a blokkolás állapotát az Azure SQL Database adatbázisában. Az adatok gyűjtéséhez alapvetően két módszer létezik.

Az első a dinamikus felügyeleti objektumok (DMOS-k) lekérdezése és az eredmények időbeli összehasonlításhoz való tárolása. A cikkben hivatkozott objektumok némelyike dinamikus felügyeleti nézet (DMV), néhány pedig dinamikus felügyeleti függvény (DMF). A második módszer az XEvents használata a végrehajtás rögzítésére.

Információgyűjtés DMV-kből

A DMVs-ra való hivatkozás célja a blokkolási hibák elhárításában az, hogy azonosítsa a blokkolási lánc élén álló munkamenet-azonosítót és az SQL-utasítást. Keresse azokat az áldozat munkamenetazonosítókat, amelyeket letiltottak. Ha egy munkamenet-azonosítót egy másik munkamenet-azonosító blokkol, vizsgálja meg az erőforrást (a blokkoló munkamenet-azonosítót) tartalmazó munkamenet-azonosítót. Ez a tulajdonos munkamenet-azonosítója is le van tiltva? Követve a láncot, megtalálhatja a fő blokkolót, majd megvizsgálhatja, miért tartja a zárat.

Ne felejtse el futtatni ezeket a szkripteket a céladatbázisban az Azure SQL Database-ben.

  • A sp_who és sp_who2 parancsok régebbi parancsok az összes aktuális munkamenet megjelenítéséhez. A DMV sys.dm_exec_sessions több adatot ad vissza egy könnyebben lekérdezni és szűrni kívánt eredményhalmazban. sys.dm_exec_sessions megtalálható a többi lekérdezés középpontjában.

  • Ha már azonosított egy adott munkamenetet, a DBCC INPUTBUFFER(<session_id>) segítségével megkeresheti a munkamenet által elküldött utolsó utasítást. Hasonló eredményeket a sys.dm_exec_input_buffer dinamikus felügyeleti függvény (DMF) segítségével lehet visszaadni egy könnyebben lekérdezhető és szűrhető eredményhalmazban, amely biztosítja a session_id és a request_id. Ha például a 66-os és request_id 0-s session_id által küldött legutóbbi lekérdezést szeretné visszaadni:

SELECT * FROM sys.dm_exec_input_buffer (66,0);
  • Nézze meg a blocking_session_id oszlopot a sys.dm_exec_requests-ben. Ha blocking_session_id = 0, a munkamenet nem lesz blokkolva. Bár sys.dm_exec_requests csak a jelenleg futó kéréseket listázza, a kapcsolatok (aktívak vagy nem) a sys.dm_exec_sessionslistában jelennek meg. A következő lekérdezésben a sys.dm_exec_requests és a sys.dm_exec_sessions közötti gyakori illesztésre építhet.

  • A minta lekérdezés futtatásával megkeresheti az aktívan végrehajtó lekérdezéseket és az SQL-köteg aktuális szövegét vagy bemeneti pufferszövegét a sys.dm_exec_sql_text vagy sys.dm_exec_input_buffer DMV-k használatával. Ha a textsys.dm_exec_sql_text mezője által visszaadott adatok NULL értékűek, a lekérdezés jelenleg nem fut. Ebben az esetben a event_infosys.dm_exec_input_buffer mezője az SQL-motornak átadott utolsó parancssztringet tartalmazza. Ez a lekérdezés más munkameneteket blokkoló munkamenetek azonosítására is használható, ideértve minden session_id által blokkolt session_id-k listáját is.

WITH cteBL (session_id, blocking_these) AS 
(SELECT s.session_id, blocking_these = x.blocking_these FROM sys.dm_exec_sessions s 
CROSS APPLY    (SELECT isnull(convert(varchar(6), er.session_id),'') + ', '  
                FROM sys.dm_exec_requests as er
                WHERE er.blocking_session_id = isnull(s.session_id ,0)
                AND er.blocking_session_id <> 0
                FOR XML PATH('') ) AS x (blocking_these)
)
SELECT s.session_id, blocked_by = r.blocking_session_id, bl.blocking_these
, batch_text = t.text, input_buffer = ib.event_info, * 
FROM sys.dm_exec_sessions s 
LEFT OUTER JOIN sys.dm_exec_requests r on r.session_id = s.session_id
INNER JOIN cteBL as bl on s.session_id = bl.session_id
OUTER APPLY sys.dm_exec_sql_text (r.sql_handle) t
OUTER APPLY sys.dm_exec_input_buffer(s.session_id, NULL) AS ib
WHERE blocking_these is not null or r.blocking_session_id > 0
ORDER BY len(bl.blocking_these) desc, r.blocking_session_id desc, r.session_id;
  • Futtassa a Microsoft támogatási szolgálata által biztosított részletesebb mintalekérdezéseket egy több munkamenet-blokkoló lánc vezetőjének azonosításához, beleértve a blokkolási láncban részt vevő munkamenetek lekérdezési szövegét is.
WITH cteHead ( session_id,request_id,wait_type,wait_resource,last_wait_type,is_user_process,request_cpu_time
,request_logical_reads,request_reads,request_writes,wait_time,blocking_session_id,memory_usage
,session_cpu_time,session_reads,session_writes,session_logical_reads
,percent_complete,est_completion_time,request_start_time,request_status,command
,plan_handle,sql_handle,statement_start_offset,statement_end_offset,most_recent_sql_handle
,session_status,group_id,query_hash,query_plan_hash) 
AS ( SELECT sess.session_id, req.request_id, LEFT (ISNULL (req.wait_type, ''), 50) AS 'wait_type'
    , LEFT (ISNULL (req.wait_resource, ''), 40) AS 'wait_resource', LEFT (req.last_wait_type, 50) AS 'last_wait_type'
    , sess.is_user_process, req.cpu_time AS 'request_cpu_time', req.logical_reads AS 'request_logical_reads'
    , req.reads AS 'request_reads', req.writes AS 'request_writes', req.wait_time, req.blocking_session_id,sess.memory_usage
    , sess.cpu_time AS 'session_cpu_time', sess.reads AS 'session_reads', sess.writes AS 'session_writes', sess.logical_reads AS 'session_logical_reads'
    , CONVERT (decimal(5,2), req.percent_complete) AS 'percent_complete', req.estimated_completion_time AS 'est_completion_time'
    , req.start_time AS 'request_start_time', LEFT (req.status, 15) AS 'request_status', req.command
    , req.plan_handle, req.[sql_handle], req.statement_start_offset, req.statement_end_offset, conn.most_recent_sql_handle
    , LEFT (sess.status, 15) AS 'session_status', sess.group_id, req.query_hash, req.query_plan_hash
    FROM sys.dm_exec_sessions AS sess
    LEFT OUTER JOIN sys.dm_exec_requests AS req ON sess.session_id = req.session_id
    LEFT OUTER JOIN sys.dm_exec_connections AS conn on conn.session_id = sess.session_id 
    )
, cteBlockingHierarchy (head_blocker_session_id, session_id, blocking_session_id, wait_type, wait_duration_ms,
wait_resource, statement_start_offset, statement_end_offset, plan_handle, sql_handle, most_recent_sql_handle, [Level])
AS ( SELECT head.session_id AS head_blocker_session_id, head.session_id AS session_id, head.blocking_session_id
    , head.wait_type, head.wait_time, head.wait_resource, head.statement_start_offset, head.statement_end_offset
    , head.plan_handle, head.sql_handle, head.most_recent_sql_handle, 0 AS [Level]
    FROM cteHead AS head
    WHERE (head.blocking_session_id IS NULL OR head.blocking_session_id = 0)
    AND head.session_id IN (SELECT DISTINCT blocking_session_id FROM cteHead WHERE blocking_session_id != 0)
    UNION ALL
    SELECT h.head_blocker_session_id, blocked.session_id, blocked.blocking_session_id, blocked.wait_type,
    blocked.wait_time, blocked.wait_resource, h.statement_start_offset, h.statement_end_offset,
    h.plan_handle, h.sql_handle, h.most_recent_sql_handle, [Level] + 1
    FROM cteHead AS blocked
    INNER JOIN cteBlockingHierarchy AS h ON h.session_id = blocked.blocking_session_id and h.session_id!=blocked.session_id --avoid infinite recursion for latch type of blocking
    WHERE h.wait_type COLLATE Latin1_General_BIN NOT IN ('EXCHANGE', 'CXPACKET') or h.wait_type is null
    )
SELECT bh.*, txt.text AS blocker_query_or_most_recent_query 
FROM cteBlockingHierarchy AS bh 
OUTER APPLY sys.dm_exec_sql_text (ISNULL ([sql_handle], most_recent_sql_handle)) AS txt;
SELECT [s_tst].[session_id],
[database_name] = DB_NAME (s_tdt.database_id),
[s_tdt].[database_transaction_begin_time], 
[sql_text] = [s_est].[text] 
FROM sys.dm_tran_database_transactions [s_tdt]
INNER JOIN sys.dm_tran_session_transactions [s_tst] ON [s_tst].[transaction_id] = [s_tdt].[transaction_id]
INNER JOIN sys.dm_exec_connections [s_ec] ON [s_ec].[session_id] = [s_tst].[session_id]
CROSS APPLY sys.dm_exec_sql_text ([s_ec].[most_recent_sql_handle]) AS [s_est];
  • Referencia a(z) sys.dm_os_waiting_tasks elemre, amely az SQL szál-/tevékenységrétegében található. Ez információkat ad vissza arról, hogy milyen SQL-várakozási típust tapasztal a kérés. Az sys.dm_exec_requests-hez hasonlóan csak az aktív kéréseket adja vissza a sys.dm_os_waiting_tasks.

Jegyzet

A várakozási típusokkal kapcsolatos további információkért, beleértve az összesített várakozási statisztikákat is, tekintse meg a DMV sys.dm_db_wait_stats. Ez a DMV csak az aktuális adatbázis összesített várakozási statisztikáit adja vissza.

  • A sys.dm_tran_locks DMV használatával részletesebb információkat kaphat arról, hogy a lekérdezések milyen zárolásokat helyeztek el. Ez a DMV nagy mennyiségű adatot képes visszaadni egy termelési adatbázissal kapcsolatban, és hasznos a jelenleg fennálló zárolások diagnosztizálásához.

A sys.dm_os_waiting_tasksbelső illesztése miatt a következő lekérdezés csak a jelenleg blokkolt kérésekre, várakozási állapotukra és zárolásaikra korlátozza a sys.dm_tran_locks kimenetét:

SELECT table_name = schema_name(o.schema_id) + '.' + o.name
, wt.wait_duration_ms, wt.wait_type, wt.blocking_session_id, wt.resource_description
, tm.resource_type, tm.request_status, tm.request_mode, tm.request_session_id
FROM sys.dm_tran_locks AS tm
INNER JOIN sys.dm_os_waiting_tasks as wt ON tm.lock_owner_address = wt.resource_address
LEFT OUTER JOIN sys.partitions AS p on p.hobt_id = tm.resource_associated_entity_id
LEFT OUTER JOIN sys.objects o on o.object_id = p.object_id or tm.resource_associated_entity_id = o.object_id
WHERE resource_database_id = DB_ID()
AND object_name(p.object_id) = '<table_name>';
  • A DMV-k segítségével a lekérdezési eredmények időbeli tárolása olyan adatpontokat biztosít, amelyek lehetővé teszik a letiltás adott időintervallumon keresztüli áttekintését a tartós blokkolások vagy trendek azonosítása érdekében.

Információk gyűjtése kiterjesztett eseményekből

Az előző információkon kívül gyakran szükséges a kiszolgálón végzett tevékenységek nyomon követése az Azure SQL Database blokkolási problémájának alapos kivizsgálásához. Ha például egy munkamenet több utasítást hajt végre egy tranzakción belül, csak az utolsó elküldött utasítás jelenik meg. Előfordulhat azonban, hogy a korábbi állítások egyike az oka annak, hogy a zárolások továbbra is fennállnak. A nyomkövetés lehetővé teszi az összes parancs megtekintését, amelyet egy munkamenet hajt végre az aktuális tranzakción belül.

A nyomkövetések kétféleképpen rögzíthetők az SQL Serveren; Bővített események (XEvents) és Profiler-nyomkövetések. Azonban az SQL Server Profiler, mint elavult nyomkövetési technológia, nem támogatott az Azure SQL Database-ben. Bővített események az újabb nyomkövetési technológia, amely sokoldalúbb és kevésbé hat a megfigyelt rendszerre, és interfésze integrálva van az SQL Server Management Studióba (SSMS).

Azok számára, akik meg szeretnék érteni, hogyan használható az Bővített Események Új Munkamenet Varázsló az SSMS-ben, tekintse meg az ezt ismertető dokumentumot. Az Azure SQL-adatbázisok esetében azonban az SSMS egy Kiterjesztett események almappát biztosít az Object Explorerben lévő adatbázisok alatt. A bővített események munkamenetvarázslója a következő hasznos események rögzítésére használható:

  • Kategóriahibák:

    • Figyelem
    • Hiba_jelentve
    • Végrehajtási figyelmeztetés
  • Kategória figyelmeztetései:

    • Hiányzó összekapcsolási feltétel
  • Kategória végrehajtása:

    • Rpc_befejezve
    • Rpc_indul
    • Sql_csomag_befejezve
    • SQL csomag indítása
  • Kategória holtpont-figyelő

    • adatbázis_xml_holtpontjelentés
  • Kategória-munkamenet

    • Létező_kapcsolat
    • Bejelentkezés
    • Kijelentkezés

Jegyzet

A holtpontokra vonatkozó részletes információkért lásd: Holtpontok elemzése és megakadályozása az Azure SQL Database-ben és a Fabric SQL Database-.

Gyakori blokkolási forgatókönyvek azonosítása és megoldása

Az előző információk vizsgálatával meghatározhatja a legtöbb blokkolási probléma okát. A cikk további része azt ismerteti, hogyan használhatja ezeket az információkat néhány gyakori blokkolási forgatókönyv azonosítására és megoldására. Ez a megbeszélés feltételezi, hogy a blokkolást végző szkriptekkel (korábban hivatkozott) rögzítette a blokkoló munkamenet-azonosítókat, és XEvent-munkamenet segítségével rögzítette az alkalmazás tevékenységet.

Blokkoló adatok elemzése

  • Vizsgálja meg a sys.dm_exec_requests és sys.dm_exec_sessions DMV-k kimenetét, hogy meghatározza a blokkoló láncok fejét, a blocking_these és session_id használatával. Ez leginkább világosan azonosítja, hogy melyik kéréseket blokkoltak, és melyek blokkolják azokat. Tekintse át a blokkolt és blokkoló munkameneteket. Van közös vagy alapvető eleme a blokkoló láncnak? Valószínűleg közös táblát használnak, és a blokkolási láncban részt vevő munkamenetek közül legalább egy írási műveletet hajt végre.

  • Vizsgálja meg a DMV-k sys.dm_exec_requests kimenetét, és sys.dm_exec_sessions a blokkolási lánc élén található munkamenet-azonosítókkal kapcsolatos információkat. Keresse meg a következő mezőket:

    • sys.dm_exec_requests.status
      Ez az oszlop egy adott kérés állapotát mutatja. Az alvó állapot általában azt jelzi, hogy a munkamenet-azonosító végrehajtotta a végrehajtást, és arra vár, hogy az alkalmazás egy másik lekérdezést vagy köteget küldjön be. A futtatható vagy futó állapot azt jelzi, hogy a munkamenet-azonosító jelenleg egy lekérdezést dolgoz fel. Az alábbi táblázat röviden ismerteti a különböző állapotértékeket.
    Állapot Jelentés
    Háttér A munkamenet-azonosító egy háttérfeladatot futtat, például holtpont-észlelést, naplóírót vagy ellenőrzőpontot.
    Alvó A munkamenet-azonosító jelenleg nem fut. Ez általában azt jelzi, hogy a munkamenet-azonosító az alkalmazás parancsára vár.
    Futás A munkamenet-azonosító jelenleg egy ütemező rendszerben fut.
    Futtatható A munkamenet-azonosító egy ütemező futtatási sorában található, és az ütemezési időre vár.
    Felfüggesztett A munkamenet-azonosító egy erőforrásra, például zárolásra vagy reteszre vár.
    • sys.dm_exec_sessions.open_transaction_count
      Ez a mező a munkamenetben megnyitott tranzakciók számát mutatja. Ha ez az érték 0-nál nagyobb, a munkamenet-azonosító egy nyitott tranzakción belül van, és a tranzakció bármely utasítása által beszerzett zárolásokat tartalmazhat.

    • sys.dm_exec_requests.open_transaction_count
      Ez a mező a kérelemben lévő nyitott tranzakciók számát is jelzi. Ha ez az érték 0-nál nagyobb, a munkamenet-azonosító egy nyitott tranzakción belül van, és előfordulhat, hogy a tranzakció bármely utasítása által megszerzett zárolásokat tart fenn.

    • sys.dm_exec_requests.wait_type, wait_timeés last_wait_type
      Ha a sys.dm_exec_requests.wait_type NULL értékű, a kérés jelenleg nem vár semmire, és a last_wait_type érték azt az utolsó wait_type jelzi, amelyet a kérés észlelt. A sys.dm_os_wait_stats és a leggyakoribb várakozási típusok leírását a sys.dm_os_wait_statscímű témakörben talál. A wait_time érték segítségével megállapíthatja, hogy a kérés folyamatban van-e. Ha a sys.dm_exec_requests tábla lekérdezése a wait_time oszlopban olyan értéket ad vissza, amely kisebb a wait_timekorábbi lekérdezésének sys.dm_exec_requests értékénél, az azt jelzi, hogy a korábbi zárolást megszerezték és feloldották, és most egy új zárolásra vár (feltéve, hogy wait_timenem nulla). Ez a wait_resource és a sys.dm_exec_requests kimenet összehasonlításával ellenőrizhető, amely megjeleníti azt az erőforrást, amelyre a kérés várakozik.

    • sys.dm_exec_requests.wait_resource Ez a mező azt az erőforrást jelzi, amelyen egy blokkolt kérés várakozik. Az alábbi táblázat a gyakori wait_resource formátumokat és azok jelentését sorolja fel:

    Erőforrás Formátum Példa Magyarázat
    Asztal DatabaseID:ObjectID:IndexID TAB: 5:261575970:1 Ebben az esetben az adatbázis-azonosító 5 a pubs mintaadatbázis, az objektumazonosító 261575970 a címek tábla, és az 1 a klaszteres index.
    Oldal DatabaseID:FileID:PageID OLDAL: 5:1:104 Ebben az esetben az 5-ös adatbázis-azonosító is pubs, az 1. fájlazonosító az elsődleges adatfájl, a 104. oldal pedig a címtáblához tartozó lap. A object_id azonosításához, amelyhez a lap tartozik, használja a sys.dm_db_page_infodinamikus felügyeleti függvényt, és adja meg az adatbázis azonosítót, a FileId-t és a PageId-t a wait_resource-ből.
    Kulcs DatabaseID:Hobt_id (indexkulcs kivonatértéke) KULCS: 5:72057594044284928 (3300a4f361aa) Ebben az esetben az 5-ös adatbázis-azonosító pubs, és Hobt_ID 72057594044284928 index_id 2-nek felel meg object_id 261575970 (címtáblázat). A sys.partitions katalógusnézet használatával kapcsolja a hobt_id-et egy adott index_id-höz és object_id-hoz. Nem lehet az indexkulcs kivonatát visszaalakítani egy konkrét kulcsértékké.
    Sor DatabaseID:FileID:PageID:Slot(sor) RID: 5:1:104:3 Ebben az esetben az 5. adatbázis-azonosító pubs, az 1. fájl az elsődleges adatfájl, a 104. oldal a címtáblához tartozó lap, a 3. pont pedig a sor pozícióját jelzi a lapon.
    Összeállít DatabaseID:FileID:PageID:Slot(sor) RID: 5:1:104:3 Ebben az esetben az 5. adatbázis-azonosító pubs, az 1. fájl az elsődleges adatfájl, a 104. oldal a címtáblához tartozó lap, a 3. pont pedig a sor pozícióját jelzi a lapon.
    • sys.dm_tran_active_transactions A sys.dm_tran_active_transactions DMV olyan nyitott tranzakciók adatait tartalmazza, amelyek más DMV-khez csatlakoztathatók a véglegesítésre vagy visszaállításra váró tranzakciók teljes képéhez. A következő lekérdezés segítségével vissza lehet adni a nyitott tranzakciókra vonatkozó információkat, amelyek más DMV-khez csatlakoznak, mint például a sys.dm_tran_session_transactions. Fontolja meg egy tranzakció aktuális állapotát, transaction_begin_timeés egyéb helyzetadatokat annak kiértékeléséhez, hogy az blokkolható-e.
    SELECT tst.session_id, [database_name] = db_name(s.database_id)
    , tat.transaction_begin_time
    , transaction_duration_s = datediff(s, tat.transaction_begin_time, sysdatetime()) 
    , transaction_type = CASE tat.transaction_type  WHEN 1 THEN 'Read/write transaction'
                                                    WHEN 2 THEN 'Read-only transaction'
                                                    WHEN 3 THEN 'System transaction'
                                                    WHEN 4 THEN 'Distributed transaction' END
    , input_buffer = ib.event_info, tat.transaction_uow     
    , transaction_state  = CASE tat.transaction_state    
                WHEN 0 THEN 'The transaction has not been completely initialized yet.'
                WHEN 1 THEN 'The transaction has been initialized but has not started.'
                WHEN 2 THEN 'The transaction is active - has not been committed or rolled back.'
                WHEN 3 THEN 'The transaction has ended. This is used for read-only transactions.'
                WHEN 4 THEN 'The commit process has been initiated on the distributed transaction.'
                WHEN 5 THEN 'The transaction is in a prepared state and waiting resolution.'
                WHEN 6 THEN 'The transaction has been committed.'
                WHEN 7 THEN 'The transaction is being rolled back.'
                WHEN 8 THEN 'The transaction has been rolled back.' END 
    , transaction_name = tat.name, request_status = r.status
    , azure_dtc_state = CASE tat.dtc_state 
                        WHEN 1 THEN 'ACTIVE'
                        WHEN 2 THEN 'PREPARED'
                        WHEN 3 THEN 'COMMITTED'
                        WHEN 4 THEN 'ABORTED'
                        WHEN 5 THEN 'RECOVERED' END
    , tst.is_user_transaction, tst.is_local
    , session_open_transaction_count = tst.open_transaction_count  
    , s.host_name, s.program_name, s.client_interface_name, s.login_name, s.is_user_process
    FROM sys.dm_tran_active_transactions tat 
    INNER JOIN sys.dm_tran_session_transactions tst  on tat.transaction_id = tst.transaction_id
    INNER JOIN sys.dm_exec_sessions s on s.session_id = tst.session_id 
    LEFT OUTER JOIN sys.dm_exec_requests r on r.session_id = s.session_id
    CROSS APPLY sys.dm_exec_input_buffer(s.session_id, null) AS ib;
    
    • Egyéb oszlopok

      A sys.dm_exec_sessions és sys.dm_exec_request többi oszlopa is betekintést nyújt a probléma gyökerébe. A hasznosságuk a probléma körülményeitől függően változik. Megállapíthatja például, hogy a probléma csak bizonyos ügyfelektől (gazdagépnév) vagy bizonyos hálózati kódtáraknál (net_library) fordul-e elő, mikor a session ID által az utolsó köteg elküldve lett last_request_start_timesys.dm_exec_sessions, mennyi ideig futott egy kérés start_timesys.dm_exec_requests használat során, és így tovább.

Gyakori blokkolási forgatókönyvek

Az alábbi táblázat leképozza a gyakori tüneteket a valószínű okokra.

A Waittype, Open_Tranés Status oszlopok a sys.dm_exec_requestáltal visszaadott információkra vonatkoznak . A sys.dm_exec_sessionsmás oszlopokat is visszaadhat. A "Feloldások?" oszlop azt jelzi, hogy a blokkolás önállóan feloldható-e, vagy a munkamenetet a KILL paranccsal kell-e megölni. További információ: KILL.

Forgatókönyv Várástípus Open_Tran Állapot Megoldja? Egyéb tünetek
1 NEM ÜRES >= 0 Futtatható Igen, amikor a lekérdezés befejeződik. A sys.dm_exec_sessions, reads, cpu_timeés/vagy memory_usage oszlopai idővel növekednek. A lekérdezés időtartama a befejezéskor magas.
2 NULLA >0. alvó Nem, de a munkamenet-azonosítót meg lehet ölni. Kiterjesztett esemény munkamenetében figyelemjel jelenhet meg az adott munkamenet-azonosítónál, ami jelzi, hogy lekérdezési időtúllépés vagy megszakítás történt.
3 NULLA >= 0 Futtatható Nem. Nem oldódik fel, amíg az ügyfél be nem olvassa az összes sort, vagy be nem zárja a kapcsolatot. A munkamenet-azonosító megölhető, de akár 30 másodpercet is igénybe vehet. Ha open_transaction_count = 0, és a munkamenet-azonosító zárolva van, miközben a tranzakcióelkülönítési szint alapértelmezett (READ COMMITTED), ez valószínűleg az oka.
4 Változik >= 0 Futtatható Nem. Nem oldja fel, amíg az ügyfél nem szakítja meg a lekérdezéseket, vagy nem zárja be a kapcsolatokat. a munkamenet-azonosítók megölhetők, de akár 30 másodpercet is igénybe vehetnek. A hostname oszlop, amely a blokkolási lánc élén lévő munkamenet-azonosítóra vonatkozik, megegyezik az általa blokkolt munkamenet-azonosítók egyikével sys.dm_exec_sessions-ben.
5 NULLA >0. visszaállítás Igen. A Kiterjesztett események munkamenet során figyelmeztető jelzés jelenhet meg ennél a munkamenet-azonosítónál, ami azt jelzi, hogy a lekérdezés időtúllépett vagy megszakadt, vagy egyszerűen visszaállítási utasítást adtak ki.
6 NULLA >0. alvó Végül. Ha a Windows megállapítja, hogy a munkamenet már nem aktív, az Azure SQL Database-kapcsolat megszakadt. A last_request_start_time értéke a sys.dm_exec_sessions-ben sokkal korábbi, mint a jelenlegi időpont.

Részletes blokkolási forgatókönyvek

  1. Hosszú végrehajtási idővel rendelkező, általában futó lekérdezés által okozott blokkolás

    megoldási: Az ilyen típusú blokkolási problémára az a megoldás, hogy megkeresse a lekérdezés optimalizálásának módját. Valójában ez a blokkolási probléma típus egyszerűen csak egy teljesítményprobléma is lehet, és megkövetelheti, hogy ennek megfelelően kezelje. Egy adott lassú lekérdezés hibaelhárításával kapcsolatos információkért tekintse meg Az SQL Serverlassan futó lekérdezéseinek hibaelhárítása című témakört. További információkért lásd: Monitorozás és teljesítmény finomhangolása.

    Az SSMS-ben található lekérdezéstárból származó jelentések szintén rendkívül ajánlott és értékes eszközök a legköltségesebb lekérdezések és az optimalizálásra szoruló végrehajtási tervek azonosításához. Tekintse át lekérdezési teljesítményelemzési.

    Ha a lekérdezés csak SELECT műveleteket hajt végre, fontolja meg az utasítás végrehajtását pillanatkép izoláció alatt, ha az engedélyezve van az adatbázisban, különösen akkor, ha az RCSI le van tiltva. Ahogy az RCSI engedélyezve van, az adatokat olvasó lekérdezések nem igényelnek megosztott (S) zárolást pillanatkép-elkülönítési szinten. Emellett a pillanatkép-elkülönítés tranzakciószintű konzisztenciát biztosít egy explicit, több utasítást tartalmazó tranzakció minden utasítására. Előfordulhat, hogy a pillanatképek elkülönítése már engedélyezve az adatbázisban. A pillanatkép-elkülönítést a módosításokat végrehajtó lekérdezésekhez is használhatja, de frissítési ütközéseketkell kezelnie.

    Ha van egy olyan hosszú ideig futó lekérdezése, amely blokkolja a többi felhasználót, és nem optimalizálható, érdemes lehet áthelyezni egy OLTP-környezetből egy dedikált jelentéskészítő rendszerbe, amely az adatbázis szinkron írásvédett replikája.

  2. Nem véglegesített tranzakcióval rendelkező alvó munkamenet-azonosító által okozott blokkolás

    Ez a blokkolás gyakran azonosítható olyan munkamenet-azonosítóval, amely alvó vagy parancsra vár, de amelynek tranzakció beágyazottsági szintje (@@TRANCOUNT, open_transaction_count a sys.dm_exec_requests forrásból) nagyobb, mint nulla. Ez akkor fordulhat elő, ha az alkalmazás időtúllépést tapasztal a lekérdezésnél, vagy megad egy megszakítási parancsot a szükséges számú ROLLBACK és/vagy COMMIT utasítás kiadása nélkül. Amikor egy munkamenet-azonosító időtúllépést vagy megszakítást kap a lekérdezéshez, leállítja az aktuális lekérdezést és köteget, de nem hajtja végre automatikusan a tranzakciót. Ezért az alkalmazás a felelős, mivel az Azure SQL Database nem feltételezheti, hogy egy teljes tranzakciót vissza kell állítani egyetlen lekérdezés megszakítása miatt. A lekérdezés időtúllépése vagy megszakítása FIGYELEM jeleseményként jelenik meg a kiterjesztett esemény munkamenet-azonosítójának esetében.

    A nem véglegesített explicit tranzakció bemutatásához adja ki a következő lekérdezést:

    CREATE TABLE #test (col1 INT);
    INSERT INTO #test SELECT 1;
    BEGIN TRAN
    UPDATE #test SET col1 = 2 where col1 = 1;
    

    Ezután hajtsa végre ezt a lekérdezést ugyanabban az ablakban:

    SELECT @@TRANCOUNT;
    ROLLBACK TRAN
    DROP TABLE #test;
    

    A második lekérdezés kimenete azt jelzi, hogy a tranzakció beágyazási szintje egy. A tranzakcióban beszerzett összes zárolás a tranzakció véglegesítéséig vagy visszagörgetéséig marad érvényben. Ha az alkalmazások kifejezetten megnyitnak és véglegesítenek tranzakciókat, egy kommunikáció vagy egyéb hiba nyitott állapotban hagyhatja el a munkamenetet és annak tranzakcióját.

    A cikk korábbi részében található, sys.dm_tran_active_transactions-ra alapuló szkript segítségével azonosíthatja az adatbázispéldányban jelenleg véglegesítés alatt álló tranzakciókat.

    Határozatok:

    • Emellett a blokkolási problémák ezen osztálya teljesítményproblémává is válhat, és megkövetelheti, hogy ennek megfelelően kezelje. Ha a lekérdezés végrehajtási ideje csökkenthető, a lekérdezés időtúllépése vagy megszakítása nem fordul elő. Fontos, hogy az alkalmazás képes legyen kezelni az időtúllépési vagy megszakítási forgatókönyveket, ha felmerülnek, de a lekérdezés teljesítményének vizsgálata is hasznos lehet.

    • Az alkalmazásoknak helyesen kell kezelniük a tranzakciók beágyazási szintjeit, különben a lekérdezés törlése után blokkolási problémát okozhatnak. Tekint:

      • Az ügyfélalkalmazás hibakezelőjében akkor is hajtsa végre IF @@TRANCOUNT > 0 ROLLBACK TRAN, ha az ügyfélalkalmazás nem hiszi, hogy egy tranzakció nyitva van. A nyitott tranzakciók ellenőrzésére azért van szükség, mert a köteg során meghívott tárolt eljárás az ügyfélalkalmazás tudta nélkül is elindíthatott volna egy tranzakciót. Bizonyos feltételek, például a lekérdezés megszakítása, megakadályozzák, hogy az eljárás az aktuális utasításon túl futjon, így még ha az eljárás logikája is van az IF @@ERROR <> 0 ellenőrzéséhez és a tranzakció megszakításához, ez a visszaállítási kód ilyen esetekben nem lesz végrehajtva.
      • Ha a kapcsolatkészletezést egy olyan alkalmazásban használják, amely megnyitja a kapcsolatot, és futtat néhány lekérdezést, mielőtt a kapcsolatot visszaengedné a készletbe (például egy webalapú alkalmazásba), a kapcsolatkészletezés ideiglenes letiltása segíthet enyhíteni a problémát, amíg az ügyfélalkalmazást nem módosítják a hibák megfelelő kezelése érdekében. A kapcsolatkészletezés letiltásával a kapcsolat felszabadítása az Azure SQL Database-kapcsolat fizikai kapcsolatának megszakadását okozza, ami azt eredményezi, hogy a kiszolgáló visszaállítja a nyitott tranzakciókat.
      • Használja a SET XACT_ABORT ON-t a kapcsolathoz, vagy bármely olyan tárolt eljárásban, amely tranzakciókat kezd, és hibák után nem végez takarítást. Futásidejű hiba esetén ez a beállítás megszakítja a nyitott tranzakciókat, és visszaadja a vezérlést az ügyfélnek. További információért tekintse át: SET XACT_ABORT.

    Jegyzet

    A kapcsolat csak akkor lesz visszaállítva, ha a kapcsolatkészletből újra felhasználják, így lehetséges, hogy a felhasználó megnyithat egy tranzakciót, majd feloldhatja a kapcsolatot a kapcsolatkészlethez, de előfordulhat, hogy a kapcsolat több másodpercig nem lesz újra felhasználva, ami alatt a tranzakció nyitva marad. Ha a kapcsolatot nem használják újra, a tranzakció megszakad, amikor a kapcsolat ideje lejár és a kapcsolat eltávolításra kerül a kapcsolatkészletből. Így optimális, ha az ügyfélalkalmazás megszakítja a tranzakciókat a hibakezelőjében, vagy SET XACT_ABORT ON használatával elkerüli ezt a lehetséges késést.

    Figyelem!

    Az SET XACT_ABORT ONután a rendszer nem hajtja végre a hibát okozó utasítást követő T-SQL-utasításokat. Ez hatással lehet a meglévő kód tervezett folyamatára.

  3. Olyan munkamenet-azonosító által okozott blokkolás, amelynek megfelelő ügyfélalkalmazása nem tudta beolvasni az összes eredménysort a befejezéshez

    Miután elküldte a lekérdezést a kiszolgálónak, minden alkalmazásnak azonnal le kell kérnie az összes eredménysort a befejezéshez. Ha egy alkalmazás nem kéri le az összes eredménysort, a zárolások megmaradhatnak a táblákon, és letilthatja a többi felhasználót. Ha olyan alkalmazást használ, amely transzparens módon küldi el az SQL-utasításokat a kiszolgálónak, az alkalmazásnak le kell kérnie az összes eredménysort. Ha nem (és nem konfigurálható erre), előfordulhat, hogy nem tudja megoldani a blokkolási problémát. A probléma elkerülése érdekében a rosszul viselkedő alkalmazásokat a fő OLTP-adatbázistól eltérő jelentési vagy döntéstámogatási adatbázisra korlátozhatja.

    Ennek a forgatókönyvnek a hatása csökken, ha az olvasás során elkötelezett pillanatkép üzemmód engedélyezve van az adatbázisban, amely az Azure SQL Database alapértelmezett beállítása. Tudjon meg többet a cikk A blokkolás megértése című szakaszában.

    Jegyzet

    Tekintse meg az Azure SQL Database-hez csatlakozó alkalmazások újrapróbálkozási logikájának és útmutatóját.

    Határozat: Az alkalmazást újra kell írni az eredmény összes sorának teljes lekérésére. Ez nem zárja ki a ELTOLÁS és a FETCH használatát a lekérdezés ORDER BY záradékában kiszolgálóoldali lapozás végrehajtásához.

  4. Visszaállítási állapotú munkamenet által okozott blokkolás

    A megszakított vagy törölt adatmódosítási lekérdezés, amelyet KILL parancs ér vagy egy felhasználó által meghatározott tranzakción kívül szakítanak meg, visszagörgetésre kerül. Ez az ügyfél hálózati munkamenetének leválasztásának mellékhatása is lehet, vagy amikor egy kérés holtpont áldozataként kerül kiválasztásra. Ez gyakran azonosítható a sys.dm_exec_requestskimenetének megfigyelésével, amely a ROLLBACK parancsot jelezheti, és a percent_complete oszlopban az előrehaladás jelenhet meg.

    A 2019-ben bevezetett gyorsított adatbázis-helyreállítási köszönhetően a hosszú visszaállítások ritkán fordulnak elő.

    Megoldás: Várja meg, amíg a munkamenet-azonosító befejezi a végrehajtott módosítások visszaállítását.

    A helyzet elkerülése érdekében ne végezzen nagy kötegírási műveleteket, indexlétrehozási vagy karbantartási műveleteket az OLTP-rendszereken elfoglalt órákban. Ha lehetséges, hajtsa végre ezeket a műveleteket alacsony tevékenységi időszakokban.

  5. Árva kapcsolat által okozott blokkolás

    Ha az ügyfélalkalmazás kezeli a hibákat, vagy az ügyfél-munkaállomás újraindul, előfordulhat, hogy bizonyos feltételek mellett a kiszolgálóhoz való hálózati kapcsolat nem lesz azonnal megszakítva. Az Azure SQL Database szempontjából úgy tűnik, hogy az ügyfél még mindig jelen van, és bármely megszerzett zárolás továbbra is fennmaradhat. Az alábbiakban olvashat bővebben a(z) Árva kapcsolatok hibaelhárítása az SQL Serverbencímű részben.

    Megoldás: Ha az ügyfélalkalmazás az erőforrások megfelelő tisztítása nélkül megszakadt, a parancs használatával megszakíthatja a KILL munkamenet-azonosítót. A KILL parancs bemeneteként a munkamenet-azonosítót kell megadni. Például a 99-es munkamenet-azonosító megszüntetéséhez adja ki a következő parancsot:

    KILL 99