Sunday, May 18, 2014

To take script out of Rebuild and Statistics of Indexes on Databases

SET NOCOUNT ON;
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @partitioncount bigint;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @partitionnum bigint;
DECLARE @partitions bigint;
DECLARE @frag float;
DECLARE @command nvarchar(4000);
DECLARE @onlineflag varchar(3);
DECLARE @MsgBody  NVARCHAR(MAX) ;
Declare @sqlcommand  varchar(max);
DECLARE @objectid_var varchar(30);
Declare @allow_page_locks int;


Create table #work_to_do
(objectid int,
indexid int,
partitionnum int,
indexdepth tinyint ,
index_level tinyint,
frag float,
onlineflag varchar(3)
)

Create table #work_to_do1
(
sqlcommand  varchar(max)
)

DECLARE table_cursor
CURSOR FOR select id from sys.sysobjects
where type='u'

-- Open the cursor.
OPEN table_cursor;

FETCH NEXT
FROM table_cursor
INTO  @objectid

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

SET @objectid_var=convert(varchar(30),@objectid)

SET @sqlCOMMAND='INSERT INTO #work_to_do
SELECT
object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
index_depth AS indexdepth,
index_level AS indexlevel,
avg_fragmentation_in_percent AS frag,''ON''
FROM sys.dm_db_index_physical_stats (DB_ID(),'+ @objectid_var + ', NULL, NULL , NULL)
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0';


--print @sqlCOMMAND

exec (@sqlCOMMAND)

FETCH NEXT
FROM table_cursor
INTO @objectid;

END;

-- Close and deallocate the cursor.
CLOSE table_cursor;
DEALLOCATE table_cursor;

--select * from #work_to_do



Update #work_to_do
set ONLINEflag='OFF'
from  sys.indexes A,INFORMATION_SCHEMA.COLUMNS c,#work_to_do B
where a.type_desc = 'CLUSTERED'
      and   (DATA_TYPE IN ('text', 'ntext', 'image') OR
            CHARACTER_MAXIMUM_LENGTH = -1)
            and TABLE_NAME=OBJECT_NAME(A.object_id)
            AND A.object_id=B.objectid
            AND A.index_id=B.indexid

Update #work_to_do
set ONLINEflag='OFF'
from #work_to_do A,sys.indexes i
                  JOIN sys.index_columns ic
                  ON i.object_id = ic.object_id
                  JOIN INFORMATION_SCHEMA.COLUMNS c
                        ON ic.column_id = c.ORDINAL_POSITION
                  WHERE c.TABLE_NAME = OBJECT_NAME(i.object_id) AND
                              ic.is_included_column = 1 AND
                              (c.DATA_TYPE IN ('text', 'ntext', 'image') OR c.CHARACTER_MAXIMUM_LENGTH = -1)
            AND A.objectid=I.object_id
            AND A.indexid=I.index_id


SET @MsgBody =
    N'<H1>Fragmented Indexes</H1>' +
    N'<table border="1">' +
    N'<tr><th>DBNAME</th><th>Table_Name</th><th>Index_Name</th>' +
    N'<th>Fragmentation</th><th>Index Operation</th><th>Online_Flag</th></tr>' +
    CAST ( ( SELECT td = db_name(),       '',
                        td = object_name(objectid),     '',
                    td = name, '',
                    td = convert(varchar(8),frag), '',
                    td = Case When frag>=30.0 Then 'REBUILD'
                                                When frag  >= 10 and frag < 30.0 Then  'REORGANIZE' END,'',
                    td = onlineflag, ''               
         FROM    #work_to_do a,sys.sysindexes b
where a.objectid=b.id
and a.indexid=b.indid
order by frag,onlineflag
              FOR XML PATH('tr'), TYPE
    ) AS NVARCHAR(MAX) ) +
    N'</table>' ;
   
    /*EXEC msdb.dbo.sp_send_dbmail
    @recipients='xxxxxxxx@xxxxx.com;',
    @subject = 'Fragmented Index Report',
    @body = @MsgBody ,
    @body_format = 'HTML' ;*/



DECLARE Index_cursor
CURSOR FOR select object_name(objectid),name,frag,onlineflag,allow_page_locks
FROM    #work_to_do a,sys.indexes b
where a.objectid=b.object_id
and a.indexid=b.index_id

