Backup Status Report in SQL Server via Email

 Set nocount ON

Declare @DBName Varchar (500), @dbIs SQL_Variant, @dbStatus SQL_Variant,@replicaid Varchar(500)

Declare @cmd Varchar (1000),@profile_name Varchar(1000), @description Varchar (500)


If  OBJECT_ID('tempdb..#DBBackup') is not NULL

     Drop table tempdb..#DBBackup


If  OBJECT_ID('tempdb..#DBBackup') is not NULL

     Drop table tempdb..#FullBackup


If  OBJECT_ID('tempdb..#DBBackup') is not NULL

     Drop table tempdb..#DiffBackup


If  OBJECT_ID('tempdb..#Log') is not NULL

     Drop table tempdb..#Log

     


Create Table #DBBackup (Server varchar(500),DB varchar(1000),Full_Backup_Status varchar(1000),Diff_Backup_Status varchar(1000), Log_Backup_Status varchar(1000))

Create Table #FullBackup (Server varchar(500),DB varchar(1000),Full_Last_Backup Datetime,Time_Since_Minute int,Backup_Size numeric,Compressed_Backup_Size Numeric)

Create Table #DiffBackup (Server varchar(500),DB varchar(1000),Diff_Last_Backup Datetime,Time_Since_Minute int,Backup_Size numeric,Compressed_Backup_Size Numeric)

Create Table #Log (Server varchar(500),DB varchar(1000),Log_Last_Backup Datetime,Time_Since_Minute int,Backup_Size numeric,Compressed_Backup_Size Numeric)

DECLARE @xml NVARCHAR(MAX)

DECLARE @body NVARCHAR(MAX)


Declare cur CURSOR for Select Name from sys.databases where name not in ('tempdb') and state_desc='ONLINE' and recovery_model_desc='FULL'  order by Name

Open cur

fetch next from cur into @DBName

while @@fetch_status=0

     Begin

Select @dbIs=Databasepropertyex (@DBName,'Updateability'),@dbStatus=Databasepropertyex (@DBName,'Status')

Select @replicaid=replica_id from sys.databases where name=@DBName

Set @description= ''

SELECT @description =  hars.role_desc

FROM sys.DATABASES d

INNER JOIN sys.dm_hadr_availability_replica_states hars ON d.replica_id = hars.replica_id

WHERE database_id = DB_ID(@DBName)

   

    if (@description<>'SECONDARY' and @dbIs='READ_WRITE')

    Begin

    insert into #DBBackup Select Upper(@@SERVERNAME) "Server", Upper(@DBName) "Database", '','',''

    End  

fetch next from cur into @DBName

  End

Close Cur

Deallocate Cur


--Full backup Status--

If Datename(weekday,(getdate()))='Monday'

   Begin

insert into #FullBackup

SELECT @@Servername 'Server', Database_Name, 

CONVERT( SmallDateTime , MAX(Backup_Finish_Date)) as Full_Last_Backup, 

DATEDIFF(d, MAX(Backup_Finish_Date), Getdate()) as Days_Since_Last,(Backup_Size/1048576) AS Backup_Size ,(Compressed_Backup_Size/1048576) AS Compressed_Backup_Size

FROM MSDB.dbo.BackupSet

WHERE Type = 'd'  and is_copy_only=0

GROUP BY Database_Name,backup_size,compressed_backup_size

Having  DATEDIFF(MINUTE, MAX(Backup_Finish_Date), Getdate()) <360

order by 2 

  End

else

   Begin

insert into #FullBackup

SELECT @@Servername 'Server', Database_Name, 

CONVERT( SmallDateTime , MAX(Backup_Finish_Date)) as Full_Last_Backup, 

DATEDIFF(d, MAX(Backup_Finish_Date), Getdate()) as Days_Since_Last,(Backup_Size/1048576) AS Backup_Size ,(Compressed_Backup_Size/1048576) AS Compressed_Backup_Size

FROM MSDB.dbo.BackupSet

WHERE Type = 'd'  and is_copy_only=0

GROUP BY Database_Name,backup_size,compressed_backup_size

