Saturday, October 30, 2010

SQL Server - Verifying backups using SMO



In order to perform a verify using SMO we require two objects, a Server object and a Restore object. In its simplest form, a Restore object requires only a few properties to be set before calling the SqlVerify method and passing in the Server object as can be seen in the following example that does a verify of a database backup from the file c:\SMOTest.bak. This example uses the overloaded SqlVerify method to return the verify error if the method returns false.

using System;
using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Restore res = new Restore();
            Boolean verified;
            String errormsg;

            res.Devices.AddDevice(@"C:\SMOTest.bak", DeviceType.File);

            verified = res.SqlVerify(svr, out errormsg);

            Console.WriteLine("verified = " + verified.ToString());

            if (verified == false)
                Console.WriteLine(errormsg);

        }
    }
}

SQL Server - Database backup using SMO


In order to perform a backup using SMO we require two objects, a Server object and a Backup object. In its simplest form, a Backup object requires only a few properties to be set before calling the SqlBackup method and passing in the Server object as can be seen in the following example that does a Full database backup of the SMO database to the file c:\SMOTest.bak

using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Backup bkp = new Backup();
            bkp.Devices.AddDevice(@"C:\SMOTest.bak", DeviceType.File);
            bkp.Database = "SMO";
            bkp.Action = BackupActionType.Database;
            bkp.Initialize = true;
            bkp.PercentCompleteNotification = 10;
            bkp.PercentComplete += new PercentCompleteEventHandler(bkp_PercentComplete);
            bkp.SqlBackup(svr);
        }

        static void bkp_PercentComplete(object sender, PercentCompleteEventArgs e)
        {
            Console.WriteLine(e.Percent.ToString() + "% backed up");
        }
    }
}

There are many other properties that can be set for the Backup object. For the full list see the Backup Object in Books On Line (if you have SQL2005 Books On Line installed click this link to be taken to the correct page).

Filegroup Backups

In the example below, just the WorkOrderGroup filegroup of the Adventureworks database is backed up (the script to convert the AdventureWorks OLTP demo database into a multi filegroup database can be found in the SQL Server Engine samples and by default is located in C:\Program Files\Microsoft SQL Server\90\Samples\Engine\Administration\FileGroups\Scripts). Filegroups to be backed up are specified by adding them to the Backup objects DatabaseFileGroups collection. In order to backup specific files, they can be added to the DatabaseFiles collection.

using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Backup bkp = new Backup();
            bkp.Database = "AdventureWorks";
            bkp.Action = BackupActionType.Files;
            bkp.DatabaseFileGroups.Add("WorkOrderGroup");
            bkp.Devices.AddDevice(@"C:\AWFGTest.bak", DeviceType.File);
            bkp.SqlBackup(svr);
        }
    }
}

Differential Backups

Performing a differential backup is very straightforward, simply set the Incremental property of the Backup object to True

Log Backups

Log backups are equally straightforward, simply set the Action property of the Backup object to BackupActionType.Log

using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Backup bkp = new Backup();
            bkp.Action = BackupActionType.Log;
            bkp.Database = "SMO";
            bkp.Devices.AddDevice(@"c:\SMOTest.trn", DeviceType.File);
            bkp.SqlBackup(svr);
        }
    }
}

SQL Server - Database restore using SMO



In this short article I'will show you how to use SMO (Server Management Object) to do restore of the database. In order to perform a restore using SMO we require two objects, a Server object and a Restore object. In its simplest form, a Restore object requires only a few properties to be set before calling the SqlRestore method and passing in the Server object as can be seen in the following example that does a Full database restore of the SMO database from the file c:\SMOTest.bak, replacing the database it it already exists. This example also uses an Event Handler for the PercentComplete event to display the restore progress.

using System;
using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
 class Program
 {
  static void Main()
  {
   Server svr = new Server();
   Restore res = new Restore();
   res.Database = "SMO";
   res.Action = RestoreActionType.Database;
   res.Devices.AddDevice(@"C:\SMOTest.bak", DeviceType.File);
   res.PercentCompleteNotification = 10;
   res.ReplaceDatabase = true;
   res.PercentComplete += new PercentCompleteEventHandler(ProgressEventHandler);
   res.SqlRestore(svr);
  }
  
  static void ProgressEventHandler(object sender, PercentCompleteEventArgs e)
  {
   Console.WriteLine(e.Percent.ToString() + "% restored");
  }
    }
}

Restoring a Database to a New Location

Using SMO, the equivalent of the T-SQL WITH MOVE syntax for restores is to use the RelocateFiles property of the Restore Object and the RelocateFile object. In the example below, we will restore a copy of the SMO database to a database called SMO2 with the data and log files on the C: drive. The RelocateFile constructor can take two parameters, the first is the logical filename and the second is the physical filename. This provides the mapping of where to move the files during the restore.

