Orchestrator bug kills database server

Update

20131031: Code to limit the size of the error log files added to the solution. So far only tested on SQL 2012 SP1 CU2.

Problem

The Database server/operating system starts complaining about low disk space. Analysis reveals that the volume containing the default MSSQL log folder is very low on space, maybe even 0 bytes free. Further analysis shows that the ERRORLOG files are taking up all remaining space on the volume.

Analysis

The ERROROLOG files is filled to the brim with messages like this one:

Date		07.01.2013 21:09:09
Log		SQL Server (Current - 07.01.2013 14:57:00)

Source		spid29s

Message
The activated proc '[Microsoft.SystemCenter.Orchestrator.Maintenance].[MaintenanceWorker]' running on queue 'OrchestratorDB.Microsoft.SystemCenter.Orchestrator.Maintenance.MaintenanceServiceQueue' output the following:  'Error: 9002, The transaction log for database 'OrchestratorDB' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases'

image

image

Orchestrator has a maintenance process that does not handle a situation were the database transaction log is unable to grow, either due to restrictions or due to the fact that the disk is full. When this happens, it bloats the ERRORLOG with the messages mentioned above. This happens very quickly as it keeps retrying several times each second, so even a 10GB volume is filled in hours. If this situation is left unchecked for a couple of days, the risk of volume NTFS corruption is high.

solution

  • Disable access to the Orchestrator database or stop the Orchestrator servers to prevent further bloating.
  • Stop the database instance
  • Delete the bloated error log to free up space
  • Restart the instance
  • Change the number of error logs SQL server is allowed to create (default is 6, sample limits to 10) and limit the size of the error log files to 50MB each. This will give you a total of 11 error logfiles, each with a max size of about 50 000 KB for a total of 550MB.
    USE [master]
    GO
    EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
     N'Software\Microsoft\MSSQLServer\MSSQLServer',
     N'NumErrorLogs', REG_DWORD, 10
    GO
    EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
     N'Software\Microsoft\MSSQLServer\MSSQLServer', 
     N'ErrorLogSizeInKb', REG_DWORD, 50000
    GO
  • Solve the problem regarding the Orchestrator DB transaction log. Usually such problems are caused by either a failed backup job (thus no log truncation) or the simple fact that you need to allocate more space for the data. If a failed backup job is the problem, consider shrinking the transaction logs back down to their normal size. See https://lokna.no/?p=349 for more information about shrinking troublesome logs (Norwegian version only).
  • Enable access to the Orchestrator database.
  • Monitor the error logs and see if the values you chose for log size and number of logs fits your workload. If the logs contain at least a day of messages, but not more than a month, you are in the butter zone.

SQLIO results parser

Ever since I first learned about it I have been a happy user of a powershell script for parsing the results of a SQLIO test run into Excel made by Mr. Jonathan Kehayias (blog). It takes the otherwise difficult to read results file and reduces it to an excel file including a couple of “management-friendly” charts  Smilefjes.

The original script can be found here.

Continue reading “SQLIO results parser”

Permission error installing Failover Cluster instance

Problem

While testing out MSSQL 2012 Always On Failover Clustering in my lab, I stumbled upon a strange error which I have never seen before: “Updating permission settings for file [Shared drive]\[Mountpoint]\System Volume Information\ResumeKeyFilter.store failed”. This happened for all drives that was mounted as a mount point (folder) instead of a drive letter.image

Continue reading “Permission error installing Failover Cluster instance”

Who tampered with the database?

I have been reading a lot about MSSQL 2012 lately, to get myself ready for when the developers and application admins find out about the new features and start nagging about having servers upgraded to the latest and (possibly) greatest. Smilefjes

I am usually very skeptical when it comes to upgrading to a new version of enterprise software within the first 6 months of its release, especially so if the current version works perfectly fine as is. So far I haven’t read anything to quell my skepticism, but sooner or later I guess I have to face the music and start upgrading or migrating databases. The good thing though about reading documentation is the rediscovery of forgotten features and possibilities. Sometimes it is nice to just let the mind take a random road trip through the interwebs, just to find out were it winds up. This time, I got reacquainted with DML triggers and events, and remembered a long forgotten scheming plan to track who was tampering with MY databases, which is the main focal point of this post.

