Tuesday 12 January 2016

DBA - An Easy Way to Monitor SQL Server Replication

In SQL Server, replication is a widely adopted technology for the purpose of real-time data replication between SQL servers. It serves the purpose of keeping data consistent between multiple end points. So the last thing we want to hear from clients is that data is no longer in synch, and as DBA, we don't want to be the last person to realize replication is out of order or broken. So here are some steps you can take to monitor SQL Server replication.
This article is written for and tested in SQL Server 2008.
Pre-requisites for setting up SQL Server monitoring
Of course, the monitoring mechanism I am introducing here is merely one of the many ways to monitor replication. Below is what's needed to set up the monitoring jobs:
1.    Database Mail
Make sure your database mail is set up properly and is sending out emails without a problem.
2.    SQL Server Agent up and running
What is used to monitor replication?
I am only using three system tables to monitor the replication latency and condition. They are dynamic management viewsys.dm_os_performance_counters, system msdb..sysjobhistory and msdb..sysjobs. In conjunction with the usage of database mail, we can set up replication monitor in five minutes and get notified whenever replication is out of synch or the replication agent fails on execution due to some unexpected cause.
Step 1: Test database mail functionality
Before we setup SQL Agent job for the replication monitoring, open up SQL Server Management Studio and Navigate down to Database Mail
sqlrep1
Right click on Database Mail then select "Send Test E-Mail"
sqlrep2
sqlrep3
In the "To" column, fill in your email and click Send Test E-Mail. This is to ensure that your database mail is functioning normally. You should get a testing email within minutes.sqlrep4
Now we have confirmed that database mail is working. We can proceed with setting up SQL Agent job to monitor replication.
Step 2: Monitoring job #1 - Latency monitoring
In replication monitoring, I usually like to gauge the performance of replication by checking the latency from publisher to distributor then from distributor to subscriber. The latency from Publisher to Distributor can be found through Performance Monitor's counter "LogReader-Delivery Latency," and the latency from Distributor to Subscriber can be found through PerfMon counter "Dist:Delivery Latency." Below are the pictures when searching both counters.
sqlrep5
LogReader: Delivery Latency
sqlrep6
Dist: Delivery Latency
Starting with SQL 2005, we can directly accessing the LogReader and Distribution delivery latency by querying dynamic management viewsys.dm_os_performance_counters.
To get LogReader Delivery Latency counter value, login into Distributor SQL instance and execute the query below:
select * from sys.dm_os_performance_counters where object_name like '%Replica%'
and counter_name like '%Logreader:%latency%'
For Distributor Delivery Latency counter value, login into Distributor SQL instance and execute the query below:
select *  from sys.dm_os_performance_counters where object_name like '%Replica%'
and counter_name like '%Dist%latency%'
Only the SQL Server instance that acts as replication Distributor will provide useful information for delivery latency.
To set up the first monitoring job, follow the steps below:
1.    Bring up SQL Server Management Studio
2.    Connect to Replication distributor SQL instance
3.    Create a new job, then copy the script below into job step command
4.    Setup the schedule to run the job every 30 minutes or adjust the frequency according to your environment
5.    Update @Tolist and @CClist to the correct email recipients; you can separate the email addresses with a semi-colon (;)
---------------------------------------------------------------------------
--Define monitoring threshold in the scale of minutes
---------------------------------------------------------------------------

declare @minutes int, @threshold int
set @minutes = 30 --> Here is where you define how many minutes latency you would like to be notified
set @threshold = @minutes * 60 * 1000

---------------------------------------------------------------------------
--Specify email distribution list, To and CC
---------------------------------------------------------------------------
declare @Tolist varchar(100)
set @Tolist = 'tiger@companyname123.com'

declare @CClist varchar(100)
set @CClist = 'lion@companyname123.com'

---------------------------------------------------------------------------------------------
--Specify the email subject, @@servername will pick up replication distributor server name
---------------------------------------------------------------------------------------------
declare @mailsubject  varchar(100)
set @mailsubject = @@SERVERNAME + ' Replication Latency'

--select datename(hh,GETDATE())