-- Open the cursor.
OPEN Index_cursor;

FETCH NEXT
FROM Index_cursor
INTO   @objectname,@indexname,@frag,@onlineflag,@allow_page_locks

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

if @frag>=30
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REBUILD WITH (ONLINE='+@onlineflag +')'
ELSE
If @allow_page_locks=1
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REORGANIZE'
Else
seT @sqlcommand='ALTER INDEX ['+@indexname+'] ON [dbo].['+@objectname+'] REBUILD WITH (ONLINE='+@onlineflag +')'

insert into #work_to_do1
select  (@sqlCOMMAND)


seT @sqlcommand='UPDATE STATISTICS [dbo].['+@objectname+'] ['+@indexname+'] WITH FULLSCAN'

insert into #work_to_do1
select  (@sqlCOMMAND)

FETCH NEXT
FROM Index_cursor
INTO  @objectname,@indexname,@frag,@onlineflag,@allow_page_locks

END;

-- Close and deallocate the cursor.
CLOSE Index_cursor;
DEALLOCATE Index_cursor;


/*********************/
DECLARE cmd_cursor
CURSOR FOR select distinct sqlcommand
FROM    #work_to_do1

-- Open the cursor.
OPEN cmd_cursor;

FETCH NEXT
FROM cmd_cursor
INTO   @sqlcommand

WHILE (1 = 1)
BEGIN;

IF @@FETCH_STATUS < 0 BREAK;

print  (@sqlCOMMAND)

FETCH NEXT
FROM cmd_cursor
INTO   @sqlcommand

END;

-- Close and deallocate the cursor.
CLOSE cmd_cursor;
DEALLOCATE cmd_cursor;



DROP TABLE #work_to_do
DROP TABLE #work_to_do1


Friday, May 16, 2014

To Find Index Creation Date

-- To find Index Creation Date


SELECT schema_name(o.schema_id) AS SchemaName

      , object_name(si.object_id) AS TableName

      , si.name AS IndexName

      , STATS_DATE(i.object_id, i.index_id) AS StatDate

FROM sys.indexes si

JOIN sys.objects o ON si.object_id = o.object_id

JOIN sys.indexes i ON i.object_id = si.object_id AND i.index_id = si.index_id

WHERE o.type <> 'S' -- exclude system objects

  AND STATS_DATE(i.object_id, i.index_id) IS NOT NULL;

===============================================================
  OR



select
    i.name as IndexName,
    o.name as TableName,
    ic.key_ordinal as ColumnOrder,
    ic.is_included_column as IsIncluded,
    co.[name] as ColumnName,
    o.create_date
from sys.indexes i
join sys.objects o on i.object_id = o.object_id
join sys.index_columns ic on ic.object_id = i.object_id
    and ic.index_id = i.index_id
join sys.columns co on co.object_id = i.object_id
    and co.column_id = ic.column_id
where i.[type] = 2
--and i.is_unique = 0
--and i.is_primary_key = 0
--and o.[type] = 'U'
--and ic.is_included_column = 0
order by o.[name], i.[name], ic.is_included_column, ic.key_ordinal;

=====================================================================


OR

--sort as you wish, you have the most recently created index first

select
crdate,
i.name,
object_name(o.id)
-- , * --optionally
from
sysindexes i
join sysobjects o ON o.id = i.id
order by
crdate desc

Saturday, May 10, 2014

File space Alert for Databases


go

drop table #templist
-- =============================================
-- Declare and using a READ_ONLY cursor
-- =============================================
set nocount on
select [name] as dbname
, fileid, sf.groupid, grp=left([groupname],20), lname=left([name],20), size_mb=[size]/128 
  ,used_mb=FILEPROPERTY([name], 'SpaceUsed')/128
  ,file_growth=case when (sf.status&0x100000) > 0 then str(growth)+' %'
     else str(growth/128)+' mb' end
  ,max_mb = case when [maxsize]<0 then 'Unrestricted'
     else str([maxsize]/128) end
  ,phname=left(filename,70)  into #templist
  from 
   sysfiles sf left outer join  sysfilegroups sfg on sf.groupid=sfg.groupid