Continue reading “Who tampered with the database?”

Maintenance plan fails to complete

Symptoms and findings

In the event log event id 12291 from SQLISPackage100 is recorded, together with event id 208 from the MSSQL Agent service:

SNAGHTML610dfe2SNAGHTML610fe6a

In the MSSQL log for the job, the following error is recorded:

The package execution returned DTSER_FAILURE (1).

Resolution

This was caused by some of the job tasks not having their database selections stored properly:

SNAGHTML615c409

So the solution was simple, just select the proper databases and remember to save the maintenance plan afterwards Smilefjes

Redundancy versus Single Points of Failure

There seems to be a widespread misconception in the IT community regarding Single Points of Failure: as long as you have N+1 redundancy in all your components, you no longer have a single point of failure. This is not necessarily correct, and can lead to a very bad day when you discover that your “bullet proof” datacenter or system design turns out to be one big basket with all your eggs in it. The fact of the matter is that adding redundancy to a component will only reduce the chance of failure, it won’t make it impossible for the component to fail. Take a MSSQL failover cluster for instance, be it Active-Active or the more common Active-Passive. Compared to a stand-alone server it offers far better redundancy, and it will limit maintenance downtime to a bare minimum. But on its own it is still a single point of failure, in fact it has several single points of failure: shared network/IP, shared storage and the cluster service itself to mention a few. I have seen all of the above fail in production, resulting in complete failure of the cluster. Especially on Win2003 and earlier, a poorly configured cluster could easily cause more problems than a stand-alone server ever would, but even if everything is set up and maintained properly, bad things will happen sooner or later.

Continue reading “Redundancy versus Single Points of Failure”

Count fragmented indexes

DECLARE @AVG_FRAG float
DECLARE @MIN_PAGES int 
SET @AVG_FRAG = 10
SET @MIN_PAGES = 1000

SELECT db.name, ips.index_type_desc, COUNT(*) as FragmentedIndexes
FROM sys.dm_db_index_physical_stats(null, null, NULL, NULL, NULL) ips
left join sys.databases db on ips.database_id = db.database_id
WHERE avg_fragmentation_in_percent > @AVG_FRAG and
ips.page_count > @MIN_PAGES
group by db.name, index_type_desc
order by db.name, index_type_desc

Lists the databases containing indexes and heaps with an average fragmentation percentage larger than @AVG_FRAG and how many indexes in the given database that are fragmented. Used to identify index issues at the instance/server level. @MIN_PAGES define the minimum size of the index. Small indexes are usually not affected by fragmentation and you can safely ignore them. The default limit in the script is set to 1000 pages (8000KiB), based on the recommendations from http://technet.microsoft.com/en-us/library/cc966523.aspx .

Datofeltenes forbannelse

Av og til må man hente ut data fra en tabell basert på dato eller tid. Slike tabeller har gjerne en egen tidsmerkekolonne, eller timestamp som det egentlig heter. Problemet er at datatypen som passer i de aller fleste databasemotorer også har en tidskomponent, slik at det er forskjell på 20100830153312 og 20100830073658 selv om de begge er fra samme dag. Man kan selvsagt jukse og sette denne til null, slik at alt blir merket med dato sånn og sånn klokken 00:00:00, men det er ikke så praktisk og krever at man tar hensyn til det hver gang man legger inn data. Og for å gjøre dette morsommere finnes det knapt noen datofunksjoner som er standardiserte på tvers av databaseplattformer, så man må finne de som passer til den versjonen man har. Dette har gitt meg mye “glede” opp gjennom årene, og siden jeg jobber med sånt forholdsvis sjelden forsøker jeg nå å dokumentere noe av det jeg stadig må finne opp på nytt.

Continue reading “Datofeltenes forbannelse”

Kopiere en MSSQL-database

Bakgrunn