if exists (
select top 1 1  from sys.dm_os_performance_counters where object_name like '%Replica%'
and counter_name like '%Logreader:%latency%' and cntr_value > @threshold
union
select top 1 1  from sys.dm_os_performance_counters where object_name like '%Replica%'
and counter_name like '%Dist%latency%' and cntr_value > @threshold)
begin

DECLARE @tableHTML  NVARCHAR(MAX) ;

SET @tableHTML =
    N'<H1>'+@@SERVERNAME+' Replication Latency</H1>' +
    N'<table border="1">' +
    N'<tr><th>Object Name</th><th>Counter Name</th>' +
    N'<th>Instance Name</th><th>latency in sec</th>' +
    CAST ( ( SELECT td = object_name,       '',
                    td = counter_name, '',
                    td = instance_name, '',
                    td = latency_sec, ''
             FROM
             (select object_name, counter_name, instance_name, round(cntr_value/1000,0) as latency_sec from sys.dm_os_performance_counters where object_name like '%Replica%'
                and counter_name like '%Logreader:%latency%' and cntr_value > @threshold
        union
          select object_name, counter_name, instance_name, round(cntr_value/1000,0) as latency_sec from sys.dm_os_performance_counters where object_name like '%Replica%'
                and counter_name like '%Dist%latency%' and cntr_value > @threshold) a
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) ) +
    N'</table>' ;

        exec  msdb.dbo.sp_send_dbmail
        @recipients= @Tolist,
        @copy_recipients = @CClist,
        @subject = @mailsubject ,
        @body_format ='HTML',
        @body = @tableHTML

END
Below is the sample email notification you will receive by setting up the above monitoring:
sqlrep7
This monitoring notification will provide the latency in seconds for each agent. You can adjust the threshold of the latency by setting the value for @minutes at the beginning of the above script; instead of "set @minutes = 30" which sets monitoring threshold as 30 minutes, you can reduce it to 5 minutes or increase to 60 minutes.
Step 3: Monitoring job #2 à Agent job status monitoring
Just setting up monitoring on delivery latency is not enough; we also need to make sure that all the agents are running without issue. The job below will help.
---------------------------------------------------------------------------
--How much time you want to trace back on agent failure
--Below example, I am tracing back job failure for current day and past 30 min
---------------------------------------------------------------------------
declare @time time
set @time = dateadd(n,-30,getdate())  -- Here I am setting to trace back only past 30 minutes

declare @date date
set @date = convert(date,getdate())   -- The job failure trace back is defined on current day

---------------------------------------------------------------------------
--Specify the publisher SQL instance name
---------------------------------------------------------------------------
declare @publisher varchar(100)        --
set @publisher = 'PUBLISHER_SERVERNAME'

---------------------------------------------------------------------------
--Specify email distribution list, To and CC
---------------------------------------------------------------------------
declare @Tolist varchar(100)
set @Tolist = 'tiger@companyname123.com'

declare @CClist varchar(100)
set @CClist = 'lion@companyname123.com'

---------------------------------------------------------------------------------------------
--Specify the email subject, @@servername will pick up replication distributor server name
---------------------------------------------------------------------------------------------
declare @mailsubject  varchar(100)
set @mailsubject = @@SERVERNAME + ' Replication failure'

if exists (
select distinct b.name,a.run_date, right('00000'+convert(varchar,a.run_time),6),message from msdb..sysjobhistory a inner join msdb..sysjobs b on a.job_id = b.job_id
where b.name like @publisher+'%' and run_status <> 1 and message like '%error%'
and convert(date,convert(varchar,a.run_date ))= @date
and right('00000'+convert(varchar,a.run_time),6)  > replace(convert(varchar(8),@time),':','')
)
begin

DECLARE @tableHTML  NVARCHAR(MAX) ;

