SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
Search:  
 
 

SQL Server Soldier :: News from the frontlines of the database wars

Add to Technorati Favorites Add to Google
More Posts « Previous page
All Posts

Database Mirroring FAQ: Why does Database Mirroring Monitor report that my mirror is disconnected?

Rating: (not yet rated) Rate this |  Discuss | 6,266 Reads | 483 Reads in Last 30 Days |no comments

Question: Why does Database Mirroring Monitor report that my mirror is disconnected?

This question was sent to a discussion list via email. My reply follows.

Sometimes, I have seen a behavior where the Principal was unable to connect to the Mirror. What is the reason for this behavior? Could it be network? I could not find any information that explain this behavior.

Any help here would be appreciated.

My answer:

This does not mean that the principal is disconnected from the mirror.

This simply means that the Database Mirroring Monitor has not connected to the mirror yet. This is not an unusual behavior to see when first looking at a mirrored database in the monitor. The monitor connects to the principal and then to the mirror. Usually, this will clear up within a few seconds on its own as it eventually makes the connection.

If it does not make the connection on its own within a short time, then the problem exists between the monitor and the mirror.


Database Mirroring FAQ: Can a 2008 SQL instance be used as the witness for a 2005 database mirroring setup?

Rating: |  Discuss | 5,057 Reads | 418 Reads in Last 30 Days |no comments

Question: Can a 2008 SQL instance be used as the witness for a 2005 database mirroring setup?

This question was sent to me via email. My reply follows.

Can a 2008 SQL instance be used as the witness for a 2005 database mirroring setup?

Databases to be mirrored are currently running on 2005 SQL instances but will be upgraded to 2008 SQL in the near future. I have not tried this, need mirroring setup and was hoping to get a jump on the future upgrade.

My answer:

Yes, a SQL 2008 machine can act as witness for 2 SQL 2005 machines. When upgrading the systems from SQL Server 2005 to SQL Server 2008, the witness can be upgraded at any time (first, last, or in the middle).


Database Mirroring FAQ: If the principal fails while running in high performance mode, what options do I have for bringing the mirror online?

Rating: (not yet rated) Rate this |  Discuss | 5,911 Reads | 481 Reads in Last 30 Days |2 comment(s)
Question: If the principal fails while running in high performance mode, what options do I have for bringing the mirror online?

This question was sent to me via email. My reply follows.

Quick question on DB mirroring client redirection after Principal fails ...

Consider a simple scenario with Asynchronous mirroring:

  1. We are implementing asynchronous [high performance] mirroring without witness.
  2. The client application connects to the mirroring session using below connection string:

    Source={PrincipalServerName};Initial Catalog={DBName};Integrated Security=SSPI;Failover Partner= {MirrorServerName}
  3. Now due to some disaster, the Principal Server goes offline and will be offline for let’s say next 48 hours.
  4. We notice that client connections fail since primary is offline and a failover has not yet be done.
  5. What steps should be taken now to connect the client application to the mirrored database?

I can force the service or break the mirroring session (assuming with possible data loss) and re-setup later when Principal comes online.

  1. Is above statement correct?
  2. If yes, what changes do I need do in the connection strings for force service and breaking the mirror?
  3. Would connection string in step#2 works with failover partner parameter?

My answer:

  1. Yes, those are your only options for bringing the mirror online at this point. Forcing the service is preferable.
  2. If you force the service, no changes will need to be made to the connection strings because the clients will be able to connect to the failover partner.

    If you break mirroring, the Failover Partner parameter of the connection string will not be honored because the database is not currently participating in mirroring. You would have to alter the connection string to point at the mirror as the principal. One caveat to this is if you were already running on the original mirror as the current principal and the server you force service on is listed as the principal in the connection string already, no changes will need to be made.
  3. As described above. Always yes for forced service, usually no but sometimes yes for breaking the mirror.

How Do I Configure SSIS to Work With a Named Instance

Rating: (not yet rated) Rate this |  Discuss | 4,016 Reads | 284 Reads in Last 30 Days |2 comment(s)

How Do I Configure SSIS to Work With a Named Instance? 

