T-SQL Tuesday #31 – Logging
It’s T-SQL Tuesday time again, and this month Aaron Nelson (blog | @sqlvariant) is hosting. The topic is logging, and if you’re like to participate, read Aaron’s post and learn the rules. We do this on the second Tuesday of every month.
If you’d like to host, contact Adam Machanic. It’s easy to do. Get on the schedule, pick a topic, and then write a post.
I’ve found documentation of events to be one of the most important things I can do in my career. Finding out what happened, what changed, or what I did has been important many times, and often helped me come through difficult situations.
Logging is the automated version of documentation. All kinds of applications, including SQL Server, produce logs of the various activity on the system. In SQL Server, we are moving to an eventing system, and if you haven’t looked at Extended Events, you should.
One of the times when I found logging to be lacking was in a startup I worked at a decade ago. We had a number of developers that were working on various development servers. They had full rights, and they were allowed to build their own objects. That was a little concern to a controlling DBA like me, but I allowed it since they often wanted new objects quickly, and if I allowed them to write their own, they’d use stored procedures.
A good compromise, if you ask me.
However in the hectic pace of development, I found that the developers didn’t often keep good notes about what was being built for which features and functions. Since we had to produce a build script fairly quickly every Monday in order to update our QA systems, we would find that developers invariably would forget objects and we would not have a well tested QA script on Monday afternoon.
I decided that we needed to better log the changes on our development server. I didn’t care about every change, especially intermediate changes to objects, but I did care about the gross changes made each day.
This was in the SQL Server 2000 days, with limited tracking of changes outside of SQL Trace. Since I had no desire to move through lots of trace files, even in an automated fashion, I decided on a much simpler method.
In sysobjects (now sys.objects), there was a crdate field, which tells you when the object was created. However that doesn’t change if an ALTER TABLE is run (or any other ALTER). That stumped me briefly, but I decided to search further.
I found that there was a schema_ver field, which is incremented every time the object is changed. Since the majority of our developer changes were ALTERs, I could track the version number and then compare this each day. I tested this out, and it worked well.
The outline of the solution is that I grabbed a copy of the sysobjects table every day and stored it in a temporary table. I then used a left join to compare this with the previous values stored in a table I’d created to store the data. When I found differences, I logged them in a table, along with the date, and sent myself an email. I would then overwrite the stored version of the objects with the version from the temp table, giving me a baseline for the next execution.
At the end of the week, I’d have an aggregate list of all objects changed, which I could then compare against our build script.
At the time we were in an agile environment, releasing new code every Wednesday, and operating on very short timelines. The logging I did cut down on mistakes and allowed us to have a smooth release process that functioned for over 18 months, with code releases nearly every Wednesday outside of holidays.