Apakah Detach / Attach atau Offline / Online Membersihkan Cache Buffer untuk Database Tertentu?

8

Seorang teman saya mengatakan kepada saya hari ini bahwa alih-alih memantulkan SQL Server, saya cukup melepaskan dan kemudian melampirkan kembali database dan tindakan ini akan menghapus halaman dan rencana basis data yang diberikan dari cache. Saya tidak setuju dan memberikan bukti saya di bawah. Jika Anda tidak setuju dengan saya atau memiliki bantahan yang lebih baik, daripada dengan cara apa pun menyediakannya.

Saya menggunakan AdventureWorks2012 pada versi SQL Server ini:

SELECT @@ VERSION;
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Edisi Pengembang (64-bit) pada Windows NT 6.1 (Build 7601: Service Pack 1)

Setelah memuat basis data, saya menjalankan kueri berikut:

Pertama, jalankan skrip penggemukan AW Jonathan K yang ditemukan di sini:

AW Get Fat

---------------------------
- Langkah 1: Barang Bpool?
---------------------------
GUNAKAN [AdventureWorks2012];
PERGILAH

PILIH
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [ukuran buffer (MB)]
   , COUNT (*) AS [buffer_count]
DARI
     sys.allocation_units AS a
     INNER GABUNG sys.dm_os_buffer_descriptors SEBAGAI b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS hal
           ON a.container_id = p.hobt_id
DIMANA
     b.database_id = DB_ID ()
     DAN p.object_id> 100
KELOMPOK OLEH
     p.object_id
   , p.index_id
DIPESAN OLEH
     buffer_count DESC;

Hasilnya ditunjukkan di sini: masukkan deskripsi gambar di sini

Lepaskan dan lampirkan kembali basis data lalu jalankan kembali kueri.

---------------------------
- Langkah 2: Lepaskan / Lampirkan
---------------------------
- Lepaskan
GUNAKAN [master]
PERGILAH
EXEC master.dbo.sp_detach_db @dbname = N'AdventureWorks2012 '
PERGILAH

- Pasang
GUNAKAN [master];
PERGILAH

BUAT DATABASE [AdventureWorks2012] HIDUP 
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Data.mdf ' 
)
    ,
( 
    FILENAME = N'C: \ sql server \ files \ AdventureWorks2012_Log.ldf ' 
)
 UNTUK ATTACH;
PERGILAH

Apa yang ada di bpool sekarang?

---------------------------
- Langkah 3: Barang Bpool?
---------------------------
GUNAKAN [AdventureWorks2012];
PERGILAH

PILIH
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [ukuran buffer (MB)]
   , COUNT (*) AS [buffer_count]
DARI
     sys.allocation_units AS a
     INNER GABUNG sys.dm_os_buffer_descriptors SEBAGAI b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS hal
           ON a.container_id = p.hobt_id
DIMANA
     b.database_id = DB_ID ()
     DAN p.object_id> 100
KELOMPOK OLEH
     p.object_id
   , p.index_id
DIPESAN OLEH
     buffer_count DESC;

Dan hasilnya: masukkan deskripsi gambar di sini

Apakah semua bacaan logis pada saat ini?

--------------------------------
- Langkah 4: Hanya Baca Logis?
--------------------------------
GUNAKAN [AdventureWorks2012];
PERGILAH

SET STATISTIK IO ON;   
    SELECT * FROM DatabaseLog;
    PERGILAH
SET STATISTIK IO OFF;  

/ *
(1597 baris terpengaruh)
Tabel 'DatabaseLog'. Pindai hitungan 1, bacaan logis 782, bacaan fisik 0, bacalah bacaan 768, bacaan logis lob 94, bacaan fisik lob 4, bacalah bacaan baca 24.
* /  

Dan kita bisa melihat bahwa buffer pool tidak sepenuhnya terhempas oleh detach / attach. Sepertinya teman saya salah. Adakah yang tidak setuju atau memiliki argumen yang lebih baik?

Pilihan lain adalah offline dan kemudian online database. Mari kita coba itu.

--------------------------------
- Langkah 5: Offline / Online?
--------------------------------
ALTER DATABASE [AdventureWorks2012] SET OFFLINE;
PERGILAH
ALTER DATABASE [AdventureWorks2012] SET ONLINE;
PERGILAH

---------------------------
- Langkah 6: Barang Bpool?
---------------------------
GUNAKAN [AdventureWorks2012];
PERGILAH

PILIH
     OBJECT_NAME (p.object_id) AS [ObjectName]
   , p.object_id
   , p.index_id
   , COUNT (*) / 128 AS [ukuran buffer (MB)]
   , COUNT (*) AS [buffer_count]
DARI
     sys.allocation_units AS a
     INNER GABUNG sys.dm_os_buffer_descriptors SEBAGAI b
           ON a.allocation_unit_id = b.allocation_unit_id
     INNER JOIN sys.partitions AS hal
           ON a.container_id = p.hobt_id
DIMANA
     b.database_id = DB_ID ()
     DAN p.object_id> 100
KELOMPOK OLEH
     p.object_id
   , p.index_id
DIPESAN OLEH
     buffer_count DESC;

Tampaknya operasi offline / online bekerja jauh lebih baik.

masukkan deskripsi gambar di sini

ooutwire
sumber

Jawaban:

9

Saya awalnya mengira Anda ke sesuatu di sini. Asumsi kerja adalah di sepanjang garis yang mungkin kolam penyangga tidak segera memerah karena memerlukan "beberapa pekerjaan" untuk melakukannya dan mengapa repot sampai memori diperlukan. Tapi...

Tes Anda cacat.

Apa yang Anda lihat di buffer pool adalah halaman yang dibaca sebagai hasil melampirkan kembali database, bukan sisa-sisa instance database sebelumnya.

Dan kita bisa melihat bahwa buffer pool tidak sepenuhnya terhempas oleh detach / attach. Sepertinya teman saya salah. Adakah yang tidak setuju atau memiliki argumen yang lebih baik?

Iya. Anda menafsirkan physical reads 0sebagai artinya tidak ada bacaan fisik

Tabel 'DatabaseLog'. Pindai hitungan 1, bacaan logis 782, bacaan fisik 0, bacalah bacaan 768 , bacaan logis lob 94, bacaan fisik lob 4, bacalah bacaan baca 24.

Seperti yang dijelaskan di blog Craig Freedman, mekanisme baca depan berurutan mencoba untuk memastikan bahwa halaman berada dalam memori sebelum mereka diminta oleh prosesor kueri, itulah sebabnya Anda melihat nol atau lebih rendah dari hitungan fisik yang dilaporkan dilaporkan.

Ketika SQL Server melakukan pemindaian berurutan dari sebuah tabel besar, mesin penyimpanan memulai mekanisme baca di depan untuk memastikan bahwa halaman berada dalam memori dan siap untuk memindai sebelum dibutuhkan oleh prosesor permintaan. Mekanisme baca depan mencoba untuk tetap 500 halaman di depan pemindaian.

Tidak ada halaman yang diperlukan untuk memenuhi permintaan Anda yang ada dalam memori sampai read-ahead menempatkannya di sana.

Mengenai mengapa hasil online / offline dalam profil kumpulan buffer yang berbeda memerlukan penyelidikan yang lebih menganggur. @MarkSRasmussen mungkin bisa membantu kami dengan itu saat dia mengunjungi lagi.

Mark Storey-Smith
sumber