21 April 2015

Mirroring with Replication in SQL Server

In SQL server environment, we can configure combination of HA features. Like Mirroring with log-shipping or Mirroring with Replication.

If you go through with below scenario you can understanding very well.


Setup
If you followed the link above, BOL provides a basic listing of the order to setup mirroring with replication.
  1. Configure the Publisher.
  2. Configure database mirroring.
  3. Configure the mirror to use the same Distributor as the principal.
  4. Configure replication agents for failover.
  5. Add the principal and mirror to Replication Monitor.
We will follow these steps while adding in a few catches and added details that need to be configured to ensure processing flows while not in a failover situation and after a failover situation.
Mirroring and Replication Landscape
In the end, the solution shown in the following diagram will be achieved.
From the above diagram, you can see that three servers are involved. Server A acts as the principal as well as the publisher.
  • Principal: The primary server in mirroring
  • Mirror: The secondary server in mirroring
  • Publisher: The primary source of replication
  • Subscriber: The subscription to the published data in replication
To follow the setup order, the first task is to setup the publisher in transactional replication. This server also acts as the principal in mirroring (which will be setup later).

17 April 2015

SQL express schedule backup


USE [master]
GO
/****** Object:  StoredProcedure [dbo].[sp_BackupDatabases] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

create PROCEDURE [dbo].[sp_BackupDatabases]  
            @databaseName sysname = null,
            @backupType CHAR(1),
            @backupLocation nvarchar(200)
AS

       SET NOCOUNT ON;
           
            DECLARE @DBs TABLE
            (
                  ID int IDENTITY PRIMARY KEY,
                  DBNAME nvarchar(500)
            )
           
             -- Pick out only databases which are online in case ALL databases are chosen to be backed up
             -- If specific database is chosen to be backed up only pick that out from @DBs
            INSERT INTO @DBs (DBNAME)
            SELECT Name FROM master.sys.databases
            where state=0
            AND name=@DatabaseName
            OR @DatabaseName IS NULL
            ORDER BY Name
           
            -- Filter out databases which do not need to backed up
            IF @backupType='F'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','AdventureWorks')
                  END
            ELSE IF @backupType='D'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','master','model','msdb','AdventureWorks')
                  END
            ELSE IF @backupType='L'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','master','model','msdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB','AdventureWorks')
                  END
            ELSE
                  BEGIN
                  RETURN
                  END
           
            -- Declare variables
            DECLARE @BackupName varchar(100)
            DECLARE @BackupFile varchar(100)
            DECLARE @DBNAME varchar(300)
            DECLARE @sqlCommand NVARCHAR(1000)
        DECLARE @dateTime NVARCHAR(20)
            DECLARE @Loop int                  
                       
            -- Loop through the databases one by one
            SELECT @Loop = min(ID) FROM @DBs

      WHILE @Loop IS NOT NULL
      BEGIN

-- Database Names have to be in [dbname] format since some have - or _ in their name
      SET @DBNAME = '['+(SELECT DBNAME FROM @DBs WHERE ID = @Loop)+']'

-- Set the current date and time n yyyyhhmmss format
      SET @dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),101),'/','') + '_' +  REPLACE(CONVERT(VARCHAR, GETDATE(),108),':','')  

-- Create backup filename in path\filename.extension format for full,diff and log backups
      IF @backupType = 'F'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_FULL_'+ @dateTime+ '.BAK'
      ELSE IF @backupType = 'D'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_DIFF_'+ @dateTime+ '.BAK'
      ELSE IF @backupType = 'L'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_LOG_'+ @dateTime+ '.TRN'

-- Provide the backup a name for storing in the media
      IF @backupType = 'F'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' full backup for '+ @dateTime
      IF @backupType = 'D'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' differential backup for '+ @dateTime
      IF @backupType = 'L'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' log backup for '+ @dateTime

-- Generate the dynamic SQL command to be executed

       IF @backupType = 'F'
                  BEGIN
               SET @sqlCommand = 'BACKUP DATABASE ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'
                  END
       IF @backupType = 'D'
                  BEGIN
               SET @sqlCommand = 'BACKUP DATABASE ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH DIFFERENTIAL, INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'        
                  END
       IF @backupType = 'L'
                  BEGIN
               SET @sqlCommand = 'BACKUP LOG ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'        
                  END

-- Execute the generated SQL command
       EXEC(@sqlCommand)

-- Goto the next database
SELECT @Loop = min(ID) FROM @DBs where ID>@Loop

END

GO

use master

--====================================================================
--usage: usp_DeleteOldBackupFiles <path>, <file extention>, <age_hours>
--i.e. usp_DeleteOldBackupFiles 'D:\MSSQL_DBBackups', 'bak', 36
--usp_DeleteOldBackupFiles 'D:\MSSQL_DBBackupsLogs', 'trn', 72
--====================================================================
GO

Create PROCEDURE [dbo].[usp_DeleteOldBackupFiles]
@path nvarchar(256),
@extention nvarchar(10),
@age_hrs int
AS
BEGIN
SET NOCOUNT ON;

DECLARE @DeleteDate nvarchar(50)
DECLARE @DeleteDateTime datetime

SET @DeleteDateTime = DateAdd(hh, -@age_hrs, GetDate())

SET @DeleteDate = (Select Replace(Convert(nvarchar, @DeleteDateTime, 111), '/', '-') + 'T' + Convert(nvarchar, @DeleteDateTime, 108))

EXECUTE master.dbo.xp_delete_file 0, @path, @extention, @DeleteDate, 1
END
--============================
-- xp_delete_file information
--============================
-- xp_delete_file actually checks the file header to see what type of file it is and will only delete certain types such
-- as database and log backups. I suppose they expanded this to certain types of log files as well but as you say this is
-- not documented by MS. Just be aware that it will not delete just any file type

-- First argument is:
-- 0 - specifies a backup file
-- 1 - specifies a report file
-- (I'm not sure what the difference between a "backup file" and a "report file" is, since you specify the extension of files
-- you're deleting with the third argument.)
--
-- Fifth argument is whether to delete recursively.
-- 0 - don't delete recursively (default)
-- 1 - delete files in sub directories
--====================================================================


-- By Shivasagar V

16 April 2015

Error message when you execute a linked server query in SQL Server: "Timeout Expired"

Hi Viewers, In our production environment today we received following error.

Server: Msg 7399, Level 16, State 1, Line 1 OLE DB provider 'SQLOLEDB' reported an error. Execution terminated by the provider because a resource limit was reached. [OLE/DB provider returned message: Timeout expired] OLE DB error trace [OLE/DB Provider 'SQLOLEDB' ICommandText::Execute returned 0x80040e31: Execution terminated by the provider because a resource limit was reached.].

Actually this error message received in one of the job history. Inside of the job is having the statements which will run the update or DML operation on one of the Linked server. There we got the error.

We tried a lot and finally we got the following KB article workarounds. It was very helpful.

Solution:
http://support.microsoft.com/en-us/kb/314530


-- By Shivasagar V

How to restore the missing Windows Installer cache files and resolve problems that occur during a SQL Server update

Today I have received this error while installing SQL service pack. This error usually comes due to missing windows installer cache files. Some of my windows team people are removed soome cache files due to space issue in C: drive. 

I have followed the workarounds which are there in below KB article. Now issue has been resolved. Thanks to microsoft KB article.

Solution: http://support.microsoft.com/en-us/kb/969052#Script

-- By Shivasagar V

Reducing or Minimizing Deadlocks

Anyway deadlocks cannot be avoid completely, following steps are useful to minimize the chance of generating a deadlock. If deadlocks are less automatically increase transaction throughput and reduce system overhead.
Small transactions are

  • Rolled back, undoing all the work performed by the transaction.
  • Resubmitted by applications because they were rolled back when deadlocked.

Steps to reducing deadlocks:

  1. Access the objects in the same order
  2. Avoid user interaction with in the transactions
  3. Always keep transactions are short and in one batch
  4. Better to use a lower isolation level.
  5. Use snapshot isolation.
  6. Use bound connections.
  7. Better to use a row versioning-type isolation level
  8. Set READ_COMMITTED_SNAPSHOT database option ON to enable read-committed transactions to use row versioning.
-- By Shivasagar V

Trace flag 1118

TRACE FLAG -1118:

Trace flag 1118 forcefully guides SQL server engine to allocates uniform extent instead of mixed page allocations. The trace flag is generally used to support in TEMPDB scalability by avoiding SGAM and other allocation contention points.

SQL Server 2008 has optimized mixed extent allocation behaviour. so that it is reducing the need for trace flag 1118 and the contention on SGAM(s).   The same logic was also added to SQL Server 2005 in cumulative update and KB article 936185.

If you have SQL Server 2008 or SQL Server 2005 and the fix applied and are still encountering TEMPDB contention consider trace flag 1118 for resolving the contention.


-- By Shivasagar V

Trace flags 1024 and 1222


Hi Viewers, this post is regards getting deadlock information/details into error logs.

Trace flag 1204
Returns the resources and types of locks participating in a deadlock and also the current command affected.
Scope: global only

Trace flag 1222
Returns the resources and types of locks that are participating in a deadlock and also the current command affected, in an XML format that does not comply with any XSD schema.
Scope: global only

--By Shivasagar V

DBCC CHECKDB

Hi viewers, today I am going to provide some clarification about DBCC CHECKDB.

Generally DBA's are using this command to check the database health check.

DBCC CHECKDB:

Runs DBCC CHECKALLOC on the database.
Runs DBCC CHECKTABLE on every table and view in the database.
Runs DBCC CHECKCATALOG on the database.
Validates the contents of every indexed view in the database.
Validates link-level consistency between table metadata and file system directories and files when storing varbinary(max) data in the file system using FILESTREAM.
Validates the Service Broker data in the database.

REPAIR_ALLOW_DATA_LOSS:
Tries to repair all reported errors. These repairs can cause some data loss.

REPAIR_FAST:
Maintains syntax for backward compatibility only. No repair actions are performed.

REPAIR_REBUILD:
REPAIR_REBUILD does not repair errors involving FILESTREAM data

-- by Shivasagar V

15 April 2015

Resource database location in SQL Server 2000 or 2005 or 2008 or 2008R2 or 2012

Hi, This time I am going to post about resource file location. Actually today I am trying  to take backup of Resource database backup on my production environment. Finally I have used below commands and I have received beautiful output.

The below script is very much helpful to find the physical location of the Resource database.

By default the Resource database id is 32767. So using this ID we can get location of the database very easily.

Use master
GO
select 'ResourceDB' AS 'Database Name'
    , NAME AS [Database File]
    , FILENAME AS [DB file Location] 
from sys.sysaltfiles 
    where dbid = 32767
GO


--- 
By Shivasagar V

5 April 2015

Error message when you execute a linked server query in SQL Server: "Timeout Expired"

You may see either one of the following error messages when you execute a linked server 

query:
Server: Msg 7399, Level 16, State 1, Line 1 OLE DB provider 'SQLOLEDB' reported an error. [OLE/DB provider returned Timeout expired]
-or-
Server: Msg 7399, Level 16, State 1, Line 1 OLE DB provider 'SQLOLEDB' reported an error. Execution terminated by the provider because a resource limit was reached. [OLE/DB provider returned message: Timeout expired]
Error 7399 is a generic error message that the provider returns, which indicates there is some sort of problem. You must use trace flag 7300 to get a more detailed and useful error message from the provider. The output from trace flag 7300 can help you to determine if this article covers the specific 7399 error message that you receive.

If you execute a DBCC TRACEON (7300, 3604) statement, and you then execute the query, you may see additional information in the error message; however, whether or not you see more information depends on the provider you use. For example:

Server: Msg 7399, Level 16, State 1, Line 1 OLE DB provider 'SQLOLEDB' reported an error. [OLE/DB provider returned message: Timeout expired] OLE DB error trace [OLE/DB Provider 'SQLOLEDB' IDBInitialize::Initialize returned 0x80004005: ].
-or-
Server: Msg 7399, Level 16, State 1, Line 1 OLE DB provider 'SQLOLEDB' reported an error. Execution terminated by the provider because a resource limit was reached. [OLE/DB provider returned message: Timeout expired] OLE DB error trace [OLE/DB Provider 'SQLOLEDB' ICommandText::Execute returned 0x80040e31: Execution terminated by the provider because a resource limit was reached.].

Solutions:

To work around this, you can reconfigure the timeout setting.

Based on which type of error you encounter, you can reconfigure the timeout setting as follows:

  • Set the remote login timeout to 30 seconds, by using this code:
    sp_configure 'remote login timeout', 30
    go 
    reconfigure with override 
    go 
         
  • Set the remote query timeout to 0 (infinite wait), by using this code:
    sp_configure 'remote query timeout', 0 
    go 
    reconfigure with override 
    go 

For more information about the remote login timeout setting and where IDBInitialize::Initialize is called, refer to the "Connecting to an OLE DB Provider" topic in MSDN or the Microsoft SQL Server 7.0 Resource Guide in the BackOffice Resource Kit.

You may also refer to the following topics in MSDN for a description of how the query processor interacts with an OLE DB provider to enable distributed and heterogeneous queries:

  • Microsoft SQL Server 2000 Distributed Queries: OLE DB Connectivity
  • Basic OLE DB

For more information please refer microsoft KB article.

1 April 2015

Identify which SQL Server instance utilizing most of the CPU



Steps to identify the SQL Server instance utilizing most of the CPU

Step 1:- First launch Windows Task Manager to find out the CPU utilization for your database server. Below is screenshot of the Task Manager at the time of the issue I experienced. You can see all three instances have the same executable i.e. 'sqlservr.exe' and also you can see 76% of the CPU is being utilized by the first sqlservr.exe process.
Windows Task Manager to see CPU usage
Based on reviewing Windows Task Manager, one immediate option to determine which SQL Server instance is using all of the CPU is to run each SQL Server instances with a different domain account.  For example, "Domain\SQLDev" for the development environment, "Domain\SQLTest" for the test environment, etc.  Unfortunately, in my circumstance all of the SQL Server instances were running under same domain account. In the image above the accounts have been erased, but they would be found in the fourth column i.e. "User Name". 
Step 2:- Now we will add the PID (Process Identifier) column in Windows Task Manager to in order to find out the PID for each process.  The PID is the Windows Operating System Process Identifier assigned to each process running on the machine. In order to enable this column, ensure the "Processes" tab is active then click on the "View" menu, then choose the "Select Columns..." option.  Once on the "Select Process Page Columns" screen click the check box for the option PID and then press the "OK" button to return to the Processes tab of Windows Task Manager.
Add PID column in Windows Task Manager
Step 3:- Now you can see the PID for the 'sqlservr.exe' process which is utilizing most of the CPU. In our example, the PID of this SQL Server instance is 2352.
Task Manager with PID value for SQL Server
Now our next step is to determine which SQL Server instance is running this PID. We have two methods to get this information. First, is the SQL Server configuration manager and second method is the SQL Server error log.
From SQL Server 2005 onwards, it is very easy to find the PID for the SQL Server instances using the SQL Server Configuration manager.  However, with SQL Server 2000 and earlier, it is not as straight forward.  We will proceed with the assumption that community members are using SQL Server 2005 and beyond.

Step 4:- Whenever we start a SQL Server instance, a PID which is also know as the "Server process ID" is assigned to that instance and this information is logged in the SQL Server error log. You can see an example of this in the screenshot below.  The "Server process ID" is normally one of the first entries in the log.
 SQL Server error log to determine the PID for the SQL Server processes
Step 5:-Another option is identify the correct PID for your SQL Server Instance is by using the SQL Server configuration manager. This can be accomplished by launching the  SQL Server Configuration Manager and clicking on the "SQL Server Services" option in the left pane. On right side of this interface, you can see the Process ID values associated with the SQL Server services.
Use SQL Server Configuration Manager to determine the PID per SQL Server instance
By correlating the information from Windows Task Manager and the SQL Server Error Log\SQL Server Configuration Manager you can correctly determine the SQL Server instance which is utilizing most of the CPU.  At this point you can review the SQL Server processes on the aforementioned instance to determine the culprit process(es) which are causing CPU pressure.

-- Shivasagar V

Connect SQL Server from the command prompt

How can we connect SQL server from the command prompt ?

Hi we can also connect SQL Server from the command prompt also. Using this feature is very helpful in some scenarios. Please go through with the below guidelines.





















I hope this is very helpful for you. for more information give me a comment I will explain you clearly.

--  Shivasagar v