ข้อผิดพลาด - ไม่สามารถรับสิทธิ์การเข้าถึงแบบเอกสิทธิ์เฉพาะบุคคลเนื่องจากฐานข้อมูลถูกใช้งาน


121

ฉันพยายามสร้างสคริปต์ (ใน 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

ฉันจะถือว่าถ้าคุณกำลังกู้คืนฐานข้อมูลคุณจะไม่สนใจเกี่ยวกับธุรกรรมที่มีอยู่ในฐานข้อมูลนั้น ขวา? หากเป็นเช่นนั้นสิ่งนี้จะเหมาะกับคุณ:

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 เป็นโหมดผู้ใช้คนเดียวอาจมีคนอื่นพยายามเชื่อมต่อกับฐานข้อมูล หากดำเนินการสำเร็จคุณจะไม่สามารถดำเนินการกู้คืนได้ เป็นการแข่งขัน! คำแนะนำของฉันคือเรียกใช้ทั้งสามคำสั่งในครั้งเดียว


ทั้งสามรายการในการทำธุรกรรม
ไอน้ำ

1
SSMS ของฉันเข้าสู่โหมดไม่ตอบสนองเมื่อใดก็ตามที่ฉันพยายามเข้าถึงฐานข้อมูล adventureworks นั้น
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คอลัมน์
Dave Mason

239
  1. กำหนดเส้นทางเพื่อกู้คืนไฟล์
  2. คลิก "ตัวเลือก" ทางด้านซ้ายมือ
  3. ยกเลิกการเลือก "สำรองข้อมูลหางล็อกก่อนกู้คืน"
  4. ทำเครื่องหมายในช่อง - "ปิดการเชื่อมต่อกับฐานข้อมูลปลายทางที่มีอยู่" ใส่คำอธิบายภาพที่นี่
  5. คลิกตกลง

16
ในกรณีของฉันช่องทำเครื่องหมายเป็นสีเทา อย่างไรก็ตามฉันเริ่มต้นใหม่และสามารถทำเครื่องหมายในช่องก่อนที่จะเลือกแหล่งที่จะกู้คืนได้ หลังจากเลือกไฟล์สำรองแล้วตัวเลือกจะเป็นสีเทาอีกครั้ง แต่ยังคงทำเครื่องหมายในช่องและการกู้คืนใช้งานได้
phansen

3
ความรุ่งโรจน์ในการช่วยฉันจากการพิมพ์ SQL วิธี GUI เดียวในบรรดาคำตอบทั้งหมด
Lionet Chen

ฉันหวังว่านี่จะได้ผลสำหรับฉันเหมือนคนอื่น ๆ แต่สำหรับฉันช่องทำเครื่องหมายยังคงเป็นสีเทาเสมอ คำตอบของ Andrei Karchueuski ด้านล่างด้านล่างได้ผลสำหรับฉัน
Devraj Gadhavi

11
ฉันยังต้องยกเลิกการเลือก "Take tail-log backup ก่อนที่จะกู้คืน" ก่อนจึงจะสามารถกู้คืนได้
Hylle

3
"สำรองข้อมูลหางล็อกก่อนที่จะกู้คืน" ซึ่งจะต้องยกเลิกการเลือกเช่นกัน ขอบคุณ
jedu

50

เรียกใช้แบบสอบถามนี้ก่อนที่จะกู้คืนฐานข้อมูล:

alter database [YourDBName] 
set offline with rollback immediate

และสิ่งนี้หลังจากกู้คืน:

  alter database [YourDBName] 
  set online

ฉันลงเอยด้วยการเปลี่ยนไปใช้วิธีนี้ใน SINGLE_USER หลังจากการเชื่อมต่อแอปพลิเคชันนำร่องเอาชนะการเรียกคืนการสืบค้นของฉันและการเรียก MULTI_USER ในภายหลัง การกู้คืนล้มเหลวในการเข้าถึงพิเศษและฐานข้อมูลเก่าถูกทิ้งไว้ในโหมด SINGLE_USER
Smörgåsbord

3
สิ่งนี้ได้ผลสำหรับฉัน และจะออนไลน์โดยอัตโนมัติเมื่อคุณกู้คืน
Dileep

3
วิธีนี้ใช้ได้ผลและหลีกเลี่ยงสภาพการแข่งขันในคำตอบที่ยอมรับ
Scott Whitlock

1
ขอบคุณ Andrei
Erdogan

11

สำหรับฉันวิธีแก้ปัญหาคือ:

  1. เลือกเขียนทับฐานข้อมูลที่มีอยู่ (WITH REPLACE) ในแท็บออปโป้ทางด้านซ้ายมือ

  2. ยกเลิกการเลือกตัวเลือกอื่น ๆ ทั้งหมด

  3. เลือกฐานข้อมูลต้นทางและปลายทาง

  4. คลิกตกลง

แค่นั้นแหละ.


1
ทำงานให้ฉันเช่นกัน ฉันต้องยกเลิกการเลือก "Take tail-log backup before restore" ด้วย
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

ฉันคิดว่าคุณต้องตั้งค่าฐานข้อมูลเป็นโหมดผู้ใช้คนเดียวก่อนที่จะพยายามกู้คืนเช่นด้านล่างตรวจสอบให้แน่ใจว่าคุณใช้ 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


1

การตั้งค่าฐานข้อมูลเป็นโหมดผู้ใช้คนเดียวไม่ได้ผลสำหรับฉัน แต่การทำให้เป็นแบบออฟไลน์แล้วนำกลับมาออนไลน์ก็ใช้งานได้ ในเมนูคลิกขวาของ DB ใต้ Tasks

อย่าลืมตรวจสอบตัวเลือก 'Drop All Active Connections' ในกล่องโต้ตอบ



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.