Having  DATEDIFF(Day, MAX(Backup_Finish_Date), Getdate()) <8

order by 2 

End

Update #DBBackup

Set Full_Backup_Status='**Need to backup verify**'

where  DB not in (Select DB from #FullBackup)


Update #DBBackup

Set Full_Backup_Status='Completed'

where Full_Backup_Status<>'**Need to backup verify**'


--Select * from #DBBackup


--Diff Backup Satatus -----

If Datename(weekday,(getdate()))='Monday'

   Begin

insert into #DiffBackup

SELECT @@Servername 'Server', Database_Name, 

CONVERT( SmallDateTime , MAX(Backup_Finish_Date)) as Full_Last_Backup, 

DATEDIFF(d, MAX(Backup_Finish_Date), Getdate()) as Days_Since_Last,(Backup_Size/1048576) AS Backup_Size ,(Compressed_Backup_Size/1048576) AS Compressed_Backup_Size

FROM MSDB.dbo.BackupSet

WHERE Type = 'I' 

GROUP BY Database_Name,backup_size,compressed_backup_size

Having  DATEDIFF(DAY, MAX(Backup_Finish_Date), Getdate()) <3

order by 2 

    End

 Else

     Begin   

    insert into #DiffBackup

SELECT @@Servername 'Server', Database_Name, 

CONVERT( SmallDateTime , MAX(Backup_Finish_Date)) as Full_Last_Backup, 

DATEDIFF(d, MAX(Backup_Finish_Date), Getdate()) as Days_Since_Last,(Backup_Size/1048576) AS Backup_Size ,(Compressed_Backup_Size/1048576) AS Compressed_Backup_Size

FROM MSDB.dbo.BackupSet

WHERE Type = 'I' 

GROUP BY Database_Name,backup_size,compressed_backup_size

Having  DATEDIFF(MINUTE, MAX(Backup_Finish_Date), Getdate()) <180

order by 2 

      End



Update #DBBackup

Set Diff_Backup_Status='**Need to backup verify**'

where  DB not in (Select DB from #DiffBackup)


Update #DBBackup

Set Diff_Backup_Status='Completed'

where Diff_Backup_Status<>'**Need to backup verify**'



SET @xml = CAST(( SELECT DB.Server As 'td',' ',DB.DB AS 'td' ,'' ,DB.Full_Backup_Status as 'td' ,'',convert(varchar(20),F.Full_Last_Backup,120) as 'td','',

Diff_Backup_Status as 'td','',convert(varchar(20),D.Diff_Last_Backup,120) as td 

from #DBBackup DB Left Outer join #FullBackup F on DB.DB=F.DB  Left outer join #DiffBackup D on DB.DB=D.DB

                    FOR XML PATH('tr'), ELEMENTS ) AS NVARCHAR(MAX))


SET @body ='<html><body><H3> Database Backup status </H3>

<table border = 1> 

<tr>

<th> Server Name </th> <th> Database Name </th> <th> Full_Backup_Status </th> <th> Full_Last_Backup </th><th> Differential_Backup_Status </th><th> Differential_Last_Backup</th> </tr>'    

 --<td bgcolor=#F0E68C><b>FreeSpace(%)<b> </td> <th>Capture_Date</th></tr>' 


SET @body = @body + @xml +'</table></body></html>'


Set @cmd= @@SERVERNAME + ': Database Backup Status'


SELECT Top 1 @profile_name=name  FROM msdb.dbo.sysmail_profile


EXEC msdb.dbo.sp_send_dbmail

@profile_name = @profile_name, -- replace with your SQL Database Mail Profile 

@body = @body,

@body_format ='HTML',

@recipients =  'itesadba@sqldbanow.com', -- replace with your email address

@subject = @cmd


DROP TABLE [#DBBackup]

DROP TABLE [#FullBackup]

DROP TABLE [#DiffBackup]

DROP TABLE [#Log]

AG Status Report in SQL

 Declare @cmd Varchar (1000),@profile_name Varchar(1000), @description Varchar (500)

DECLARE @xml NVARCHAR(MAX), @body NVARCHAR(MAX)

SET @xml = CAST(( SELECT @@Servername As 'td',' ',Name AS 'td' ,'' ,role_desc as 'td' ,'',operational_state_desc as 'td'

from Sys.availability_groups_cluster AS AGC  Inner Join Sys.dm_hadr_availability_replica_cluster_states As RCS

on RCS.group_id=AGC.group_id Inner Join Sys.dm_hadr_availability_replica_states As ARS on ARS.replica_id=RCS.replica_id

Inner Join Sys.availability_group_listeners AS AGL

ON AGL.group_id=ARS.group_id

Where operational_state_desc is not NULL

order by 3  FOR XML PATH('tr'), ELEMENTS ) AS NVARCHAR(MAX))

SET @body ='<html><body><H3> Availability Groups status </H3>

<table border = 1> 

<tr>

<th> Server Name </th> <th> Availability Groups </th> <th> Role </th> <th>Status </th> </tr>'    


SET @body = @body + @xml +'</table></body></html>'


Set @cmd= @@SERVERNAME + ': Availability Groups status'


SELECT Top 1 @profile_name=name  FROM msdb.dbo.sysmail_profile


EXEC msdb.dbo.sp_send_dbmail

@profile_name = @profile_name, -- replace with your SQL Database Mail Profile 

@body = @body,

@body_format ='HTML',

--@recipients =  'ajeyudu@sqldbanow.com', -- replace with your email address

@recipients =  'IT.ESA-DBA@sqldbanow.com', -- replace with your email address

@subject = @cmd

Troubleshooting master database corrupted in SQL Server

 One of an instance master database data file was corrupted and I was unable to start the server. How to troubleshoot this scenario?

Possible Scenarios

If the master files are corrupted or damaged, instance cannot be started. We have to rebuild master database then by running the server in single user mode we have to restore latest backup to get previous settings.

Steps

1.      Check the error log for exact reason.

2.      Rebuild master database as follows by running setup from

C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Release

For windows authentication:

setup /ACTION=REBUILDDATABASE /QUIET /INSTANCENAME=<instance
name> /SQLSYSADMINACCOUNTS=<accounts>

 

For mixed mode:

setup /ACTION=REBUILDDATABASE /QUIET /INSTANCENAME=<instance
name> /SQLSYSADMINACCOUNTS=<accounts> /SAPWD=password

3.      Once rebuilding is completed then run the server in single user mode

4.   Restore master database by replacing existing one.

Restart the server in multi user mode.

Troubleshooting host name changes in SQL Server

 When the machine name is changed where we have installed SQL Server, all the instances services are started but replication, Jobs, Alerts, Maintenance plans causes errors. Hence we have to rename the instance.

To rename instance we can use the following SP

Steps:

1.      Check the old server name as follows

SELECT @@servername

2.      Drop the server and add the new server name

             SP_DROPSERVER   <oldName>

           SP_ADDSERVER <newName>, local

3.      Restart the instance

4.      Check the server name again

SELECT @@servername

How to apply patches in SQL Server SQL Cluster Environment:

 SQL Cluster Environment:

Apply a SQL Service Pack or hot-fix in a 2 node Active/Passive SQL Cluster environment.

Active SQL Server: SQLDBANOWDBALABS

Passive SQL Server: SQLDBANOWDBALABS-DR

1. First apply the SQL Service Pack on Passive Server. (SQLDBANOWDBALABS-DR)

2. Post SP/hot-fix installation completion, restart the Passive Server if prompted.

3. Failover the SQL Cluster Service/Instance from Active to Passive Server.

Post Failover:

New Active Server: SQLDBANOWDBALABS-DR

New Passive Server: SQLDBANOWDBALABS

4. Now apply the SQL Service pack on New Passive Server. (SQLDBANOWDBALABS)

5. Post SP/hot-fix installation completion, restart the New Passive Server if prompted.

6. Failback the SQL Cluster Service/Instance from Active to Passive Server.

Post Failback:

Active Server: SQLDBANOWDBALABS

Passive Server: SQLDBANOWDBALABS-DR

7. Finally verify the SQL Cluster Services and Cluster Disk Health Check in Failover Cluster Manager.