Khi khôi phục bản sao lưu, làm cách nào để ngắt kết nối tất cả các kết nối đang hoạt động?


166

SQL Server 2005 của tôi không khôi phục bản sao lưu do các kết nối hoạt động. Làm thế nào tôi có thể buộc nó?


Bạn có luôn muốn hủy tất cả các kết nối đến cơ sở dữ liệu mà bạn muốn "khôi phục lại" không? Hoặc sẽ có lúc bạn không muốn giết các kết nối hiện có? Ngoài ra, bạn có phải lo lắng về kết nối tổng hợp?
Philip Kelley

Câu trả lời:


177

Studio quản lý máy chủ SQL 2005

Khi bạn nhấp chuột phải vào một cơ sở dữ liệu và nhấp vào Tasksvà sau đó nhấp vào Detach Database, nó sẽ trả về một hộp thoại với các kết nối hoạt động.

Màn hình tách ra

Bằng cách nhấp vào liên kết trong "Tin nhắn", bạn có thể tắt các kết nối đang hoạt động.

Sau đó, bạn có thể hủy các kết nối đó mà không cần tách cơ sở dữ liệu.

Thêm thông tin ở đây .

Studio quản lý máy chủ SQL 2008

Giao diện đã thay đổi cho SQL Server Management studio 2008, đây là các bước (thông qua: Tim Leung )

  1. Bấm chuột phải vào máy chủ trong Object Explorer và chọn 'Activity Monitor'.
  2. Khi điều này mở ra, mở rộng nhóm Quy trình.
  3. Bây giờ sử dụng trình đơn thả xuống để lọc kết quả theo tên cơ sở dữ liệu.
  4. Hủy bỏ các kết nối máy chủ bằng cách chọn tùy chọn 'Kill Process' nhấp chuột phải.

21
Nếu bạn gặp vấn đề tương tự như @Ryan, có thể là do bạn đang sử dụng Management Studio 2008 (hoặc cao hơn), thay vì Management Studio 2005. Để thực hiện điều tương tự trong Management Studio 2008, nhấp chuột phải vào máy chủ của bạn trong Object Explorer và chọn 'Activity Monitor'. Khi điều này mở ra, mở rộng nhóm Quy trình. Bây giờ sử dụng trình đơn thả xuống để lọc kết quả theo tên cơ sở dữ liệu. Bây giờ bạn có thể tắt các kết nối của mình bằng cách chọn tùy chọn 'Kill Process' nhấp chuột phải.
Tim Leung

195

Bạn muốn đặt db của mình thành chế độ người dùng, thực hiện khôi phục, sau đó đặt lại thành nhiều người dùng:

ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK AFTER 60 --this will give your current connections 60 seconds to complete

--Do Actual Restore
RESTORE DATABASE YourDB
FROM DISK = 'D:\BackUp\YourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:\Data\YourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:\Data\YourLDFFile.ldf'

/*If there is no error in statement before database will be in multiuser
mode.  If error occurs please execute following command it will convert
database in multi user.*/
ALTER DATABASE YourDB SET MULTI_USER
GO