SET @tableHTML =
    N'<H1>'+@@SERVERNAME+' Replication Agent Failed</H1>' +
    N'<table border="1">' +
    N'<tr><th>Job Name</th><th>Run Date</th>' +
    N'<th>Run Time</th><th>Failure Message</th>' +
    CAST ( ( SELECT td = name,       '',
                    td = run_date, '',
                    td = run_time, '',
                    td = message, ''
             FROM
             (select name, MAX(run_date) as run_date, MAX(run_time) as run_time, message from
                (select distinct b.name,a.run_date, run_time = right('00000'+convert(varchar,a.run_time),6),message from msdb..sysjobhistory a inner join msdb..sysjobs b on a.job_id = b.job_id
                where b.name like @publisher+'%' and run_status <> 1 and message like '%error%'
                and convert(date,convert(varchar,a.run_date ))= @date
                and right('00000'+convert(varchar,a.run_time),6)  > replace(convert(varchar(8),@time),':','') ) a
                group by name, message
                ) a
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) ) +
    N'</table>' ;

        exec  msdb.dbo.sp_send_dbmail
        @recipients= @Tolist,
        @copy_recipients = @CClist,
        @subject = @mailsubject ,
        @body_format ='HTML',
        @body = @tableHTML

end
Below is the sample notification content for monitoring the replication agent status
sqlrep8

You can set the monitoring to run every 30 minutes to check if any agent failed to run. If you have one distributor server that services for multiple publishing servers, you will want to set up one job per each publishing server and update "set @publisher = 'PUBLISHER_SERVERNAME'" to the respective publishing server name.
Conclusion
Replication monitoring can go way beyond the above setting, but if you are looking for something that's quick and easy to set up, I believe these two monitoring will serve the purpose just fine.

Thursday 7 January 2016

SSIS - Options to deploy a package in SSIS (2008)

Introduction

In this article we are going to see on how to deploy a SSIS package once we are done with developing, building and executing the package. Deploying an application is something which we need to take care since it performs based on the requirement like when the package should execute, who should execute the package etc. We have 3 options available with deploying a SSIS package and the options are as follows
1.       Deployment Utility
2.       Command line Executable
3.       SQL Server Management Studio
We will see on each approach and the steps involved in deploying the package. You can refer to my previous articles on SSIS to get some idea before going ahead with this article. The URL’s for those articles can be viewed at the below URL

Type

Type 1 : Deployment Utility
This approach is used to create an installer for the package and can be execute at the place where ever it’s required. This Utility is available by default to all the Integration projects; we will see the steps to make use of this utility.
Steps:
Go to BIDS (Check my previous articles on how to go to BIDS) and open the package solution which you want to deploy and right click on the project and go to properties as shown in the below figure.
A dialog will open where you have the option as Deployment Utility. Clicking on that will show the options at the right side of the dialog box where we need to set the CreateDeploymentUtility to TRUE and give the path where the installer need to be created as shown in the below screen
Once we are done, now right click on the project and give BUILD it will show the result at the bottom of the page if the build is succeeded or failed. If it’s succeeded it will create the deployment installer as shown in the below screen. You can copy these files to any location and double click to make use of it

Type 2: Command Line Executable
Microsoft has provided an Executable DTUTIL.EXE that can be used to deploy SSIS packages. This command like utility is a good option to script the package. We can use this executable directly or can make use of it in the batch file.
To execute it at the command prompt check the below script. Go to the path of the package and execute the below scripts.
DTUTIL /FILE Package1.dtsx
       /COPY
       SQL;SSISPackage1

In order to deploy the package at the file system level then go with the below script
DTUTIL /FILE Package1.dtsx
       /COPY
       FILE;C:\SSIS\SSISPackage1.dtsx

For more option on this utility check the below url

Type 3: SQL Server Management Studio
This approach required integration services to be connected and must be in running mode in order to use this deployment option. In the object browser you can see something like below
To deploy our package right click on the File system and select the Import Package from the menu. Fill the details as shown in the below screen
Clicking on OK will deploy the package

Conclusion

This article describes on the options available to deploy the SSIS packages.

SSIS - Options to execute a package in SSIS

Introduction

In this article we will see on how to deploy a package once we are done with creating and building the package.

Type :

Once a package is created and build it successfully, we have 3 options to make a deployment. We will look into each approach with an example.

Type 1:

DTEXEC command line utility
SQL Server provides a command line utility (DTEXEC.EXE) that helps the developers to execute the SSIS package. It can be directly used from the command prompt by moving around to the folder where the package is available and executing making use of this EXE.
DTEXEC /? Provides the list of available options to execute the package from the command prompt as shown in the below screen
So to execute the package go to that folder where the package is available and provide the syntax as shown in the below screen
This is the result once we execute a package in SSIS Command line utility. This example shows an error that package is not executed properly and it has some errors which need to be fixed.
For more details on DTEXEC utility refer to the below msdn article
Type 2:
SSIS Package Windows Application
This approach is straight forward a user interface option to execute the package. Microsoft has provided a user interface or we can say a tool kind of option to execute the SSIS packages. DTEXECUI.EXE is the User interface exe which performs the task of executing the package.
We can launch DTEXECUI.EXE by double clicking on the package itself directly (i.e. go to project folder and double click on *.dtsx file). It will open the graphical user interface as shown below.
As we can see there are many options available in order to execute the package based on our needs. If we want to follow the standard format then directly clicking on EXECUTE button at the bottom will do the task. We can navigate through each option and customize the package based on our needs.
You can have a look at the msdn article on DTEXECUI.EXE utility at the below url
Type 3:
SQL Server Agent Scheduling
The last and the final approach to execute the SSIS packages are the SQL Server Integration services Job step type which helps to schedule the package and execute it based on our needs. This is one of the easiest approaches since we have the UI to schedule the package and execute it without any user interactions.
In order to do these approaches go to SQL Server Management Studio à Connect to the Database using the credentials àopen object explorer and go to JOBS à Select New Job and fill the details based on our needs


Conclusion

In this article we have seen the different options to execute the SSIS packages. We will look into the deployment options in the upcoming articles.

Wednesday 6 January 2016

DBA - Database cannot be opened due to inaccessible files or insufficient memory or disk space

Msg 945, Level 14, State 2, Line 1
Database 'db' cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server errorlog for details. 


One of my friends called me that their application is giving error message of disk space , and i asked him to increase the space of drive. later he responded me that he shrinked the files and space has been raised to 150 GB, but the error is still there.
I asked him to access the Database through management studio
When he tried to access the database, through a query or by trying to look at the database properties in Management Studio, he got the following message:

Database 'db' cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server errorlog for details. 


Here is Solution/Fix/workaround of this problem.

1. check the DB status, most of the time , it will return 1

use master
select databaseproperty('dbname','isShutdown')

2. Change the database to offline to clear the db status 

use master
alter database
 dbname set offline

3. Now change the database to online, at this step log file and data files will be verified by sql server


use master
alter database dbname set online


This solution solved the problem.

Replication - Cannot execute as the database principal because the principal "dbo" does not exist

Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission

I got this error during SQL Server Transaction Replication.
Solution:

            Expand Object explorer, Right click on Database, Select Properties, and click on Files



Provide the owner of database

Sunday 3 January 2016

SSRS - Loading and Using A SQL Server Database Image

This blog entry discusses how to add an image to SQL Server for storage within the database, followed by how to use it in SSRS.
When including an image within a SQL Server Reporting Services report, you have 3 options:
  1. Embedded.  The image is embedded within the report.  This is my least favorite choice, as it’s not easily reusable and maintenance of a change would be a big headache if very many reports existed with individual embedded images.
  2. External.  The image is loaded to the Report Project and may be reused among multiple SSRS reports.  This approach was discussed in this ImagePaths in SSRS entry.  
  3. Database.  The image is loaded to a SQL Server database and, like option 2, may be reused among multiple SSRS reports.  Because it’s stored in the database, it can be used for many other types of solutions as well.  This is the most flexible of the 3 options - and the topic of the rest of this entry.

Using OPENROWSET to Insert Image Into Table

1.  First, let’s create a table in SQL Server Management Studio to hold the image file.
CREATE TABLE dbo.Images
(
      [ImageID] [int] IDENTITY(1,1) NOT NULL,
      [ImageName] [varchar](40) NOT NULL,
      [OriginalFormat] [nvarchar](5) NOT NULL, 
      [ImageFile] [varbinary](max) NOT NULL
 )    
Note that the data type we’re using for the image is varbinary(max) instead of the image data type.  That’s because the image data type is being removed in a future version of SQL Server.
2.  Right-click this dog image and save it to your c:\ drive as “MyImage.png”.
  
