Bir yedeklemeyi geri yüklerken, tüm etkin bağlantıları nasıl kesebilirim?


166

SQL Server 2005'im etkin bağlantılar nedeniyle yedeklemeyi geri yüklemiyor. Nasıl zorlayabilirim?


Eğer Do hep siz "üzerinde geri" istediğiniz veritabanına tüm bağlantıları öldürmek istiyor? Yoksa mevcut bağlantıları öldürmek istemediğiniz zamanlar olacak mı? Ayrıca, bağlantı havuzu oluşturma konusunda endişelenmeniz mi gerekiyor?
Philip Kelley

Yanıtlar:


177

SQL Server Management Studio 2005

Bir veritabanını sağ tıklatıp Taskssonra da tıklattığınızda Detach Database, etkin bağlantılarla bir iletişim kutusu görüntülenir.

Ekranı Ayır

"Mesajlar" altındaki köprüye tıklayarak etkin bağlantıları öldürebilirsiniz.

Ardından bu bağlantıları veritabanını ayırmadan öldürebilirsiniz.

Daha fazla bilgi burada .

SQL Server Management Studio 2008

SQL Server Management studio 2008 için arayüz değişti, işte adımlar (üzerinden: Tim Leung )

  1. Nesne Gezgini'nde sunucuyu sağ tıklayın ve 'Etkinlik İzleyicisi'ni seçin.
  2. Bu açıldığında, İşlemler grubunu genişletin.
  3. Şimdi sonuçları veritabanı adına göre filtrelemek için açılır menüyü kullanın.
  4. Sağ tıklayarak 'İşlemi Sonlandır' seçeneğini seçerek sunucu bağlantılarını kesin.

21
@Ryan ile aynı sorunu yaşıyorsanız, bunun nedeni büyük olasılıkla Management Studio 2005 yerine Management Studio 2008 (veya üstü) kullanmanızdır. Management Studio 2008'de aynı şeyi yapmak için Object'te sunucunuzu sağ tıklayın Explorer'a gidin ve 'Etkinlik İzleyicisi'ni seçin. Bu açıldığında, İşlemler grubunu genişletin. Şimdi sonuçları veritabanı adına göre filtrelemek için açılır menüyü kullanın. Artık sağ tıklayarak 'İşlemi Sonlandır' seçeneğini seçerek bağlantılarınızı kesebilirsiniz.
Tim Leung

195

Db'nizi tek kullanıcı moduna ayarlamak, geri yüklemeyi yapmak, sonra tekrar çoklu kullanıcı olarak ayarlamak istiyorsunuz:

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

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

Resmi başvuru: https://msdn.microsoft.com/en-us/library/ms345598.aspx


11
HEMEN GERİ DÖNÜŞ VERMEK yerine, belirli bir GECİKMEDEN sonra yalnızca GERİ DÖNDÜRME ile ilgili olabilir, böylece kullanıcı sorgularına doğal olarak tamamlanma fırsatı verir.
John Sansom

2
İyi bir nokta, güncel sorguların tamamlanmasına izin vermek için AFTER 60 komutunu içerecek şekilde geri dönüş için güncellendi
brendan

Merhaba @brendan, geri alma 60 saniyeden fazla sürerse ne olur? teşekkürler
user3583912

11
Eğer bir veritabanı geri yüklüyorsanız, açık işlemler isteyip kaybolacak ROLLBACK IMMEDIATEya ROLLBACK AFTER 60. Bu verileri kaydetmenin tek yolu geri alma işleminden sonra başka bir yedekleme yapmaktır. Ancak farklı bir yedekten geri yüklüyorsunuz. Peki, beklemenin anlamı nedir? Bir şey mi kaçırıyorum?
Dave Mason

@DMason, bu soruyu da merak ediyorum. Single_user'u geri alma moduyla kullanmak bekleme süresi boyunca yeni bağlantıları engelliyor mu? Eğer öyleyse, en azından salt okunur eylemlerin tamamlanmasına izin vermek için daha temiz / daha güzel bir yol olup olmadığını merak ediyorum?
Jason

43

Bu kod benim için çalıştı, bir veritabanının tüm mevcut bağlantılarını öldürür. Tek yapmanız gereken Set @dbname = 'databaseName' satırını değiştirmek, böylece veritabanı adınıza sahip olmak.

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

bundan sonra geri yükleyebildim


1
Bu en hızlı yaklaşımdı (SingleUserMode * 20 = 60s, Kill * 20 = 5s).
Karson

Benim için işe yaramadı. Veritabanı hala kullanımda. SQL Server 2008 kullanıyorum.
Marek Bar

Ben bu kodu birkaç kez, birbiri ardına, çalışan ÇOK OLAN hile yapacak bulundu. Bazen KILL ile geri yükleme arasında bir şeyler gizleniyor. Ve bazen öldürdükten sonra öldürmeyi çalıştırmanız gerekir.
John Waclawski

Tamamen yeniden bağlanmaya çalışırken uygulamanın saldırganlığına bağlıdır. Tembel kullanıcılar mı? Harika çalışıyor. Bir saniyeden kısa sürede yeniden bağlanan yüksek hacimli uygulama sunucusu? Çok değil.
BradC

