Lỗi - Không thể lấy được quyền truy cập độc quyền vì cơ sở dữ liệu đang được sử dụng


118

Tôi thực sự đang cố gắng tạo một tập lệnh (trong Sql Server 2008) để khôi phục một cơ sở dữ liệu từ một tệp sao lưu. Tôi đã tạo mã sau và gặp lỗi -

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.

Làm sao để sửa lỗi này ?

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

Nếu tôi có thể làm cho điều này hoạt động, có lẽ tôi có thể tạo một tập lệnh đáng tin cậy để khôi phục nhiều cơ sở dữ liệu từ một thư mục. Tôi không thể tìm thấy bất kỳ mã đáng tin cậy nào trên mạng. Mã của tôi có thể đáng tin cậy vì nó được tạo bởi chính SS.
Steam

Câu trả lời:


105

Tôi giả sử rằng nếu bạn đang khôi phục một db, bạn không quan tâm đến bất kỳ giao dịch hiện có nào trên db đó. Đúng? Nếu vậy, điều này sẽ phù hợp với bạn:

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

Bây giờ, một mục bổ sung cần lưu ý. Sau khi bạn đặt db thành chế độ người dùng duy nhất, người khác có thể cố gắng kết nối với db. Nếu chúng thành công, bạn sẽ không thể tiếp tục quá trình khôi phục của mình. Đó là một cuộc đua! Đề xuất của tôi là chạy cả ba câu lệnh cùng một lúc.


cả ba câu lệnh trong một giao dịch.
Steam

1
SSMS của tôi chuyển sang chế độ không phản hồi bất cứ khi nào tôi cố gắng truy cập cơ sở dữ liệu của các tác phẩm phiêu lưu đó.
Steam

2
Anh ấy thực sự có nghĩa là USE master, không phải USER master.
async

7
Chỉ cần thêm ALTER DATABASE [AdventureWorksDW] SET MULTI_USERvào cuối để đảm bảo cơ sở dữ liệu trở lại ở chế độ đa người dùng bình thường.
gnaanaa

1
@gnaanaa: Nếu cơ sở dữ liệu đã SINGLE_USERsao lưu ở chế độ tại thời điểm sao lưu, thì nó sẽ ở SINGLE_USERchế độ khi bản sao lưu được khôi phục. Nếu nó ở MULTI_USERchế độ tại thời điểm sao lưu, nó sẽ ở MULTI_USERchế độ khi nó được khôi phục. Bạn thực hiện một điểm tuyệt vời: nó chắc chắn đáng để kiểm tra sau khi khôi phục xong. Bạn cũng có thể chạy KHÔI PHỤC HEADERONLY trên phương tiện dự phòng và kiểm tra IsSingleUserhoặc làm phép toán theo từng bit trên Flagscột.
Dave Mason

236
  1. Đặt đường dẫn để khôi phục tệp.
  2. Nhấp vào "Tùy chọn" ở phía bên trái.
  3. Bỏ chọn "Sao lưu tail-log trước khi khôi phục"
  4. Đánh dấu vào hộp kiểm - "Đóng các kết nối hiện có với cơ sở dữ liệu đích". nhập mô tả hình ảnh ở đây
  5. Bấm OK.

16
Trong trường hợp của tôi, hộp kiểm đó chuyển sang màu xám. Tuy nhiên, tôi đã bắt đầu lại và có thể chọn hộp trước khi chọn nguồn để khôi phục. Sau khi chọn tệp sao lưu, tùy chọn lại chuyển sang màu xám nhưng hộp vẫn được chọn và quá trình khôi phục đã hoạt động.
phansen

3
Kudos vì đã cứu tôi khỏi việc nhập SQL. Phương pháp GUI duy nhất trong số tất cả các câu trả lời.
Lionet Chen

Tôi hy vọng điều này sẽ làm việc cho tôi như những người khác. Nhưng đối với tôi, hộp kiểm luôn chuyển sang màu xám. Câu trả lời của Andrei Karchueuski dưới đây, phù hợp với tôi.
Devraj Gadhavi

11
Tôi cũng phải bỏ chọn "Hãy sao lưu tail-log trước khi khôi phục" trước khi có thể khôi phục.
Hylle

