Kullanıcıları bir SQL Server 2008 veritabanından nasıl atarsınız?


22

Geri yükleme yapmamız gerekiyor, çünkü diğer kullanıcılar bağlı değil. Her sürecin bağlantısını kestiğimizi sandık ama görünüşe göre değil.

Management Studio'dan herkesi nasıl atabiliriz ki, bu yedeklemeyi yapabiliriz?

Yanıtlar:


25

Bunu yapmanın iki yolu vardır:

  1. Nesne Gezgini'nde veritabanına sağ tıklayın, Görevler> Ayır'a gidin. Bağlantıları Bırak onay kutusunu seçin.

  2. Veritabanını burada belirtildiği gibi tek kullanıcılı moda ayarlayın :

    -- hit Ctrl+Shift+M in SSMS to fill in the template parameter
    USE master;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET SINGLE_USER
    WITH ROLLBACK IMMEDIATE;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET READ_ONLY;
    GO
    
    ALTER DATABASE N'<Database Name, sysname,>'
    SET MULTI_USER;
    GO
    

Lol o kadar çok yorum olduğunu fark etmedim. Marian haklı, gerçek mührü çalıştırmana gerek yok, kullanıcıları öldürecek senaryoyu yaz. @NickChammas Evet, okunması yalnızca kullanıcıların yeniden bağlantı kurmasını önler. Çok kullanıcılı olarak ayarladığınızda geri yüklemeyi yapabilirsiniz. Ayrıca db adları bir şablondan gelir ve '<Veritabanı Adı, sysname>' gibi etiketlerin Ctrl + Shift + M kullanımıyla değiştirilmesi amaçlanmıştır. Şablonlu olmayan bir komut dosyasında dbnames, çevrelerinde tırnak atar.
Wil

43

Her zaman aşağıdakileri kullanırım:

USE master; -- get out of dbname myself
GO
-- kick all other users out:
ALTER DATABASE [dbname] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- prevent sessions from re-establishing connection:
ALTER DATABASE [dbname] SET OFFLINE;

Bazen bu biraz zaman alabilir, bazen de engellendiği için bunu çalışan birisin ve sen veritabanına etkin bir bağlantınız . Aynı veritabanı bağlamına sahip olabilecek diğer sorgu pencerelerini kontrol edin; buna açık diyaloglar, Nesne Gezgini, IntelliSense, uzun süredir devam eden işler vb. Dahildir.

Bu veritabanının ayarlarında yaptığım değişiklikleri tamamladığımda, basitçe:

ALTER DATABASE [dbname] SET ONLINE;
ALTER DATABASE [dbname] SET MULTI_USER;

Yine de, bazen, bu veritabanında yapmam gereken şey veritabanının çevrimiçi olmasını gerektirir, bu yüzden bazen onu tek kullanıcı modunda bırakıp şunu yapmam gerekir:

ALTER DATABASE [dbname] SET ONLINE;
GO
USE [dbname];

Şimdi değişiklikleri yapabilirim ve sonra diğer kullanıcıların bağlanmasına hazır olduğumda, basitçe:

ALTER DATABASE [dbname] SET MULTI_USER;

2

Normalde veri tabanını single_user içine yerleştiririm ve sonra gecikmeyi beklerim ve ardından veri tabanını aşağıdaki gibi çok kullanıcılı duruma getiririm:

-- to kill all connections for particular db ... otherwise the restore will fail as exclusive lock cannot be obtained for the db being restored.

    alter database db_name
    set single_user with rollback immediate
    waitfor delay '00:00:05'  -- wait for 5 secs
    alter database db_name
    set multi_user
    restore database db_name from disk = 'D:\restore\db_name.bak'
    with replace, stats = 10, recovery -- if you want to recover your database online
    -- optional if you dont have the same directory/file structure
    move 'datafile logical name' to 'E:\data\physical_name.mdf',
    move 'logfile logical name' to 'F:\log\physical_name_log.ldf'

Aslında, geri yükleme deyimi ile tek bir komut dosyası (işlem) çalıştırdığınız için "multi_user" ayarına gerek yoktur. Kurtarma işlemiyle geri yükleme, veritabanını çok kullanıcılı moda geri koymaya özen gösterir.
Svein Terje Gaup

1

Yukarıdaki seçeneklerin hiçbiri benim için işe yaramadı çünkü sunucu çoklu uzak bağlantı girişimleri tarafından dövüldü.

Windows güvenlik duvarında belirli bir veritabanı portunu kapattığımda normal Alter .. Set Multi_User ilk denemede çalıştı.


-1

Aşağıdaki aslında tüm bağlantıları keser. Tek kullanıcı modunun ayarlanmasının başarısız olduğu durumlarda oldukça yararlı

declare @execSql varchar(1000), @databaseName varchar(100)
-- Set the database name for which to kill the connections
set @databaseName = 'databasename'
set @execSql = '' 
select  @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '
from    master.dbo.sysprocesses
where   db_name(dbid) = @databaseName
     and
     DBID <> 0
     and
     spid <> @@spid
exec(@execSql)

1
Bu işe yaramaz çünkü sysprocessesher zaman bu veritabanında kilitlenebilecek tüm oturumları hesaba katmaz (bir sorgunun veritabanı A bağlamında çalıştırıldığı basit senaryoyu düşünün, ancak A'daki bir tabloya ve B'deki bir tabloya katılır) .
Aaron Bertrand

-1

Aşağıdaki komut dosyasını herkesi nuke etmek veya belirli bir DB için değiştirmek için kullanabilirsiniz.

Öldürülebilecek herhangi bir şey olacak! Ancak SQL servis SPID'leri etkilenmeyecek.

Drop table #who

go 

Create table #who(  [spid] int,
                    [ECID] int,
                    [Status] varchar(100),
                    [Loginname] varchar(200),
                    [Hostname] varchar(200),
                    [blk] bit,
                    dbname varchar(200),
                    cmd varchar(1000),
                    requestID int
                  )

go

Insert into #who (Spid, ECID, Status, Loginname, hostname,blk, dbname, cmd, requestid)
exec sp_who

Declare cursKillUsers Cursor for Select 'Kill ' + cast(spid as varchar(100)) + ';' [SQL] from #who where dbname like '%'
Declare @sql varchar(200)
Open cursKillUsers
Fetch next from cursKillUsers into @sql
While @@fetch_status = 0 
begin

    print @sql
    Exec (@sql)
    Fetch next from cursKillUsers into @sql

end

close cursKillUsers
deallocate cursKillUsers

-3

Bu kodu kullanıyorum:

ALTER DATABASE [Dbname] set offline with rollback immediate
GO
ALTER DATABASE [Dbname] set online
GO

Ancak TEK KULLANICI örneğinin yazmanın daha az olduğunu görebiliyorum.


3
Ayrıca veritabanını tekrar çevrimiçi yapmak, geri yüklemeye başlamadan önce diğer kullanıcıların tekrar bağlanabileceği anlamına gelir.
Aaron Bertrand
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.