with-NOTE Although no data is backed up from NCIX_FG, the backup still contains definitions of nonclustered indexes because index metadata information is stored in system tables, which a
Trang 1436 C 33 Efficient backups without indexes
CREATE NONCLUSTERED INDEX ncix_Table1 ON dbo.Table1 (Col1) WITH DROP_EXISTING , ONLINE = ON
ON NCIX_FG;
The DROP_EXISTING option causes the newly created index to be created as thereplacement of the existing index, without needing to explicitly drop the existingindex (which could damage query performance for queries that might be in flight,while the index is dropped) The ONLINE option can be used to further reduce con-currency impact with SQL Server 2005 or 2008 Enterprise Edition
The ON NCIX_FG clause is the main focus of our attention in this statement, whichdefines the new location for the nonclustered index
Backing up only the PRIMARY filegroup
Now that we’ve successfully separated our nonclustered indexes (one only) from the
PRIMARY filegroup into a separate filegroup, it’s now possible to perform a tables-onlyfilegroup backup Instead of issuing a standard BACKUP DATABASE command, add a file-group specification to back up only the PRIMARY filegroup For example:
BACKUP DATABASE BackupTest FILEGROUP = 'PRIMARY'
TO DISK = 'E:\BackupTest_Primary.bak'
SQL Server will then perform a filegroup backup of the PRIMARY filegroup only, out copying any contents from the newly created NCIX_FG to the backup set
with-NOTE Although no data is backed up from NCIX_FG, the backup still contains
definitions of nonclustered indexes because index metadata information
is stored in system tables, which are located in the PRIMARY filegroup(sys.indexes, sys.index_columns and so on) This means that we can re-create the nonclustered indexes in the restore process from their defini-tions, even though we don’t have their allocated data structures in ourbackup file
Restoring the PRIMARY filegroup backup
The process required to restore the database from the PRIMARY filegroup backup fers depending on whether you’re restoring only to perform data extraction purposes
dif-(re-creation of indexes not required), or whether you intend to bring the database fully online (re-creation of indexes is required).
Restoring from the PRIMARY filegroup backup to perform data extraction is ple and faster than restoring a full backup On the other hand, restoring the databaseback to its full state to bring it back into a production role—including a rebuild of allnonclustered indexes—requires more steps than from a simple full database backup Let’s quickly review both of the steps required in each scenario
Trang 2extrac-RESTORE DATABASE BackupTest FILEGROUP = 'PRIMARY' FROM DISK = 'E:\BackupTest_Primary.bak' WITH RECOVERY
SQL Server will then restore the PRIMARY filegroup and recover the database, ing it online and available for querying This allows extraction of data by executingSELECT commands, but INSERT, UPDATE, or DELETE commands will fail with error 8607:Msg 8607, Level 16, State 1, Line 1: The table '[Tablename]' cannot be modified because one or more nonclustered indexes reside in a filegroup which is not online.
bring-It’s also possible that SELECT statements might fail if a nonclustered index is used toprocess the query, either via selection by SQL Server’s query optimizer or explicitindex hint In this case, error 315 will be returned:
Msg 315, Level 16, State 1, Line 2: Index "[IndexName]" on table "[TableName]" (specified in the FROM clause) is disabled or resides in a filegroup which
is not online.
In this scenario, you might need to either remove index hints, or explicitly hint SQL
Server to access the table via its heap or clustered index storage, instead of via thenonclustered index (which is offline)
Restoring for production use
Restoring a database from a PRIMARY filegroup backup for production use doesrequire a few more steps than restoring from a regular full database backup The mostsignificant of these involves rebuilding nonclustered indexes from the underlyingtables
In summary, these are the steps required to bring a database fully online from a
PRIMARY filegroup backup:
1 Restore the primary filegroup backup and recover the database
2 Script out index definitions from the PRIMARY filegroup, using a new filegroupname
3 Restart SQL Server in single-user mode (with -m startup parameter)
4 Connect to SQL Server using the Dedicated Administrator Connection
5 Delete nonclustered index definitions from the sys.sysindexes system view
6 Remove -m startup parameter and restart SQL Server in multi-user mode
7 Create a new, renamed filegroup to re-create the nonclustered indexes in
8 Rebuild nonclustered indexes in the new filegroup
Trang 3438 C 33 Efficient backups without indexes
NOTE Scripting nonclustered index definitions from the PRIMARY filegroup isstill possible even though the nonclustered index filegroup hasn’t beenrestored, because index definitions exist within the system meta tables
in the PRIMARY filegroup, regardless of where the physical index age allocations are located This is a crucial fact that enables this tech-nique to work
stor-Before walking through each of these steps, two issues associated with this techniqueshould be discussed:
An update to system views is required to re-create nonclustered indexes (step 5)
The nonclustered index filegroup’s name must be changed (step 7)
ISSUE 1: INDEX DEFINITIONS MUST BE REMOVED BY UPDATING A SYSTEM VIEW
The process of re-creating indexes following restoration of the PRIMARY filegrouprequires deleting existing index metadata from the sys.sysindexes system view prior
to re-creating indexes (step 3 in the previous list) This fact might discourage somefrom using this technique, but it should be pointed out that updating this system viewdoes not, in and of itself, compromise the integrity of the database, as the databasetables that contain the real data in our database are stored within the PRIMARY file-group and are not affected by the update of this system view
WARNING Updating a system catalog is an operation that’s not supported by
Microsoft An alternative supported solution is to reconstruct the base by scripting its definition, re-creating the database, exporting alltable data from the backup, and re-importing to the new re-createddatabase
data-This system update is required because neither DROP INDEX nor CREATE INDEX WITHDROP_EXISTING work when only the PRIMARY filegroup has been restored Eachfails with an error stating that the index’s filegroup is offline as SQL Server attempts
to remove the index’s allocations, which aren’t available during execution of thecommand
To avoid this system catalog update, an alternative is to re-create an entirely newdatabase by scripting all database objects from the PRIMARY filegroup (tables,indexes, and all other objects) and exporting all data from the restored PRIMARY file-group into that new database This is obviously more time-consuming than only re-creating nonclustered indexes (as tables are also re-created in the new database), butit’s a workable alternative that allows you to bring a database back online from PRI-MARY filegroup backup without using any system catalog updates
ISSUE 2: NEW NONCLUSTERED INDEX FILEGROUP MUST BE RENAMED
Another issue is that the filegroup that contained the nonclustered indexes in thesource database (NCIX_FG in our example) cannot be fully removed from therestored database without further system catalog updates
This is less of a problem though, as another filegroup can be added to therestored database and nonclustered indexes be built into it The name of a filegroup
Trang 4Restoring the PRIMARY filegroup backup
is rarely important to an application, so this doesn’t pose a serious problem—simplycreate another filegroup (for example NCIX_FG2) and rebuild nonclustered indexesinto it instead This is what we’ll do in our example
Restoring for production use —step by step
Let’s walk through the individual steps required to restore our database for tion use from a PRIMARY filegroup backup
produc-STEP 1—RESTORE THE PRIMARY FILEGROUP BACKUP AND RECOVER THE DATABASE
The first step is identical to the restore process for extraction only Assuming our MARY filegroup backup remains located in the root of E:\ drive, execute the followingcommand:
PRI-RESTORE DATABASE BackupTest FILEGROUP = 'PRIMARY' FROM DISK = 'E:\BackupTest_Primary.bak' WITH RECOVERY
This restores the database’s PRIMARY filegroup, meaning that all tables, views, storedprocedures, user-defined functions, and other database objects stored in the PRIMARY
filegroup have been restored to the database Index definitions have also beenrestored to the system catalogs (which reside in the PRIMARY filegroup), but theirdata structure allocations have not, as they are located within the dedicated nonclus-tered index filegroup (NCIX_FG in our example)—which was neither backed up norrestored
STEP 2—SCRIPT OUT INDEX DEFINITIONS FROM PRIMARY FILEGROUP
In the current state of our database, it’s not possible to rebuild our nonclusteredindexes using more convenient options such as DBCC DBREINDEX, ALTER INDEXREBUILD, or CREATE INDEX WITH DROP_EXISTING Each of these generates an errorwhether executed from a normal connection or dedicated administrator connection(DAC), because each requires existing index allocations to be available during execu-tion of the command
Instead, we’ll script index definitions out to a file and use the script later (step 8),
to rebuild the indexes, after we have dropped index definitions from the dexes system catalog and created a new nonclustered index filegroup to contain thenew indexes
To generate the index scripts, use the utility stored procedure (SP) described later
in this chapter, named usp_Manage_NCIX_FileGroup This SP accepts two ters—@ScriptOnlyOrExecute (nvarchar(6)) and @NCIXFGName (nvarchar(255)) The @ScriptOnlyOrExecute parameter should be set to N'Script', whichinstructs the SP to generate scripts only, without executing them
The @NCIXFGName parameter should be provided with the name of a new group to rebuild nonclustered indexes into At this stage, this filegroup does notexist, but we’ll create it in step 7 The name provided for this new filegroup must bedifferent from the existing nonclustered index filegroup for this database (which is
Trang 5file-440 C 33 Efficient backups without indexes
NCIX_FG in our example) because that filegroup’s descriptive metadata still exists inthe system catalogs For our example, we’ll create another filegroup named
N'NCIX_FG2'
EXEC usp_Manage_NCIX_FileGroup N'Script', N'NCIX_FG2'Output from the execution of this procedure should contain a list of CREATE INDEXstatements, one per nonclustered index in the database Save this output to a scriptfile (for example NCIXScripts.sql) for later use in step 7 Note that each CREATE INDEXstatement will include the filegroup name NCIX_FG2 When we run this script later,nonclustered indexes will be re-created within this filegroup, so we’ll need to add it tothe database (which we do in step 7)
STEP 3—RESTART SQL SERVER IN SINGLE-USER MODE
Before we can re-create our nonclustered indexes, we need to remove existing indexdefinitions from the database by deleting them from the sys.sysindexes system catalog.This requires us to connect to SQL Server in single-user mode, using the DAC before
we can perform the DELETE
Starting SQL Server in single-user mode requires adding the -m startup parametervia the SQL Server 2005 or 2008 Configuration Manager utility, as displayed in figure 4
1 Navigate to the SQL Server Program Files menu
2 Open the SQL Server Configuration Manager utility
3 Right-click on the relevant instance of SQL Server from the right-hand window
4 Select the Properties menu
5 Click on the Advanced tab
6 Select the Startup Parameters configuration
7 Add ; -m to the end of the existing list of Startup Parameters (or the beginning
of Startup Parameters with SQL Server 2008)
8 Click Apply, and click OK in the warning dialog box that appears
Trang 6Restoring the PRIMARY filegroup backup
9 When the Properties dialog box closes, right-click on the SQL Server instanceand select Restart
STEP 4—CONNECT TO SQL SERVER USING DEDICATED ADMINISTRATOR CONNECTION
Once the SQL Server instance has been restarted, connect through the DAC to allowupdates to the system catalogs Connect or reconnect an SSMS connection by addingADMIN: to the beginning of the server name in your connection dialog box, as dis-played in figure 5
STEP 5—DELETE NONCLUSTERED INDEX DEFINITIONS
Once connected through the DAC, delete existing nonclustered index definitionsfrom the system schema by running the following command:
DELETE FROM sys.sysindexes WHERE OBJECTPROPERTY (id, 'IsUserTable') = 1 AND indid > 1 AND indid < 255
Executing this command allows us to run the script generated in step 2 to re-create allnonclustered indexes—but first we need to remove the -m startup parameter, restart
Figure 4 Adding the -m startup parameter in SQL Server Configuration Manager
Figure 5 Specifying the Dedicated Administrator Connection using the SSMS connection dialog box
Trang 7442 C 33 Efficient backups without indexes
the SQL Server, and add a new nonclustered index using the filegroup name specifiedfor the @NCIXFGName parameter in step 2
STEP 6—REMOVE -M STARTUP PARAMETER AND RESTART SQL SERVER
To remove the -m startup parameter, follow the steps outlined in step 3 but remove
; -m from the Startup Parameters configuration before restarting the SQL Serverinstance
STEP 7—CREATE A NEW, RENAMED FILEGROUP
Once the SQL Server instance has been restarted in multi-user (normal) mode, a newfilegroup must be added prior to re-creating the database’s nonclustered indexes This
is a two-step process; first we create the filegroup by executing the following command:ALTER DATABASE BackupTest
ADD FILEGROUP NCIX_FG2;
Then, we add at least one file to the filegroup by executing the following command:ALTER DATABASE BackupTest
ADD FILE ( NAME = N'NCIX_FG2_F1' , FILENAME = N'C:\ NCIX_FG2_F1.ndf')
STEP 8—REBUILD NONCLUSTERED INDEXES IN THE NEW FILEGROUP
To re-create the nonclustered indexes in the new filegroup, connect to the databaseusing SSMS and execute the script created in step 2
Generate a script to re-create nonclustered indexes during the restore process
if necessary
The workflow of this stored procedure iterates over a database’s indexes, generating aCREATE INDEX statement for each index, and either executes the statement (whenreorganizing the database in preparation for performing PRIMARY filegroup backups)
or prints the statement (to generate scripts for re-creating nonclustered indexes ing restore) The value supplied for the @ScriptOnlyOrExecute parameter defineswhich behavior will occur Supply N'Execute' to execute the scripts (moving the
Trang 8usp_Manage_NCIX_Filegroup
indexes into the filegroup named in the other parameter @NCIXFGName) or N'Script'
to script out the CREATE INDEX statements when restoring the database
Note that slightly different CREATE INDEX statements are generated when cute' is supplied to the @ScriptOnlyOrExecute parameter When N'Execute' is sup-plied, WITH DROP_EXISTING is appended to the CREATE INDEX statement so that eachexisting index remains in place while a new copy is being created in the new, dedi-cated nonclustered index filegroup In addition, the script identifies whether the edi-tion of the SQL Server instance is Enterprise or Standard Edition and includes WITHONLINE=ON if Enterprise Edition is detected The idea here is to cause minimal inter-ruption to queries during reorganization of the database, with close to zero interrup-tion if the Enterprise Edition of SQL Server is in use
Here’s a sample usage Move all nonclustered indexes into a newly created group named 'NCIX_FG':
file-EXEC usp_Manage_NCIX_FileGroup N'Exec', N'NCIX_FG'
As in listing 1, script out CREATE INDEX statements into a newly created filegroupnamed 'NCIX_FG2'
EXEC usp_Manage_NCIX_FileGroup N'Script', N'NCIX_FG2' CREATE PROCEDURE [dbo].[usp_Manage_NCIX_FileGroup]
@ScriptOnlyOrExecute NVARCHAR(6) /* N'Script' or N'Exec' */
, @NCIXFGName NVARCHAR(255) /* the name new filegroup to move NCIXs into*/
AS SET NOCOUNT ON /*cursor variables*/
DECLARE @tnm NVARCHAR(128), @ixnm NVARCHAR(128), @cnm NVARCHAR(128) , @schnm NVARCHAR(128), @isPK BIT, @isUn BIT, @isIncCol BIT , @cixnm NVARCHAR(128), @ctbschnm NVARCHAR(256)
, @ixcr NVARCHAR(4000), @ixcnt INT, @indid INT, @order NVARCHAR(5) , @inccols NVARCHAR(4000)
SELECT @ixcnt = 0, @cixnm = N'', @ctbschnm = N'' /*open cursor over schema / table / index / columns*/
DECLARE cr CURSOR FOR SELECT ss.name, so.name, si.name, N'[' + sc.name + N']', is_primary_key , CASE WHEN is_descending_key = 0 THEN N'' ELSE N' DESC' END , is_included_column, si.index_id, is_unique
FROM sys.schemas ss JOIN sys.objects so on ss.schema_id = so.schema_id JOIN sys.indexes si on so.object_id = si.object_id JOIN sys.index_columns ic ON si.object_id = ic.object_id AND si.index_id = ic.index_id JOIN sys.columns sc ON ic.object_id = sc.object_id AND ic.column_id = sc.column_id WHERE OBJECTPROPERTY (so.object_id, 'IsUserTable') = 1 AND si.index_id > 1 AND si.index_id < 255 /*only interested in NCIXs*/ ORDER BY ss.name, so.name, si.name, ic.index_column_id
/*order crucial for cursor logic*/
Listing 1 Scripting CREATE INDEX commands to a new filegroup
Trang 9444 C 33 Efficient backups without indexes
OPEN cr FETCH NEXT FROM cr INTO @schnm, @tnm, @ixnm, @cnm, @isPK, @order, @isIncCol,
@indid, @isUn /*move over cursor, constructing & executing a drop / create index statement per index*/
WHILE @@FETCH_STATUS = 0 BEGIN
IF @ixnm != @cixnm or (@schnm+@tnm != @ctbschnm) /*new index or table*/ BEGIN
/*if index, table or schema name changes, reinitialise*/
IF @schnm+@tnm != @ctbschnm SET @ctbschnm = @schnm+@tnm SELECT @ixcnt = @ixcnt + 1
IF @ixcnt > 1 BEGIN SELECT @ixcr = LEFT(@ixcr, LEN(@ixcr) - 2) + N')' + CASE WHEN LEN(@inccols) > 1 THEN N' INCLUDE (' + LEFT(@inccols, LEN(@inccols) - 2) + N')' ELSE N'' END + N' WITH (DROP_EXISTING = ON'
+ CASE WHEN SERVERPROPERTY('EngineEdition') = 3 THEN N', ONLINE = ON)' ELSE N')' END
+ N' ON [' + @NCIXFGName + ']' /*execution of create NCIX in other FG occurs
on first row of NEXT index*/
PRINT @ixcr; IF @ScriptOnlyOrExecute = N'Exec' EXEC(@ixcr) END
SELECT @cixnm = @ixnm, @inccols = '' SET @ixcr = N'create ' + CASE WHEN @isUn = 1 THEN N'unique ' ELSE N'' END + N'nonclustered index [' + @ixnm + N'] on [' + @schnm + N'].[' + @tnm + N'] (' + @cnm + @order + N', '
END ELSE BEGIN /*if same index, build key of included cols csv list*/
IF @isIncCol != 0 SET @inccols = @inccols + @cnm + N', ' ELSE SET @ixcr = @ixcr + @cnm + @order + N', '
END FETCH NEXT FROM cr INTO @schnm, @tnm, @ixnm, @cnm, @isPK, @order,
@isIncCol, @indid, @isUn END
/*should usually be one last index (assuming there were any)*/
IF @ixcnt > 1 BEGIN SELECT @ixcr = LEFT(@ixcr, LEN(@ixcr) - 2) + N')' + CASE WHEN LEN(@inccols) > 1 THEN N' INCLUDE (' + LEFT(@inccols, LEN(@inccols) - 2) + N')' ELSE N'' END + N' WITH (DROP_EXISTING = ON'
+ CASE WHEN SERVERPROPERTY('EngineEdition') = 3 THEN N', ONLINE = ON)' ELSE N')' END + N' ON [' + @NCIXFGName + ']'
Trang 10Planning before moving NCIXs into a dedicated filegroup
PRINT @ixcr; IF @ScriptOnlyOrExecute = N'Exec' EXEC(@ixcr) END
CLOSE cr ; DEALLOCATE crNote the following points about the preceding script:
The script iterates over all schemas and their user tables within the currentdatabase, identifying all nonclustered indexes and generating a CREATEINDEX WITHDROP_EXISTING ON [NCIX_FG] script for each index, which is then exe-cuted dynamically to move each nonclustered index
The script will not attempt to move tables Heaps or clustered indexes are inated by the cursor query’s WHERE filter:
elim-and si.index_id > 1 elim-and si.index_id < 255"
Unique definitions, key order, and included columns are all also preserved, sononclustered indexes should be moved identically with their current definitions
Each individual CREATE INDEX statement is also printed, allowing easy review ofthe commands that have been dynamically executed by the script
Planning before moving NCIXs into a dedicated filegroup
Using the usp_Manage_NCIX_FileGroup utility stored procedure makes moving all ofyour database’s nonclustered indexes into a new, dedicated nonclustered index file-group an easy process, but there are some important considerations that need to beaddressed before doing this
Moving NCIXs temporarily requires additional disk space
As nonclustered indexes are moved into the new, dedicated nonclustered index group, extra space needs to be consumed in the filesystem by the filegroup to allocatenew page extents to contain the moved nonclustered indexes
At the same time, space is being freed within the PRIMARY filegroup (as each clustered index is moved out to the new filegroup) but this space is not freed back tothe filesystem Filegroup space is only returned to the filesystem if the filegroup’s filesare explicitly shrunk, using DBCC SHRINKFILE This doesn’t happen automatically, somoving nonclustered indexes out of the PRIMARY filegroup to a new dedicated non-clustered index filegroup will require consumption of more filesystem space
How much more space is required depends on how much nonclustered indexdata your database contains The more nonclustered index data you have, the morefilesystem space you need for the new filegroup but the more space you will save inyour tables-only filegroup backups
The amount of space consumed by nonclustered indexes can be roughly mated in SQL Server 2005 and SQL Server 2008 by running the following query:SELECT SUM(page_count) * 8192.0 / 1048576 as NCIXs_Mb
esti-FROM sys.dm_db_index_physical_stats(db_id(), NULL, NULL, NULL , 'LIMITED')
Trang 11446 C 33 Efficient backups without indexes
WHERE OBJECTPROPERTY (object_id, 'IsUserTable') = 1 AND index_id > 1 AND index_id < 255
Here is a similar query for SQL Server 2000:
SELECT SUM(dpages) * 8192.0 / 1048576 as NCIXs_Mb FROM sysindexes
WHERE OBJECTPROPERTY (id, 'IsUserTable') = 1 AND indid > 1 AND indid < 255
Moving NCIXs creates empty space in PRIMARY filegroup
Once nonclustered indexes have been moved out of the PRIMARY filegroup to a newdedicated nonclustered index filegroup, a significant amount of space will have beenfreed within the PRIMARY filegroup
This space can be returned to the filesystem by shrinking the filegroup’s files viaDBCC SHRINKFILE, but using this command will significantly fragment any clusteredindexes within the filegroup
Another option is to add another dedicated filegroup for table storage (heapsand clustered indexes), leaving the PRIMARY filegroup for system tables only Theprocess of building this additional filegroup requires even more filesystem space, butallows you to re-create the table storage structures within it without fragmentingthose structures After completion of this step, you can shrink the PRIMARY filegroupwithout significant impact
Alternatively, you can leave the free space in the PRIMARY filegroup A problemwith this approach is that restoring backups of the database in this state requiresequivalent filesystem space on the server the backup is being restored to Given thatthe PRIMARY filegroup contains a significant amount of empty space, this might cre-ate difficulties in restoring backups on standby or development servers
Log shipping
So what about combining this technique with log shipping and piecemeal restore?Log shipping standby databases are typically initialized by restoring a full backup ofthe primary database, and then continuously synchronized by performing regulartransaction log backups on the primary database, and restoring those transaction logbackups on the standby with NORECOVERY until the standby database needs to bebrought online
It’s also possible to initialize a standby database by restoring a tables-only group, then continuously synchronizing via a similar process—except that restora-tion of log files on the standby utilizes SQL Server 2005’s new piecemeal restorefeature to include a FILEGROUP clause to the RESTORE LOG commands Consider thisexample:
file-RESTORE LOG StandbyDatabase FILEGROUP = 'PRIMARY' FROM DISK = 'E:\PrimaryDatabase_LogBackup_20090301090005.lbak' WITH NORECOVERY
Trang 12Summary
Using the FILEGROUP clause directs the RESTORE command to ignore entries in thetransaction log that belong to the dedicated nonclustered index filegroup, onlyrestoring log entries that relate to tables (ignoring log entries that relate to nonclus-tered indexes)
An advantage from combining this technique with log shipping and piecemealrestore is that initialization of the log shipping standby database is faster because asmaller tables-only filegroup backup only needs to be copied from the log shippingprimary server to the standby server and restored to the standby database Unfortu-nately, there’s no way to eliminate index-related transaction log entries from the logbackup files, so this technique does not solve the widespread problem of routineindex maintenance breaking log shipping systems
On the other hand, it might be considered a disadvantage that this techniquecomplicates the process of bringing the standby database online in the event of afailover requirement, as indexes also need to be rebuilt
It’s important to point out that it’s also possible to continue using regular logshipping (without piecemeal filegroup level restore) while still taking advantage ofthe disk space, time, and energy savings from switching regular daily full databasebackups to tables-only filegroup backups Initializing log shipping in this scenario stillrequires a full backup of the primary database, but this is still possible because fulldatabase backups can still be taken—irrespective of whether tables and indexes havebeen separated into separate filegroups or not
In this mode of regular backups and log shipping, you can continue to take lar tables-only filegroup backups of the primary database while still fully restoringtransaction log backups against a standby database that has been initialized from afull backup If log shipping ever breaks, take an ad hoc full backup to re-initialize thelog shipping standby database
regu-Summary
You have much to gain from eliminating index data from backups by the methoddescribed in this chapter Reductions in disk space required to store backups, timetaken to process routine backups, and also energy consumed in the process, are allreal, tangible benefits
As with many other technology choices, these advantages need to be weighedagainst the inconvenience of a slightly more complex and time-consuming restoreprocess in the event that a database needs to be fully reconstructed from backup Inmany cases, though, restoration of backups is only performed for ad hoc extraction
of historical data, in which case using this technique makes the restoration processfaster, allowing quicker recovery of data
Another benefit is that the reduction in size of backup files from this techniquealso allows for more copies of historical backups to be maintained Although thismight not be of significant value with smaller databases, with larger databases it could
Trang 13448 C 33 Efficient backups without indexes
make the difference between being able to store a second backup file rather thanonly a single full database backup
Perhaps Microsoft might consider including a feature that allows backups to betaken of table data only, without requiring updates to the system schema, in a futurerelease of SQL Server Such a feature might even extend to filtering log backups tocontain only table-related entries so that log shipping standby servers can be kept in atables-only state without needing to copy all transaction log entries (including unnec-essary index entries) during log shipping
Although some might consider the updates to system catalogs or increased timerequired to restore a database as unacceptable, the benefits gained every day in diskspace, backup processing time, and energy saved should outweigh these issues inmany cases
About the author
Greg Linwood is the Managing Director of MyDBA—a dedicated SQL Server supportbusiness—and also Australian Director of SQLskills, a specialist provider of SQL
Server training Greg has worked in a range of developer and DBA capacities with SQL
Server since 1993, and was the first Australian to receive Microsoft’s SQL Server MVP
award in 2003 He has gained significant expertise in SQL Server tuning, and most ofhis professional time is currently spent tuning customer SQL Server systems Greg ispassionate about building high-quality SQL Server community events in Australia, and
is one of the founders of the Australian SQL Server User Group, leading the bourne SQL Server User Group
Trang 14to become a superhero!
Glenn Berry
This chapter covers how to use database mirroring not only to increase availability
in the traditional sense, but also for less common situations that are not typicallymentioned in the SQL Server documentation or literature One example is usingdatabase mirroring to seamlessly upgrade from SQL Server 2005 to SQL Server 2008with a 10–15-second outage Another example is using database mirroring to movemultiple terabytes of data from one storage system to another with a 10–15-second
outage This chapter reveals these secret techniques.
Why should I use database mirroring?
SQL Server 2005 introduced database mirroring, and SQL Server 2008 enhanced it.Back in the pre-SQL Server 2005 days, you had several choices for high availabilitysolutions with SQL Server, including failover clustering, log shipping, and replica-tion In many situations, database mirroring offers key advantages over all oldertechnologies It is simple to set up and administer, it offers fast automatic failover, itworks at the database level (rather than at the instance or table level), and it can beused with commodity-level hardware
Database mirroring offers fast failover (usually much faster than failover ing), and automatic failover (unlike log shipping or replication) It also avoids thesingle point of failure that you have with the shared storage in failover clustering
cluster-In addition, it is much easier to administer than failover clustering (where addingand removing drives can be pretty painful, for example)
How does database mirroring work?
If you are unfamiliar with how database mirroring works, here is a quick primer You have one user database, which must be running with the FULL recovery
model, which is called the principal The principal is available for client
connec-tions, and does most of the work You also have a complete, synchronized copy of
Trang 15450 C 34 Using database mirroring to become a superhero!
that database (which must be running on another SQL Server instance, preferably on
another server) The copy, known as the mirror, is not available for client connections.
Optionally, if you want automatic failover, you have a third instance of SQL Server,
hopefully on its own server, which is the witness The witness can run on older
hard-ware, and it can be SQL Server Express Edition Its job is to help determine when afailover is required, by communicating with the principal and mirror One witnessinstance can be used for multiple principal/mirror pairs if needed, because the wit-ness is not doing intense work, and it can also be used as a Central ManagementServer with SQL Server 2008
All of the write activity on the principal (including DDL and DML) is sent over yournetwork to the mirror, where it is replayed on the mirror Depending on how yourdatabase mirroring is configured, this may be happening synchronously or asynchro-nously You must be running in high-safety mode (synchronous) with a witness, toallow automatic failover If you are running Enterprise Edition of SQL Server, you canrun in high-performance mode (asynchronous), which does not allow automaticfailover, but can still be useful for many situations
With database mirroring, you have two complete copies of your data, which can be
a good thing Failover clustering uses shared, external storage, usually a storage areanetwork (SAN), where drives are owned by a particular node in the cluster Shared stor-
age is a common single point of failure If unavailable, the cluster service will not start,and SQL Server will not start on the cluster
From a storage perspective, having a second copy of the data with the mirror can
be expensive, but it protects you from the single point of failure you have with afailover cluster (assuming the mirror database is on a different storage system thanthe principal database) This second copy of your data is ready to go after recovery hascompleted The mirror database can be available much faster than a databaserestored from backups or SAN snapshots As a DBA responsible for multiple, mission-critical databases, having the databases mirrored gives me additional peace of mind,because the mirrors represent additional copies of the data, over and above my nor-mal backups and SAN snapshots
How do you set up database mirroring?
You have several ways to do this, depending on your objectives, available ture, and budget You should invest sufficient time and resources in testing your infra-structure (including server and network hardware) to make sure it can handle youranticipated workload reliably Make sure you have enough disk space available toaccommodate possible log file growth if you encounter temporary issues with the mir-roring session
If you need or want a robust, high availability solution with automatic failover and
the ability to run comfortably on the mirror server for an extended period, consider
using these best practices
Make sure that both the principal and mirror have identical hardware:
Trang 16or reorganizations This will also ensure that you can comfortably run your workload
on the mirror hardware for an extended period
Make sure that both the principal and mirror are running a 64-bit version of dows Server 2008 or better Windows Server 2008 R2 will be 64-bit only; and it is likelythat the next version after SQL Server 2008 will be 64-bit only; therefore, time is run-ning out on the 32-bit era Improved memory management alone is a great reason toswitch to a 64-bit version
You should choose a 64-bit version of the Enterprise Edition of SQL Server 2008,because Enterprise Edition has several valuable enhancements (such as parallel logrestore and log stream compression) that are important for database mirroring SQL
Server 2008 native backup compression is helpful when you are initially setting up amirror, because your backups and restores will be smaller and will usually completemore quickly The compressed backup files will be easier to move from the principal
to the mirror (because they are smaller) SQL Server 2008 also offers automatic pagerepair for database mirroring SQL Server 2005 database mirroring also works well,although it lacks the enhancements that were added in SQL Server 2008
Both sides of the partnership should be running the same build of SQL Server, that
is, the same Service Pack and Cumulative Update level If you want automatic failover,you must have a witness instance, which should be on the same build of SQL Server asthe principal and mirror
You also should standardize on common drive sizes, drive letters, and paths for tain SQL Server uses, such as data files, transaction logs, tempdb, backups, and so on.For example, you might decide to use P:, Q:, R:, and S: for data files; L: for your trans-action log; T: for tempdb; and G: and H: for database backups, for both the principaland mirror sides of the mirroring partnership This is important, because if youdecide to add a new data file to your principal, the G: drive, for example, but there is
cer-no identical drive letter and path on the mirror, your database mirroring state will besuspended (and the transaction log will not be truncated) until you correct the situa-tion Backup drives should also have the same drive letters, because if you end up run-ning on the mirror hardware for an extended period, you would want to be runningyour normal full and transaction log backup routine on the mirror side (which is nowthe principal) Having identical drive letters and paths makes this much easier Eventhough tempdb cannot be mirrored, you still should include it in your drive letterstandardization efforts, for consistency’s sake, because that will help you make surethat both instances are configured identically
Trang 17452 C 34 Using database mirroring to become a superhero!
One valid objection that you may hear regarding database mirroring is that it isonly available at the user database level; therefore, it does not include things like log-ins and SQL Agent jobs This is easy enough to correct with a little preparation Youshould try hard to use Windows Authentication instead of SQL Server Authenticationfor your logins, and then create the same Windows logins on the mirror instance This
will avoid the possibility of orphaned users that you can get with SQL Server tion If you must use SQL Server Authentication, you can create the SQL Server logins
Authentica-on the mirror instance with the same SID as on the principal instance, which will alsoavoid the orphaned users issue The queries in listing 1 show how to create a SQL
Server login with an identical SID on the mirror instance
Get the SID for an existing login SELECT [name], sid
FROM sys.server_principals WHERE type_desc = 'SQL_LOGIN' Create SQL Server login with a specific SID (to avoid orphaned user problem)
CREATE LOGIN yourloginname WITH PASSWORD = 'yourpassword',
sid = 0xA306A5DFBF321A4D98D71520DAE1C1D3, CHECK_POLICY = OFF
You can script SQL Agent jobs out on the principal, and then create them on the ror ahead of time, keeping them disabled on the mirror until you need them How-ever, ensuring that the SQL Agent jobs are maintained on the mirror will require somediscipline Job changes are migrated over time
You should make sure that both sides of the mirroring partnership are properlyconfigured for SQL Server 2008, depending on your type of workload For both onlinetransaction processing (OLTP) and decision support system (DSS) types of workloads,
I would grant the Lock Pages in Memory and Perform Volume Maintenance Tasksrights to the SQL Server Service Account Prior to SQL Server 2008 SP1CU2 (Build2714), the Lock Pages in Memory right worked only with the Enterprise Edition of
SQL Server 2005/2008 The Perform Volume Maintenance Tasks right is necessary forthe Windows Instant File Initialization feature to work This allows SQL Server to allo-cate file space for data files (during database creation, file grows, and databaserestores), without zeroing out the file first This can pose a small security risk, but Ithink the benefit far outweighs the risk Database restores are much quicker with Win-dows Instant File Initialization enabled This is important when you are trying toestablish a mirror on a busy production database
You should also set instance level options with sp_configure for things like maxserver memory (MB), max degree of parallelism, optimize for ad hoc workloads, clrenabled, and backup compression default to appropriate values depending on yourworkload type Max degree of parallelism is usually set to “1” for OLTP workloads andhalf the number of processor cores for DSS workloads Optimize for ad hoc workloads
Listing 1 Script to create a login with identical SID on the mirror instance
Trang 18How do you prepare the mirror?
and backup compression default should both be enabled in most cases If you haveany NET CLR assemblies in the database that you want to mirror, you need to makesure that clr enabled is set to “1” on the SQL Server instance where the mirror data-base will live
How do you prepare the mirror?
Finally, after all of the preliminary configuration work, you are ready to prepare the
mir-ror for database mirmir-roring If possible, you should try to do this during non-peak
hours, and you should also consider deferring normal index maintenance tasks whileyou are trying to establish the mirror, so that log-intensive operations are minimized
as much as possible This will make it much easier to establish the mirror
To prepare the mirror, you need to take a full database backup of the user base that you want to mirror (which must be running in FULL recovery model) Usingbackup compression, whether it is SQL Server native backup compression or a solu-tion from a third party, is highly recommended in this situation, because it will makethe backup file(s) much smaller, and it will allow the full backup to complete muchmore quickly When the full backup is complete, you will need to copy the database
data-backup to the mirror instance Speed is of the essence here, because your full data-backup is
falling behind the live database each second during this process
If you are using a modern SAN on your principal instance, you may be able to snap the backup drive(s) over to the mirror host nearly instantaneously Otherwise, you will
have to copy the backup file(s) over your network to the mirror host, which may takequite a bit of time If both servers are running Windows Server 2008, network copytime can be reduced courtesy of the improvements in Server Message Block 2.0 If thebackup file(s) are compressed, that will obviously reduce the copy and restore timeeven further
After the backup file(s) are available on the mirror host, you should restore thedatabase with the NORECOVERY option This is important If you restore with RECOV-ERY (which is the default for both the SQL Server Management Studio (SSMS) GUI
and T-SQL), you will not be able to establish the mirror, and you will have to restoreall over again You should always script out the restore, to double-check it, and youshould change the progress update setting to 1 percent, so that you can get a betterestimate of how long the restore will take Depending on the size and activity level ofyour database, and your hardware and network infrastructure, this full backup, copy,and restore sequence could take several hours You can dramatically reduce this timeframe by having a robust I/O subsystem, using backup compression, making sure themirror instance SQL Server Service account has the Perform Volume MaintenanceTasks right, and using Windows Server 2008
Again, depending on your level of write activity on the principal and the timeelapsed for the full backup, copy, and restore sequence, you will probably have takenone or more transaction log backups on the principal during this period You shouldalso use backup compression here if possible Each of these backup files should becopied over to the mirror instance, where they need to be restored with NORECOVERY,
Trang 19454 C 34 Using database mirroring to become a superhero!
in sequence Depending on how long the full backup took, some of the initial tion log backup restores will be skipped when you try to restore them, because theirlog sequence numbers will be included in the full backup With SQL Server 2008, youmust back up and restore at least one log backup; otherwise you will not be able toestablish the mirror
For example, if your full backup, copy, and restore took six hours, your mirror will
be about six hours behind the principal after the full restore is finished You will ally find that the transaction log restores go relatively quickly, and you will start to rap-idly catch up to the principal If you are taking hourly transaction log backups on theprincipal, you will typically see the restore take a few minutes (depending on severalfactors, mainly I/O capacity on the mirror), which will allow you to eventually catch up
usu-to the principal It is important usu-to try usu-to catch up as much as possible, because SQL
Server will refuse to establish the mirror if it is too far behind the principal
After you are caught up as closely as possible, you need to create the mirroringendpoints and issue the appropriate ALTER DATABASE commands to establish the mir-ror The database mirroring wizard in SQL Server Management Studio (SSMS) workswell enough for this, but beware that it will want to start the mirroring session inhigh-safety mode (synchronous) by default, which I do not recommend You can alsouse T-SQL to do this In most cases, you should start database mirroring in high-performance mode (asynchronous), to make sure that the performance of the prin-cipal is not negatively affected by the mirror trying to get fully synchronized The
SSMS tool called Database Mirroring Monitor, which was introduced with SQL Server
2005 SP1, makes it much easier to watch what is going on as the databases get chronized You can also watch some database mirroring specific counters in Perfor-mance Monitor (under SQL Server: Database Mirroring), and you can run somesystem catalog and Dynamic Management View (DMV) queries to monitor databasemirroring Some of these are shown in listing 2
syn - Basic info about mirrored databases SELECT DB_NAME(database_id) AS 'database_name', * FROM sys.database_mirroring
WHERE database_id > 4 eliminate system databases AND mirroring_state != NULL
Check mirroring endpoints SELECT *
FROM sys.database_mirroring_endpoints Check witness status
SELECT * FROM sys.database_mirroring_witnesses Check mirroring connections SELECT *
FROM sys.dm_db_mirroring_connections Check auto page repair history (SQL 2008 only) SELECT DB_NAME(database_id) AS 'database_name', * FROM sys.dm_db_mirroring_auto_page_repair
Listing 2 Queries to monitor database mirroring
Trang 20How do you prepare the mirror?
You should not rely on the status message in the Object Explorer tree in SSMS to tellyou the status of your database mirror, because it does not auto refresh If you do notmanually refresh the database status in Object Explorer, you will never know the truestatus of the database mirroring session This will give you a false sense of security andwell-being, because the status might say Principal, Synchronized, even if the true sta-tus is something else like Principal, Suspended (unless you manually refresh it) Per-haps a future version of SQL Server will have a feature that would let you configure
SSMS to let it automatically refresh this status periodically In the meantime, you canuse Database Mirroring Monitor to configure alerts that can automatically notify youabout the status of your database mirror You can also query sys.databases andcheck the log_reuse_wait_desc column to see if the description is DATABASE_MIRRORING (which tells you that mirroring has a problem), as you see below:
Get log reuse wait description SELECT [name], log_reuse_wait_desc FROM sys.databases
If a problem with your database mirroring session is preventing the transaction logfrom being truncated internally when you take a transaction log backup, the transac-tion log on the principal database will start to fill up and eventually grow (if auto-grow
is enabled) This is usually caused by a communications problem or a REDO queue onthe mirror
One final tip about establishing your first database mirroring session on a tion server is to try creating a small test database on the principal for a trial run onthat server Create an empty database running FULL recovery model, then take a fullbackup and log backup (even though it is empty, with no activity) Then restore thefull backup and log backup, with no recovery Finally, create the endpoints and alterthe database to create the mirror This should take you less than five minutes, and itwill validate connectivity and security for all of the servers and instances involved Itwill also validate that you are performing all of the tasks correctly, in the rightsequence, before you try it on your production database This tip is also useful fortroubleshooting if you run into problems later on a production server
One last thing you need to take care of is to talk to your developers about how andwhere they store their application-level connection strings, and what data access tech-nologies they are using to connect to your database With most data access technolo-
gies, you will be able to use transparent client redirect, by adding a failover partner to the
connection string This will allow clients to automatically connect to the server that isacting as the principal before and after a failover, whether it is automatic or manual.This modified connection string should be in place before you attempt a databasefailover If the modified connection string is not available, implicit client redirectionwill usually work, but explicit client redirection is a better choice If you ever need orwant to remove mirroring from the database, you should remove the failover partnerinformation from the connection strings for that database
Now you have mirroring set up and running well, with no performance issues.What superhero functions can you perform with database mirroring?