After an upgrade to SQL 2012 SP3, a clustered instance fails to start listing error 33009, 912 and 3417:
2016-04-28 14:32:23.39 spid14s Error: 33009, Severity: 16, State: 2. 2016-04-28 14:32:23.39 spid14s The database owner SID recorded in the master database differs from the database owner SID recorded in database 'msdb'. You should correct this situation by resetting the owner of database 'msdb' using the ALTER AUTHORIZATION statement. 2016-04-28 14:32:23.39 spid14s Error: 912, Severity: 21, State: 2. 2016-04-28 14:32:23.39 spid14s Script level upgrade for database 'master' failed because upgrade step 'msdb110_upgrade.sql' encountered error 33009, state 2, severity 16. This is a serious error condition which might interfere with regular operation and the database will be taken offline. If the error happened during upgrade of the 'master' database, it will prevent the entire SQL Server instance from starting. Examine the previous errorlog entries for errors, take the appropriate corrective actions and re-start the database so that the script upgrade steps run to completion. 2016-04-28 14:32:23.39 spid14s Error: 3417, Severity: 21, State: 3. 2016-04-28 14:32:23.39 spid14s Cannot recover the master database. SQL Server is unable to run. Restore master from a full backup, repair it, or rebuild it. For more information about how to rebuild the master database, see SQL Server Books Online.
Something went down the steep road to oblivion during the upgrade process, and the instance is as dead as an overrun squirrel. To be more specific, the master database does not like the looks of the owner attribute on the msdb database, and is down right refusing to complete the upgrade process.
- Start the instance with trace flag 902 to disable the upgrade scripts and get the server back online. You can do this by command line if you wish, but for clustered instances it is easier to use SQL Server config manager. There will be some existing startup parameters. Do not mess with those, just add a new one using the handy “Add” button provided.
- Wait for the instance to start, and log in using SSMS.
- To find out what SID is where, run the following script
--Sid in master SELECT SID FROM master..sysdatabases WHERE Name = 'msdb' --Sid in database SELECT [SID] FROM msdb.sys.database_principals WHERE Name = 'DBO'
It will probably show 0x01 (sa) for one of the results, and an Active directory SID for the other one:
If you want to know what username SQL Server has stored for the SID, use this command, replacing 0x01 with the SID from the previous result:
--Sid to username SELECT Name AS [LoginName] FROM master..syslogins WHERE SID = 0x01
Be aware that if the username has been changed in AD, lets say you changed DOMAIN\johnsmith to DOMAIN\jsmith1, SQL Server will not necessarily be aware of this. You can validate the username in AD using powershell. See https://technet.microsoft.com/en-us/library/ff730940.aspx. And just to make the point clear, do not mess around with account names in AD if they are linked to SQL Server. It may lead to login failures, and possibly cows being abducted by aliens at your local dairy farm.
Change the database owner to match the value stored in master. Remember to use brackets for AD users.
ALTER Authorization ON DATABASE::msdb TO [DOMAIN\USER]
Then remove the trace flag and restart the instance to try the upgrade scripts again. If the current owner is not the owner you want, allow the upgrade to finish and change it again.