Scollega / collega o offline / online cancella la cache del buffer per un database particolare?


8

Un mio amico mi ha detto oggi che invece di rimbalzare su SQL Server, potevo semplicemente staccare e quindi ricollegare un database e questa azione avrebbe cancellato le pagine e i piani del database dalla cache. Non sono d'accordo e fornisco le mie prove di seguito. Se non sei d'accordo con me o hai una confutazione migliore, allora forniscilo.

Sto usando AdventureWorks2012 su questa versione di SQL Server:

SELEZIONA VERSIONE @@;
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Developer Edition (64 bit) su Windows NT 6.1 (Build 7601: Service Pack 1)

Dopo aver caricato il database, eseguo la seguente query:

Innanzitutto, esegui lo script di ingrasso AW di Jonathan K trovato qui:

AW ingrassare

---------------------------
- Passaggio 1: Bpool Stuff?
---------------------------
USE [AdventureWorks2012];
PARTIRE

SELEZIONARE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [dimensione buffer (MB)]
   , COUNT (*) AS [buffer_count]
A PARTIRE DAL
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     PARTNER INTERNO sys.partitions AS p
           ON a.container_id = p.hobt_id
DOVE
     b.database_id = DB_ID ()
     AND p.object_id> 100
RAGGRUPPARE PER
     p.object_id
   , p.index_id
ORDINATO DA
     buffer_count DESC;

Il risultato è mostrato qui: inserisci qui la descrizione dell'immagine

Scollegare e ricollegare il database, quindi eseguire nuovamente la query.

---------------------------
- Passaggio 2: scollega / collega
---------------------------
- Stacca
USE [master]
PARTIRE
EXEC master.dbo.sp_detach_db @dbname = N'AdventureWorks2012 '
PARTIRE

- Allega
USE [master];
PARTIRE

CREA DATABASE [AdventureWorks2012] ON 
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Data.mdf ' 
)
    ,
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Log.ldf ' 
)
 PER ATTACCO;
PARTIRE

Cosa c'è nel bpool adesso?

---------------------------
- Passaggio 3: roba di Bpool?
---------------------------
USE [AdventureWorks2012];
PARTIRE

SELEZIONARE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [dimensione buffer (MB)]
   , COUNT (*) AS [buffer_count]
A PARTIRE DAL
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     PARTNER INTERNO sys.partitions AS p
           ON a.container_id = p.hobt_id
DOVE
     b.database_id = DB_ID ()
     AND p.object_id> 100
RAGGRUPPARE PER
     p.object_id
   , p.index_id
ORDINATO DA
     buffer_count DESC;

E il risultato: inserisci qui la descrizione dell'immagine

Tutte le letture sono logiche a questo punto?

--------------------------------
- Passaggio 4: solo letture logiche?
--------------------------------
USE [AdventureWorks2012];
PARTIRE

SET STATISTICS IO ON;   
    SELEZIONA * DA DatabaseLog;
    PARTIRE
SET STATISTICS IO OFF;  

/ *
(1597 filari interessati)
Tabella 'DatabaseLog'. Conteggio scansioni 1, letture logiche 782, letture fisiche 0, letture avanti 768, letture logiche lob 94, letture fisiche lob 4, letture readsb lob 24.
* /  

E possiamo vedere che il pool di buffer non è stato completamente spazzato via dal distacco / collegamento. Sembra che il mio amico avesse torto. Qualcuno non è d'accordo o ha una discussione migliore?

Un'altra opzione è offline e quindi online il database. Proviamolo.

--------------------------------
- Passaggio 5: offline / online?
--------------------------------
ALTER DATABASE [AdventureWorks2012] SET OFFLINE;
PARTIRE
ALTER DATABASE [AdventureWorks2012] SET ONLINE;
PARTIRE

---------------------------
- Passaggio 6: roba di Bpool?
---------------------------
USE [AdventureWorks2012];
PARTIRE

SELEZIONARE
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [dimensione buffer (MB)]
   , COUNT (*) AS [buffer_count]
A PARTIRE DAL
     sys.allocation_units AS a
     INNER JOIN sys.dm_os_buffer_descriptors AS b
           ON a.allocation_unit_id = b.allocation_unit_id
     PARTNER INTERNO sys.partitions AS p
           ON a.container_id = p.hobt_id
DOVE
     b.database_id = DB_ID ()
     AND p.object_id> 100
RAGGRUPPARE PER
     p.object_id
   , p.index_id
ORDINATO DA
     buffer_count DESC;

Sembra che l'operazione offline / online abbia funzionato molto meglio.

inserisci qui la descrizione dell'immagine

Risposte:


9

Inizialmente pensavo fossi su qualcosa qui. L'ipotesi di lavoro era sulla falsa riga che forse il pool di buffer non è stato immediatamente svuotato poiché richiede "un po 'di lavoro" per farlo e perché preoccuparsi fino a quando non è richiesta la memoria. Ma...

Il tuo test è difettoso.

Quello che vedi nel pool di buffer sono le pagine lette come risultato del ricollegamento del database, non i resti dell'istanza precedente del database.

E possiamo vedere che il pool di buffer non è stato completamente spazzato via dal distacco / collegamento. Sembra che il mio amico avesse torto. Qualcuno non è d'accordo o ha una discussione migliore?

Sì. Stai interpretando physical reads 0nel senso che non c'erano letture fisiche

Tabella 'DatabaseLog'. Conteggio scansioni 1, letture logiche 782, letture fisiche 0, letture read-ahead 768 , letture log lob 94, letture fisiche lob 4, letture read lob 24.

Come descritto sul blog di Craig Freedman, il meccanismo sequenziale di lettura anticipata cerca di garantire che le pagine siano in memoria prima che vengano richieste dall'elaboratore di query, motivo per cui viene visualizzato un conteggio delle letture fisiche pari a zero o inferiore alle aspettative.

Quando SQL Server esegue una scansione sequenziale di una tabella di grandi dimensioni, il motore di archiviazione avvia il meccanismo di lettura anticipata per garantire che le pagine siano in memoria e pronte per la scansione prima che siano necessarie al processore delle query. Il meccanismo di lettura anticipata cerca di rimanere 500 pagine davanti alla scansione.

Nessuna delle pagine richieste per soddisfare la tua richiesta era in memoria fino a quando non le hai messe lì.

Sul motivo per cui i risultati online / offline in un diverso profilo del pool di buffer meritano un'indagine un po 'più inattiva. @MarkSRasmussen potrebbe essere in grado di aiutarci con la prossima visita.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.