where 1 = 2

alter table  #templist add UpdateStatement varchar(512)


DECLARE Cur_SysDB CURSOR
READ_ONLY
FOR 
SELECT name FROM SYSDATABASES 

DECLARE @name varchar(40)
OPEN Cur_SysDB

FETCH NEXT FROM Cur_SysDB INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
  exec ('insert into #templist 
  select ''' + @name + ''' as Dbnamename,  fileid, sf.groupid, grp=left([groupname],20), lname=left([name],20), size_mb=[size]/128 
  ,used_mb=FILEPROPERTY([name], ''SpaceUsed'')/128
  ,file_growth=case when (sf.status&0x100000) > 0 then str(growth) + '' %''
     else str(growth/128)+'' mb'' end
  ,max_mb = case when [maxsize]< 0 then ''Unrestricted''
     else str([maxsize]/128) end
  ,phname=left(filename,70),
    ''use [' + @name + '] ; update #templist set used_mb = FILEPROPERTY([name], ''''SpaceUsed'''')/128
from [' + @name + '].dbo.sysfiles sf left outer join  [' + @name + '].dbo.sysfilegroups sfg on sf.groupid=sfg.groupid 
  where  phname collate database_default = filename '' as updatestatement
  from ' + @name 
   + '.dbo.sysfiles sf left outer join  ' + @name + '.dbo.sysfilegroups sfg on sf.groupid=sfg.groupid   order by 1')
END
FETCH NEXT FROM Cur_SysDB INTO @name
END

CLOSE Cur_SysDB
DEALLOCATE Cur_SysDB


go

-- drop table #templist
DECLARE Cur_SysDBUpdate CURSOR
READ_ONLY
FOR 
SELECT distinct UpdateStatement  FROM #templist

DECLARE @updatestatement varchar(512)
OPEN Cur_SysDBUpdate

FETCH NEXT FROM Cur_SysDBUpdate INTO @updatestatement
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
      Exec (@updatestatement)
END
FETCH NEXT FROM Cur_SysDBUpdate INTO @updatestatement
END

CLOSE Cur_SysDBUpdate
DEALLOCATE Cur_SysDBUpdate

go
-- select dbname , case when used_mb > 0 then cast(used_mb as decimal(5,2)) / cast(size_mb as decimal(5,2) * 100 else 0.00 end from #templist
set nocount off
go
select dbname, grp, lname, size_mb, used_mb,cast( case when used_mb > 0 then 
convert(dec(29,2), used_mb) / cast(size_mb as decimal(29,2)) * 100 
else '0' end as decimal(5,2)) USagepercent , phname,file_growth, max_mb
  from #templist where dbname like 'tempd' and grp is not null
order by 4 desc

Tuesday, December 24, 2013

Script to find the SQL Server Installation created Date

select @@SERVERNAME servername,create_date 'InstallationDate' from sys.server_principals

where sid = 0x010100000000000512000000

This e-mail and any files transmitted with it are for the sole use of the intended recipient(s) and may contain confidential and privileged information. If you are not the intended recipient(s), please reply to the sender and destroy all copies of the original message. Any unauthorized review, use, disclosure, dissemination, forwarding, printing or copying of this email, and/or any action taken in reliance on the contents of this e-mail is strictly prohibited and may be unlawful.

Monday, December 9, 2013

log shipping configuration

LOG SHIPPING

·         Restoring data from backups takes more time i.e., application down time is more. So to reduce this down time Microsoft had developed new features. They are a) Log Shipping, b) Database Mirroring and c) Clustering.

·         Based on the database criticality we go for these features. In Log Shipping, down time is minimal.

·         Log Shipping is a high availability feature where data is sent from one server to another server through T-log file backups. This feature is available from SQL Server 2000 onwards.

·         The server which is configured for log shipping is called Primary Server and the database is called Primary Database. The server which receives data is called Secondary Server or Stand-by Server, and the database is called Secondary Database or Stand-by Database.

·         The secondary database will be either in restoration mode or stand-by mode.

·         This technique is useful for database availability by maintaining the second warm database that fill in certain intervals.

·         Whenever the Primary Server gets unavailable, then Secondary server can be used as Primary server to get the database online.

