Saat mengembalikan cadangan, bagaimana cara memutuskan koneksi semua koneksi yang aktif?

166

SQL Server 2005 saya tidak mengembalikan cadangan karena koneksi aktif. Bagaimana saya bisa memaksanya?

Jader Dias
sumber
Apakah Anda selalu ingin membunuh semua koneksi ke database yang ingin Anda "pulihkan"? Atau akankah ada saat-saat ketika Anda tidak ingin mematikan koneksi yang ada? Juga, apakah Anda harus khawatir tentang koneksi pooling?
Philip Kelley

Jawaban:

177

SQL Server Management Studio 2005

Ketika Anda mengklik kanan pada database dan klik Taskslalu klik Detach Database, itu memunculkan dialog dengan koneksi aktif.

Lepaskan Layar

Dengan mengklik tautan di bawah "Pesan" Anda dapat mematikan koneksi yang aktif.

Anda kemudian dapat mematikan koneksi tersebut tanpa melepaskan basis data.

Informasi lebih lanjut di sini .

SQL Server Management Studio 2008

Antarmuka telah berubah untuk SQL Server Management studio 2008, berikut adalah langkah-langkahnya (via: Tim Leung )

  1. Klik kanan server di Object Explorer dan pilih 'Monitor Aktivitas'.
  2. Saat ini terbuka, perluas grup Proses.
  3. Sekarang gunakan drop-down untuk memfilter hasil berdasarkan nama database.
  4. Matikan koneksi server dengan memilih opsi klik kanan 'Kill Process'.
George Stocker
sumber
21
Jika Anda memiliki masalah yang sama dengan @Ryan, itu mungkin karena Anda menggunakan Management Studio 2008 (atau lebih tinggi), daripada Management Studio 2005. Untuk melakukan hal yang sama di Management Studio 2008, klik kanan server Anda di Object Explorer dan pilih 'Monitor Aktivitas'. Saat ini terbuka, perluas grup Proses. Sekarang gunakan drop-down untuk memfilter hasil berdasarkan nama database. Anda sekarang dapat mematikan koneksi Anda dengan memilih opsi klik kanan 'Kill Process'.
Tim Leung
195

Anda ingin mengatur db ke mode satu pengguna, lakukan pengembalian, lalu atur kembali ke multiuser:

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

