Total Pageviews

Wednesday, March 28, 2012

Why not to shrink your database

I receive a lot of client calls in regards to SQL Server performance.  One of the most common issues is slow query performance and high CPU usage.  Normally, this is caused by index fragmentation or poorly written queries.  Today, I'm going to cover index fragmentation and what usually causes it.

A lot of new DBAs are interested in saving disk space.  To achieve this goal, they will often perform a database shrink, sometimes even after they rebuild the indexes in a maintenance plan that runs every night.

A database shrink, not to be confused with a file shink of the log file, will reclaim unused space in the database file.  The unused space is a result of data being deleted or moved due to a full page.  Honestly, it sounds like a good idea, until you step back and look at what an index actually is, how it works, and how it is relevant to data.

A clustered index actually works at the data level.  In the index B-tree, the clustered index catalogs the data on the actual page it resides on.  So, if data is moved, then that part of the index is fragmented.  During a shink, SQL will re-arrange or move the data to other pages which causes index fragmentation.  Below is an example.

USE master;
GO


--If the database MyDB exists, delete it
IF EXISTS (
SELECT name
FROM sys.databases
WHERE name=N'MyDB')
DROP DATABASE MyDB;
GO


--Creates the database MyDB
CREATE DATABASE MyDB
GO
use MyDB
GO


--Creates a table Persons1 with 2 fields, ID and Column1
CREATE TABLE Persons1 (ID INT IDENTITY, Column1 Char(8000) DEFAULT 'Test')
GO


--Creates a clustered index on the ID field of the persons1 table
create clustered index idx_ID on dbo.persons1(ID)
GO


--Inserts 1280 records to the Persons1 table
INSERT INTO Persons1 DEFAULT VALUES;
GO 1280


--Shows the percentage of framentation of the clustered index
SELECT [avg_fragmentation_in_percent] FROM sys.dm_db_index_physical_stats (
    DB_ID ('MyDB'), OBJECT_ID ('Persons1'), 1, NULL, 'LIMITED');
GO





--Deletes the first 500 rows of the Person1 table
delete TOP(500) from Persons1
GO


--Shows the percentage of framentation of the clustered index
SELECT [avg_fragmentation_in_percent] FROM sys.dm_db_index_physical_stats (
    DB_ID ('MyDB'), OBJECT_ID ('Persons1'), 1, NULL, 'LIMITED');
GO





--Shrinks the database files, reclaiming space in the files.  It also
--fragements the clustered index extremely bad
dbcc shrinkdatabase(MyDB)
GO





--Shows the percentage of framentation of the clustered index
SELECT [avg_fragmentation_in_percent] FROM sys.dm_db_index_physical_stats (
    DB_ID ('MyDB'), OBJECT_ID ('Persons1'), 1, NULL, 'LIMITED');
GO





With my results of a database shrink using 2 fields and 780 records, a shrink caused roughly 63% fragmentation.  Imagine what the results would be on a database with a lot of tables, records, and indexes.  So, shrinking the database is never a good idea as it causes massive fragmentation of the indexes.

Wednesday, March 14, 2012

SQL Server and Instant File Initialization

Performance tuning and disaster recovery have always fascinated me in regards to SQL Server.  Whether it be an index tweak, RAID subsystem configuration or a proper disaster recovery plan.  Today, I want to briefly talk about a feature called Instant File Initialization, added to SQL Server 2005 and on.  A lot of people have never even heard of it.  What is it you ask?  Well let me tell you.

Instant file initialization is based on an NTFS feature that was added to Windows Server 2003 and on.  Basically, and I am being  very basic on the description as this post will not be very long, when a SQL database file is created in on the OS, it is prefilled with zeros.  So, if a new database is created, a database is grown, or a database is restored, the first thing that happens is that the file is created, or extended.  The very next thing that happens is the OS will prefill the pages in file with zeros (SQL Server Databases are created using 8KB pages).  The process of prefilling the pages with zeros can be very time consuming and I/O intensive.  With Instant File Initialization, this process is skipped, the file is made available once the file is created, and SQL Server can start populating it with data.

To show an example of this, I am going to use a test database that I created called MyDB.  This database is roughly 5GB in size.  I will first restore a backup without using Instant File Initialization.






