오류-데이터베이스가 사용 중이므로 독점 액세스를 얻을 수 없습니다.


119

실제로 하나의 백업 파일에서 하나의 데이터베이스를 복원하는 스크립트 (Sql Server 2008에서)를 만들려고합니다. 다음 코드를 작성했는데 오류가 발생합니다.

Msg 3101, Level 16, State 1, Line 3
Exclusive access could not be obtained because 
the database is in use.
Msg 3013, Level 16, State 1, Line 3
RESTORE DATABASE is terminating abnormally.

이 문제를 어떻게 해결합니까?

IF DB_ID('AdventureWorksDW') IS NOT NULL 
BEGIN 
RESTORE DATABASE [AdventureWorksDW] 
FILE = N'AdventureWorksDW_Data' 
FROM  
DISK = N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\Backup\AdventureWorksDW.bak' 
WITH  FILE = 1, 
MOVE N'AdventureWorksDW_Data' 
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW.mdf', 
MOVE N'AdventureWorksDW_Log'  
TO N'C:\Program Files\Microsoft SQL Server\
MSSQL10_50.SS2008\MSSQL\DATA\AdventureWorksDW_0.LDF', 
NOUNLOAD,  STATS = 10 
END

이 작업을 수행 할 수 있다면 하나의 폴더에서 여러 데이터베이스를 복원하는 안정적인 스크립트를 만들 수 있습니다. 인터넷에서 신뢰할 수있는 코드를 찾을 수 없습니다. 내 코드는 SS 자체에서 생성되기 때문에 신뢰할 수 있습니다.
Steam

답변:


106

DB를 복원하는 경우 해당 DB의 기존 트랜잭션에 신경 쓰지 않는다고 가정합니다. 권리? 그렇다면 다음과 같이 작동합니다.

USE master
GO

ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO

RESTORE DATABASE AdventureWorksDW
FROM ...
...
GO

이제 알아야 할 추가 항목이 하나 있습니다. db를 단일 사용자 모드로 설정하면 다른 사람이 db에 연결을 시도 할 수 있습니다. 성공하면 복원을 진행할 수 없습니다. 경주입니다! 내 제안은 한 번에 세 가지 문을 모두 실행하는 것입니다.


트랜잭션의 세 문 모두.
Steam

1
해당 adventureworks 데이터베이스에 액세스하려고 할 때마다 SSMS가 응답하지 않는 모드가됩니다.
Steam

2
그는 실제로 의미 USE master가 아닙니다 USER master.
async

7
ALTER DATABASE [AdventureWorksDW] SET MULTI_USER데이터베이스가 일반 다중 사용자 모드로 돌아가는지 확인하려면 끝에 추가 하십시오.
gnaanaa

1
@gnaanaa : 백업 된 데이터베이스가 SINGLE_USER백업시 모드에 있었다면 SINGLE_USER백업이 복원 될 때 모드가됩니다. MULTI_USER백업시 모드 였다면 MULTI_USER복원시 모드로됩니다. 중요한 점을 지적합니다. 복원이 완료된 후 확인하는 것이 좋습니다. 백업 미디어에서 RESTORE HEADERONLY 를 실행 IsSingleUser하고 Flags열 에서 비트 단위 연산을 확인 하거나 수행 할 수도 있습니다 .
데이브 메이슨

236
  1. 파일을 복원 할 경로를 설정하십시오.
  2. 왼쪽에있는 "옵션"을 클릭하십시오.
  3. "복원하기 전에 비상 로그 백업 수행"을 선택 취소하십시오.
  4. "대상 데이터베이스에 대한 기존 연결 닫기"확인란을 선택합니다. 여기에 이미지 설명 입력
  5. 확인을 클릭하십시오.

16
제 경우에는 확인란이 회색으로 표시되었습니다. 그러나 다시 시작하여 복원 할 소스를 선택하기 전에 확인란을 선택할 수있었습니다. 백업 파일을 선택한 후 옵션이 다시 회색으로 표시되었지만 상자는 여전히 선택되어 있고 복원이 작동했습니다.
phansen apr

3
SQL 입력에서 나를 구한 것에 대한 찬사. 모든 답변 중 유일한 GUI 방법입니다.
Lionet Chen

나는 이것이 다른 사람들처럼 저에게 효과적 이었기를 바랍니다. 그러나 나를 위해 확인란은 항상 회색으로 유지되었습니다. 아래 의 Andrei Karchueuski의 대답 은 나를 위해 일했습니다.
Devraj Gadhavi

11
또한 복원하기 전에 "복원하기 전에 테일 로그 백업 수행"을 선택 취소해야했습니다.
Hylle

3
"복원하기 전에 비상 로그 백업 수행"도 선택 취소해야합니다. 감사합니다
jedu

50

데이터베이스를 복원하기 전에 다음 쿼리를 실행하십시오.

alter database [YourDBName] 
set offline with rollback immediate

그리고 이것은 복원 후 :

  alter database [YourDBName] 
  set online

파일럿 응용 프로그램 연결이 내 쿼리의 복원 및 후속 MULTI_USER 호출을 이기면 SINGLE_USER를 통해이 방법으로 전환했습니다. 복원이 독점 액세스를 얻지 못했고 이전 db가 SINGLE_USER 모드로 남아 있습니다.
Smörgåsbord

3
이것은 나를 위해 일했습니다. 복원하면 자동으로 온라인 상태가됩니다.
Dileep

3
이것은 작동하며 수락 된 답변에서 경쟁 조건을 피합니다.
스콧 위트 락

1
감사합니다 Andrei.
Erdogan

11

저에게 해결책은 다음과 같습니다.

  1. 왼쪽 옵토 인 탭에서 기존 데이터베이스 덮어 쓰기 (WITH REPLACE)를 선택합니다.

  2. 다른 모든 옵션을 선택 취소하십시오.

  3. 소스 및 대상 데이터베이스를 선택하십시오.

  4. 확인을 클릭하십시오.

그게 다야.


1
나를 위해 일했습니다. "복원 전에 테일 로그 백업 수행"도 선택 취소해야했습니다.
yuva

7

다음 스크립트를 사용하여 데이터베이스를 복원하기 전에 데이터베이스에 대해 열려있는 모든 연결을 찾아 종료하십시오.

declare @sql as varchar(20), @spid as int

select @spid = min(spid)  from master..sysprocesses  where dbid = db_id('<database_name>') 
and spid != @@spid    

while (@spid is not null)
begin
    print 'Killing process ' + cast(@spid as varchar) + ' ...'
    set @sql = 'kill ' + cast(@spid as varchar)
    exec (@sql)

    select 
        @spid = min(spid)  
    from 
        master..sysprocesses  
    where 
        dbid = db_id('<database_name>') 
        and spid != @@spid
end 

print 'Process completed...'

이것이 도움이되기를 바랍니다 ...


3

복원을 시도하기 전에 db를 단일 사용자 모드로 설정해야한다고 생각합니다. 아래와 같이 사용하고 있는지 확인하십시오. master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER

2

방금 sqlexpress 서비스를 다시 시작한 다음 복원이 정상적으로 완료되었습니다.


다운 투표에 대해 뭐라고 말할 수 있나요?
BabaNew

1
OP는 DB가 이미 사용 중일 수 있다는 사실을 고려하지 않았기 때문에 복원 스크립트에 문제가있었습니다. 해결책은 DB에 대한 독점 액세스를 허용하는 적절한 명령으로 스크립트를 업데이트하는 것이 었습니다. 서비스를 다시 시작하면 효과가 있었을 수 있지만 문제에 대한 적절한 해결책은 아닙니다.
PL

1
Use Master
alter database databasename set offline with rollback immediate;

--Do Actual Restore
RESTORE DATABASE databasename
FROM DISK = 'path of bak file'
WITH MOVE 'datafile_data' TO 'D:\newDATA\data.mdf',
MOVE 'logfile_Log' TO 'D:\newDATA\DATA_log.ldf',replace

alter database databasename set online with rollback immediate;
GO

1

해결 방법 1 : SQL 서비스를 다시 시작하고 DB 복원을 시도합니다. 해결 방법 2 : 시스템 / 서버를 다시 시작하고 DB 복원을 시도합니다. 해결 방법 3 : 현재 DB를 복구하고 현재 / 대상 DB를 삭제하고 DB를 복원합니다.


1

DB를 단일 사용자 모드로 설정하는 것은 저에게 효과가 없었지만 오프라인으로 전환 한 다음 다시 온라인으로 전환하면 효과가있었습니다. 작업 아래에있는 DB의 오른쪽 클릭 메뉴에있다.

대화 상자에서 '모든 활성 연결 삭제'옵션을 확인하십시오.


0

프로덕션에서 개발로 데이터베이스 복원을 수행하는 방법은 다음과 같습니다.

참고 : SSAS 작업을 통해 프로덕션 데이터베이스를 매일 개발에 푸시하고 있습니다.

1 단계 : 개발중인 전날 백업 삭제 :

declare @sql varchar(1024);

set @sql = 'DEL C:\ProdAEandAEXdataBACKUP\AE11.bak'
exec master..xp_cmdshell @sql

2 단계 : 프로덕션 데이터베이스를 개발에 복사 :

declare @cmdstring varchar(1000)
set @cmdstring = 'copy \\Share\SQLDBBackup\AE11.bak C:\ProdAEandAEXdataBACKUP'
exec master..xp_cmdshell @cmdstring 

3 단계 : .sql 스크립트를 실행하여 복원

SQLCMD -E -S dev-erpdata1 -b -i "C:\ProdAEandAEXdataBACKUP\AE11_Restore.sql"

AE11_Restore.sql 파일에있는 코드 :

RESTORE DATABASE AE11
FROM DISK = N'C:\ProdAEandAEXdataBACKUP\AE11.bak'
WITH MOVE 'AE11' TO 'E:\SQL_DATA\AE11.mdf',
MOVE 'AE11_log' TO 'D:\SQL_LOGS\AE11.ldf',
RECOVERY;

0

Db를 복원 할 디스크 공간이 충분하지 않을 때이 오류가 발생했습니다. 일부 공간을 청소하면 해결되었습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.