Referensi: Pinal Dave ( http://blog.SQLAuthority.com )

Referensi resmi: https://msdn.microsoft.com/en-us/library/ms345598.aspx

brendan
sumber
11
Alih-alih mengeluarkan ROLLBACK SEGERA, itu mungkin berkaitan dengan ROLLBACK hanya setelah DELAY tertentu, dengan demikian memberikan kesempatan kepada pengguna untuk membuka peluang secara alami.
John Sansom
2
Poin bagus, diperbarui ke rollback untuk memasukkan perintah SETELAH 60 untuk memungkinkan pertanyaan saat ini untuk menyelesaikan
brendan
Hai @brendan, bagaimana jika rollback membutuhkan waktu lebih dari 60 detik? terima kasih
user3583912
11
Jika Anda memulihkan database, transaksi terbuka akan hilang baik Anda ROLLBACK IMMEDIATEatau ROLLBACK AFTER 60. Satu-satunya cara untuk menyimpan data itu adalah dengan melakukan backup lain setelah rollback. Tetapi Anda sedang memulihkan dari cadangan yang berbeda. Jadi, apa gunanya menunggu? Apakah saya melewatkan sesuatu?
Dave Mason
@ DMason, saya ingin tahu tentang pertanyaan ini juga. Apakah menggunakan single_user dengan mode rollback mencegah koneksi baru selama waktu tunggu? Jika demikian, saya ingin tahu apakah ini cara yang lebih bersih / lebih baik untuk setidaknya membiarkan tindakan read-only selesai daripada mengakhiri secara tiba-tiba?
Jason
43

Kode ini berfungsi untuk saya, itu membunuh semua koneksi yang ada dari database. Yang harus Anda lakukan adalah mengubah baris Set @dbname = 'databaseName' sehingga memiliki nama database Anda.

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

setelah ini saya bisa mengembalikannya

RagnaRock
sumber
1
Ini adalah pendekatan tercepat (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson
Itu tidak berhasil untuk saya. Basis data masih digunakan. Saya menggunakan SQL Server 2008.
Marek Bar
Saya telah menemukan menjalankan kode itu beberapa kali, satu setelah yang lain, akan BENAR-BENAR melakukan trik. Terkadang ada sesuatu yang menyelinap di antara KILL Anda dan pulihkan. Dan kadang-kadang Anda harus menjalankan kill MAKA mengembalikan satu demi satu.
John Waclawski
Tergantung sepenuhnya pada agresivitas aplikasi yang mencoba untuk terhubung kembali. Beberapa pengguna yang malas? Bagus sekali. Server aplikasi bervolume tinggi yang terhubung kembali dalam waktu kurang dari satu detik? Tidak terlalu banyak.
BradC
5

Coba ini:

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
pengguna2276214
sumber
4

Restart server SQL akan memutuskan pengguna. Cara termudah yang saya temukan - bagus juga jika Anda ingin menjadikan server offline.

Tetapi untuk beberapa alasan yang sangat aneh, opsi 'Ambil Offline' tidak dapat diandalkan dan dapat membuat hang atau membingungkan konsol manajemen. Mulai ulang lalu ambil karya offline

Terkadang ini adalah opsi - jika misalnya Anda telah menghentikan server web yang merupakan sumber koneksi.

Simon_Weaver
sumber
+1. Jawaban yang diterima tidak akan berfungsi untuk SQL Express (misalnya dalam lingkungan dev) karena SQL Express tidak memiliki Activity Monitor
Matt Frear
1
@MattFrear: Ini tidak benar! Setidaknya di 2008 R2 Express saya melihat tombol toolbar dan entri menu konteks pada node server.
Stephan
4
Restart seluruh server SQL akan mematikan koneksi ke semua database. Server mungkin mendukung banyak basis data, tetapi hanya satu yang perlu dipulihkan sekarang.
Ross Presser
3
Ini benar-benar cara terburuk untuk mematikan koneksi ke 1 basis data. Terutama jika Anda memiliki banyak database lain yang masih digunakan oleh pengguna lain. Saya sangat menyarankan MELAWAN menggunakan metode ini. Ini 100%, total berlebihan !!
John Waclawski
@ JohnWaclawski Saya tidak tahu tentang yang terburuk tapi pasti pemalas - itu sebabnya saya kadang-kadang berkata. Itu tidak benar-benar menghemat waktu dibandingkan metode lain
Simon_Weaver
3

Saya mengalami masalah ini saat mengotomatiskan proses pemulihan di SQL Server 2008. Pendekatan saya (berhasil) adalah campuran dari dua jawaban yang diberikan.

Pertama, saya menjalankan semua koneksi dari basis data tersebut, dan membunuh mereka.

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

Kemudian, saya mengatur basis data ke mode single_user

ALTER DATABASE dbName SET SINGLE_USER

Lalu, saya menjalankan pemulihan ...

RESTORE DATABASE and whatnot

Bunuh koneksi lagi

(same query as above)

Dan atur database kembali ke multi_user.

ALTER DATABASE dbName SET MULTI_USER

Dengan cara ini, saya memastikan bahwa tidak ada koneksi yang menahan database sebelum mengatur ke mode tunggal, karena yang pertama akan membeku jika ada.

Eric Wu
sumber
2

Tidak ada yang berfungsi untuk saya, tidak bisa menghapus atau memutuskan pengguna saat ini. Juga tidak dapat melihat koneksi aktif ke DB. Restart SQL Server (Klik kanan dan pilih Restart) memungkinkan saya untuk melakukannya.

Sang Coder
sumber
2

Untuk menambah saran yang sudah diberikan, jika Anda memiliki aplikasi web yang berjalan melalui IIS yang menggunakan DB, Anda mungkin juga harus menghentikan (tidak mendaur ulang) kumpulan aplikasi untuk aplikasi saat Anda memulihkan, kemudian memulai kembali. Menghentikan kumpulan aplikasi mematikan koneksi http aktif dan tidak mengizinkan lagi, yang sebaliknya dapat memicu proses yang terhubung ke dan dengan demikian mengunci basis data. Ini adalah masalah yang diketahui misalnya dengan Sistem Manajemen Konten Umbraco saat memulihkan basis datanya

Chris Halcrow
sumber
1

Tidak satu pun di atas bekerja untuk saya. Basis data saya tidak menunjukkan koneksi aktif menggunakan Activity Monitor atau sp_who. Saya akhirnya harus:

  • Klik kanan simpul basis data
  • Pilih "Lepas ..."
  • Centang kotak "Jatuhkan Koneksi"
  • Pasang kembali

Bukan solusi yang paling elegan tetapi berfungsi dan tidak perlu me-restart SQL Server (bukan pilihan bagi saya, karena server DB meng-host banyak database lain)

Brent Wagoner
sumber
Ini total berlebihan. Gunakan kode KILL di atas. Bekerja pada ratusan pekerjaan pemulihan untuk saya.
John Waclawski
Basis data yang saya gunakan tidak akan MEMBUNUH segalanya - namun, mungkin ada masalah dengan pengaturannya. Saya setuju itu umumnya lebih mudah.
Brent Wagoner
0

Saya lebih suka melakukan ini,

ubah database yang ditetapkan offline dengan rollback segera

dan kemudian pulihkan database Anda. setelah itu,

mengubah database yang ditetapkan online dengan rollback segera

Aniyan Kolathur
sumber