Notice that the time it took to restore is 11:49 minutes?  Now, I'm going to allow SQL Server to utilize Instant File Initialization.  To do this, you have to go to the local security policy editor under Administrative tools, and make a change to the "Perform Volume Maintenance Tasks".  The change that needs to be made is, you have to add the user or group of the service account that starts the SQL Server service.  This is done in the Security Settings->Local Policies->User Rights Assignment->Perform Volume Maintenance Tasks in the Local Policy Editor.  

*FYI, best practices for SQL Server is not to start the SQL Server service using an account that is part of the administrators group.  Normally, I create a group, and add a user to that group.  I will add that group to the "Perform Volume Maintenance Tasks" in the local policy.  Then we have to restart the SQL Server service.


Now, after making the appropriate changes, and restarting the SQL Server service, I start the restore.


Look at that!  It finished in 6:37 minutes!  That is 5:12 minutes faster for a restore, or 44% faster.  This not only works for restores, but with file growth and creating new files as well.  It does not work for the Log file though.  That still has to be prefilled with zeros due to the circular nature.

*There is a slight security risk with using this option.  Windows Administrators have access to all files stored on the server.  By giving the SQL group the "Perform Volume Maintenance Tasks" permission, the SQL Administrator can then use an undocumented command to view individual pages on the hard drive even if they are encrypted.  This command is "DBCC PAGE".

The options for DBCC PAGE are as follows:
0 - print just the page header 
1 - page header plus per-row hex dumps and a dump of the page slot array
2 - page header plus whole page hex dump 
3 - page header plus detailed per-row interpretation

One other thing about Instant File Initialization.  With Windows operating systems, when a file is deleted, it is not really deleted.  The disk space is just marked as usable.  So, when you create a new file or grow a file, it is actually potentially overwriting deleted files.  So, if you like to recover deleted files, don't use this option.

Thursday, March 8, 2012

Teaming with Windows Server 2012

It seems like ever day there are questions about how to team the NICs in Windows Server.  With Broadcom, you have to use BACS, which we all know is not full proof.  Intel makes it a little easier with teaming done in the driver.  Windows Server 8 has made it extremely simple.  You can use the Server Manager (which really calls the exe), Powershell, or the standalone exe to create and manage a team.  Below are the steps to create a team.

Server Manager

  1. Open Server Manager (Windows Key and click Server Manager)
  2. Local Server
  3. Network Adapter Teaming
EXE (The easiest way)
  1. Windows Key + R
  2. run lbfoadmin.exe
*Using the NIC Teaming Manager, you can now create NIC teams on remote servers.  As well as many other remote features, such as adding roles and features to remote servers.

Steps to create a new team
  1. Select the server you want to create the team on.
  2. Under teams, click the down arrow next to the "TASKS" drop down.
  3. Click on "New Team".
  4. In the New Team Wizard, enter a team name.
  5. Select the NICs that you want to be in the team.
  6. Click Additional Properties
  7. Select the teaming mode (Can use Static Teaming, Switch Independent, or LACP)
  8. Select the Local Distribution Mode (Can use Address Hash or Hyper-V Port)
  9. Select the Primary Team Interface (Can use the Default or Specific VLAN)
  10. Click OK.
Once you have created the team, it will show up under the TEAM section and the status should be OK.  If you go and look at the Network Adapters, you will see your physical NICs and the new Team NIC.  If you look at the properties for the physical NICs in the team, you will notice that everything is unchecked except for the Microsoft Network Adapter Multiplexor Protocol.  This is the protocol used for teaming and load balancing.  The actual IP address will be stored in the new Virtual Team NIC.

This can also be done using a PowerShell commandlet.  Here are the steps for PowerShell.

