Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
misken
Starting Member
8 Posts |
Posted - 2014-08-01 : 07:24:47
|
Hello all,Im a junior developer consultant that got an assignment as an accidental DBA a couple of weeks ago, and since i got interested in Transaction logs i studied(googling forums) and realized there was a need to monitor it.I wrote a script, then kept going making it run from one server by linking servers. Now i dont quite have the guts to implement it before getting some constructive criticism, pointers or warnings from more experienced DBAs since the job runs as a domain user through a proxy as sysadmin on all these server(for DBCC Loginfo). Heres my script, tried it and works like charm for what i wanted :)Any heads ups for it?USE master-- Add linked servers - Separated from the rest of the batch job since adding linked servers need an individual batchDECLARE @iterator int = 1DECLARE @numberOfRows int = (SELECT COUNT(*) FROM DBA_Maintenance.dbo.Server_List)DECLARE @lsrvName nvarchar(12)WHILE (@iterator <= @numberOfRows)BEGIN -- protection against the possibility of servers being removed from the infrastructure(and hence from the server_list-table) since the PK wont replace removed PK nr tryagain: IF (SELECT ServerName FROM DBA_Maintenance.dbo.Server_List WHERE RowNumber = @iterator) IS NULL BEGIN SET @iterator = @iterator +1 GOTO tryagain ENDSET @lsrvName = (SELECT ServerName FROM DBA_Maintenance.dbo.Server_List WHERE RowNumber = @iterator) if exists(select * from sysservers WHERE srvname = @lsrvName) exec sp_dropserver @lsrvName EXEC sp_addlinkedserver @lsrvName, N'SQL Server' SET @iterator = @iterator +1ENDGO IF OBJECT_ID('tempdb..#Loginfo') IS NOT NULL DROP TABLE #Loginfo CREATE TABLE #Loginfo (FileID varchar(3), FileSize numeric(20,0), StartOffset bigint, FSeqNo bigint, Status char(1), Parity varchar(4), CreateLSN numeric(25,0)) IF OBJECT_ID('tempdb..#VLF_temp') IS NOT NULL DROP TABLE #VLF_temp -- OBS!!! If the target server is SQL 2012, then Column "RecoveryUnitId numeric(10,0)" must be added as first column in table definition CREATE TABLE #VLF_temp (FileID varchar(3), FileSize numeric(20,0), StartOffset bigint, FSeqNo bigint, Status char(1), Parity varchar(4), CreateLSN numeric(25,0)) IF OBJECT_ID('tempdb..#VLF_db_total_temp') IS NOT NULL DROP TABLE #VLF_db_total_temp CREATE TABLE #VLF_db_total_temp (name sysname, vlf_count int) DECLARE all_servers CURSOR READ_ONLY FOR SELECT RowNumber, ServerName FROM DBA_Maintenance.dbo.Server_List DECLARE @databasename sysname DECLARE @RowNumber int DECLARE @srvName nvarchar(12) DECLARE @ExecLinkedSrv nvarchar(400) DECLARE @tempSrvName nvarchar(12) OPEN all_serversFETCH NEXT FROM all_servers INTO @RowNumber, @srvName -- Declare all_databases Cursor (cant Declare to linked server with a straight DECLARE due to variables)DECLARE @getCurrentServersDBsCursor nvarchar(255)DECLARE @mailBody varchar(Max) = N'Indications for possible fragmentation:' + CHAR(13) + CHAR(13)DECLARE @give_sa nvarchar(max)WHILE (@@FETCH_STATUS = 0)BEGIN EXEC master.dbo.sp_serveroption @server=@srvName, @optname=N'remote proc transaction promotion', @optvalue=N'FALSE' SET @getCurrentServersDBsCursor = N'DECLARE all_databases CURSOR READ_ONLY FOR ' + N'SELECT name FROM [' + @srvName + N'].[master].dbo.sysdatabases' EXEC sp_executesql @getCurrentServersDBsCursor OPEN all_databases FETCH NEXT FROM all_databases INTO @databasename WHILE (@@fetch_status = 0) BEGIN -- dont know how to fix this. Its for the notorious syntax error next to '-' thing. IF @databasename LIKE '%-%' BREAK DECLARE @remoteStatement nvarchar(max)= N'DBCC LOGINFO WITH NO_INFOMSGS' DECLARE @localStatement nvarchar(max) = @srvName + N'.' + @databaseName + '.dbo.sp_executesql @remoteStatement;' INSERT INTO #VLF_temp exec sp_executesql @localStatement, N'@remoteStatement nvarchar(max)', @remoteStatement; INSERT INTO #VLF_db_total_temp SELECT @databasename, COUNT(*) FROM #VLF_temp TRUNCATE TABLE #VLF_temp FETCH NEXT FROM all_databases INTO @databasename END DEALLOCATE all_databasesDECLARE temptable CURSOR FOR SELECT TOP 3 @srvName as [Servername], name as [DBName], vlf_count as [VLFCount]FROM #VLF_db_total_tempWHERE vlf_count > 100ORDER BY vlf_count DESCDECLARE @Servername varchar(12)DECLARE @DBName sysnameDECLARE @VLFCount intDECLARE @firstVLFSize varchar(50)DECLARE @lastVLFSize varchar(50) OPEN temptable FETCH NEXT FROM temptable INTO @Servername, @DBName, @VLFCount BEGIN SET @mailBody += N'Server:' + @Servername +CHAR(13) +CHAR(13) WHILE (@@FETCH_STATUS = 0) BEGIN SET @remoteStatement = N'DBCC LOGINFO WITH NO_INFOMSGS' SET @localStatement = @srvName + N'.' + @DBName + '.dbo.sp_executesql @remoteStatement;' INSERT INTO #Loginfo exec sp_executesql @localStatement, N'@remoteStatement nvarchar(max)', @remoteStatement; SET @firstVLFSize = (SELECT TOP 1 (FileSize /1024.0/1024.0) AS lastFiles_Size FROM #Loginfo) SET @lastVLFSize = (SELECT TOP 1 (FileSize /1024.0/1024.0) AS lastFiles_Size FROM #Loginfo ORDER BY FSeqNo DESC) SET @mailBody += char(9) +N'Database: '+ @DBName + CHAR(13)+ char(9) +N'Number of VLFs: '+CAST(@VLFCount AS varchar(50)) + CHAR(13) + char(9) +N'Size of first virtual log file: ' + SUBSTRING(@firstVLFSize, 1, 7) + ' MB'+ CHAR(13) + char(9) +N'Size of last virtual log file: ' + SUBSTRING(@lastVLFSize, 1, 7) + ' MB' + CHAR(13)+ CHAR(13) FETCH NEXT FROM temptable INTO @Servername, @DBName, @VLFCount ENDCLOSE temptableDEALLOCATE temptableTRUNCATE TABLE #VLF_tempTRUNCATE TABLE [#VLF_db_total_temp]TRUNCATE TABLE [#Loginfo]FETCH NEXT FROM all_servers INTO @RowNumber, @srvNameENDENDDEALLOCATE all_serversDROP TABLE [#VLF_temp]DROP TABLE [#VLF_db_total_temp]DROP TABLE [#Loginfo]DECLARE LinkedServersToRemove CURSOR FOR SELECT * FROM DBA_Maintenance.dbo.Server_ListOPEN LinkedServersToRemoveFETCH NEXT FROM LinkedServersToRemove into @RowNumber, @tempSrvNameWHILE (@@fetch_status = 0)BEGIN if exists(select TOP 1 srvname from sysservers WHERE srvname = @tempSrvName) exec sp_dropserver @tempSrvName FETCH NEXT FROM LinkedServersToRemove into @RowNumber, @tempSrvNameENDCLOSE LinkedServersToRemoveDEALLOCATE LinkedServersToRemoveexec msdb.dbo.sp_send_dbmail@profile_name = 'profile',@recipients = 'mail_address',@body = @mailBody,@subject = 'T-Log fragmentation report'GOSys.developer/accidental DBA |
|
MichaelJSQL
Constraint Violating Yak Guru
252 Posts |
Posted - 2014-08-01 : 08:16:40
|
You might look into configuring an alert rather than linked servers. And if you really want to implement some management power -- look into Master Target management and Data collectionhttp://technet.microsoft.com/en-us/library/bb677248(v=sql.105).aspxhttp://msdn.microsoft.com/en-us/library/ms180992.aspx |
|
|
misken
Starting Member
8 Posts |
Posted - 2014-08-01 : 09:45:08
|
Thnx Michael for the input. The alerts doesnt seem to have what i was looking for, which is automaticly keeping track of number of VLF's.The master target management looks pretty interesting though, does it have the option of monitoring the number of VLFs, and maybe also the min/max sizes, initial VLF size etc.What im trying to achieve, is to escape the need to log in to all of these servers to run the LOGINFO and PERFLOG to get the information i need for planning optimization only for the servers that could need some attention.I hope i made sense :)Sys.developer/accidental DBA |
|
|
MichaelJSQL
Constraint Violating Yak Guru
252 Posts |
Posted - 2014-08-01 : 10:19:06
|
Yes, With alerts you would need to setup on each server. I don't remember if you can deploy via master target (would need to check - but think you can), but you can deploy all jobs via master target. So if you create a master server and add your targets - you could deploy a job with your script to email you based on a threshold. once you define all your targets, you can manage them from one central server.The data collection piece I believe has custom sql collection and will be able to collect this data and automatically send it back to a central DWH |
|
|
misken
Starting Member
8 Posts |
Posted - 2014-08-04 : 03:47:17
|
Oh I will definitely look into it more, thanks!Is there anything in the script that could issue any security problem or any "shouldnt do"?I know cursors isnt the best thing because of the overhead, but its a small job and runs quite fastSys.developer/accidental DBA |
|
|
MichaelJSQL
Constraint Violating Yak Guru
252 Posts |
Posted - 2014-08-04 : 14:43:36
|
At quick glance it looks like you are looking up some servers, creating linked servers, running DBCC LOGINFO and sending out the results - It should be good - there are plenty of scripts on like this out on the web. it should be fine. |
|
|
misken
Starting Member
8 Posts |
Posted - 2014-08-05 : 05:13:12
|
Gr8 thnx for the tips and help m8 :)Sys.developer/accidental DBA |
|
|
|
|
|
|
|