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.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.
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%%!
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
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
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!
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ää: