Selvitä avain ja sivun odotusresurssi umpikujassa ja lukoissa

Jos käytät estettyjen prosessien raporttia tai keräät SQL Serverin toimittamia lukkiutumiskaavioita säännöllisesti, kohtaat seuraavanlaisia:

waitresource="SIVU: 6:3:70133"

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

Joskus tutkimassasi jättimäisessä XML-tiedostossa on enemmän tietoa (umpikujakuvaajat sisältävät luettelon resursseista, jotka auttavat sinua löytämään kohteen ja hakemistojen nimet), mutta ei aina.

Tämä teksti auttaa sinua ymmärtämään ne.

Kaikki täällä oleva tieto on Internetissä eri paikoissa, se on vain hyvin levitetty! Haluan koota kaiken - DBCC PAGE:sta hobt_id:hen ja dokumentoimattomiin %%physloc%% ja %%lockres%% -funktioihin.

Puhutaan ensin SIVUN lukkojen odotuksista ja sitten siirrytään KEY-lukkoihin.

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

Jos kyselysi odottaa PAGE-lukossa, SQL Server antaa sinulle kyseisen sivun osoitteen.

Jakamalla "SIVU: 6:3:70133" saamme:

  • tietokannan_tunnus = 6
  • data_file_id = 3
  • sivun_numero = 70133

1.1) Pura tietokannan_id:n salaus

Etsitään tietokannan nimi kyselyllä:

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

Tämä on julkinen DB WideWorldImporters SQL-palvelimellani.

1.2) Etsitään tiedostolle nimi - jos olet kiinnostunut

Aiomme käyttää data_file_id seuraavassa vaiheessa löytääksemme taulukon nimen. Voit yksinkertaisesti siirtyä seuraavaan vaiheeseen, mutta jos olet kiinnostunut tiedoston nimestä, löydät sen suorittamalla kyselyn löydetyn tietokannan yhteydessä ja korvaamalla tässä kyselyssä data_file_id:

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

WideWorldImporters-tietokannassa tämä on tiedosto nimeltä WWI_UserData ja olen palauttanut sen tiedostoon C:MSSQLDATAWideWorldImporters_UserData.ndf. (Hups, huomasit minut laittamasta tiedostoja järjestelmälevylle! Ei! Se oli hankalaa).

1.3) Hanki objektin nimi DBCC PAGE -sivulta

Nyt tiedämme, että tiedoston 70133 sivu #3 kuuluu WorldWideImporters-tietokantaan. Voimme tarkastella tämän sivun sisältöä dokumentoimattoman DBCC PAGE:n ja jäljityslipun 3604 avulla.
Huomautus: Käytän mieluummin DBCC PAGE:ta palautetussa kopiossa varmuuskopiosta toisella palvelimella, koska se on dokumentoimaton asia. Joissakin tapauksissa hän voi johtaa kaatopaikan syntymiseen (noin kääntäjä - linkki ei valitettavasti johda mihinkään, mutta URL-osoitteen perusteella puhumme suodatetuista indekseistä).

/* 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

Selaamalla tuloksia löydät kohteen_id ja index_id.
Selvitä avain ja sivun odotusresurssi umpikujassa ja lukoissa
Melkein valmis! Nyt voit löytää taulukoiden ja hakemistojen nimet kyselyllä:

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

Ja nyt näemme, että lukko-odotus oli Sales.OrderLines-taulukon PK_Sales_OrderLines-hakemistossa.

Huomautus: SQL Server 2014:ssä ja uudemmissa versioissa objektin nimi löytyy myös dokumentoimattomasta DMO:sta sys.dm_db_database_page_allocations. Mutta sinun on tehtävä kysely tietokannan jokaiselta sivulta, mikä ei näytä kovin hyvältä suurille tietokannoille, joten käytin DBCC PAGE:ta.

1.4) Onko mahdollista nähdä estetyn sivun tiedot?

No kyllä. Mutta... oletko varma, että todella tarvitset sitä?
Se on hidasta jopa pienillä pöydillä. Mutta se on siistiä, joten koska olet lukenut tähän asti... puhutaanpa aiheesta %%physloc%%!

%%physloc%% on dokumentoimaton taikuudenpala, joka palauttaa fyysisen tunnisteen jokaiselle merkinnälle. voit käyttää %%physloc%% yhdessä sys.fn_PhysLocFormatterin kanssa SQL Server 2008:ssa ja uudemmissa.

Nyt kun tiedämme, että halusimme lukita sivun Sales.OrderLinesissa, voimme tarkastella kaikkia tämän taulukon tietoja, jotka on tallennettu tietotiedostoon #3 sivulla #70133, käyttämällä tätä kyselyä:

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

Kuten sanoin, se on hidasta jopa pienillä pöydillä. Lisäsin pyyntöön NOLOCKin, koska meillä ei vieläkään ole takeita siitä, että tarkasteltavat tiedot ovat täsmälleen samat kuin lukon havaitessa - jotta voimme turvallisesti tehdä likaisia ​​lukuja.
Mutta hurraa, pyyntö palauttaa minulle samat 25 riviä, joiden puolesta pyyntömme taisteltiin
Selvitä avain ja sivun odotusresurssi umpikujassa ja lukoissa
Tarpeeksi SIVUN lukoista. Entä jos odotamme KEY-lukkoa?

2) waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (takahajautus, jonka salaus voidaan purkaa käyttämällä %%lockres%%, jos todella haluat)

Jos kyselysi yrittää lukita tietueen hakemistossa ja lukittuu itsestään, päädyt täysin erityyppiseen osoitteeseen.
Jakamalla "6:72057594041991168 (ce52f92a058c)" osiin, saadaan:

  • tietokannan_tunnus = 6
  • Hobt_id = 72057594041991168
  • magic hash = (ce52f92a058c)

2.1) Pura tietokannan_id:n salaus

Tämä toimii täsmälleen samalla tavalla kuin yllä oleva esimerkki! Etsi tietokannan nimi kyselyllä:

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

Minun tapauksessani se on edelleen sama DB WideWorldImporters.

2.2) Pura hobt_id:n salaus

Löydetyn tietokannan yhteydessä sinun on suoritettava kysely sys.partitionsille liitosparilla, joka auttaa määrittämään taulukon ja indeksin nimet...

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

Se kertoo minulle, että pyyntö odotti Application.Countries-lukossa PK_Application_Countries-hakemiston avulla.

2.3) Nyt vähän taikuutta %%lockres%% - jos haluat selvittää mikä merkintä lukittiin

Jos haluan todella tietää, millä rivillä lukko oli, saan sen selville tekemällä kyselyn itse taulukosta. Voimme käyttää dokumentoimatonta %%lockres%%-funktiota löytääksemme merkinnän, joka vastaa maagista tiivistettä.
Huomaa, että tämä kysely skannaa koko taulukon, ja suurilla pöydillä tämä ei välttämättä ole hauskaa:

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

Lisäsin NOLOCKin (Klaus Aschenbrennerin neuvosta Twitterissä), koska tukokset voivat muodostua ongelmaksi. Haluamme vain tarkastella sitä, mitä siellä on nyt, emmekä sitä, mitä siellä oli kaupan alkaessa - en usko, että tietojen johdonmukaisuus on meille tärkeää.
Voila, ennätys, jonka puolesta taistelimme!
Selvitä avain ja sivun odotusresurssi umpikujassa ja lukoissa

Kiitokset ja lisälukemista

En muista, kuka ensimmäisenä kuvasi monia näistä asioista, mutta tässä on kaksi viestiä vähiten dokumentoiduista asioista, joista saatat pitää:

Lähde: will.com

Lisää kommentti