Archive
SQL DBA – Move tempDB to another drive in simple steps
Today we will see how to move your SQL Server tempDB database from its default location to an another drive. Reason could be anything like Disk maintenance, Failure recovery, etc. This can be done by using the normal ALTER DATABASE statement, we will see how.
–> Script: Let’s first check the location of master DB:
USE tempdb GO SELECT * FROM sys.database_files
–> Now execute the ALTER DATABASE statement with MODIFY FILE option:
USE master; GO ALTER DATABASE tempdb MODIFY FILE ( NAME = tempdev, FILENAME = 'E:\SystemDatabases\tempDB\tempdb.mdf' ); GO ALTER DATABASE tempdb MODIFY FILE ( NAME = templog, FILENAME = 'E:\SystemDatabases\tempDB\templog.ldf' ); GO
The file “tempdev” has been modified in the system catalog. The new path will be used the next time the database is started.
The file “templog” has been modified in the system catalog. The new path will be used the next time the database is started.
–> Now Restart the SQL Server services from SSMS Object Explorer or by going to RUN –> services.msc.
As soon as the SQL Server services are started, the SQL engine re-creates the tempDB database files. So there is no need to physically move them to the new location.
–> To confirm the new location, just execute following query and check the path:
SQL Error – Logical file ‘XYZ_Log2’ is not part of database ‘XYZ’. Use RESTORE FILELISTONLY to list the logical file names.
I was restoring Databases as a routine monthly job. Suddenly in between I came across an error which didn’t let me restore a Database. I restored other Databases and left this one to do at the end. Finally I picked it up again and saw that some new kind of error I was facing. The error message says to use “RESTORE FILELISTONLY”, I check the syntax on MSDN and found that this Database had two log files (LDF) earlier, but now configured for only one. And as I was using the same old script to Restore it, I was getting this error.
Let’s try to reproduce it in a standalone box:
–> I took a backup of AdventureWorks2012 Database on my machine.
I created the RESTORE script and added another line of log file at line 8 below:
USE [master] GO RESTORE DATABASE [AdventureWorks2012] FROM DISK = N'E:\Softwares\MS_bits\AdventureWorks2012.bak' WITH FILE = 1, MOVE N'AdventureWorks2012_Data' TO N'E:\MSSQL11\DATA\AdventureWorks2012_Data.mdf', MOVE N'AdventureWorks2012_Log' TO N'E:\MSSQL11\Log\AdventureWorks2012_Log.ldf', MOVE N'AdventureWorks2012_Log2' TO N'E:\MSSQL11\Log\AdventureWorks2012_Log2.ldf', NOUNLOAD, REPLACE, NOUNLOAD, STATS = 5 GO
On executing I got an error as expected, shown below:
Msg 3234, Level 16, State 2, Line 1
Logical file ‘AdventureWorks2012_Log2’ is not part of database ‘AdventureWorks2012’. Use RESTORE FILELISTONLY to list the logical file names.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.
As suggested in the Error Message, I used the “RESTORE FILELISTONLY” command to check what all files this Database is using:
RESTORE FILELISTONLY from disk=N'E:\Softwares\MS_bits\AdventureWorks2012.bak'
And I could see only two, one MDF & one LDF, as shown below:
LogicalName PhysicalName Type FileGroupName AdventureWorks2012_Data E:\MSSQL11\DATA\AdventureWorks2012_Data.mdf D PRIMARY AdventureWorks2012_Log E:\MSSQL11\Log\AdventureWorks2012_log.ldf L NULL
So, I removed the extra LDF log file option from the RESTORE script, as shown below:
RESTORE DATABASE [AdventureWorks2012x] FROM DISK = N'E:\Softwares\MS_bits\AdventureWorks2012.bak' WITH FILE = 1, MOVE N'AdventureWorks2012_Data' TO N'E:\MSSQL11\DATA\AdventureWorks2012_Data.mdf', MOVE N'AdventureWorks2012_Log' TO N'E:\MSSQL11\Log\AdventureWorks2012_Log.ldf', --MOVE N'AdventureWorks2012_Log2' TO N'E:\MSSQL11\Log\AdventureWorks2012_Log2.ldf', NOUNLOAD, REPLACE, NOUNLOAD, STATS = 5 GO
The above statement executed fine and the Database restored successfully.
So, I learnt a new thing here about the “RESTORE FILELISTONLY” command. This command tell us what all Database files (MDF, NDF, LDF) a Backup file contains without actually Restoring the Database.
SQL DBA – Disable/Enable multiple SQL Jobs at once
Seems to be a simple topic. But yes when it comes to do these type of tasks we tend to recall the syntax and end up searching internet (bing/google) for the solution.
–> Disabling a single SQL Job can be done simply through SSMS. Right click on the SQL Job and select Disable. To enable it back simply select Enable for a disabled Job.
This can also be done by a TSQL query as shown below:
USE msdb;
GO
-- Disable a SQL Job:
EXEC dbo.sp_update_job
@job_name = N'syspolicy_purge_history',
@enabled = 0 ;
GO
select enabled, * from sysjobs where name = 'syspolicy_purge_history'
GO
–> Now if you’ve to Disable Multiple or All the Jobs in SQL Agent, how will you do it?
Selecting All SQL Jobs on SSMS and right clicking won’t give you the Disable option. And here it become more tricky as there is only way to do this by TSQL query. But there is no single TSQL query defined in SQL Server to Disable all SQL Jobs at once. So, we will have to create a Dynamic SQL which will create Script for all SQL Jobs dynamically to Disable each and every SQL Job. Let’s see how:
USE msdb; GO -- Disable Multiple SQL Jobs at once: DECLARE @dynSql NVARCHAR(MAX) = '' SELECT @dynSql += N'exec msdb.dbo.sp_update_job @job_name = ''' + name + N''', @enabled = 0;' + CHAR(10) + CHAR(13) FROM msdb.dbo.sysjobs WHERE enabled = 1 ORDER BY name; PRINT @dynSql;
-- Here is the output of above PRINT statement: exec msdb.dbo.sp_update_job @job_name = 'ExecuteSPuspGetBillOfMaterials', @enabled = 0; exec msdb.dbo.sp_update_job @job_name = 'syspolicy_purge_history', @enabled = 0;
Simple Copy-Paste the the above Dynamically generated SQL Script and Execute it, it will Disable all SQL Jobs at once.
SQL DBA – Move user Database (.mdf & .ldf files) to another drive
Here in this post we will see how to move user created Database to an another drive from the default drive.
–> The first 2 ways I’ve discussed in my other blog posts, please check the links below:
1. Detach & Attach task, video
2. Backup & Restore task, link, video
3. By using ALTER command, Syntax below:
ALTER DATABASE SET OFFLINE;
GO— Manually move the file(s) to the new location.
ALTER DATABASE Database name
MODIFY FILE (
NAME = ‘Database name’,
FILENAME = ‘New Location’
)
GOALTER DATABASE Database name SET ONLINE;
GO
–> Script used in above video:
Step #1. Create a new Database in SSMS with name “ManDB”.
Step #2. Check the current location of database:
select * from ManDB.sys.database_files --ManDB D:\Program Files (x86)\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\ManDB.mdf --ManDB_log D:\Program Files (x86)\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\ManDB_log.ldf
Step #3. Take the database offline, so that we can move files from one drive to another:
ALTER DATABASE ManDB SET OFFLINE; GO
Step #4. Move the file(s) to the new location manually.
Step #5. Change the system catalog settings:
ALTER DATABASE ManDB MODIFY FILE ( NAME = 'ManDB', FILENAME = 'E:\SQLDBs\ManDB.mdf' ) GO ALTER DATABASE ManDB MODIFY FILE ( NAME = 'ManDB_log', FILENAME = 'E:\SQLDBs\ManDB_log.ldf' ) GO
Step #6. Take the database back online:
ALTER DATABASE ManDB SET ONLINE; GO
Step #7. Check the new location:
select * from ManDB.sys.database_files --ManDB E:\SQLDBs\ManDB.mdf --ManDB_log E:\SQLDBs\ManDB_log.ldf
SQL DBA – When was the Database restored (Query)?
When you are working on your DEV database system, very often you restore databases from PRODUCTION systems in order to get fresh and latest data.
Sometimes questions crops in our mind like:
1. When exactly the backups were restored on DEV system.
2. Which user restored the backup on DEV.
3. When the backups were taken on PROD system.
4. What was the backup process start time and end time, so that you are sure you have correct snapshot of data.
5. What was the corresponding database name on PROD, as on DEV you can restore with a different name.
6. What was the backup file location while restoring the databases.
All these questions can be answered by the below sample query:
USE msdb GO SELECT rs.destination_database_name AS TargetDBName, rs.restore_date AS RestoreDate, rs.user_name AS RestoreBy, bs.backup_start_date AS BackupStartDate, bs.backup_finish_date AS BackupFinishDate, bs.database_name AS SourceDBName, bmf.physical_device_name AS SourceDBFiles FROM msdb.dbo.restorehistory rs INNER JOIN msdb.dbo.backupset bs ON rs.backup_set_id = bs.backup_set_id INNER JOIN msdb.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id ORDER BY rs.restore_date DESC
You can use the above query and tweak as per your needs.






