How to change the location of the Default Trace Files?

I had a situation where a 500 GB drive needed to be repurposed and the…oh 20GB worth of databases on it needed to be moved somewhere else.  Even though this included the system databases this was not overly complicated and not something you can’t find instructions for anywhere else thanks to our friend google.  A little more complicated was that the default trace files were also being written to that location.  Although I suspect the worst result of leaving that location would be a failed message in the logs and no default trace, I didn’t want SQL to do anything silly like fail to start the moment it couldn’t write to the default trace.  It seems this is either such a blindingly simple thing to do that people haven’t posted a how to online, or that it’s not something people have a call to do much.  At any rate, I found this blog post on sqlconcepts that indicates you can’t change default settings for the default trace.  Luckily while that is true of the size or the number of files retained, it is a relatively simple matter to change the location.

Reading the microsoft article on the default trace it says that the default location is MSSQL\LOG which is technically true, and also led me to believe that the default trace was stored, by default, in the same location as the error logs.  You can change the location your error logs are written to by adjusting the location of your current error logs in your SQL Server startup parameters.  I tested this on my local instance(SQL 2012) and everything ran fine, switching to the new location after a server restart.  I guess this makes sense given that the default trace really is another sort of error log.

On a slight tangent due to the sql concepts post above:  If you want to retain more history than the default(5 20MB files – which can equate to not very much at all on a heavily used server) it is possible to do so by simply scheduling a job which copies the trace files to another location.  You can either just copy all *.trc files out of your errorlog location to your archive location, or if you want to get fancy and only copy the new files you can get the current file name with:

select path from sys.traces where id=1

So long as the default trace is enabled it should always have an id of 1 as it is started(and rolled) whenever SQL Server restarts.

 

I hope this is helpful to someone.

A Merry Christmas to the Nephews

Following on from the Birthday Present I made my daughters, I promised my sister some games for her boys Christmas presents.  December turned into a pretty crazy month, but I got the last one finished on Christmas eve.

James Space game is here.

Alex’s Very Noisy motorbike game is here.

And Daniels memory game is here.

 

Best played in Google Chrome or Mozilla Firefox, because some versions of Internet Explorer will not deal with the sound files correctly.

 

Why log shipping backups fail in an Always On Availability Group – Resolved

Sometimes it bother me how long it takes to throw a single switch which resolves a problem.  This was one of those times.

Here’s the scenario.  An availability group is set up and you want to log ship one of the databases to a designated DR server so you have both HA and DR at your disposal.  Everything sets up just as it should, but when you run the backup no file appears in your backup directory.  What’s going on?

For a while I went around in circles trying to second guess my log shipping setup.  Then I made a second database, successfully configured log shipping, but the moment I added it to the availability group it began exhibiting the same behaviour.  There are no errors in the logs, the backup job says it’s successful, but when you go into the error logs all you find is it is deleting old backups that have fallen out of retention.  No backup is made.  The databases last backup date does not change.

I went so far as reading the entire support notes on books online around availability groups trying to find anything to suggest this couldn’t be done.  Then I repeated my experiments to confirm that log shipping worked fine outside the availability group, but failed when it was added.  Finally I came to the conclusion that should have been obvious an hour earlier.  The problem must be something to do with the group set up.  Once I got there the likely culprit was clear – the availability group was trying to enforce a backup being taken off the secondary replica, and the log shipping job didn’t like that.  It seems to check if it can take a local backup, see that it can’t and so skip straight to the historic backup purge.

Here’s how to correct it.

  1.  In management studio expand Always On High Availability and then Availability Groups.
  2. Right click on your chosen group and choose properties.
  3. In the left pane select backup preferences.
  4. Select ‘Primary’ as your backup source.  Click Okay.

Now run your log shipping log backup job and everything should perform as expected.

 

How to be a programmer………

This article was linked to from a recent Brent Ozar PLC newsletter.  It contains a bunch of tips about how to be a programmer(Not how to program, but how to be a programmer – the distinction is important).  I think it was absolutely brilliant and has huge areas of crossover to other technical roles…such as DBA’s.

 

(Dead Link)http://samizdat.mines.edu/howto/HowToBeAProgrammer.html?x#id2855381(Dead Link)