5

Bunu dene:

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

SQL sunucusunu yeniden başlatmak kullanıcıların bağlantısını kesecektir. Bulduğum en kolay yol - sunucuyu çevrimdışına almak istiyorsanız da iyi.

Ancak çok garip bir nedenden dolayı 'Çevrimdışı Ol' seçeneği bunu güvenilir bir şekilde yapmaz ve yönetim konsolunu asabilir veya karıştırabilir. Yeniden başlatılıyor ve çevrimdışı çalışmalar yapıyor

Bazen bu bir seçenektir - örneğin, bağlantıların kaynağı olan bir web sunucusunu durdurduysanız.


+1. SQL Express'te Etkinlik Monitörü bulunmadığından, kabul edilen yanıt SQL Express (örneğin geliştirici ortamında) için çalışmaz
Matt Frear

1
@MattFrear: Bu doğru değil! En azından 2008 R2 Express'te sunucu düğümünde bir araç çubuğu düğmesi ve bir bağlam menüsü girişi görüyorum.
Stephan

4
Tüm bir SQL sunucusunun yeniden başlatılması, tüm veritabanlarına olan bağlantıları kesecektir. Bir sunucu birçok veritabanını destekliyor olabilir, ancak şimdi yalnızca bir tanesinin geri yüklenmesi gerekir.
Ross Presser

3
Bu kesinlikle 1 veritabanına bağlantı öldürmek için en kötü yoldur. Özellikle de diğer kullanıcılar tarafından kullanılmakta olan başka veritabanlarınız varsa. Bu yöntemi kullanarak TEKRAR tavsiye ederim. % 100, toplam overkill !!
John Waclawski

@JohnWaclawski En kötüsünü bilmiyorum ama kesinlikle tembelim - bu yüzden bazen dedim. Yine de diğer yöntemlere göre hiçbir zamandan tasarruf etmiyor
Simon_Weaver

3

SQL Server 2008'de bir geri yükleme işlemini otomatikleştirirken bu sorunla karşılaştım. (Başarılı) yaklaşımım, verilen yanıtların ikisinin bir karışımıydı.

İlk olarak, söz konusu veritabanının tüm bağlantılarını çalıştırıyorum ve onları öldürüyorum.

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

Sonra veritabanını single_user moduna ayarladım

ALTER DATABASE dbName SET SINGLE_USER

Sonra geri yüklemeyi çalıştırıyorum ...

RESTORE DATABASE and whatnot

Bağlantıları tekrar öldür

(same query as above)

Ve veritabanını tekrar multi_user olarak ayarlayın.

ALTER DATABASE dbName SET MULTI_USER

Bu şekilde, tek moda ayarlamadan önce veritabanını tutan hiçbir bağlantı olmadığından eminim, çünkü eski varsa donacak.


2

Bunların hiçbiri benim için çalışmadı, mevcut kullanıcıları silemedi veya bağlantılarını kaldıramadı. Ayrıca, DB ile etkin bir bağlantı göremedim. SQL Server'ı yeniden başlatmak (Sağ tıklayın ve Yeniden Başlat'ı seçin) bunu yapmama izin verdi.


2

Daha önce verilen tavsiyelere eklemek için, DB'yi kullanan IIS üzerinden çalışan bir web uygulamanız varsa, geri yükleme sırasında uygulama havuzunu durdurmanız (geri dönüştürmemeniz) ve yeniden başlatmanız da gerekebilir . Uygulama havuzunun durdurulması etkin http bağlantılarını öldürür ve artık izin vermez, aksi takdirde veritabanına bağlanan ve böylece veritabanını kilitleyen işlemlerin tetiklenmesine izin verebilir. Bu, örneğin veritabanını geri yüklerken Umbraco İçerik Yönetim Sistemi ile ilgili bilinen bir sorundur


1

Yukarıdakilerin hiçbiri benim için çalışmadı. Veritabanım, Etkinlik İzleyicisi'ni veya sp_who kullanan hiçbir etkin bağlantı göstermedi. Sonuçta:

  • Veritabanı düğümüne sağ tıklayın
  • "Ayır ..." ı seçin
  • "Bağlantıları Kes" kutusunu işaretleyin
  • Reattach

En zarif çözüm değil ama işe yarıyor ve SQL Server'ı yeniden başlatmayı gerektirmiyor (DB sunucusu bir sürü diğer veritabanını barındırdığı için benim için bir seçenek değil)


Bu tamamen fazlalık. Yukarıdaki KILL kodunu kullanın. Benim için yüzlerce geri yükleme işi üzerinde çalışıyor.
John Waclawski

Birlikte çalıştığım veritabanı her şeyi ÖLDÜRMEYECEKTİR - ancak kurulumlarıyla ilgili bir sorun olabilir. Katılıyorum genel olarak çok daha kolay.
Brent Waggoner

0

Böyle yapmayı tercih ederim,

veritabanı geri alma anında çevrimdışı olarak değiştir

ve sonra veritabanınızı geri yükleyin. Daha sonra,

veritabanını geri almayla çevrimiçi olarak değiştirmeyi değiştir

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.