3.  Now let’s insert the dog image into the database table we created in step 1.
INSERT INTO dbo.Images
(
       ImageName
      ,OriginalFormat
      ,ImageFile
)
SELECT
      'Sample Image'
      ,'png'
      ,ImageFile
FROM OPENROWSET(BULK N'C:\MyImage.png', SINGLE_BLOB) AS ImageSource(ImageFile);
That’s it!  Now you’re ready to use it.  I like to include an “Original Format” field so that I can easily remember what to set for the MIME type in SSRS.

SSRS Image Properties

In this section we’ll discuss how to use the database image in SSRS.
1.  First, create a dataset within your report which contains the following query.  I’m calling my dataset “HeaderImage.”
SELECT ImageFile
FROM dbo.Images
2.  From the Toolbox, drag an Image Report Item onto the body of the report.  Configure it as follows:
Select the image source:  Database
Use this field:  =First(Fields!ImageFile.Value, “HeaderImage”)
Use this MIME type:  image/png    (this is the MIME type & subtype, which classifies file types on the web for consistent handling between browsers & O/S)


And voila, you have a drooling puppy on your report - just what you've always wanted! 

Saturday 2 January 2016

SSRS - Drillthrough report in SSRS Step by Step

Drillthrough report in SSRS

A Drillthrough is a kind of report that a user opens by clicking a link within another report. Drillthrough reports commonly contain details about an item that is contained in an original summary report. The data in the drillthrough report is not retrieved until the user clicks the link in the main report.

Here I am showing you how to create Drillthrough Report.
For this I am creating two Report  i.e. Parent and Child Report.

Here is an example from  AdventureWorks Database for Parent Report.




SQL Scripts
SELECT        CustomerID, ContactID, Demographics, ModifiedDate
FROM            Sales.Individual

Now insert a table and  Format the column


And Now create a Child Report
Here I am also using  AdventureWorks Database for Child Report.




SQL Scripts
SELECT        CustomerID, ContactID, Demographics, ModifiedDate
FROM            Sales.Individual
WHERE        (CustomerID = @CustID)

Here I am creating a Parameter Custid.

Here both report created and now its time to map the parent report to child report. For this
We go to the parent report [CustomerID] column.

Right click on [CustomerID] column and choose Text Box Properties


Go to Action tab and map these:


Then Click on OK.

And now run the report. Below the preview of Drillthrough report.



SSRS - Alternating Table Row Color In SSRS Step by Step

Alternating Table Row Color  In SSRS Step by Step

Here is an example from AdventureWorks Database.


Sql Script.

SELECT TOP 1000 [StateProvinceID]
      ,[StateProvinceCode]
      ,[CountryRegionCode]
      ,[Name]
      ,[rowguid]
      ,[ModifiedDate]
  FROM [AdventureWorks].[Person].[StateProvince]

Select the Header Row of the table in the report.
Go to Properties Window.
 Under the BackgroundColor property, Select color from drop down.

Now, Select the Data Row of the table in the report.
Go to Properties Window.

Under the BackgroundColor property, select expression from the drop down.
Enter the expression "=IIF(RowNumber(Nothing) mod 2 = 0, "SeaGreen","Pink") " in the Expression Window.
Click OK.
Below is a Preview of a SSRS report with two different colors for alternate rows.


SSRS - Create SSRS report using Excel Data Source Step by Step

By creating a report using Excel as a Data Source we will follow the following steps ...



Right click on Shared Data Source folder and choose Add New Data Source. A new popup screen will open. Give the Data Source Name and Choose ODBC from the dropdown box.


Then Click on Edit button. A new screen will open. From the new screen i.e. Connection Properties go to the Use user or system data source name and from the drop down choose Excel Files .




Then Choose the Use Connection String and click on Build button. A new pop up screen will open . Click on New button.






Then click on Next button



Choose the Microsoft Excel Driver and click on Next button and then click on Finish button.



Then click on Select Workbook button and choose the file and click on OK button.





Click on OK




Test the connection and press OK.







Click on OK.
Click on Reports folder and choose add new items and choose Report. Map your Data Source and click OK.



Right click on Dataset Folder and Write the query for the table. (I have used a very simple query .For ex.)



This is Your Report from Excel data source.