I particularly liked the sections on how to deal with difficult people, how to provide estimates, and perhaps best was knowing when to go home:)

How to Find Which Databases Have Indexes With Page Level Locking Disabled

I’ve recently had to look over a client server where a maintenance plan had been failing for some time.  The inhouse DBA was unaware of the failures because he had no alerting on the jobs and the big red crosses weren’t big or red enough to have caught his attention.  When I looked at the cause of the failures it was due to a native maintenance plan not being able to reoganise an index with page level locking disabled.  Whenever a reorganise plan hits a database with page level locking disabled it generates the following error:

Executing the query “ALTER INDEX Indexname] ON [dbo]….” failed with the following error: “The index “Indexname” (partition 1) on table “tablename” cannot be reorganized because page level locking is disabled.”. Possible failure reasons: Problems with the query, “ResultSet” property not set correctly, parameters not set correctly, or connection not established correctly.

There are two ways of getting around this.  The first way is to generate TSQL scripts to enable Page level locking prior to the re-organise and then re-enable it after the maintenance is completed.  JP Chen has the scripts to do that here.  Note:  Haven’t tested those, but they look right.  I suspect you may need to exclude the system tables as well.

The second, and easier way, is to set up a rebuild step and move the affected databases into that step of your maintenance plan.  Rebuilds do not require a page lock because the index is completely rebuilt rather than shuffled around.  The TSQL to figure out which database you need to move from the re-organise to the rebuild step is:

exec sp_MSforeachdb ‘use ? select db_name(), (case when count(*)>0 then ”Page Locks Disabled:” ELSE ”Page Locks” END) from sys.indexes where allow_page_locks=0 and name not in(”queue_clustered_index”,”queue_secondary_index”)’

and if you want to get the specific indexes you can use this:

exec sp_MSforeachdb ‘use ? select db_name(), object_id,name from sys.indexes where allow_page_locks=0 and name not in(”queue_clustered_index”,”queue_secondary_index”)’

Standard disclaimer about sp_MSforeachdb being an undocumented stored procedure and maintenance plans being somewhat limited form of doing your index mainteance apply:)

 

 

TSQL – get sizes of unused indexes

Here’s a TSQL snippet that will give you the sizes of the indexes that the query optimiser isn’t using.  Note that the NULL values are SINCE THE LAST RESTART.  So if you just restarted your server then this is rather a waste of time.

 
SELECT object_name(ui.object_id), si.name as [Index Name],ui.index_id, ui.last_user_seek, ui.last_user_scan, ui.user_seeks, ui.user_scans,
ui.user_lookups,ui.user_updates,
8 * sa.used_pages AS [Index Size]
from sys.dm_db_index_usage_stats ui
inner join sys.indexes si on ui.object_id=si.object_id and ui.index_id=si.index_id
INNER JOIN
sys.partitions sp ON si.object_id = sp.OBJECT_ID AND si.index_id = sp.index_id
INNER JOIN sys.allocation_units AS sa ON sa.container_id = sp.partition_id
where database_id=7
and object_name(ui.object_id) not like ‘sys%’
and ui.last_user_seek is NULL
and ui.last_user_scan is NULL
ORDER by 10 desc

Error while enabling windows feature: netfx3. – resolved

Something I have run into a few times now which is an annoying timewaster is the following error:

Error While Enabling Windows Feature netfx3

Error While Enabling Windows Feature netfx3

You’ll get it on windows 2012 installations when installing SQL 2012(And probably lower versions) and it’s caused by dotnet 3.5not being enabled on the windows installation. It’s frustrating because it happens during the actual installation and is not flagged in any of the pre-requisite checks.  This is because Windows assumes it either has access to the install media to install it from, or can download it from the internet.  On your SQL Servers you shouldn’t have direct internet access, and you are unlikely to have the install media lying around.  At any rate – here’s how to fix it:

1.  Place the install media back to it’s original location(Most likely the CD drive).

2.  From Server Manager choose ‘Add Roles and Features’.

3.  Add ‘.NET framework 3.5 features’.

4.  Now redo your SQL Install and you should be fine.

Enable dotnet 3_5