3
"Hãy sao lưu tail-log trước khi khôi phục" điều này cũng cần được bỏ chọn. Cảm ơn
jedu

50

thực hiện truy vấn này trước khi khôi phục cơ sở dữ liệu:

alter database [YourDBName] 
set offline with rollback immediate

và cái này sau khi khôi phục:

  alter database [YourDBName] 
  set online

Tôi đã kết thúc chuyển sang phương pháp này qua SINGLE_USER sau khi kết nối ứng dụng thử nghiệm đánh bại khôi phục truy vấn của tôi và cuộc gọi MULTI_USER tiếp theo. Không khôi phục được để có quyền truy cập độc quyền và db cũ được để ở chế độ SINGLE_USER.
Smörgåsbord

3
điều này đã làm việc cho tôi. và nó sẽ tự động trực tuyến sau khi bạn khôi phục nó.
Dileep

3
Điều này hoạt động và nó tránh điều kiện chủng tộc trong câu trả lời được chấp nhận.
Scott Whitlock

1
Cảm ơn Andrei.
Erdogan

11

Đối với tôi, giải pháp là:

  1. Chọn Ghi đè cơ sở dữ liệu hiện có (CÓ THAY THẾ) trong tab optoins ở phía bên trái.

  2. Bỏ chọn tất cả các tùy chọn khác.

  3. Chọn cơ sở dữ liệu nguồn và đích.

  4. Nhấp vào ok.

Đó là nó.


1
Làm việc cho tôi là tốt. Tôi cũng phải bỏ chọn "Sao lưu tail-log trước khi khôi phục".
yuva 20/09/18

7

Sử dụng tập lệnh sau để tìm và loại bỏ tất cả các kết nối đã mở đến cơ sở dữ liệu trước khi khôi phục cơ sở dữ liệu.

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...'

Hy vọng điều này sẽ giúp ...


3

Tôi nghĩ bạn chỉ cần đặt db thành chế độ người dùng duy nhất trước khi cố gắng khôi phục, như bên dưới, chỉ cần đảm bảo rằng bạn đang sử dụng master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER

2

Tôi vừa khởi động lại dịch vụ sqlexpress và sau đó khôi phục hoàn thành tốt


tôi có thể nói gì về downvote ... đối với tôi nó đã hoạt động!
BabaNew

1
OP đã gặp vấn đề với tập lệnh khôi phục của mình vì anh ấy không tính đến thực tế là DB của anh ấy có thể đã được sử dụng. Giải pháp là cập nhật tập lệnh của anh ta với các lệnh thích hợp cho phép anh ta truy cập độc quyền vào DB. Mặc dù việc khởi động lại dịch vụ có thể hiệu quả với bạn, nhưng đó không phải là giải pháp thích hợp cho vấn đề của anh ấy.
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

Giải pháp 1: Khởi động lại các dịch vụ SQL và cố gắng khôi phục DB Giải pháp 2: Khởi động lại hệ thống / máy chủ và cố gắng khôi phục DB Giải pháp 3: Lấy lại DB hiện tại, Xóa DB hiện tại / đích và cố gắng khôi phục DB.


1

Đặt DB thành chế độ một người dùng không hoạt động đối với tôi, nhưng việc sử dụng nó ở chế độ ngoại tuyến và sau đó đưa nó trở lại trực tuyến đã hoạt động. Nó nằm trong menu chuột phải của DB, bên dưới Nhiệm vụ.

Đảm bảo kiểm tra tùy chọn 'Bỏ tất cả kết nối đang hoạt động' trong hộp thoại.


0

Đây là cách tôi đang thực hiện khôi phục cơ sở dữ liệu từ sản xuất đến phát triển:

LƯU Ý: Tôi đang thực hiện thông qua công việc SSAS để thúc đẩy cơ sở dữ liệu sản xuất phát triển hàng ngày:

Bước 1: Xóa bản sao lưu ngày hôm trước trong quá trình phát triển:

declare @sql varchar(1024);

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

Bước 2: Sao chép cơ sở dữ liệu sản xuất để phát triển:

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

Bước 3: Khôi phục bằng cách chạy tập lệnh .sql

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

Mã nằm trong tệp 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

Tôi gặp lỗi này khi không có đủ dung lượng đĩa để khôi phục Db. Làm sạch một số không gian đã giải quyết nó.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.