డెడ్‌లాక్‌లు మరియు లాక్‌లలో డెసిఫర్ కీ మరియు పేజ్ వెయిట్‌రిసోర్స్

మీరు బ్లాక్ చేయబడిన ప్రాసెస్ రిపోర్ట్‌ని ఉపయోగిస్తే లేదా SQL సర్వర్ అందించే డెడ్‌లాక్ గ్రాఫ్‌లను క్రమానుగతంగా సేకరిస్తే, మీరు ఇలాంటి వాటిని ఎదుర్కొంటారు:

waitresource=“PAGE: 6:3:70133“

waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)“

కొన్నిసార్లు మీరు చదువుతున్న దిగ్గజం XMLలో మరింత సమాచారం ఉంటుంది (డెడ్‌లాక్ గ్రాఫ్‌లు ఆబ్జెక్ట్ మరియు ఇండెక్స్ పేర్లను కనుగొనడంలో మీకు సహాయపడే వనరుల జాబితాను కలిగి ఉంటాయి), కానీ ఎల్లప్పుడూ కాదు.

వాటిని అర్థంచేసుకోవడానికి ఈ వచనం మీకు సహాయం చేస్తుంది.

ఇక్కడ ఉన్న మొత్తం సమాచారం ఇంటర్నెట్‌లో వివిధ ప్రదేశాలలో ఉంది, ఇది చాలా పంపిణీ చేయబడింది! నేను అన్నింటినీ కలిపి ఉంచాలనుకుంటున్నాను - DBCC PAGE నుండి hobt_id వరకు మరియు నమోదుకాని %%physloc%% మరియు %%lockres%% ఫంక్షన్‌ల వరకు.

ముందుగా, PAGE లాక్‌లపై నిరీక్షణల గురించి మాట్లాడుదాం, ఆపై మనం KEY లాక్‌లకు వెళ్తాము.

1) waitresource=“PAGE: 6:3:70133” = Database_Id: FileId: PageNumber

మీ ప్రశ్న PAGE లాక్‌లో వేచి ఉంటే, SQL సర్వర్ మీకు ఆ పేజీ చిరునామాను ఇస్తుంది.

“PAGE: 6:3:70133”ని విచ్ఛిన్నం చేయడం ద్వారా మనకు లభిస్తుంది:

  • డేటాబేస్_ఐడి = 6
  • data_file_id = 3
  • పేజీ_సంఖ్య = 70133

1.1) డేటాబేస్_ఐడిని డీక్రిప్ట్ చేయండి

ప్రశ్నను ఉపయోగించి డేటాబేస్ పేరును కనుగొనండి:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO

ఇది పబ్లిక్ DB వైడ్‌వరల్డ్ దిగుమతిదారులు నా SQL సర్వర్‌లో.

1.2) డేటా ఫైల్ పేరు కోసం వెతుకుతోంది - మీకు ఆసక్తి ఉంటే

మేము పట్టిక పేరును కనుగొనడానికి తదుపరి దశలో data_file_idని ఉపయోగించబోతున్నాము. మీరు తదుపరి దశకు దాటవేయవచ్చు, కానీ మీరు ఫైల్ పేరుపై ఆసక్తి కలిగి ఉంటే, మీరు కనుగొన్న డేటాబేస్ సందర్భంలో ప్రశ్నను అమలు చేయడం ద్వారా దాన్ని కనుగొనవచ్చు, ఈ ప్రశ్నలో data_file_idని ప్రత్యామ్నాయం చేయండి:

USE WideWorldImporters;
GO
SELECT 
    name, 
    physical_name
FROM sys.database_files
WHERE file_id = 3;
GO

WideWorldImporters డేటాబేస్‌లో ఇది WWI_UserData అని పిలువబడే ఫైల్ మరియు నేను దానిని C:MSSQLDATAWideWorldImporters_UserData.ndfకి పునరుద్ధరించాను. (అయ్యో, మీరు నన్ను సిస్టమ్ డిస్క్‌లో ఫైల్‌లను పెట్టడాన్ని పట్టుకున్నారు! లేదు! అది ఇబ్బందికరంగా ఉంది).

1.3) DBCC PAGE నుండి వస్తువు పేరు పొందండి

డేటా ఫైల్ 70133లోని #3 పేజీ వరల్డ్‌వైడ్ ఇంపోర్టర్స్ డేటాబేస్‌కు చెందినదని ఇప్పుడు మనకు తెలుసు. మేము డాక్యుమెంట్ చేయని DBCC PAGE మరియు ట్రేస్ ఫ్లాగ్ 3604ని ఉపయోగించి ఈ పేజీలోని కంటెంట్‌లను చూడవచ్చు.
గమనిక: నేను మరొక సర్వర్‌లోని బ్యాకప్ నుండి పునరుద్ధరించబడిన కాపీలో DBCC PAGEని ఉపయోగించడానికి ఇష్టపడతాను, ఎందుకంటే ఇది నమోదుకాని విషయం. కొన్ని సందర్భాల్లో, ఆమె డంప్ సృష్టించబడటానికి దారితీయవచ్చు (సుమారు అనువాదకుడు - లింక్, దురదృష్టవశాత్తు, ఎక్కడా దారితీయదు, కానీ url ద్వారా నిర్ణయించడం, మేము ఫిల్టర్ చేయబడిన సూచికల గురించి మాట్లాడుతున్నాము).

/* This trace flag makes DBCC PAGE output go to our Messages tab
instead of the SQL Server Error Log file */
DBCC TRACEON (3604);
GO
/* DBCC PAGE (DatabaseName, FileNumber, PageNumber, DumpStyle)*/
DBCC PAGE ('WideWorldImporters',3,70133,2);
GO

ఫలితాల ద్వారా స్క్రోల్ చేయడం, మీరు object_id మరియు index_idని కనుగొనవచ్చు.
డెడ్‌లాక్‌లు మరియు లాక్‌లలో డెసిఫర్ కీ మరియు పేజ్ వెయిట్‌రిసోర్స్
దాదాపుగా అయిపోయింది! ఇప్పుడు మీరు ప్రశ్నను ఉపయోగించి పట్టిక మరియు సూచిక పేర్లను కనుగొనవచ్చు:

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.objects as so 
JOIN sys.indexes as si on 
    so.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE 
    so.object_id = 94623380
    and si.index_id = 1;
GO

మరియు ఇప్పుడు మేము లాక్ నిరీక్షణ Sales.OrderLines పట్టిక యొక్క PK_Sales_OrderLines ఇండెక్స్‌లో ఉన్నట్లు చూస్తాము.

గమనిక: SQL సర్వర్ 2014 మరియు తర్వాత, ఆబ్జెక్ట్ పేరును నమోదు చేయని DMO sys.dm_db_database_page_allocations ఉపయోగించి కూడా కనుగొనవచ్చు. కానీ మీరు డేటాబేస్‌లోని ప్రతి పేజీని ప్రశ్నించాలి, ఇది పెద్ద డేటాబేస్‌ల కోసం చాలా బాగుంది, కాబట్టి నేను DBCC PAGEని ఉపయోగించాను.

1.4) బ్లాక్ చేయబడిన పేజీలోని డేటాను చూడటం సాధ్యమేనా?

అవును మంచిది. కానీ... మీకు ఇది నిజంగా అవసరమని మీరు ఖచ్చితంగా అనుకుంటున్నారా?
చిన్న బల్లల మీద కూడా నెమ్మదిగా ఉంటుంది. కానీ ఇది చాలా బాగుంది, కాబట్టి మీరు ఇంతవరకు చదివారు కాబట్టి... %%physloc%% గురించి మాట్లాడుకుందాం!

%%physloc%% అనేది ప్రతి ఎంట్రీకి భౌతిక ఐడెంటిఫైయర్‌ని అందించే డాక్యుమెంట్ లేని మ్యాజిక్ భాగం. మీరు ఉపయోగించవచ్చు SQL సర్వర్ 2008 మరియు అంతకంటే ఎక్కువలో sys.fn_PhysLocFormatterతో పాటు %%physloc%%.

ఇప్పుడు మేము Sales.OrderLinesలో పేజీని లాక్ చేయాలనుకుంటున్నామని మాకు తెలుసు, ఈ ప్రశ్నను ఉపయోగించి పేజీ #3లోని #70133 డేటా ఫైల్‌లో నిల్వ చేయబడిన ఈ పట్టికలోని మొత్తం డేటాను మనం చూడవచ్చు:

Use WideWorldImporters;
GO
SELECT 
    sys.fn_PhysLocFormatter (%%physloc%%),
    *
FROM Sales.OrderLines (NOLOCK)
WHERE sys.fn_PhysLocFormatter (%%physloc%%) like '(3:70133%'
GO

నేను చెప్పినట్లుగా, ఇది చిన్న పట్టికలలో కూడా నెమ్మదిగా ఉంటుంది. నేను రిక్వెస్ట్‌కి NOLOCKని జోడించాను ఎందుకంటే లాక్‌ని గుర్తించినప్పుడు మనం చూడాలనుకుంటున్న డేటా సరిగ్గా అదే విధంగా ఉంటుందని మాకు ఇప్పటికీ ఎలాంటి హామీ లేదు - కాబట్టి మేము సురక్షితంగా డర్టీ రీడ్‌లను చేయవచ్చు.
కానీ, హుర్రే, మా ప్రశ్న ఏ 25 వరుసల కోసం పోరాడిందో అదే క్వెరీ నాకు తిరిగి ఇస్తుంది
డెడ్‌లాక్‌లు మరియు లాక్‌లలో డెసిఫర్ కీ మరియు పేజ్ వెయిట్‌రిసోర్స్
PAGE లాక్‌ల గురించి సరిపోతుంది. మనం కీ లాక్ కోసం ఎదురుచూస్తుంటే?

2) waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (మీకు నిజంగా కావాలంటే %%lockres%% ఉపయోగించి డీక్రిప్ట్ చేయగల మ్యాజిక్ హాష్)

మీ ప్రశ్న ఇండెక్స్‌లో రికార్డ్‌ను లాక్ చేయడానికి ప్రయత్నించి, స్వయంగా లాక్ చేయబడితే, మీరు పూర్తిగా భిన్నమైన చిరునామాతో ముగుస్తుంది.
“6:72057594041991168 (ce52f92a058c)”ని భాగాలుగా విభజిస్తే, మనకు లభిస్తుంది:

  • డేటాబేస్_ఐడి = 6
  • hobt_id = 72057594041991168
  • మేజిక్ హాష్ = (ce52f92a058c)

2.1) డేటాబేస్_ఐడిని డీక్రిప్ట్ చేయండి

ఇది పై ఉదాహరణకి సరిగ్గా అదే పని చేస్తుంది! ప్రశ్నను ఉపయోగించి డేటాబేస్ పేరును కనుగొనండి:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO

నా విషయంలో ఇప్పటికీ అలాగే ఉంది DB వైడ్‌వరల్డ్ దిగుమతిదారులు.

2.2) hobt_idని డీక్రిప్ట్ చేయండి

కనుగొనబడిన డేటాబేస్ సందర్భంలో, మీరు పట్టిక మరియు సూచిక పేర్లను గుర్తించడంలో సహాయపడే జత జతలతో sys.విభజనలకు ఒక ప్రశ్నను అమలు చేయాలి...

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.partitions AS p
JOIN sys.objects as so on 
    p.object_id=so.object_id
JOIN sys.indexes as si on 
    p.index_id=si.index_id and 
    p.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE hobt_id = 72057594041991168;
GO

ఇది అప్లికేషన్‌పై అభ్యర్థన వేచి ఉందని నాకు చెబుతుంది. PK_Application_Countries ఇండెక్స్‌ని ఉపయోగించి దేశాలు లాక్ చేయబడ్డాయి.

2.3) ఇప్పుడు ఒక చిన్న మ్యాజిక్ %%lockres%% - మీరు ఏ ఎంట్రీ లాక్ చేయబడిందో తెలుసుకోవాలనుకుంటే

లాక్ ఏ అడ్డు వరుసలో ఉందో నేను నిజంగా తెలుసుకోవాలనుకుంటే, టేబుల్‌ను ప్రశ్నించడం ద్వారా నేను కనుగొనగలను. మ్యాజిక్ హాష్‌కి సరిపోయే ఎంట్రీని కనుగొనడానికి మేము నమోదు చేయని %%lockres%% ఫంక్షన్‌ని ఉపయోగించవచ్చు.
దయచేసి ఈ ప్రశ్న మొత్తం పట్టికను స్కాన్ చేస్తుందని మరియు పెద్ద పట్టికలలో ఇది సరదాగా ఉండకపోవచ్చని గుర్తుంచుకోండి:

SELECT
    *
FROM Application.Countries (NOLOCK)
WHERE %%lockres%% = '(ce52f92a058c)';
GO

నేను NOLOCKని జోడించాను (ట్విట్టర్‌లో క్లాస్ అస్చెన్‌బ్రెన్నర్ సలహా మేరకు) ఎందుకంటే అడ్డంకులు సమస్యగా మారవచ్చు. మేము ఇప్పుడు అక్కడ ఉన్న వాటిని చూడాలనుకుంటున్నాము మరియు లావాదేవీ ప్రారంభమైనప్పుడు అక్కడ ఉన్న వాటిని కాదు - డేటా అనుగుణ్యత మాకు ముఖ్యం అని నేను అనుకోను.
Voila, మేము పోరాడిన రికార్డు!
డెడ్‌లాక్‌లు మరియు లాక్‌లలో డెసిఫర్ కీ మరియు పేజ్ వెయిట్‌రిసోర్స్

కృతజ్ఞతలు మరియు తదుపరి పఠనం

వీటిలో చాలా విషయాలను మొదట ఎవరు వివరించారో నాకు గుర్తులేదు, కానీ మీరు ఇష్టపడే అతి తక్కువ డాక్యుమెంట్ చేయబడిన విషయాల గురించి ఇక్కడ రెండు పోస్ట్‌లు ఉన్నాయి:

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి