There are a few basic ways
you can use database snapshots effectively. Each use is for a particular
purpose, and each has its own benefits. After you have factored in the
limitations and restrictions mentioned earlier, you can consider these
uses. Let’s look at each of them separately.
Reverting to a Snapshot for Recovery Purposes
Probably
the most basic usage of database snapshots is decreasing recovery time
of a database by restoring a troubled database with a database
snapshot—referred to as reverting. As Figure 1
shows, one or more regularly scheduled snapshots can be generated
during a 24-hour period, effectively providing you with data recovery
milestones that can be rapidly used. As you can see in this example,
four database snapshots are six hours apart (6:00 a.m., 12:00 p.m., 6:00
p.m., and 12:00 a.m.). Each is dropped and re-created once per day,
using the same snapshot name. Any one of these snapshots can be used to
recover the source database rapidly in the event of a logical data error
(such as rows deleted or a table being dropped). This technique is not
supposed to take the place of a good maintenance plan that includes full
database backups and incremental transaction log dumps. However, it can
be extremely fast to get a database back to a particular milestone.
To revert to a particular snapshot interval, you simply use the RESTORE DATABASE command with the FROM DATABASE_SNAPSHOT
statement. This is a complete database restore; you cannot limit it to
just a single database object. In addition, you must drop all other
database snapshots before you can use one of them to restore a database.
As you can also see in Figure 1,
a targeted SQL statement variation from a complete database restore
from a snapshot could be used instead if you knew exactly what you
wanted to restore at the table and row level. You could simply use SQL
statements (such as an UPDATE SQL statement or an INSERT
SQL statement) from one of the snapshots to selectively apply only the
fixes you are sure need to be recovered (reverted). In other words, you
don’t restore the whole database from the snapshot, you only use some of
the snapshots’ data with SQL statements and bring the messed-up data
row values back in line with the original values in the snapshot. This
is at the row and column level and usually requires quite a bit of
detailed analysis before it can be applied to a production database.
It is also possible to use a snapshot to recover a
table that someone accidentally dropped. There is a little data loss
since the last snapshot, but it is a simple INSERT INTO statement from the latest snapshot before the table drop. So be careful here, but consider the value as well.
Safeguarding a Database Prior to Making Mass Changes
Often, you plan regular events against your database
tables that result in some type of mass update being applied to big
portions of the database. If you do a quick database snapshot before
any of these types of changes, you are essentially creating a nice
safety net for rapid recovery in the event you are not satisfied with
the mass update results. Figure 2 illustrates this type of safeguarding technique.
If you are not satisfied with the entire update operation, you can use RESTORE DATABASE
from the snapshot and revert it to this point. Or, if you are happy
with some updates but not others, you can use the SQL statement UPDATE to selectively update (restore) particular values back to their original values using the snapshot.
Providing a Testing (or Quality Assurance) Starting Point (Baseline)
In
testing and the QA phases of your development life cycle, you often
need to conduct tests over and over. These are either logic tests or
even performance tests. To aid testing and QA, database snapshots can be
made of a test database prior to full testing (create a testing
baseline database snapshot) and then the test database can be reverted
back to its original state at a moment’s notice, using that baseline
snapshot. This procedure can be done any number of times. Figure 3 shows how easy it is to simply create a testing reference point (or synchronization point) with a database snapshot.
You then just run your test scripts or do any manual
testing—as much as you want—and then revert back to this starting point
rapidly. Then you run more tests again.
Providing a Point-in-Time Reporting Database
If what you really need is a true point-in-time
reporting database from which you can run ad hoc or canned reports,
often a database snapshot can serve this purpose much better than
resorting to log shipping or data replication. Key to determining when
you can use this database snapshot technique is whether the reporting
load on this database server instance can easily support the reporting
workload and whether the update transactions against this database are
adversely affected by the database snapshot overhead of each transaction. Figure 4 shows the typical database snapshot configuration for one or more database snapshots that are to be used for reporting.
Remember, this is a point-in-time snapshot of the
source database. How frequently you need to create a new snapshot is
dictated by your reporting requirements for data latency (how old the
data can be in these reports).
Providing a Highly Available and Offloaded Reporting Database from a Database Mirror
If you are using database mirroring to improve your
availability, you can also create a database snapshot against this
mirrored database and expose the snapshot to your reporting users. Even
though the mirrored database cannot be used for any access whatsoever
(it is in constant restore mode), SQL Server allows a snapshot to be
created against it (as shown in Figure 5).
This is a very powerful configuration in that a database snapshot
against a mirror does not impact the load of the principal
server—guaranteeing high performance against the principal server. Also,
when the database snapshot is isolated over to the mirror server, the
performance of the reporting users is also more predictable because they
are not competing with the transactional users for resources on the
principal server. The only real issues arise when the principal server
fails over to the mirror database. You now have both transactional and
reporting users using the same database server instance, and the
performance of them all is affected.
A possible solution to this situation would be to
automatically (or manually) drop the database snapshot on the mirror
server if it becomes the principal and create a new snapshot on the old
principal server if it is available (it is now the mirror). You then
just point all your reporting users to this new database snapshot. This
task can be handled fairly easily in an application server layer. This
solution is basically a reciprocal principal/mirror reporting
configuration approach that always tries to get the database snapshot
that is used for reporting to be on the server that is the mirror
server. You would never really want to have active database snapshots on
both the principal server and mirror server at the same time. This is
way too much overhead for both servers. You want just the database
snapshots to be on the mirror server.