Find DB Restore History along with machine hostname/ip address - sql-server

I want to find out from which laptop or desktop a given database was restored during a given time period. Currently every one in my team is using the same SQL Server user id, so I have to find from which machine the database restore was triggered.
That way I can figure out who actually did the database restore.
I have already found the below query which gives the details of restore history. But this doesn't give the ipaddress or hostname of the machine from which restore was done.
SELECT
[rs].[destination_database_name],
[rs].[restore_date],
[bs].[backup_start_date],
[bs].[backup_finish_date],
[bs].[database_name] as [source_database_name],
[bmf].[physical_device_name] as [backup_file_used_for_restore]
FROM msdb..restorehistory rs
INNER JOIN msdb..backupset bs ON [rs].[backup_set_id] = [bs].
[backup_set_id]
INNER JOIN msdb..backupmediafamily bmf ON [bs].[media_set_id] = [bmf].
[media_set_id]
ORDER BY [rs].[restore_date] DESC

After you get the restore datetime from the query you put, you can go to Application event viewer and check the computer name
Example:

Related

Failed assembly deploy due to non-matching SIDs

Database names and logins are anonymized in what follows. There are some answers
on SO that are similar to this situation, but not exactly the same, hence my question.
Attempting to deploy an assembly to production database FOO_PROD fails with message:
Msg 33009, Level 16, State 2, Line 17
The database owner SID recorded in the master database differs from the
database owner SID recorded in database 'FOO_PROD'. You should correct
this situation by resetting the owner of database 'FOO_PROD' using the
ALTER AUTHORIZATION statement.
Indeed, the following two queries demonstrate the difference in SID.
First, we look at the SID of FOO_PROD:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'FOO_PROD'
which shows the result of:
SID, LoginName
0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
Second, we look at the SID of FOO_PROD in the master database:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'master'
which shows the result of:
SID, LoginName
0x01, [sa]
We notice that indeed, just as Visual Studio complained, the SIDs do not
match. They must be made to match in order to proceed (apparently).
Constraints: The SID on FOO_PROD cannot be changed because several other systems
that use the database expect it to have the SID and LoginName it currently has.
Question 1: Is the solution then to change the SID, LoginName on the master database? Would
it hurt anything or be a bad idea to do so?
Say you respond that it is ok to change the SID, LoginName on master, then,
how does one make the change to the 'master' database? Well, I've
not done it before, but candidate solutions and commentary can be found here:
The database owner SID recorded in the master database differs from the database owner SID
However, this situation is different from those presented in the link above, I
think, in that the change must happen to/on the master database ala:
exec sp_changedbowner [BATZ\boink]
Question 2: Is that the correct way to do it?
Naturally I'll check with stakeholders if such a change to master database will
cause undesired outcomes, but I hope to get some guidance here before I even
check on that.
Update based on #srutzky's updated answer:
-- Step 1
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
returns:
name, owner_sid, name
FOO_PROD, 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
Then
-- Step 2
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
returns:
sid, name
0x01, sa
Yes, the SIDs really do need to match as a mismatch is an indication of a potentially harmful DB being restored to the instance; this is a safe-guard.
BUT, first we need to know exactly what we are looking at. While there is definitely a mismatch in the owner SIDs between the record in FOO_PROD and the record in master (hence the error message), your queries are not looking at the value in FOO_PROD. Your two queries are looking at the value in master for the owner of FOO_PROD, and in master (again) for the owner of master (entirely irrelevant here), respectively.
Step 1
Do not use sys* objects for anything as those are compatibility Views so that older stuff written for SQL Server 2000 and prior still work (well, dbo.sys* tables in msdb are still valid). Starting with SQL Server 2005, only sys.* objects (no need to specify master.) should be used. Meaning, use:
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
Step 2
You need to check the value IN the database itself for the owner's SID as it has it recorded, which is not in sys.databases (or even in master..sysdatabases). When checking the Database's value for it's owner, you need to look in sys.database_principals for the dbo User as follows:
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
Step 3
Using sp_changedbowner is required if you are on SQL Server 2005, but starting with SQL Server 2008 that stored procedure is deprecated in favor of the newer ALTER AUTHORIZATION (though it still works). But yes, this is the way to make them the same as it will sync both locations to whichever Login you specify.
However, you need to make sure that BATZ\boink is a valid Windows Login for the domain that the SQL Server instance belongs to, AND that this particular Windows Login has an SID of 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000. If the Login does not exist, hopefully you will be able to create it via CREATE LOGIN.
Since the owner in the database is SA, and you want to change the owner recorded in Master to SA, just run
alter authorization on database::[foo_prod] to sa

SQL Server 2012 - Finding out which transaction logs have been applied to a NORECOVER db

I have a copy of an offsite production database used for reporting which is running on SQL Server 2012. I want to start updating it hourly with transaction logs from that offsite production database.
No big deal, restore a full backup (w/ NORECOVERY) to get things started and apply the transaction logs (w/ NORECOVERY) as they come in.
However, in the event of a problem with the restore (or with getting the log files) I could end up with several transaction log files, some of which have been applied and others that have not. When that happens, how do I figure out which file to start with in my TSQL script?
I tried looking in the restore history table like this:
select distinct
h.destination_database_name,
h.restore_date,
s.server_name,
m.physical_device_name as backup_device,
f.physical_name
from
msdb..restorehistory h
inner join
msdb..backupfile f on h.backup_set_id = f.backup_set_id
inner join
msdb..backupset s on f.backup_set_id = s.backup_set_id
inner join
msdb..backupmediafamily m on s.media_set_id = m.media_set_id
where
h.destination_database_name = 'mydb'
and h.restore_date > (GETDATE() -0.5)
order by
h.restore_date
But checking restorehistory is no good because the NORECOVERY flag means no records have been added in that table. So is there another way to check this, via T-SQL, that works for a NORECOVERY database?
Assuming this is a rare manual operation, the simplest way to is scan the errorlog.
SQL Server's built-in log shipping (and some third party implementations) have tables, views and user interfaces that make this simpler.

backup database task in SSIS

I am new to SSIS ,and I am trying to make a package that automatically creates a backup of the Prod server and restores it on Dev server. For that I am using a backup database task in control flow . I am trying to store the name of the backup file that is created into a variable and then pass the same to the restore task . But I am not able to understand the format in which this filename is created . It is like
\Configurations_backup_2015_07_29_133104_1546397.bak'.
Can anyone help me with how to fetch this name and pass it directly to restore task.
Thanks
Try executing below query to get the backup name created by the task. The same can be stored into a variable and passed on for restore.
select top 1
bs.database_name,
bmf.physical_device_name
from
msdb.dbo.backupset as bs
inner join
msdb.dbo.backupmediafamily as bmf
on bmf.media_set_id = bs.media_set_id
where
bs.database_name = 'master' --mention your database name
and bs.type = 'D'
order by
bs.backup_start_date desc

SQL Server 2008 SSIS Export Wizard - find out how long it took

We ran a SQL Server 2008 Export wizard overnight to copy 100+ tables from one server to another. The process worked fine (if a little slow over our network)
The report produced at the end does not show a start and end time for the operation for some unknown reason
I know the names of all the tables created (they are brand new on the target server) - is there any SQL I can run against sys.tables or a similar table that can show the last write time against the table?
The create_date value on sys.tables seems to imply that the export wizard creates empty copies of each table before starting the data insert rather than doing each one in turn
You can get an estimation by looking at the index usage statistics
SELECT Object_Name(object_id) As object
, Max(last_user_update) As last_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
GROUP
BY Object_Name(object_id)
ORDER
BY object

Database is in Transition state

Today I was trying to restore a database over an already existing database, I simply right clicked the database in SSMS --> Tasks --> Take Offline so I could restore the database.
A small pop up window appeared and showed Query Executing..... for sometime and then threw an error saying Database is in use cannot take it offline. From which I gathered there are some active connections to that database so I tried to execute the following query
USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO
Again at this point the SSMS showed Query Executing..... for a sometime and then threw the following error:
Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
After this I could not connect to the database through SSMS. and when I tried to Take it offline using SSMS it threw an error saying:
Database is in Transition. Try later .....
At this point I simply could'nt touch the database anything I tried it returned the same error message Database is in Transition.
I got on google read some questions where people had faced similar issue and they recommended to close the SSMS and open it again, So did I and
Since it was only a dev server I just deleted the database using SSMS and restored on a new database.
My question is what could have possibly caused this ?? and how I can Avoid this to happen in future and if I ever end up in the same situation in future is there any other way of fixing it other then deleting the whole database ???
Thank you
Check this out. This will help you release locks. Works great! https://dba.stackexchange.com/questions/57432/database-is-in-transition-error
use this
select
l.resource_type,
l.request_mode,
l.request_status,
l.request_session_id,
r.command,
r.status,
r.blocking_session_id,
r.wait_type,
r.wait_time,
r.wait_resource,
request_sql_text = st.text,
s.program_name,
most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;
and then
for each processnumber
kill <processnumber>
Check out this article.
http://oostdam.info/index.php/sectie-blog/289-sql-error-952-8ways-to-solve-it
I use TSQL most of the time, so I have not run into this issue yet.
What version is the SQL Server database and at what patch level?
Next time, do a usp_who2 to see what threads are running.
http://craftydba.com/wp-content/uploads/2011/09/usp-who2.txt
Since the output is in a table, you can search by database.
Kill all threads using the database before the trying the ALTER statement.
A night about 6 months ago, I had a terrible time getting a 2000 database offline due to an application constantly hitting it. I eventually disabled the user account so I would not get any more logins.

Resources