By default, SSIS (SQL Server Integration Services) uses the msdb database of the default instance on the server for storing packages. SSIS can still manage packages stored as files in the file system without any changes to the current setup. To be able to use the msdb database of a named instance, you have to manually edit the SSIS configuration file. Here are the steps for that:

  1. Shut down the IS service
  2. Find the configuration file: <install location>\Microsoft SQL Server\90\DTS\Binn\MsDtsSrvr.ini.xml
  3. Open the configuration file in a text editor such as Notepad
  4. To configure a named instance instead of the default instance, change the existing ServerName entry to ServerName\InstanceName under the Folder node of type SQLServerFolder
  5. To configure a named instance in addition to the default instance, add a new Folder node of type SQLServerFolder under the TopLevelFolders node
  6. Save and close the configuration file
  7. (Re)start the IS service

Before change:

<?xml version="1.0" encoding="utf-8"?>
<DtsServiceConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <StopExecutingPackagesOnShutdown>true</StopExecutingPackagesOnShutdown>
 <TopLevelFolders>
  <Folder xsi:type="SqlServerFolder">
   <Name>MSDB</Name>
   <ServerName>.</ServerName>
  </Folder>
  <Folder xsi:type="FileSystemFolder">
   <Name>File System</Name>
   <StorePath>..\Packages</StorePath>
  </Folder>
 </TopLevelFolders> 
</DtsServiceConfiguration>

After change to a named instance:

<?xml version="1.0" encoding="utf-8"?>
<DtsServiceConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <StopExecutingPackagesOnShutdown>true</StopExecutingPackagesOnShutdown>
 <TopLevelFolders>
  <Folder xsi:type="SqlServerFolder">
   <Name>MSDB</Name>
   <ServerName>MyServer\Myinstance01</ServerName>
  </Folder>
  <Folder xsi:type="FileSystemFolder">
   <Name>File System</Name>
   <StorePath>..\Packages</StorePath>
  </Folder>
 </TopLevelFolders> 
</DtsServiceConfiguration>


After adding a named instance to the default:

<?xml version="1.0" encoding="utf-8"?>
<DtsServiceConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <StopExecutingPackagesOnShutdown>true</StopExecutingPackagesOnShutdown>
 <TopLevelFolders>
  <Folder xsi:type="SqlServerFolder">
   <Name>MSDB</Name>
   <ServerName>.</ServerName>
  </Folder>
  <Folder xsi:type="SqlServerFolder">
   <Name>MSDB</Name>
   <ServerName>MyServer\Myinstance01</ServerName>
  </Folder>
  <Folder xsi:type="FileSystemFolder">
   <Name>File System</Name>
   <StorePath>..\Packages</StorePath>
  </Folder>
 </TopLevelFolders> 
</DtsServiceConfiguration>


How many mirrored databases can I have on a server?

Rating: (not yet rated) Rate this |  Discuss | 4,598 Reads | 367 Reads in Last 30 Days |4 comment(s)

 How many mirrrored databases can I have on a server?

10 mirrored databases per server is the recommendation for a 32 bit computer WITH 4 processors or less. 64 bit computers have twice as many threads which means, in theory, that you can have twice as many mirrored databases. Also more processors = more threads = more mirrored databases. I interpolated the recommendations out from the base recommendation to other system profiles as follows: 

 

32-bit 64-bit
Number of CPUs Threads Mirrored Databases Threads Mirrored Databases
<= 4 processors 256 10 512 20
8 processors 288 11 576 22
16 processors 352 13 704 27
32 processors 480 18 960 37
 Others are correct to point out that this is a recommendation, not a hard limit. What your server can actually handle depends on the architecture as well as the amount of other traffic being handled by the server.

 


Deleting Duplicates without a unique key

Rating: (not yet rated) Rate this |  Discuss | 4,988 Reads | 273 Reads in Last 30 Days |no comments

The following was sent to me by my friend and colleague Dave Miller:

Dave's Email:

Wanted to pass along something I hadn't used before and found useful to easily get rid of duplicates in a set of data. The functionality has existed in the SQL language and was supported in SQL Server 2005. This uses Common Table Expressions (CTE) and the ROW_NUMBER() function.

The PARTITION BY portion of the statment specifies when to reset the row number, in my example I had:

  PersonId     Type     PNumber    
A 1 123  
A 1 345  
B 1 123 ***DELETE 
A 2 123  
B 1 123  
B 1 123 ***DELETE 
A 2 123 ***DELETE 
B 1 1234  


