• subscribe

Surprising memory usage with database snapshots


Posted @ 7/4/2011 1:28 PM By Paul Randal

 

Question: I’ve noticed that when I use a database snapshot for end-of-month reporting, there seems to be memory pressure on the buffer pool. How can this be if a database snapshot doesn’t create a copy of the real database?

Answer: What you’re noticing is a little-known fact about how database snapshots work.

It’s true that when a database snapshot is created, the source database is not copied into the database snapshot. It’s also true that the only data file pages that are copied into the database snapshot are those that change after the database snapshot is created (and those required to make the database snapshot transactionally consistent when it is created – see this blog post for an explanation).

These two behaviors mean that a database snapshot of a database that does not change should take up a minimal amount of disk space. But what about memory in the buffer pool?

As an example, I took a contrived sales database called SalesDB (which you can download from our resources page here). I attached the database and created a database snapshot on it, using the code below:

CREATE DATABASE SalesDB_Snapshot
ON (
    NAME = N'SalesDBData',
    FILENAME = N'C:\SQLskills\test\SalesDBData.mdfss')
AS SNAPSHOT OF SalesDB;
GO

Next I forced all the data file pages in the Sales table to be read using a SELECT COUNT (*) in the context of the SalesDB database and in the context of the SalesDB_Snapshot database:

USE SalesDB;
GO
SELECT COUNT (*) FROM Sales;
GO
USE SalesDB_Snapshot;
GO
SELECT COUNT (*) FROM Sales;
GO

You would expect the second SELECT statement to use the same set of pages as the first. We can check this using a script I published recently (see here) to examine the buffer pool contents.

The results show that there is 376MB in the buffer pool for both databases!

Although data file pages will not be copied into the database snapshot data files until they change, if a page from the source database is used in the context of the database snapshot to satisfy a query, it must be stored in its own buffer in the buffer pool. You can confirm this for yourself using DBCC PAGE on the same page in both databases and you’ll see them stored in buffer with different memory addresses.

This behavior means you can have many pages that are essentially duplicated in the buffer pool – which can cause memory pressure and excess I/Os, depending on what queries you’re running against the database snapshot. There is no way to change this behavior, and it’s unlikely to change in future as this is the simplest mechanism to use under the covers.

Related Content:

Comments

Add A Comment
    There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here


More about Kimberly and Paul . . .

Paul worked on the SQL Server team for nine years in development and management roles, writing many of the DBCC commands, and he was ultimately responsible for SQL Server 2008’s core storage engine. Paul blogs at SQLskills.com/blogs/Paul.

Kimberly worked on the SQL Server team in the early 1990s as a tester and writer before leaving to found SQLskills and embrace her passion for teaching and consulting. Kimberly blogs at SQLskills.com/blogs/Kimberly.

They've written Microsoft white papers and books for SQL Server 2008, 2005 and 2000, and they're regular, top-rated presenters worldwide on database maintenance, high availability, disaster recovery, design, performance tuning, and SQL Server internals. Together they teach SQLskills Immersion Events, which are wildly popular classes that teach the essential skills required to be an effective DBA; these classes also cover the required topics of the Microsoft Certified Master (MCM) certification.