Prosedyren beskriver to metoder for å ta en fullstendig kopi (snapshot) av en database på filnivå. En slik backup gir hurtig restore, og kan med fordel brukes før man tester oppgraderinger eller om man ønsker en kopi av databasen for testformål. Eksemplene er fra en MSSQL 2008 server, men prosedyren kan brukes på de fleste MSSQL versjoner. Grensesnittet er varierer på de forskjellige versjonene, men det bør ikke være så vanskelig å finne igjen bildene på en nyere eller eldre utgave. Continue reading “Kopiere en MSSQL-database”

Shrinkfile

Innimellom vokser  SQL data eller logfiler til gigantiske proporsjoner, uten at de nødvendigvis inneholder noe fornuftig.Du kan få en liste over  loggbruk og størrelse ved å kjøre følgende kommando:

DBCC sqlperf(logspace)

Transaksjonsloggen bør vanligvis ikke være større enn ca 25% av databasestørrelsen, men det kommer an på hvor ofte den tømmes. Dersom den plutselig blir betydelig større enn normalt for en gitt database er det grunn til bekymring og videre etterforskning.

Hvor stor databasen er og hvor mye av plassen som brukes til noe fornuftig kan du sjekke for en og en database med følgende kommandoer:

USE [DatabaseNavn];
GO
EXEC sp_spaceused @updateusage = N'TRUE';
GO

I SQL 2008 management studio kan du også få opp en Disk usage rapport som gir fancy kakediagram og forklaringer i tillegg.

For å krympe en fil må du vit hva den heter. Dette sjekkes i databaseinnstillinger. Det er ikke det faktiske filnavnet du er ute etter, men det logiske navnet.

USE [Databasenavn]
GO
DBCC SHRINKFILE ([logisk filnavn], [Ønsket størrelse i MiB])
GO

For å unngå diskfragmentering bør du angi en størrelse som er omtrent det du tror den trenger å være. For loggfiler har vi en tommelfingerregel som sier at samlet størrelse på loggfilen (og det skal helst bare være en) bør være 25% av samlet størrelse på datafil(ene). Dette vil gi et godt utgangspunkt.

Feilsøking

Innimellom vil en shrinkfile resultere i en eller annen feilmelding (sjekk messages-vinduet). Det skyldes vanligvis en av følgende:

  • For lite ledig diskplass
  • Slutten av filen er i bruk. (loggfiler er delt opp i mindre virtuelle logger)
  • Databasen/loggen er korrupt

Først og fremst bør du sjekke i feilloggen om databasen er korrupt eller om den har andre feil relatert til problemdatabasen.

Dersom du har for lite diskplass, frigjør plass om mulig. Eventuelt kan du dismounte basen og flytte den til en annen større disk først.

For å sjekke hvor mange elementer loggen består av kan man kjøre DBCC LOGINFO:

image

Status 0 angir at fragmentene kan fjernes ved krymping. Siden Shrinkfile bare sletter fra slutten av filen(som er bunnen  av listen over), kan den bare slette opp til og med den siste fragmenten med status 0.

Dersom siste fragment ikke har status 0 kan du korrigere dette. Hvordan du går frem avhenger av om du bruker Simple recovery eller ikke. Dersom du har simple recovery, kjør denne kommandoen isteden:

USE [Databasenavn]
GO
CHECKPOINT
DBCC SHRINKFILE ([logisk filnavn], [Ønsket størrelse i MiB])
GO>

Dersom det ikke virker første gang, kjør den flere ganger. Du kan sjekke fremgang ved å kjøre Loginfo som nevnt over.

Om du bruker full eller bulk logged recovery, ta en backup av loggen og prøv igjen. Kjør eventuelt flere backup etter hverandre om det ikke hjelper på første forsøk. Om alt annet feiler kan du bytte til simple recovery model midlertidig, men det bør være siste utvei. Noen anbefaler å ta basen offline og slette loggfilene. Dette er direkte farlig, da det kan føre til at basen ikke lar seg åpne igjen etterpå. Siden prosedyren over ofte brukes for å rydde opp etter en feilsituasjon er dette særdeles risikabelt. Loggfilen er den viktigste filen til databasen.

Se https://www.sqlskills.com/blogs/paul/why-you-should-not-shrink-your-data-files/ for mer informasjon (engelsk).