The following query will remove the duplicates:

WITH PersonPhones AS (
    SELECT ROW_NUMBER() OVER (PARTITION BY PersonId, PhonetypeId, PhoneNumber ORDER BY PersonId, PhonetypeId, PhoneNumber) AS GroupIndex,
        PersonId,
        PhonetypeId,
        PhoneNumber
    FROM Person.Phone pp
)
DELETE FROM PersonPhones WHERE GroupIndex > 1

The CTE would create a table with the following data, where anything that is a duplicate has a GroupIndexId > 1

  GroupIndex     PersonId     Type     PNumber    
1 A 1 123  
1 A 1 345  
1 A 2 123  
2 A 2 123 ***DELETE 
1 B 1 123  
2 B 1 123 ***DELETE 
3 B 1 123 ***DELETE 
1 B 1 1234  


This method could be used to get the nth item of a group also.


What every DBA that manages a large number of SQL Servers should know about SQL 2008!!

Rating: (not yet rated) Rate this |  Discuss | 5,476 Reads | 253 Reads in Last 30 Days |2 comment(s)

Error when importing RegServer list from SQL 2005 to SQL 2008

I discovered the already known bug in SQL 2008 that you can't import a SQL 2005 server list (exported as a regsrvr file). For someone like me who deals with a large numger of SQL Servers, this is a major issue. Fortunately, Buck Woody has provided a simple solution on his Blog: Importing SQL Server 2005 Registered Servers to SQL Server 2008. This saved me a great deal of time and, more importantly, a great deal of annoyance!!

Thanks Buck!!

My Bug Report

I reloaded my laptop and installed a new installation of SQL 2008 RTM (Dev. Ed.). Previous setup was SQL 2005 SP2. Prior to wiping hard drive, I exported the registered servers to regsrvr files (1 for database engine, 1 for AS, and 1 for IS). I can’t import SQL 2005 regsrvr files into SQL 2008. For me, this is a big hindrance!! Is there a workaround?

When I try to import these files into the SQL 2008 SSMS, I get the following error for all 3 regsrvr files:

Cannot import from C:\Users\v-rodav\Desktop\SQLIS.regsrvr.
The operation 'Import' failed. (Microsoft.SqlServer.Management.RegisteredServers)
Serialization output is invalid. (Microsoft.SqlServer.Management.Sdk.Sfc)
'None' is an invalid XmlNodeType. Line 17, position 10. (System.Xml)

SQL 2008 SSMS Version info:

Microsoft SQL Server Management Studio      10.0.1600.22 ((SQL_PreRelease).080709-1414 )
Microsoft Analysis Services Client Tools      2007.0100.1600.022 ((SQL_PreRelease).080709-1414 )
Microsoft Data Access Components (MDAC)      6.0.6001.18000 (longhorn_rtm.080118-1840)
Microsoft MSXML      3.0 4.0 5.0 6.0
Microsoft Internet Explorer      7.0.6001.18000
Microsoft .NET Framework      2.0.50727.3053
Operating System      6.0.6001


How do I automatically respond to mirrored database failovers?

Rating: (not yet rated) Rate this |  Discuss | 5,879 Reads | 222 Reads in Last 30 Days |no comments

Automatic Failover - an incomplete solution

Automatic failover with Database Mirroring is great, but what about all of the other things that you need to happen when the database fails over? There is no built-in support in Database Mirroring for anything external to the database. This is where automatic activation in the Service Broker comes to the rescue.

Service Broker and Automatic Activation

The Service Broker can be used to automatically activate a stored procedure when certain events occur. The stored procedure would need to process the messages in the Service Broker's queue and respond accordingly. Setting this up requires the following database objects stored externally to the mirrored database:

  1. Stored procedure to process the messages in the queue
  2. Service Broker queue
  3. Service Broker service
  4. A route for the Service Broker service
  5. An Event Notification for the DATABASE_MIRRORING_STATE_CHANGE event

Automatic activation stored procedure

Your stored procedure will need to read from the Service Broker queue and process the messages. The event will be sent as an XML message and will need to be parsed to determine how the database mirroring state has changed. For the following example, the Service Broker queue that I am going to create will be named DBMirrorQueue. This sample code reads the first message in the queue and parses the message. Based ont he parsed message, you will need to decide whether you should take any action.