Power Shell
  1. Open PowerShell (Windows Key and click Windows PowerShell)
  2. New-NetLbfoTeam (exact command:  New-NetLbfoTeam <TeamName> <NIC1>, <NIC2>
In summary, Microsoft has really made great steps to streamline the NIC Teaming process and has eliminated the requirement of 3rd party drivers and software.  I hope to have more for you soon.

Windows Server 8 - Where's the start button!!!

Server Version
So a lot of people have been asking "If there is no start button, how do I navigate in Windows 8 Server?".   This is a quick note on some of the keyboard commands for Windows 8 Server.  I haven't had time to play with the client version yet.

Windows Key → [Search Term] → Enter will allow you to launch an application very quickly. Pressing the Windows key launches the Start Screen, but immediately typing a search term for an application and pressing Enter will launch the application you desire very quickly.

Windows Key + F will bring up the Metro interface to search for files. Selecting a file will open a Metro app first, but if there is no Metro app to open the file it will choose a Desktop app instead.

Windows Key + W allows you to search for settings in a similar way to files. A lot of the time the selections will open the Control Panel

Esc (when on the Start Screen) or Windows Key + D immediately ditches the Start Screen for the Desktop

Windows Key + E opens Windows Explorer in case you need to browse files and either don't have it pinned to the taskbar or don't want to search for it.

Windows Key + C shows the Charm Bar, which can be hard to get to display with a mouse (especially with multiple monitors).

Windows Key + I shows the information pane that usually only appears once you mouse to the Charm Bar and click Settings. This panel has handy buttons to control volume, networks and power.

Windows Key + P shows multi-display options.

Windows Key + H brings up sharing options for the application you are using.

Windows Key + X shows a context menu filled with links to Windows related settings, such as Command Prompt, Event Viewer, Task Manager, Programs & Features, and more.

Windows Key + . (that is a period) chucks the program you're using into either one of Windows 8's multi-tasking sidebars.

Windows Key + [1-9] activates one of the programs pinned to your taskbar, with the number you enter corresponding to the location on the taskbar.

Windows Key + Tab displays the new Windows 8 Metro multi-tasking sidebar.


On a side note, to install Windows 8 Server into an ESX virtual machine, there are updates that must be run on the ESX host(http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2006859)  It does work however.


Client Version
OK, so a lot of people are probably saying "I thought there was a start button".  On Windows 8 Server, they completely took it out.  On Windows 8 Client, it is off by default.  As of right now, still beta, you can enable the start button via a registry key.  However, I prefer to focus on the Server version.  If you want to add it back to the client version, follow these steps:

1.  Open the registry editor.  (Windows Key + R and run regedit)
2.  Navigate to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer
3.  Change the RPEnabled entry from 1 to 0

Tuesday, March 6, 2012

Cluster Validation Report for Microsoft Clustering fails "Validate Cluster Network Configuration"

Welcome to my very first blog post!

Today I was setting up a small test lab using a single Domain Controller, a Storage Server, and 2 Cluster Nodes.  I created my first VM and installed Windows server 2008 R2.  Now, my experience tells me that I should sysprep first, but I skipped this step to save 2 minutes (I'll get back to this in a bit).  I then cloned the server for the additional 3 machines needed.  I ran DCPromo and setup the DC.  I added the other 3 machines to the domain and verified that DNS worked as it should.  So far so good.  I then prepaired my storage server so that I can host my iSCSI targets.  Now, with the clustered nodes, I setup my iSCSI targets and then added the cluster feature.  As any good Admin would do, I ran a cluster validation report, and it failed on the network.

The exact error message I was getting was as follows:

Validate Cluster Network Configuration

Validate the cluster networks that would be created for these servers.
An error occurred while executing the test.
There was an error initializing the network tests.
There was an error creating the server side agent (CPrepSrv).
Creating an instance of the COM component with CLSID {E1568352-586D-43E4-933F-8E6DC4DE317A} from the IClassFactory failed due to the following error: 80070005.

The first thing I did was to go into DCom on the domain controller and change the impersonation level from identity to impersonate, then rebooted the domain controller.  Once it was back up, I ran the validation report and experienced the same result.  I removed the clustered nodes from the domain and added them back again.  I was thinking maybe it was the forest functioning level, but that should not make a difference.  And then it hit me, I didn't sysprep the machine that I created the cloned VMs from.  After finally deciding to perform a google search, or bing if you like, I found http://support.microsoft.com/kb/2012835 that describes this entire issue.  Of course SIDs are the major concern in this situation.

For those of you who do not know, sysprep is the Microsoft utility that prepares the system image for deployment.  Basically, it removes the computer name, IP addresses, SIDs, etc.  Starting with Windows Server 2008 R2, it is installed with the OS in the C:\Windows\System32\Sysprep folder.  Using the /generalize switch will reset the system clock on the image for the OS activation.

So, the lesson for the day is not to be a lazy admin and do things the correct way.  2 minutes of waiting would have saved a couple of hours.