Tham khảo: Pinal Dave ( http://blog.SQLAuthority.com )

Tài liệu tham khảo chính thức: https://msdn.microsoft.com/en-us/l Library / ms345598.aspx


11
Thay vì phát hành ROLLBACK NGAY LẬP TỨC, có thể chỉ thích hợp ROLLBACK sau khi TRÌ HOÃN cụ thể, do đó cung cấp cho người dùng các truy vấn cơ hội để hoàn thành một cách tự nhiên.
John Sansom

2
Điểm hay, được cập nhật thành rollback để bao gồm lệnh SAU 60 để cho phép các truy vấn hiện tại hoàn thành
brendan

Xin chào @enamendan, nếu rollback mất hơn 60 giây thì sao? cảm ơn
dùng583912

11
Nếu bạn đang khôi phục cơ sở dữ liệu, các giao dịch mở sẽ bị mất cho dù bạn ROLLBACK IMMEDIATEhay ROLLBACK AFTER 60. Cách duy nhất để lưu dữ liệu đó là thực hiện sao lưu khác sau khi khôi phục. Nhưng bạn đang khôi phục từ một bản sao lưu khác. Vì vậy, những gì đang chờ đợi? Tui bỏ lỡ điều gì vậy?
Dave Mason

@DMason, tôi cũng tò mò về câu hỏi này. Việc sử dụng single_user với chế độ rollback có ngăn chặn các kết nối mới trong thời gian chờ không? Nếu vậy, tôi tự hỏi liệu đó có phải là cách sạch hơn / đẹp hơn để ít nhất là để các hành động chỉ đọc hoàn thành thay vì kết thúc chúng đột ngột không?
Jason

43

Mã này làm việc cho tôi, nó giết tất cả các kết nối hiện có của cơ sở dữ liệu. Tất cả những gì bạn phải làm là thay đổi dòng Set @dbname = 'databaseName' để nó có tên cơ sở dữ liệu của bạn.

Use Master
Go

Declare @dbname sysname

Set @dbname = 'databaseName'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End

sau này tôi đã có thể khôi phục nó


1
Đây là cách tiếp cận nhanh nhất (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson

Nó không làm việc cho tôi. Cơ sở dữ liệu vẫn đang được sử dụng. Tôi sử dụng SQL Server 2008
Marek Bar

Tôi đã tìm thấy việc chạy mã đó nhiều lần, lần này đến lần khác, sẽ NGAY LẬP TỨC. Đôi khi một cái gì đó lẻn vào giữa KILL của bạn và khôi phục. Và đôi khi bạn phải chạy lệnh giết THÌ khôi phục cái này ngay sau cái kia.
John Waclawski

Phụ thuộc hoàn toàn vào sự tích cực của ứng dụng đang cố gắng kết nối lại. Vài người dùng lười biếng? Công trình tuyệt vời. Máy chủ ứng dụng khối lượng lớn kết nối lại trong một giây? Không nhiều lắm.
BradC

5

Thử cái này:

DECLARE UserCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT
    spid
FROM
    master.dbo.sysprocesses
WHERE DB_NAME(dbid) = 'dbname'--replace the dbname with your database
DECLARE @spid SMALLINT
DECLARE @SQLCommand VARCHAR(300)
OPEN UserCursor
FETCH NEXT FROM UserCursor INTO
    @spid
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQLCommand = 'KILL ' + CAST(@spid AS VARCHAR)
    EXECUTE(@SQLCommand)
    FETCH NEXT FROM UserCursor INTO
        @spid
END
CLOSE UserCursor
DEALLOCATE UserCursor
GO

4

Khởi động lại máy chủ SQL sẽ ngắt kết nối người dùng. Cách dễ nhất tôi đã tìm thấy - cũng tốt nếu bạn muốn đưa máy chủ ngoại tuyến.

Nhưng đối với một số lý do rất nghiêm trọng, tùy chọn 'Take Offline' không làm điều này một cách đáng tin cậy và có thể treo hoặc nhầm lẫn bảng điều khiển quản lý. Khởi động lại sau đó lấy tác phẩm ngoại tuyến

Đôi khi, đây là một tùy chọn - ví dụ: nếu bạn đã dừng một máy chủ web là nguồn của các kết nối.


+1. Câu trả lời được chấp nhận sẽ không hoạt động đối với SQL Express (ví dụ: trong môi trường nhà phát triển) vì SQL Express không có Trình giám sát hoạt động
Matt Frear

1
@MattFrear: Điều này không đúng! Ít nhất trong 2008 R2 Express tôi thấy một nút thanh công cụ và một mục menu ngữ cảnh trên nút máy chủ.
Stephan

4
Khởi động lại toàn bộ máy chủ SQL sẽ giết kết nối đến tất cả các cơ sở dữ liệu. Một máy chủ có thể đang hỗ trợ nhiều cơ sở dữ liệu nhưng hiện tại chỉ cần khôi phục một cơ sở dữ liệu.
Ross Presser

3
Đây hoàn toàn là cách tồi tệ nhất để hủy kết nối tới 1 cơ sở dữ liệu. Đặc biệt nếu bạn có nhiều cơ sở dữ liệu khác vẫn đang được người dùng khác sử dụng. Tôi khuyên bạn nên sử dụng phương pháp này. Đó là 100%, tổng số quá mức cần thiết !!
John Waclawski

@JohnWaclawski Tôi không biết về điều tồi tệ nhất nhưng chắc chắn là lười nhất - đó là lý do tại sao đôi khi tôi nói. Dù sao nó cũng không thực sự tiết kiệm thời gian so với các phương thức khác
Simon_Weaver

3

Tôi đã gặp vấn đề này trong khi tự động hóa một bộ xử lý khôi phục trong SQL Server 2008. Cách tiếp cận (thành công) của tôi là sự kết hợp của hai trong số các câu trả lời được cung cấp.

Đầu tiên, tôi chạy qua tất cả các kết nối của cơ sở dữ liệu đã nói và giết chúng.

DECLARE @SPID int = (SELECT TOP 1 SPID FROM sys.sysprocess WHERE dbid = db_id('dbName'))
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = top 1 spid from master.dbo.sysprocesses
        where dbid = db_id('dbName')
End

Sau đó, tôi đặt cơ sở dữ liệu sang chế độ single_user

ALTER DATABASE dbName SET SINGLE_USER

Sau đó, tôi chạy khôi phục ...

RESTORE DATABASE and whatnot

Giết các kết nối một lần nữa

(same query as above)

Và đặt cơ sở dữ liệu trở lại multi_user.

ALTER DATABASE dbName SET MULTI_USER

Bằng cách này, tôi đảm bảo rằng không có kết nối nào giữ cơ sở dữ liệu trước khi cài đặt ở chế độ đơn, vì trước đây sẽ đóng băng nếu có.


2

Không ai trong số này làm việc cho tôi, không thể xóa hoặc ngắt kết nối người dùng hiện tại. Cũng không thể thấy bất kỳ kết nối hoạt động nào với DB. Khởi động lại SQL Server (Nhấp chuột phải và chọn Khởi động lại) cho phép tôi làm điều đó.


2

Để thêm lời khuyên đã được đưa ra, nếu bạn có một ứng dụng web chạy qua IIS sử dụng DB, bạn cũng có thể cần phải dừng (không tái chế) nhóm ứng dụng cho ứng dụng trong khi khôi phục, sau đó khởi động lại. Việc dừng nhóm ứng dụng sẽ tắt các kết nối http đang hoạt động và không cho phép nữa, điều này có thể sẽ cho phép các quy trình được kích hoạt kết nối và từ đó khóa cơ sở dữ liệu. Đây là sự cố đã biết ví dụ với Hệ thống quản lý nội dung Umbraco khi khôi phục cơ sở dữ liệu của nó


1

Không ai ở trên làm việc cho tôi. Cơ sở dữ liệu của tôi không hiển thị bất kỳ kết nối hoạt động nào bằng Activity Monitor hoặc sp_who. Cuối cùng tôi đã phải:

  • Nhấp chuột phải vào nút cơ sở dữ liệu
  • Chọn "Tách ..."
  • Chọn hộp "Thả kết nối"
  • Reattach

Không phải là giải pháp tao nhã nhất nhưng nó hoạt động và nó không yêu cầu khởi động lại SQL Server (không phải là một tùy chọn cho tôi, vì máy chủ DB đã lưu trữ một loạt các cơ sở dữ liệu khác)


Đây là tổng số quá mức cần thiết. Sử dụng mã KILL ở trên. Hoạt động trên hàng trăm công việc khôi phục cho tôi.
John Waclawski

Cơ sở dữ liệu tôi đang làm việc sẽ không giết tất cả mọi thứ - tuy nhiên, nó có thể là một vấn đề với thiết lập của họ. Tôi đồng ý rằng nói chung dễ dàng hơn nhiều.
Brent Wagoner

0

Tôi thích làm như thế này,

thay đổi cơ sở dữ liệu ngoại tuyến với rollback ngay lập tức

và sau đó khôi phục cơ sở dữ liệu của bạn. sau đó,

thay đổi cơ sở dữ liệu trực tuyến với rollback ngay lập tức

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.