Kesalahan - Akses eksklusif tidak dapat diperoleh karena database sedang digunakan

119

Saya sebenarnya mencoba membuat skrip (di Sql Server 2008) untuk memulihkan satu database dari satu file cadangan. Saya membuat kode berikut dan saya mendapatkan kesalahan -

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.

Bagaimana cara memperbaiki masalah ini?

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
Uap
sumber
Jika saya bisa membuat ini berfungsi, mungkin saya bisa membuat skrip yang andal untuk memulihkan banyak database dari satu folder. Saya tidak dapat menemukan kode yang dapat diandalkan di internet. Kode saya mungkin dapat diandalkan karena dibuat oleh SS itu sendiri.
Steam

Jawaban:

106

Saya akan berasumsi bahwa jika Anda memulihkan db, Anda tidak peduli dengan transaksi yang ada di db itu. Baik? Jika demikian, ini seharusnya berhasil untuk Anda:

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

Sekarang, satu hal tambahan yang harus diperhatikan. Setelah Anda menyetel db ke mode pengguna tunggal, orang lain dapat mencoba menyambung ke db. Jika berhasil, Anda tidak dapat melanjutkan pemulihan. Ini balapan! Saran saya adalah menjalankan ketiga pernyataan sekaligus.

Dave Mason
sumber
ketiga pernyataan dalam transaksi.
Steam
1
SSMS saya masuk ke mode tidak merespons setiap kali saya mencoba mengakses database petualangan itu.
Steam
2
Dia sebenarnya bermaksud USE master, tidak USER master.
asinkron
7
Cukup tambahkan ALTER DATABASE [AdventureWorksDW] SET MULTI_USERdi bagian akhir untuk memastikan database kembali ke mode multi-pengguna normal.
gnaanaa
1
@gnaanaa: Jika basis data yang dicadangkan berada dalam SINGLE_USERmode pada waktu pencadangan, itu akan berada dalam SINGLE_USERmode ketika cadangan dipulihkan. Jika berada dalam MULTI_USERmode pada waktu pencadangan, itu akan berada dalam MULTI_USERmode saat dipulihkan. Anda membuat poin yang bagus: itu pasti layak untuk diperiksa setelah pemulihan selesai. Anda juga dapat menjalankan RESTORE HEADERONLY di media cadangan dan memeriksa IsSingleUseratau melakukan matematika bijak di Flagskolom tersebut.
Dave Mason
236
  1. Tetapkan jalur untuk memulihkan file.
  2. Klik "Opsi" di sisi kiri.
  3. Hapus centang "Ambil cadangan tail-log sebelum memulihkan"
  4. Centang kotak - "Tutup koneksi yang ada ke database tujuan". masukkan deskripsi gambar di sini
  5. Klik OK.
Vinu M Shankar
sumber
16
Dalam kasus saya, kotak centang itu berwarna abu-abu. Namun saya memulai kembali dan dapat mencentang kotak sebelum memilih sumber untuk memulihkan. Setelah memilih file cadangan, opsi menjadi abu-abu lagi tetapi kotak masih dicentang dan pemulihan berfungsi.
phansen
3
Kudos karena menyelamatkan saya dari mengetik SQL. Satu-satunya metode GUI di antara semua jawaban.
Lionet Chen
Saya berharap ini akan berhasil untuk saya seperti orang lain. Namun bagi saya kotak centang selalu berwarna abu-abu. Jawaban Andrei Karchueuski di bawah ini, berhasil untuk saya.
Devraj Gadhavi
11
Saya juga harus menghapus centang "Ambil cadangan tail-log sebelum memulihkan" sebelum saya dapat memulihkan.
Hylle
3
"Ambil cadangan tail-log sebelum memulihkan" ini juga perlu dihapus centangnya. Terima kasih
jedu
50

jalankan kueri ini sebelum memulihkan database:

alter database [YourDBName] 
set offline with rollback immediate

dan yang ini setelah memulihkan:

  alter database [YourDBName] 
  set online
Andrei Karcheuski
sumber
Saya akhirnya beralih ke metode ini melalui SINGLE_USER setelah koneksi aplikasi percontohan mengalahkan pemulihan kueri saya dan panggilan MULTI_USER berikutnya. Pemulihan gagal mendapatkan akses eksklusif dan db lama dibiarkan dalam mode SINGLE_USER.
Smörgåsbord
3
ini berhasil untuk saya. dan online secara otomatis setelah Anda memulihkannya.
Dileep
3
Ini berfungsi, dan ini menghindari kondisi balapan dalam jawaban yang diterima.
Scott Whitlock
1
Terima kasih Andrei.
Erdogan
11

Bagi saya, solusinya adalah:

  1. Centang Timpa database yang sudah ada (WITH REPLACE) di tab optoins di sisi kiri.

  2. Hapus centang semua opsi lain.

  3. Pilih database sumber dan tujuan.

  4. Klik ok.

Itu dia.

Aayush Verma
sumber
1
Bekerja untuk saya juga. Saya juga harus menghapus centang "Ambil cadangan tail-log sebelum memulihkan".
yuva
7

Gunakan skrip berikut untuk menemukan dan mematikan semua koneksi yang dibuka ke database sebelum memulihkan database.

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

Semoga ini bisa membantu ...

Aqeel Haider
sumber
3

Saya pikir Anda hanya perlu mengatur db ke mode pengguna tunggal sebelum mencoba memulihkan, seperti di bawah ini, pastikan Anda menggunakan master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER
Jason
sumber
2

Saya baru saja memulai kembali layanan sqlexpress dan kemudian pemulihan selesai dengan baik

BabaNew
sumber
apa yang bisa saya katakan tentang downvote ... bagi saya itu berhasil!
BabaNew
1
OP memiliki masalah dengan skrip pemulihannya karena dia tidak mempertimbangkan fakta bahwa DB-nya mungkin sudah digunakan. Solusinya adalah memperbarui skripnya dengan perintah yang tepat sehingga dia memiliki akses eksklusif ke DB. Saat memulai ulang layanan mungkin berhasil untuk Anda, itu bukanlah solusi yang tepat untuk masalahnya.
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
Puneeth
sumber
1

Solusi 1: Mulai ulang layanan SQL dan coba pulihkan DB Solusi 2: Mulai ulang sistem / server dan coba pulihkan DB Solusi 3: Ambil kembali DB saat ini, Hapus DB saat ini / tujuan dan coba pulihkan DB.

Joseph Joy
sumber
1

Mengatur DB ke mode pengguna tunggal tidak berhasil untuk saya, tetapi menjadikannya offline, dan kemudian membawanya kembali online berhasil. Ini ada di menu klik kanan DB, di bawah Tasks.

Pastikan untuk mencentang opsi 'Jatuhkan Semua Koneksi Aktif' di dialog.

Jeffrey Harmon
sumber
0

Inilah cara saya melakukan pemulihan database dari produksi ke pengembangan:

CATATAN: Saya melakukannya melalui tugas SSAS untuk mendorong database produksi ke pengembangan setiap hari:

Langkah 1: Hapus cadangan hari sebelumnya dalam pengembangan:

declare @sql varchar(1024);

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

Langkah2: Salin database produksi ke pengembangan:

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

Langkah3: Pulihkan dengan menjalankan skrip .sql

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

Kode yang ada di dalam file 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;
NonProgrammer
sumber
0

Saya mendapat kesalahan ini ketika tidak ada cukup ruang disk untuk memulihkan Db. Membersihkan beberapa ruang memecahkannya.

pengguna3790083
sumber
0

mengubah db asli ke offline berhasil untuk saya

buat offline

Ali Karaca
sumber