·         There will be some downtime to change the roles of the server at fail-over.

·         In Log shipping 3 jobs to be done. They are a) Back-up job b) Copy job and c) Restore job

·         Back-up job is performed at Primary Server. Copy and Restore jobs are performed at Secondary Server.

 

How Log Shipping works?

·         Take Full backup and t-log backup of the primary database is copied to the stand-by server.

·         Restore the backup into Stand-by database as either in read-only or no-recovery mode.

·         When Stand-by database is in read-only mode then we can even only access the data but cannot modify it. Whereas in no-recovery mode we cannot even access the data.

·         Log shipping is done only when the Primary database is either in Full or Bulk-logged recovery mode.

·         When performing log shipping to a server in stand-by mode a TUF (Transaction Undo File) file is created. This file contains information on all the modifications performed at the time backup is taken. This file is very important in stand-by mode because when restoring the log, uncommitted transactions will be stored in this TUF file and the committed transaction log will be restored in stand-by database making the database available to read-only. When the next restoration is done this uncommitted transaction in TUF file checks with the T-log backup whether the transactions are committed or not. If they are committed they will be written to disk, else they are stored in TUF file until it gets committed or rolled back.

·         Backup job runs on Primary database and the default scheduling time is 15 minutes.

·         Copy job copies the backup files to the Stand-by server, this job runs on Stand-by server and the default scheduling time is 15 minutes.

·         Restore job restores the copied files into the Stand-by database, this job runs on Stand-by server and the default scheduling time is 15 minutes.

 

Pre-requisites:

·         The Primary database must be either in Full or bulk-logged recovery model.

·         There is no naming convention for the log shipping database.

·         Log Shipping is a Manual fail-over. Automatic fail-over is not there in Log shipping.

·         Log shipping information stored in MSDB.

·         Here we may configure one more server called Monitor server, which monitors the primary server and secondary server.

·         Minimum down time is required.

 

CONFIGURING LOG SHIPPING

Let’s our database is “test” in “WINDC” server.

Right click on the database for which we are going to configure log shipping and select tasksà Ship Transaction Logs

Select “Enable this as a primary database in a log shipping configuration” option.

Click on “Backup Setting” for setting for backup process. Here we have to provide the network path and the local path of the backup folder and click on “Schedule” for scheduling the backup time interval.

By default, the schedule is for every 15 minutes. For our example we are reducing it to 5 minutes.

Click ok.

Click “Add” to configure the secondary server.

Click “connect” to connect to the secondary server and to the secondary database.

Provide the name for the secondary database.

Under “copy files” tab we provide the information where the files are copied, usually this folder will be on secondary server location. So here we provide the network path and click on “Schedule” for scheduling the copy job.

By default, it will be for 15 minutes, for our convenience it is reduced to 5 minutes.

Under “Restore Transaction Log” tab we provide the state of the secondary server, when the alert to be raised if restore does not occur, and schedule of the restore.

By default the schedule for restore is for 15 minutes, for our convenience it is reduced for 5 minutes.

Click ok.

Check on for Monitor server instance for configuring a monitor server and click on settings.

Click on Connect and connect to the monitor server and click ok.

Click ok.

Save Log Shipping Configuration window appears and here if any error occur we have to fix them. Click on close.

In “Primary server” “Job Activity Monitor” we can observe the job success (backup taken success)

 

ERRORS

Scenario: accidentally, if the user had deleted the jobs and databases in both Primary server and Secondary Server. The user have created another database and configured log shipping then the alert job will be failed and it still points to the previous log shipping database even though it is not present. (It is not recommended process to delete the jobs and databases without breaking log shipping)

Using primary_id, we have to delete the table in primary server.

First we deleted the data from “log_shipping_monitor_primary” using “primary_id”.

Now we have deleted the data from “log_shipping_monitor_secondary” using “secondary_id”

In secondary server, when we check “log_shipping_monitor_secondary” still alert is working.

We have deleted the old data from the table “log_shipping_monitor_secondary” using “secondary_id”

Now we can see the Transaction log shipping status working fine.

 

If Log Shipping is out of synch or LSN of the log files are disturbed?

If log shipping is out of synch then we have to take