Hata - Veritabanı kullanımda olduğundan özel erişim elde edilemedi


121

Aslında bir yedekleme dosyasından bir veritabanını geri yüklemek için bir komut dosyası (Sql Server 2008'de) yapmaya çalışıyorum. Aşağıdaki kodu yaptım ve bir hata alıyorum -

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.

Bu sorunu nasıl çözerim?

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

Bunu çalıştırabilirsem, belki birden fazla veritabanını bir klasörden geri yüklemek için güvenilir bir komut dosyası oluşturabilirim. İnternette güvenilir bir kod bulamadım. Kodum, SS'nin kendisi tarafından oluşturulduğu için güvenilir olabilir.
Steam

Yanıtlar:


106

Bir veritabanını geri yüklüyorsanız, bu veritabanındaki mevcut işlemleri umursamadığınızı varsayacağım. Sağ? Öyleyse, bu sizin için çalışmalıdır:

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

Şimdi, dikkat edilmesi gereken bir ek öğe. Db'yi tek kullanıcı moduna ayarladıktan sonra, başka biri db'ye bağlanmayı deneyebilir. Başarılı olurlarsa, geri yüklemenize devam edemezsiniz. Bu bir yarış! Benim önerim, üç ifadeyi de aynı anda çalıştırmaktır.


bir işlemdeki üç ifadenin tümü.
Steam

1
Adventureworks veritabanına her erişmeye çalıştığımda SSMS'im yanıt vermiyor moduna giriyor.
Steam

2
Aslında demek USE masterdeğil USER master.
eşzamansız

7
ALTER DATABASE [AdventureWorksDW] SET MULTI_USERVeritabanının normal çoklu kullanıcı moduna döndüğünden emin olmak için sadece sonuna ekleyin .
gnaanaa

1
@gnaanaa: Yedeklenen veritabanı SINGLE_USERyedekleme zamanında SINGLE_USERmoddaysa, yedekleme geri yüklendiğinde modda olacaktır . O olsaydı MULTI_USERyedekleme zamanda modunda, bu olacak MULTI_USERo geri yüklendiğinde modu. Harika bir noktaya değindiniz: geri yükleme bittikten sonra kesinlikle kontrol etmeye değer. Ayrıca , yedekleme medyasında BAŞLIKYI GERİ YÜKLE'yi çalıştırabilir IsSingleUserve Flagssütunda bit bazında matematik kontrol edebilir veya yapabilirsiniz .
Dave Mason

237
  1. Dosyayı geri yüklemek için yolu ayarlayın.
  2. Sol taraftaki "Seçenekler" i tıklayın.
  3. "Geri yüklemeden önce kuyruk günlüğünü yedekle" seçeneğinin işaretini kaldırın
  4. Onay kutusunu işaretleyin - "Hedef veritabanına mevcut bağlantıları kapat". görüntü açıklamasını buraya girin
  5. Tamam'ı tıklayın.

16
Benim durumumda bu onay kutusu griydi. Ancak baştan başladım ve geri yüklenecek kaynağı seçmeden önce kutuyu işaretleyebildim. Yedekleme dosyasını seçtikten sonra seçenek tekrar gri oldu, ancak kutu yine de işaretlendi ve geri yükleme çalıştı.
phansen

3
Beni SQL yazmaktan kurtardığın için tebrikler. Tüm cevaplar arasında tek GUI yöntemi.
Lionet Chen

Umarım bu da diğerleri gibi benim için işe yarardı. Ama benim için onay kutusu her zaman gri renkte kaldı. Andrei Karchueuski'nin aşağıdaki cevabı benim için çalıştı.
Devraj Gadhavi

11
Ayrıca geri yükleme yapmadan önce "Geri yüklemeden önce kuyruk günlüğü yedeklemesini al" seçeneğinin işaretini kaldırmam gerekiyordu.
Hylle

3
"Geri yüklemeden önce kuyruk günlüğü yedeklemesini al" seçeneğinin de işaretlenmemiş olması gerekir. Teşekkürler
jedu

50

veritabanını geri yüklemeden önce bu sorguyu yürütün:

alter database [YourDBName] 
set offline with rollback immediate

ve bunu geri yükledikten sonra:

  alter database [YourDBName] 
  set online

Pilot uygulama bağlantısı sorgumun geri yüklemesini ve sonraki MULTI_USER çağrısını geçtikten sonra SINGLE_USER üzerinden bu yönteme geçmeyi sonlandırdım. Geri yükleme özel erişim elde edemedi ve eski veritabanı SINGLE_USER modunda bırakıldı.
Smörgåsbord

3
bu benim için çalıştı. ve geri yüklediğinizde otomatik olarak çevrimiçi olur.
Dileep

3
Bu işe yarıyor ve kabul edilen cevapta yarış koşullarından kaçınıyor.
Scott Whitlock

1
Teşekkürler Andrei.
Erdoğan

11

Benim için çözüm şudur:

  1. Sol taraftaki optoin sekmesinde Mevcut veritabanının üzerine yaz (DEĞİŞTİRİLMELİDİR) seçeneğini işaretleyin.

  2. Diğer tüm seçeneklerin işaretini kaldırın.

  3. Kaynak ve hedef veritabanını seçin.

  4. Tamam'ı tıklayın.

Bu kadar.


1
Benim için de çalıştı. "Geri yüklemeden önce kuyruk günlüğü yedeklemesini al" seçeneğinin işaretini de kaldırmak zorunda kaldım.
yuva

7

Veritabanını geri yüklemeden önce veritabanına açılan tüm bağlantıları bulmak ve sonlandırmak için aşağıdaki komut dosyasını kullanın.

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

Umarım bu yardımcı olur ...


3

Aşağıdaki gibi geri yüklemeyi denemeden önce db'yi tek kullanıcı moduna ayarlamanız gerektiğini düşünüyorum, sadece kullandığınızdan emin olun. master

USE master
GO
ALTER DATABASE AdventureWorksDW
SET SINGLE_USER

2

Sqlexpress hizmetini yeniden başlattım ve ardından geri yükleme tamamlandı


olumsuz oy hakkında ne söyleyebilirim ... benim için işe yaradı!
BabaNew

1
OP'nin geri yükleme komut dosyasıyla ilgili bir sorunu vardı çünkü DB'sinin zaten kullanımda olabileceği gerçeğini dikkate almadı. Çözüm, komut dosyasını, DB'ye özel erişim sağlayan uygun komutlarla güncellemekti. Hizmeti yeniden başlatmak sizin için işe yaramış olsa da, sorunu için uygun çözüm bu değildi.
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

Çözüm 1: SQL hizmetlerini yeniden başlatın ve DB'yi geri yüklemeyi deneyin Çözüm 2: Sistemi / sunucuyu yeniden başlatın ve DB'yi geri yüklemeyi deneyin 3. Çözüm: Mevcut DB'yi geri alın, Geçerli / hedef DB'yi silin ve DB'yi geri yüklemeyi deneyin.


1

DB'yi tek kullanıcı moduna ayarlamak benim için işe yaramadı, ancak çevrimdışı duruma getirmek ve ardından tekrar çevrimiçi duruma getirmek işe yaradı. Görevler altında, DB'nin sağ tıklama menüsünde bulunur.

İletişim kutusundaki 'Tüm Etkin Bağlantıları Bırak' seçeneğini işaretlediğinizden emin olun.


0

Üretimden geliştirmeye veritabanı geri yüklemesinin bir yolu:

NOT: Üretim veritabanını günlük geliştirmeye itmek için SSAS işi aracılığıyla yapıyorum:

Adım 1: Geliştirmede önceki gün yedeklemesini silin:

declare @sql varchar(1024);

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

Adım 2: Üretim veritabanını geliştirmeye kopyalayın:

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

3. Adım: .sql komut dosyasını çalıştırarak geri yükleyin

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

AE11_Restore.sql dosyasındaki kod:

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'yi geri yüklemek için yeterli disk alanı olmadığında bu hatayı aldım. Biraz alanı temizlemek sorunu çözdü.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.