Declare @Message XML,
    @DBName sysname,
    @MirrorStateChange int,
    @ServerName sysname,
    @PostTime datetime,
    @SPID int,
    @TextData nvarchar(500),
    @DatabaseID int,
    @TransactionsID int,
    @StartTime datetime

/* Receive first unread message in service broker queue */
Receive Top (1) @Message = Cast(message_body as XML)
From DBMirrorQueue;

/* Parse type of state change and database affected */
Set @MirrorStateChange = @Message.value('(/EVENT_INSTANCE/State)[1]', 'int'); -- 7 or 8 = database failed over, 11 = synchronizing, 1 or 2 = synchronized
Set @DBName = @Message.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'sysname');
Set @ServerName = @Message.value('(/EVENT_INSTANCE/ServerName)[1]', 'sysname');
Set @PostTime = @Message.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime');
Set @SPID = @Message.value('(/EVENT_INSTANCE/SPID)[1]', 'int');
Set @TextData = @Message.value('(/EVENT_INSTANCE/TextData)[1]', 'nvarchar(500)');
Set @DatabaseID = @Message.value('(/EVENT_INSTANCE/DatabaseID)[1]', 'int');
Set @TransactionsID = @Message.value('(/EVENT_INSTANCE/TransactionsID)[1]', 'int');
Set @StartTime = @Message.value('(/EVENT_INSTANCE/StartTime)[1]', 'datetime');

Service Broker Queue

Creating a Service Broker queue named DBMirrorQueue:

/* Create Queue if not exists */
If Not Exists (Select 1 From sys.service_queues Where name = 'DBMirrorQueue')
  Begin
    Create Queue DBMirrorQueue
        With Status = On,
        Retention = Off,
        Activation (Procedure_Name = dbo.DBA_MirroringStateChanged,
            Max_Queue_Readers = 1,
            Execute As Self);
  End

Service Broker Service

Creating a Service Broker Service named DBMirrorService on the BMMirrorQueue using the built-in PostEventNotification service type:

/* Create Service if not exists */
If Not Exists (Select 1 From sys.services Where name = 'DBMirrorService')
  Begin
    Create Service DBMirrorService
        On Queue DBMirrorQueue ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
  End

Service Broker Route

Creating a Service Broker route named DBMirrorRoute for the DBMirrorService service:

/* Create Route if not exists */
If Not Exists (Select 1 From sys.routes Where name = 'DBMirrorRoute')
  Begin
    Create Route DBMirrorRoute
        With Service_Name = 'DBMirrorService',
        Address = 'Local';
  End

Event Notification

DATABASE_MIRRORING_STATE_CHANGE is not one of the events that can be automatically trapped. The event is available as a manually created Event Notification.

Creating an event notification named DBMirrorStateChange to raise a notification for the DATABASE_MIRRORING_STATE_CHANGE event:

/* Create Event Notification if not exists */
If Not Exists (Select 1 From sys.server_event_notifications Where name = 'DBMirrorStateChange')
  Begin
    Create Event Notification DBMirrorStateChange
        On Server
        For DATABASE_MIRRORING_STATE_CHANGE
        To Service 'DBMirrorService', 'current database';
  End


How do I .... grant access permissions for SSIS to users?

Rating: (not yet rated) Rate this |  Discuss | 3,700 Reads | 248 Reads in Last 30 Days |no comments
SSIS access permissions are managed via Component Services. It is the DCOM object named MSDTSServer. Here are the steps to follow. 
  1. Component Services -> Computers -> My Computer -> DCOM Config -> MSDTSServer
  2. Right click on MSDTSServer
  3. Click properties
  4. Click on the Security tab
  5. Select Customize and add the users/groups to the Launch/Activation and Access tabs accordingly
  6. Add the user to the local Distributed COM Users group
  7. Restart the SSIS service

 


I've got a date with an Error Log -- Error Logs Part II

Rating: (not yet rated) Rate this |  Discuss | 4,125 Reads | 224 Reads in Last 30 Days |no comments

Error Logs Part II -- Enumerating the error logs

In my first post on SQL Server Error Logs, I briefly mentioned using xp_enumerrorlogs to list the archived error logs. Here I want to demonstrate how to use the procedure to find and output all error logs since a specific date.