using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Restore res = new Restore();
            res.Database = "SMO2";
            res.Action = RestoreActionType.Database;
            res.Devices.AddDevice(@"C:\SMOTest.bak", DeviceType.File);
            res.ReplaceDatabase = true;

            res.RelocateFiles.Add(new RelocateFile("SMO", @"c:\SMO2.mdf"));
            res.RelocateFiles.Add(new RelocateFile("SMO_Log", @"c:\SMO2.ldf"));

            res.SqlRestore(svr);
        }
    }
}

Reading Backup File Information

There are a number of methods of the Restore object that can be used to obtain information about a backup device and the files it contains including ReadBackupHeader, ReadFileList and ReadMediaHeader. In the example below, we will use the ReadFileList method to obtain the list of Logical filenames on the disk device c:\SMOTest.bak and display them on the console.

using System;
using System.Data;
using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Restore res = new Restore();
            DataTable dt;
            DataRow[] foundrows;

            res.Devices.AddDevice(@"C:\SMOTest.bak", DeviceType.File);
            dt = res.ReadFileList(svr);

            foundrows = dt.Select();

            foreach (DataRow r in foundrows)
            {
                Console.WriteLine(r["LogicalName"].ToString());
            }
        }
    }
}

Log Restoresjavascript:void(0)

Log restores are equally straightforward, simply set the Action property of the Restore object to RestoreActionType.Log. Additional properties can be set for Log backups such as ToPointInTime which allows recovery to a specific point in time.

using System;
using Microsoft.SqlServer.Management.Smo;

namespace SMOTest
{
    class Program
    {
        static void Main()
        {
            Server svr = new Server();
            Restore res = new Restore();
            res.Database = "SMO";
            res.Action = RestoreActionType.Log;
            res.Devices.AddDevice(@"C:\SMOTest.trn", DeviceType.File);
            res.NoRecovery = false;
            res.SqlRestore(svr);
        }
    }
}

Friday, October 29, 2010

SQL Server - Restore Database and difference between RECOVERY and NORECOVERY

When I was preparing myself for exam 70-432 I found, that one objective was about database restoring. After study I had one question I couldn't answer. The question was: what is the difference between RECOVERY and NORECOVERY? After a short googling I found some definitions. On MSDN I found this:

Comparison of RECOVERY and NORECOVERY
Roll back is controlled by the RESTORE statement through the [ RECOVERY | NORECOVERY ] options:

NORECOVERY specifies that roll back not occur. This allows roll forward to continue with the next statement in the sequence.
In this case, the restore sequence can restore other backups and roll them forward.

RECOVERY (the default) indicates that roll back should be performed after roll forward is completed for the current backup.

Recovering the database requires that the entire set of data being restored (the roll forward set) is consistent with the database. If the roll forward set has not been rolled forward far enough to be consistent with the database and RECOVERY is specified, the Database Engine issues an error.

But in books online I think it is much more better explained:

While doing RESTORE Operation if you restoring database files, always use NORECOVER option as that will keep database in state where more backup file are restored. This will also keep database offline also to prevent any changes, which can create itegrity issues. Once all backup file is restored run RESTORE command with RECOVERY option to get database online and operational.

It is also important to be acquainted with the restore sequence of how full database backup is restored.

First, restore full database backup, differential database backup and all transactional log backups WITH NORECOVERY Option. After that, bring back database online using WITH RECOVERY option.

Following is the sample Restore Sequence
RESTORE DATABASE mydbname FROM full_database_backup WITH NORECOVERY;

RESTORE DATABASE mydbname FROM differential_backup WITH NORECOVERY;

RESTORE LOG mydbname FROM log_backup WITH NORECOVERY;

-- Repeat this till you restore last log backup

RESTORE DATABASE mydbname WITH RECOVERY;

SQL Server - Table (Index) Seeks and Scans

Generally scans and seeks are the iterators that SQL Server uses to read data from tables and indexes. This types of iterators belog to the most fundamental ones that SQL Server supports. They appear in nearly every query plan.

Scan

Scan returns entire table (or index). That means, that scan touches every row in the table whether or not it qualifies. For this reason, tha cost of scan is proportional to the total number of rows in table. Scan is an efficient stratedy if table is small or if most the rows qualify for the predicate.

Index Scan is nothing but scanning on the data pages from the first page to the last page. If there is an index on a table, and if the query is touching a larger amount of data, which means the query is retrieving more than 50 percent or 90 percent of the data, and then optimizer would just scan all the data pages to retrieve the data rows. If there is no index, then you might see a Table Scan (Index Scan) in the execution plan.

If the table is large and if most of the rows do not qualify, we touch many more pages and rows and perform many more I/Os than is necessary.

Seek

Since a seek only touches rows that qualify and pages that contain these qualifying rows, the cost is proportional to the number of qualifying rows and pages rather than to the total number of rows in the table.

Index seeks are generally preferred for the highly selective queries. What that means is that the query is just requesting a fewer number of rows or just retrieving the other 10 (some documents says 15 percent) of the rows of the table.