xp_enumerrorlogs

This procedure returns 3 columns: Archive #, Date, and Log File Size (Byte). Archive numbering is 0 based with 0 being the currently active log file. As a log file is archived, the number increases; 0 becomes 1, 1 becomes 2, and so on. The output is ordered alphabetically by the Archive #.

 Finding which archive to start with is easy. You just find the newest file that is older than the date for which you are searching. The one catch here, is that if your date is beyond the range of the archives, your query will not find an archive. As a sanity check, if no archive is found beyond the range of my search date, I simply choose the oldest file available.

From there, it's a simple looping process to read in each file starting with the highest archive number and continuing down to 0, the currently active number.

The Script: ErrorLogsSinceDate

Declare @OldestLog datetime,
    @FirstLog int
Declare @ErrorLog Table (LogID int identity(1, 1) not null primary key,
                        LogDate datetime null,
                        ProcessInfo nvarchar(100) null,
                        LogText nvarchar(max) null)
Declare @EnumLogs Table (ArchiveNum int not null primary key,
                        ArcDate Datetime not null,
                        LogFileSize bigint not null)

Set @OldestLog = '12/31/2007'

Insert Into @EnumLogs
Exec master..xp_enumerrorlogs

Select Top 1 @FirstLog = ArchiveNum
From @EnumLogs
Where ArcDate < @OldestLog
Order By ArcDate Desc

If @FirstLog Is Null
  Begin
        Select Top 1 @FirstLog = ArchiveNum
        From @EnumLogs
        Order By ArchiveNum Desc
  End

While @FirstLog >= 0
  Begin
        Insert Into @ErrorLog (LogDate, ProcessInfo, LogText)
        Exec master..xp_readerrorlog @FirstLog

        Set @FirstLog = @FirstLog - 1
  End

Select *
From @ErrorLog
Order By LogID Desc

 


Shhhh!! Be vewy, vewy quiet. I'm hunting Select *!!

Rating: (not yet rated) Rate this |  Discuss | 1,402 Reads | 48 Reads in Last 30 Days |no comments

"Select *" is bad. Everyone knows it, but everyone still uses it. I use it. Most of the time it is fairly innocuous. No harm, no foul, right?

Updating your procedures to not use Select * can be a daunting task. Here's a tip to help you work smarter, not harder. Do less work that is more meaningful.

Shhhh!! Be vewy, vewy quiet. I'm hunting Select *!!


Suggested Reading: Deadlock Notifications in SQL Server 2005

Rating: (not yet rated) Rate this |  Discuss | 2,740 Reads | 127 Reads in Last 30 Days |no comments
Here's a good article on setting up Deadlock Notifications in SQL Server 2005 written by Patrick LeBlanc.

Undocumented use of the Columns_Updated() function

Rating: (not yet rated) Rate this |  Discuss | 2,792 Reads | 148 Reads in Last 30 Days |no comments
Q I need an easy way to see if a delete transaction has fired a trigger. Do you have any ideas for how I can get this information?

Read my answer to this question in the August issue of TechNet Magazine's SQL Q&A column

Who said that breaking up is hard to do?

Rating: (not yet rated) Rate this |  Discuss | 2,013 Reads | 89 Reads in Last 30 Days |no comments

Some of you younger DBA’s out there may not know who Neil Sedaka is or remember his poignant words "Breaking up is hard to do" in the song by the same title. I'm sure we've all gone through a break up at some point. But breaking up isn't necessarily a bad thing, especially when it comes to large or complex queries.

Breaking up can be a good thing. Or so that is the point I try to make in my article Breaking Up is Easy to Do


The War Begins :: Reporting for duty

Rating: (not yet rated) Rate this |  Discuss | 2,915 Reads | 142 Reads in Last 30 Days |no comments

No, I'm not going to keep making corny references to war and being a soldier. But in many ways, we dba's are soldiers in a war against poor performance. Often it can be a struggle to get the information and resources you need, but that doesn't lessen the expectation that we can deliver speedy results.

I hope this first article will help a few people resolve issues a little bit quicker by helping them search their error logs.

SQL Server Error Logs

I intend to follow up this article with a more advaned look at the error logs and how to use it to search for hidden problems before they become public.

More Posts « Previous page