In general query optimizer tries to use an Index Seek which means that optimizer has found a useful index to retrieve recordset. But if it is not able to do so either because there is no index or no useful indexes on the table then SQL Server has to scan all the records that satisfy query condition.

Thursday, October 28, 2010

Exams 70-432 and 70-450

Hello,
yesterday I passed exam 70-450 PRO: Designing, Optimizing and Maintaining a Database Administrative Solution Using Microsoft SQL Server 2008 and I have became MCITP Database Administrator 2008. Now I want to share with you my exam and study experiences with you.

When you want to become MCITP Database Administrator 2008, you must first pass exam 70-432 TS: Microsoft SQL Server 2008, Implementation and Maintenance. For this exam is very good book  SQL Server 2008 Administration: Real-World Skills for MCITP Certification and Beyond (Exams 70-432 and 70-450) and official Microsoft Press Training kit with included MeassureUp practice test. For exam 70-450 I used Professional Microsoft SQL Server 2008 Administration book as a base.

I can't go into what the questions asked were, but my advice is – make sure you cover all new features provided with SQL Server 2008, and most admin stuff like database performance optimization, high availability etc. Download trial SQL Server 2008 [developer version] from Microsoft’s website and have at least 2 instances installed for your personal practise. If you attend any Microsoft launch event. they usually give away a licensed copy of SQL Server Standard edition. You don't need to install SQL Server 2008 R2, but it doesn't hurt to get familiar with that version.

Exam 70-432 – TS: Microsoft SQL Server 2008, Implementation and Maintenance

Installing and Configuring SQL Server 2008 (10 percent)
Maintaining SQL Server Instances (13 percent)
Managing SQL Server Security (15 percent)
Maintaining a SQL Server Database (16 percent)
Performing Data Management Tasks (14 percent)
Monitoring and Troubleshooting SQL Server (13 percent)
Optimizing SQL Server Performance (10 percent)
Implementing High Availability (9 percent)








Exam 70-450 – PRO: Designing, Optimizing, and Maintaining a Database Administrative Solution Using Microsoft SQL Server 2008

Designing a SQL Server Instance and a Database Solution (14 percent)
Designing a Database Server Security Solution (15 percent)
Designing a Database Solution for High Availability (15 percent)
Designing a Backup and Recovery Solution (20 percent)
Designing a Monitoring Strategy (13 percent)
Designing a Strategy to Maintain and Manage Databases (14 percent)
Designing a Strategy for Data Distribution (9 percent)

Tuesday, October 26, 2010

Connecting to SQL Server via SMO


When you want to connect to the SQL Server 2005 (or later version), you can use SMO. To get started with SMO, you must first add reference to Visual studio. In Add Reference window select Microsoft.SqlServer.Smo, Microsoft.SqlServer.SmoExtended, Microsoft.SqlServer.Management.Sdk.Sfc, and Microsoft.SqlServer.ConnectionInfo.

After that, you have to add two namespaces, that you will need:

using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

Now, you can start working with SMO objects. First object, you need to use is ServerConnection object. This object represents connection to SQL Server instance.

ServerConnection conn = new ServerConnection("INSTANCE", "LOGIN", "PASSWORD");
try
{
    Server srv = new Server(conn);
    Console.WriteLine("Server: " + srv.Name);
    Console.WriteLine("Edition: " + srv.Information.Edition);

}
catch (Exception err)
{
    Console.WriteLine(err.Message);
}

you can also use windows integrated authentication:

ServerConnection conn = new ServerConnection();
conn.ServerInstance = "INSTANCE";
try
{
    Server srv = new Server(conn);
    Console.WriteLine("Server: " + srv.Name);
    Console.WriteLine("Edition: " + srv.Information.Edition);

}
catch (Exception err)
{
    Console.WriteLine(err.Message);
}

Monday, October 25, 2010

CodeProject Articles

A few weeks ago I have posted 2 aricles. First article was about saving large files into SQL Server using ASP.NET webservices and the second one was about customizing a DataGridView.
Saving Files Into Database Using .NET Web Services
How to Create ProgressBar Column in DataGridView

Get local and remote SQL Server Instances


In this post I will show you how to get list of remote and local SQL Server Instances. When you want to do this, you can use SQL SMO.SMO provides a method for enumerating SQL Server instances on network. Method EnumAvailableSqlServers returns DataTable with a few columns. In this case we will use Name column. This method has one parameter LocalOnly of boolean data type. When this parameter is true, than method returns only local instances.


DataTable dt = SmoApplication.EnumAvailableSqlServers(false);

            if (dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    Console.WriteLine(dr["Name"] + "      " + dr["IsLocal"]);
                }
            }

Another approach, how to get local instances is to get it from registry.

RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Microsoft SQL Server");
String[] instances = (String[])rk.GetValue("InstalledInstances");
if (instances.Length > 0)
{
      foreach (String element in instances)
      {
            if (element == "MSSQLSERVER")
                  Console.WriteLine(System.Environment.MachineName);
            else
                  Console.WriteLine(System.Environment.MachineName + @"\" + element);
      }
}