SQL Server yerinde yükseltmeleri eskisi gibi tavsiye edilmiyor mu?


78

SQL Server 6.5'ten beri açık ve kapalı olarak çalışıyorum, hala kafamda çalan eski tavsiye hiçbir zaman yerinde yükseltme yapmamaktı.

Şu anda 2008 R2 DEV ve TEST sistemlerimi SQL Server 2012'ye yükseltiyorum ve aynı donanımı kullanmam gerekiyor. Raporlama hizmetleri yapılandırmamı geri yüklemek zorunda kalmama düşüncesi çok çekici ve duvar zamanından dolayı gerçekten iyiyim. Herhangi bir analiz hizmeti yoktur veya olağandışı veya standart olmayan herhangi bir şey yoktur - yalnızca veritabanı altyapısı ve raporlama servisleri kuruludur.

Yerinde yükseltme ile ilgili ciddi sorunlar yaşandı mı? Yoksa yerinde yükseltme konusundaki konumumu yeniden değerlendirmeli miyim?


Raporlama hizmetleri kurulumuyla 1 sunucuda şirket içi yükseltme yapmayı seçtim. Karşılaştığım tek sorun, yerel istemci 11 ile SSMS'de import export aracını kullanmaya çalışmaktı. Dönüşümün denenmesi, tanınmayan veri türleri ile ilgili bir hatayla başarısız oldu. Kullandığım geçici çözüm paketi kaydetmek ve iyi çalıştıran SQL Veri Araçları'nda (BIDS değiştirme) çalıştırmaktı. Bunun SSIS 2008 için yapılandırma dosyası ile yazılmaması gerektiğini düşünüyorum. Daha sonra ortaya çıktı, sadece yerel müşteriyi 10 olarak değiştirebilirsin.
DamagedGoods

Yanıtlar:


92

Gerçekten Kısa Cevap - Yerinde tamam. Daha sonra yapılandırmanızı inceleyebilir ve SQL Server 2012 için en iyi uygulamaları uygulayabilirsiniz.

SQL Server Yükseltmeleri / Migrasyonları Üzerine Daha Uzun Bir Cevap

Yani bu bir fikir meselesi ve mutlaka yanlış veya doğru bir cevap yok, ancak bir çok nedenden ötürü, göç tarzı güncellemelerini yerinde tercih ediyorum. Olduğu söyleniyor - bazı nedenlerden dolayı müşterilerimden bazıları yerinde yapmaktan başka çaresi yoktu ve gerçekten de SQL Server 2005'ten beri, yerinde yükseltmeler eskisi kadar kötü değildi.

Yerinde Yükseltmeye Geçiş Neden Neden

  • Daha Kolay Geri Alma - Bir şeyler ters giderse, basitçe "yükseltme işlemini durdurduk .." diyerek bağlantı sorununu eski sunucuya dönüştürün "diyerek geri alabilirsiniz. Yerinde ile tamir ediyorsun ya da yerindesin.
  • Donanımı Yenile - Donanım hızla değişiyor. 4 yıl önce şirketiniz için doğru olan donanıma kolayca takılabilir, ancak yerinde yükseltme ile bugün ve gelecek dört yıl boyunca doğru değilsiniz. Yeni donanım için yine de bir noktada bir geçiş yapmanız gerekecek.
  • Daha İyi Hissediyorum - Tabii ... Bu öznel, ancak yeni bir işletim sistemi yüklemesiyle başladığınızı, işyerindeki kişiden hiç bir örümcek ağı olmayan yeni bir SQL yüklemesiyle başladığınızı (veya daha önce bildiğiniz şeyi bilmediğinizi) iyi hissettiriyor. bugün) bu gelecekte baş ağrısına neden olabilir.
  • Yeni İşletim Sistemi - Geçiş, bugün en son ve en iyilerinde değilseniz, yeni bir işletim sistemi sürümüyle başlama şansı verir.
  • Test Edebilirsiniz - SQL'i kurmadan ve veri tabanları ve kullanımla bulutlamadan önce yeni bir makineye bir dizi taban çizgisi almak istediğiniz oldu mu? Bunu şimdi yapabilirsin.
  • Bazen en iyi uygulamalara gizlice girmek daha kolaydır - Belki de SQL Server hizmet hesabı yerel bir yöneticiydi. Belki Yerleşik Yöneticiler SA sunucu rolündedir. Belki daha önce işe yaraması için işler bir şekilde hacklenmiştir. Hepsini düzeltebilir ve yeni başlayabilirsiniz.
  • Ücretsiz test ortamı ve ekstra uyku - Bu yeni ortamı hayata geçirirken geçirdiğiniz gerçek günden önce çalışabileceğiniz bir ortama sahip olmak büyük bir avantajdır. Yeni bir ortama geçiş yapmak, çalışma saatlerinde, gerçek kesim gününüzden çok daha önce inşa edebileceğiniz ve vaktinden önce birçok yolla test edebileceğiniz anlamına gelir. Tüm uygulamalarda ve sistemlerde günlerce tam regresyon testi yapabilir ve son uygulama / ekleri tamamlamadan ve tüm uygulamaları sonlandırmadan ve yeni ortama erişmeden önce büyük bir gönül rahatlığınız vardır.
  • Hepsini bir kerede yapmak zorunda değilsiniz - Karşılaştığım çok yaygın bir durum, birkaç örnekle birleştirmeye çalışan bir ortam. Belki de sürüm başına bir tane, belki de "seviye" ve sürüm başına bir tane. Bu projelerin birçoğunun test, proje planları ve satıcı sertifikalarının zamanında olmasına bağlı olarak çeşitli uygulamalar ve veritabanları için farklı zaman çizelgeleri vardır. Geçiş yapmak, hazır olduklarında, hazır olduklarında veritabanlarını taşıyabileceğiniz ve bir nedenden ötürü hareket edemeyen veritabanlarının isteklerini yerine getirebileceğiniz anlamına gelir.

Unutma , bunu bir göç olarak yapman gerektiğini söylemiyorum . Yerinde çalışır ve bütçenizde yeni bir donanım satın almayı planlamıyorsanız ve bu yükseltme için bunu yapamıyorsanız işe yarar. Güncelleme sürecindeki destek 6.5 günde olduğundan çok daha iyidir, bu yüzden kendinizi kötü bir pozisyona sokmazsınız.

Geliştirme / test için yerinde yapmayı planlıyor ancak üretim için bir göç yapmak istiyorsanız, üretimden önce en az bir geçiş yapmayı düşünebilirsiniz. Bu yolla kontrol listenizi vaktinden önce çözebilir ve aklınıza gelmeyen tüm olası sorunları çözebilirsiniz.

Takma / Çıkarma - Migrasyonlar İçin Yedekleme / Geri Yükleme

Geçiş yaklaşımı ile gitmeye karar verirseniz, hala tartışmaya devam edebileceğiniz bir karar daha vardır ve bu şekilde veritabanınızı yeni ortama taşıyabilirsiniz. Veritabanınızı eski sunucudan ayırabilir ve yenisine ekleyebilir ya da yedekleyebilir ve geri yükleyebilirsiniz.

Yedeklemeyi / geri yüklemeyi tercih ederim. Çıkarma / takma hakkında duyduğum en büyük avantaj, zaman kazandırması. Benim için yedekleme / geri yükleme birkaç nedenden dolayı kazanır:

  • Eskiyi erişilebilir durumda tut - Bu, kaynak sunucuda hala erişilebilir bir veritabanına sahip olmanızı sağlar. ayırma / takma işlemi aynı şekilde yapılmalıdır, ancak birkaç adım gerektirecektir ve ayırma / takma ile bu durumu karmaşıklaştırabilecek insan hatası için yer vardır.
  • Yedeklemenizin garantisini veriyorsunuz - Sadece bir veri tabanından bir veri tabanı almak ve potansiyel olarak bir yedekleme adımını unutmak yerine, bu yedeği aldığınızdan emin oldunuz.
  • İnsan hatası - Yanlış dosyayı silerseniz, bir şeyi nereye gönderdiğinizi unutun veya adımlarınızı tersine karıştırın, verileri taşıyarak ve veritabanınızdaki dosyaları günlük olarak taşıyarak büyük risk alırsınız. Şimdi bunu kesmek yerine kopyalayarak azaltabilirsiniz (ve ayırırsanız, kes ve yapıştır alışkanlığından çıkmalısınız), ancak karışıklık yaratabilirsiniz. SQL Server artık bu dosyaları kilitlemiyor ve bir dosyayı riske atmam için yanlışlıkla silmek çok kolay.
  • Gerçekten o kadar yavaş değil - Bir yedekleme almak ve kopyalamak biraz daha zaman alıyor, ancak bunun için fazladan bir risk ödemeye razı değilim. Aslında - tam kurtarma modelini ve günlük yedeklemelerini kullanarak, "Geçiş Yaklaşımı Nasıl Daha Hızlı Yapılır?" Bölümünde açıklandığı gibi kesintiler için daha az zaman alabilir

Yedekleme / geri yükleme yapmaya karar verirseniz - bu, eski kaynak veritabanınızın hala çevrimiçi olacağı anlamına gelir. Yedeklemeyi aldıktan sonra bu veritabanını çevrimdışı duruma getirmeyi seviyorum. Bazen bir adım daha ileri gidiyorum ve güvenlik, iş, bağlantılı sunucu, sertifikalar, veritabanı posta ayarları ve diğer örnek geniş bilgiyi yazdıktan sonra tüm SQL örneğini çevrimdışı duruma getiriyorum. Bu, birinin "Her şey harika görünüyor!" Dediği test sırasında bir sorunu önler. sadece bir veya iki gün sonra eski sunucudaki eski veritabanına konuştuklarını fark etmek için. Bu veritabanlarını çevrimdışı duruma getirmek veya tüm örneği çevrimdışı duruma getirmek, bu hatalı pozitifleri ve yaptıkları karmaşayı önlemenizi sağlar.

Göç Yaklaşımı Daha Hızlı Nasıl Yapılır?

Tam geri kazanım modelini kullanarak, kesinti süresi düşük olan, yoğun bir üretim ortamı için eskiden yeni bir ortama geçiş için gerekli duruş süresini en aza indirebilirsiniz. Temel olarak - en son tam yedeklemeyi, herhangi bir türevsel yedeği ve önceden alınmış kütük yedeklemelerini geri yükleyerek, geçirdiğiniz ortamı aşamalı hale getirin NORECOVERY- daha sonra son kesilmesi için yapmanız gereken tek şey, henüz geri yüklenmemiş günlük yedeklemelerini geri yüklemek ve belirterek geri yüklemek istediğiniz son günlük yedeklemesi WITH RECOVERY. Bu şekilde, büyük bir veritabanı için, gerçek kesinti kesintisi süresi penceresi, kesinti süresi penceresinden önceki tam, diferansiyel ve çoğu günlük geri ödemelerinin maliyeti ödenerek büyük ölçüde en aza indirilebilir. Yorumlarda bunu işaret ettiğin için Tao için teşekkürler !

Yerinde Yükseltme Nasıl Daha Güvenli Hale Getirilir

Yerinde yaklaşımı seçerken deneyiminizi ve sonuçlarınızı geliştirmek için yapabileceğiniz birkaç şey.

  • Yedekleme - Çevrenizdeki tüm kullanıcı ve sistem veritabanlarının vaktinden önce uygun yedeklemelerini alın ve iyi olduklarından emin olun (paranoyakım .. Aslında gerçekten iyi olduklarını bilmek için onları ilk önce geri yüklerim .. Vaktinizi boşa harcıyor olabilirsiniz. (Ama felaket durumunda kendinize teşekkür edebilirsiniz) .. Bu ortamda SQL ve OS kurulumu hakkında herhangi bir yapılandırma bilgisini yazınız.
  • Başlamadan önce her şeyi iyi test edin - İyi bir ortamınızın ve iyi bir veritabanınızın olduğunu doğrulayın. Hata günlüklerine bakmak ve düzenli olarak DBCC CHECKDB çalıştırmak gibi şeyler yapmalısınız, ancak yerinde yükseltme yapmadan önce başlamak için iyi bir zaman. Önceden herhangi bir sorunu düzeltin.
  • İşletim sistemi sağlığını sağlama - Yalnızca SQL'in sağlıklı olduğundan emin olmayın, sunucunuzun sağlıklı olduğundan emin olun. Sisteminizde herhangi bir gnarly hata veya uygulama hatası olay günlüğü? Boş alanınız nasıl?
  • En kötüsüne hazırlanın - bir süre önce bir blog yazı dizim vardı, bir süre önce, başarısızlığa hazırlık yapmıyorsanız - aslında başarısız olmaya hazırlanıyorsunuz . Hala inanıyorum. Bu nedenle, sahip olabileceğiniz sorunları önceden düşünün ve onlarla başa çıkın. Kendinizi "başarısızlık" zihniyetine sokun, aksi takdirde sahip olamayacağınız şeyleri düşüneceksiniz.

Yükseltme veya Geçiş Kontrol Listelerinin Önemi

Yükseltme yapmaya karar verirseniz (yerinde veya geçiş olsun) bir kontrol listesi oluşturmayı ve bu kontrol listesini her ortamda kullanmayı düşünmelisiniz. Bu kontrol listesine en azından bunlardan birkaçı eklemelisiniz:

  1. Başlangıçta - Test yükseltme yapmak, uygulamalarınızı en son Veritabanı Uyumluluğu düzeyinde test etmek ve SQL'i yapmadan önce ne tür görevleri yapmanız gerektiğini görmek için önceden SQL Server Yükseltme Danışmanı gibi bir araç kullanmayı düşünün. Sunucu yükseltme veya taşıma.
  2. Ön Adımlar - Temizleme, işletim sistemi görevleri, önceden yamalama, yükseltme için uygulama hazırlama (temiz kapatma, bağlantı dizesi çalışması), yedeklemeler vb.
  3. Yükseltme / Geçiş Adımları - Yükseltme veya geçişin başarılı olması ve doğru sırada yapılması için yapmanız gereken her şey. Kurulum, değiştirme (veya teste ve yaklaşımınıza bağlı olarak değişmemesi) uyumluluk modu veritabanlarında vb.
  4. Geçiş Sonrası / Yükseltme Adımları - Çeşitli testler, yeni sürüm veya yeni sunucu yapılandırma seçenekleri, en iyi uygulama uygulamaları, güvenlik değişiklikleri vb.
  5. Geri Alma Adımları - Tüm yol boyunca geri alma adımlarına ve dönüm noktalarına sahip olmalısınız. Bu kadar ileri gidersen ve bu olursa ne yapacaksın? "Tam bir geri alma işlemi yap" kriterleri nelerdir? Ve bu geri dönüşü nasıl yaparsınız (ters bağlantı dizgisi değişir, ayarları değiştirir, eski sürüme geri döner, yerindeyse yeniden yükleyin, geçiş durumunda eski sunucuyu işaret eder)

Daha sonra üretim yükseltmesi yapacak kişinin, üretim dışındaki bir ortamda kontrol listesini takip etmesini sağlayın - özellikle eğer mümkünse üretime benzeyen ("Prod of prod", "dediğim gibi ...) ve sorunları veya noktaları not edin Kontrol listesindeki eksiklikler nedeniyle kontrol listesinden ayrılmaları veya doğaçlama yapmaları gereken yer. Ardından değişiklikleri birleştirin ve üretim değişikliğinizle eğlenin .

Geçiş sonrası iyice test etmenin veya yükseltme işleminden önce ve geçişinizden önce yeterince önemini vurgulayamam. Yükseltmenin ortasında geri alma kararı vermek kolay bir karar vermeli - özellikle göç sırasında. Rahatsız edici bir şey varsa, geçişin sıcağında etkili ve güvenilir bir şekilde sorununu gideremezseniz, geri alın ve anlayın. Bu yeni ortamda yaşadığınızda ve kullanıcılar bağlandığında - geri alma zor bir görev haline gelir. Bir SQL Server veritabanını önceki bir sürüme geri yükleyemezsiniz. Bu, el işi ve veri taşıma anlamına gelir. Eski ortamı öldürmek için her zaman birkaç hafta beklerim, ancak canlı kullanıcılarınız yeni ortama dokunmadan önce tüm sorunlarınızı bularak bu eski ortama ihtiyaç duymamak için elinizden geleni yapmalısınız. Tercihen yükseltme / taşıma işlemine başlamadan önce.

SQL Server Raporlama Servisleri göçü / yükseltme hakkında kısa not Bir SSRS kurulumunu geçirmek, pek çok kişinin düşündüğü gibi herculean bir görev değildir. Bu teknik / çevrimiçi kitap makalesi aslında oldukça kullanışlıdır . O makalede en önemli öğütlerinden biri "şifreleme anahtarlarını yedekle" vb You bağlantıları çok sayıda için kaydettiğiniz duyarlı planlanan rapor e-posta alıcı e-posta adresleri gibi bilgilerin, bağlantı birçok bilgi var, özellikle Müşterilerimden birinin ne kadar önemli olduğunu bir süre sonra sorabilir. Biliyorlar çünkü bu adımı karıştırdım ve rapor programlarını ve bağlantı dizgisi izinlerini değiştirmek için çok fazla zaman harcadım.


14

Tecrübelerime göre aynı karar verme süreci öncekiyle aynı şekilde yapılmalı. AFAIK, SQL Server kurulumunda, kendi içerisinde MS SQL Server ürününde ve yazılımları milyonlarca kod satırı ile kullanıma sunarken karşılaşabileceğiniz olası sorunlar olmamıştır. Kötü bir şey olabilir ve şimdi 'ROLLBACK' seçeneğiniz kalmadı.

Ancak, başka alternatifler de var. Sistemin bir görüntüsünü almayı, başka bir yere geri yüklemeyi, yükseltme işlemini gerçekleştirmeyi ve ne olduğunu görmeyi düşünebilirsiniz. Bu test size çok fazla rahatlık vermelidir, ancak ürün kutusunda herhangi bir sorun çıkacağını kesinlikle garanti etmemektedir. Ancak bu, SQL 6.5 günlerinde geri alınamayan bir seçenektir.

Sadece en kötü durum senaryosunu varsayardım. Yerinde yükseltme yaparsınız ve sefil bir şekilde başarısız olur. Daha sonra RTO ve RCO'nuzda bundan kurtulmanız gerekir. İşletme riskleri anlıyor mu ve azaltmak için planlarınız var mı?

İş bu konuda uygun değilse, o zaman yapma benim tavsiyem olur.


2

Sunucularınızı sanal bir ortamda çalıştırıyorsanız, bir klonda anlık görüntü gerçekleştirebilir ve ardından yerinde yükseltmeyi uygulayabilir ve yükseltmenin başarılı olduğunu doğrulamak için örneği test edebilirsiniz. Çalışırsa, anlık görüntüyü uygulayabilir ve klonu üretim sunucusunu yapabilirsiniz. Kötü giderse, anlık görüntüyü silebilir ve tekrar denemek için yükseltme öncesi görüntüye geri dönebilir veya klonu ve tam bir geçişi silebilirsiniz.


1
Yalnızca depolama alanı da sanallaştırılmışsa ve anlık görüntünün bir parçasıysa. Depolama doğrudan VM'ye
eklenirse

1

Büyük bir donanım yatırımı nedeniyle mevcut SQL Server sürümünü (2012, 3 sunucu, 22 örnek, ~ 300 veritabanı) tutarken sadece işletim sistemini yükseltmemiz gerekiyordu. Yansıtma, vb. Gibi karmaşık kurulumlar yoktur.

Bu örnek, SQL Server yükseltilmediğinden tam olarak soruya uymuyor. Bence bu hala iyi bir cevap, çünkü gösterilen adımlar aslında gerçek bir göçten daha kolay olacaktır.

Genel Bakış: Önlem olarak tam yedekleme almak için harici bir sürücü takıldı. Yalnızca model ve msdb aslında harici sürücüden geri yüklenir. Ldf / mdf ayırmak / bağlamak için yerinde kaldı. Bazı yerel hesaplara DB içinde referans verildi. İşletim sisteminde yeniden yaratıldıktan sonra, DB içindeki referanslar yeniden yaratıldı (çünkü SID'ler değişebilir).

Sonra burada bizim için çalışan adımlar vardı:

1) 12. (Sunucu Rolleri) ve 18 - 23 arasındaki adımlarda geri yüklenecek sunucu seviyesi ayarlarını not alın.

2) SQL Server 2012'den SP3'e yama (herhangi bir sistem dbs'i geri yüklemek istiyorsak gereken tutarlılık).

3) Sürümlerin her örnekle eşleştiğini doğrulayın. "@@ versiyonunu seç"

4) Bu betiği çalıştırarak bu 6 diziyi oluşturun. Çok sayıda örnek varsa, Redgate SQL Multiscript çok büyük bir zaman tasarrufu sağlar (Araçlar -> Seçenekler => Satır Uzunluğunu maksimuma (8192) ayarlayın ve ardından Metin Çıktısını kullanın).

  • yedek
  • Onarmak
  • ayırmak
  • iliştirmek
  • Girişleri Yeniden Oluştur
  • Kullanıcıları Girişlere Bağlama

    -- (1) BACKUP / (2) RESTORE
    --    
    --*** SET THESE to external drive location
    --*** and create the Destination Directories
    declare 
        @backupInstanceDir  varchar(300) = 'F:\ExternalDriveBackups\' + replace(@@servername, '\', '_'),
        @dateSuffix         varchar(100) = '2015-12-14'; 
    
    if (object_id('tempdb..DatabaseStatus') is not null)
    drop table #DAtabseSTatus;
    
    select 
        d.name DbName, 
        d.state_desc DbState,
        d.user_access_desc UserMode,
        convert(bit, (d.is_read_only * -1 + 1)) as IsWritable,
        d.is_trustworthy_on as IsTrustWorthy,
        d.is_in_standby IsInStandby,
        d.recovery_model_desc RecoveryModel,
        suser_sname(d.owner_sid) as Owner,
        convert(bit, 
            case when d.database_id <= 4 or d.is_distributor = 1
                then 1
                else 0
            end) as IsSystemDb,
        mf.type_desc as FileType,
        mf.name FileName,
        mf.state FileState,
        mf.state_desc FileStatDesc,
        mf.physical_name PhysicalName,
        mf.type as FileTypeId    
    into #DatabaseStatus
    from
        sys.master_files AS mf
    join sys.databases AS d
    ON  mf.database_id = d.database_id
    where
        1=1
    order by
        d.name,
        mf.physical_name;
    
    if object_id('tempdb..#sqlOut') is not null
        drop table #sqlOutBU
    
    if object_id('tempdb..#sqlOut') is not null
        drop table #sqlOutRE
    
    create table #sqlOutBU
    (
        Command nvarchar(max) not null,
        Row int identity(1,1) not null primary key
    );
    
    create table #sqlOutRE
    (
        Command nvarchar(max) not null,
        Row int identity(1,1) not null primary key
    );
    
    insert into #sqlOutBU select char(10) + '-- BACKUP SCRIPT' + char(10);
    insert into #sqlOutRE select char(10) + '-- RESTORE SCRIPT' + char(10);
    
    
    insert into #sqlOutBU select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';
    
    insert into #sqlOutRE select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';        
    
    PRINT '--Script for Backing up all DBs in a SQL Server Instance to a specific location' 
    
    SET nocount ON 
    
    insert into #sqlOutBU select char(10) + 
    '--' + char(10) + '-- BACKUP ' + @@servername + '--' + char(10) + 
    'use [Master]; set deadlock_priority high;' + char(10);
    
    insert into #sqlOutRE select '
    -- RESTORE
    --
    -- BE SURE TO BACKUP SYSTEM DBS TO AN ALTERNATE LOCATION JUST BEFORE RESTORING!
    --
    use [Master]; set deadlock_priority high;' + char(10);
    
    DECLARE @dbname nvarchar(128) 
    declare dblist_cursor cursor fast_forward for 
    select [name] from master.sys.databases where [name] != 'tempdb'
    order by iif(database_id <= 4, '0', '1') + [name]
    
    open dblist_cursor 
    fetch next from dblist_cursor into @dbname 
    
    while @@fetch_status = 0 
    begin 
    
        declare @bak nvarchar(300) = @backupInstanceDir + '\' + @dbname + '_' + @dateSuffix + '.bak';
    
        insert into #sqlOutBU select char(10) + 'backup database [' + @dbname + '] to disk = ''' + @bak + ''' WITH COPY_ONLY, NOFORMAT, NOINIT, ' + char(10) + 
            'NAME = N''' + @dbName + '-Full'', SKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 25;';
    
        insert into #sqlOutRE select 'restore database [' + @dbName + '] from disk = ''' + @bak + ''' WITH FILE = 1,' + char(10) +
        (
            select '    move ''' + FileName + ''' to ''' + PhysicalName + '''' From #DatabaseStatus
            where FileType = 'Rows' and DbName = @dbName
        ) + ',' + char(10) +
        (
            select '    move ''' + FileName + ''' to ''' + PhysicalName + '''' From #DatabaseStatus
            where FileType = 'Log' and DbName = @dbName
        ) + ',' + char(10) +
        '    NOUNLOAD, REPLACE, STATS = 25;' + char(10);               
    
        fetch next from dblist_cursor into @dbname 
    end 
    
    close dblist_cursor 
    deallocate dblist_cursor 
    
    insert into #sqlOutBU select char(10) + 'go' + char(10);
    insert into #sqlOutRE select char(10) + 'go' + char(10);
    
    select Command from #sqlOutBU order by Row; -- BACKUP SCRIPT
    select Command from #sqlOutRE order by Row; -- RESTORE SCRIPT
    
    go
    
    
    
    --
    -- (3) DETACH  -  Org Author: Artemakis Artemiou
    --      
    
    if object_id('tempdb..#sqlOutDT') is not null
        drop table #sqlOutDT
    
    create table #sqlOutDT
    (
        Command nvarchar(max) not null,
        Row int identity(1,1) not null primary key
    );
    
    insert into #sqlOutDT select char(10) + '-- DETACH all DBs from a SQL Server Instance' + char(10);      
    
    insert into #sqlOutDT select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';
    
    SET nocount ON 
    
    insert into #sqlOutDT select char(10) + '--' + char(10) + '-- DETACH ' + @@servername + char(10) + '--' + char(10) + '
    use MAster; set deadlock_priority high;' + char(10) + char(10);
    
    DECLARE @dbname nvarchar(128) 
    DECLARE dblist_cursor CURSOR fast_forward FOR 
    SELECT [name] 
    FROM   master.sys.databases 
    WHERE  database_id > 4 
    
    OPEN dblist_cursor 
    FETCH next FROM dblist_cursor INTO @dbname 
    
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
        insert into #sqlOutDT select
        'alter database ' + @dbname + ' set single_user with rollback immediate;' + char(10) +
        'EXEC sp_detach_db ''' + @dbname + ''', ''true'';' + char(10);
        FETCH next FROM dblist_cursor INTO @dbname 
    END 
    
    CLOSE dblist_cursor 
    DEALLOCATE dblist_cursor 
    
    insert into #sqlOutDT select char(10) + 'go' + char(10);
    select Command from #sqlOutDT order by Row;
    
    go
    
    
    
    --
    -- (4) ATTACH  -  Org Author: Artemakis Artemiou
    --    
    
    if object_id('tempdb..#sqlOut') is not null
        drop table #sqlOutAT
    
    create table #sqlOutAT
    (
        Command nvarchar(max) not null,
        Row int identity(1,1) not null primary key
    );
    
    insert into #sqlOutAT select char(10) + '-- ATTACH ALL DBs to a SQL Server Instance' + char(10);
    
    insert into #sqlOutAT select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';
    
    SET NOCOUNT ON
    
    insert into #sqlOutAT select char(10) + '--' + char(10) + '-- ATTACH ' + @@servername + char(10) + '--' + char(10) + 
    'use MAster;' + char(10) + char(10);
    
    DECLARE @dbname nvarchar(128);
    
    DECLARE DBList_cursor CURSOR fast_forward FOR 
    select [name] from master.sys.databases where database_id > 4
    order by name;
    
    OPEN DBList_cursor
    
    FETCH NEXT FROM DBList_cursor 
    INTO @dbname
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
    declare @attach_TSQL_script varchar(max)
    set @attach_TSQL_script=''
    set @attach_TSQL_script=@attach_TSQL_script+'CREATE DATABASE ' + @dbname +' ON ' 
    
    declare @tsql varchar(max),@filename varchar(max)
    set @tsql='DECLARE DBFiles_cursor CURSOR FOR select [filename] from '+ @dbname + '.sys.sysfiles'
    
    execute (@tsql) 
    
    PRINT '--'+@dbname 
    
    OPEN DBFiles_cursor
    FETCH NEXT FROM DBFiles_cursor INTO @filename
    
    WHILE @@FETCH_STATUS = 0
    BEGIN   
    set @attach_TSQL_script=@attach_TSQL_script+ char(10)+'    (FILENAME = '''+ @filename +'''),' 
    FETCH NEXT FROM DBFiles_cursor INTO @filename
    END
    
    set @attach_TSQL_script=SUBSTRING(@attach_TSQL_script,0,len(@attach_TSQL_script))
    set @attach_TSQL_script=@attach_TSQL_script+ char(10) +'    FOR ATTACH;';
    
    insert into #sqlOutAT select @attach_TSQL_script + char(10);
    
    PRINT @attach_TSQL_script 
    PRINT ''
    
    CLOSE DBFiles_cursor
    DEALLOCATE DBFiles_cursor
    
    FETCH NEXT FROM DBList_cursor 
    INTO @dbname
    
    END 
    
    CLOSE DBList_cursor
    DEALLOCATE DBList_cursor
    
    insert into #sqlOutAT select char(10) + 'go' + char(10);
    select Command from #sqlOutAT order by Row;
    go
    
    
    
    --
    -- (5) GENERATE A 'RE-CREATE LOGINS' SCRIPT
    --
    -- This script was modified from a version that was designed to copy from one server to another:
    --      http://stackoverflow.com/a/5983773/538763
    --
    
    
    USE [master]
    
    if object_id('tempdb..#sqlOut') is not null
    drop table #sqlOut;
    
    create table #sqlOut
    (
    Command nvarchar(max) not null,
    Row int identity(1,1) not null primary key
    );
    
    insert into #sqlOut select char(10) + '-- RECREATE LOGINS' + char(10);
    
    
    insert into #sqlOut select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';
    
    insert into #sqlOut select 'use Master;' + char(10);
    go
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    declare @Debug bit = 0;
    declare @PartnerServer varchar(100) = @@SERVICENAME;  -- use current server before it is shutdown (disabled below)
    
    declare
        @MaxID int,
        @CurrID int,
        @SQL nvarchar(max),
        @LoginName sysname,
        @IsDisabled int,
        @Type char(1),
        @SID varbinary(85),
        @SIDString nvarchar(100),
        @PasswordHash varbinary(256),
        @PasswordHashString nvarchar(300),
        @RoleName sysname,
        @Machine sysname,
        @PermState nvarchar(60),
        @PermName sysname,
        @Class tinyint,
        @MajorID int,
        @ErrNumber int,
        @ErrSeverity int,
        @ErrState int,
        @ErrProcedure sysname,
        @ErrLine int,
        @ErrMsg nvarchar(2048);
    
    declare @Logins Table (LoginID int identity(1, 1) not null primary key,
                        [Name] sysname not null,
                        [SID] varbinary(85) not null,
                        IsDisabled int not null,
                        [Type] char(1) not null,
                        PasswordHash varbinary(256) null)
    declare @Roles Table (RoleID int identity(1, 1) not null primary key,
                    RoleName sysname not null,
                    LoginName sysname not null)
    declare @Perms Table (PermID int identity(1, 1) not null primary key,
                    LoginName sysname not null,
                    PermState nvarchar(60) not null,
                    PermName sysname not null,
                    Class tinyint not null,
                    ClassDesc nvarchar(60) not null,
                    MajorID int not null,
                    SubLoginName sysname null,
                    SubEndPointName sysname null)
    
    Set NoCount On;
    
    If CharIndex('\', @PartnerServer) > 0
    Begin
    Set @Machine = LEFT(@PartnerServer, CharIndex('\', @PartnerServer) - 1);
    End
    Else
    Begin
    Set @Machine = @PartnerServer;
    End
    
    -- Get all Windows logins from principal server
    Set @SQL = 'Select P.name, P.sid, P.is_disabled, P.type, L.password_hash' + CHAR(10) +
        'From ' /*+ QUOTENAME(@PartnerServer) + '.*/ + 'master.sys.server_principals P' + CHAR(10) +
        'Left Join '/* + QUOTENAME(@PartnerServer) + '.*/ + 'master.sys.sql_logins L On L.principal_id = P.principal_id' + CHAR(10) +
        'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
        'And P.name <> ''sa''' + CHAR(10) +
        'And P.name Not Like ''##%''' + CHAR(10) +
        'and P.Name Not like ''NT SERVICE%''' + CHAR(10) +
        'And CharIndex(''' + @Machine + '\'', P.name) = 0;';
    
    Insert Into @Logins (Name, SID, IsDisabled, Type, PasswordHash)
    Exec sp_executesql @SQL;
    
    -- Get all roles from principal server
    Set @SQL = 'Select RoleP.name, LoginP.name' + CHAR(10) +
        'From '/* + QUOTENAME(@PartnerServer) + '.*/ + 'master.sys.server_role_members RM' + CHAR(10) +
        'Inner Join '/* + QUOTENAME(@PartnerServer) + .*/ +'master.sys.server_principals RoleP' +
        CHAR(10) + char(9) + 'On RoleP.principal_id = RM.role_principal_id' + CHAR(10) +
        'Inner Join '/* + QUOTENAME(@PartnerServer) + '.*/ + 'master.sys.server_principals LoginP' +
        CHAR(10) + char(9) + 'On LoginP.principal_id = RM.member_principal_id' + CHAR(10) +
        'Where LoginP.type In (''U'', ''G'', ''S'')' + CHAR(10) +
        'And LoginP.name <> ''sa''' + CHAR(10) +
        'And LoginP.name Not Like ''##%''' + CHAR(10) +
        'And LoginP.name Not Like ''NT SERVICE%''' + CHAR(10) +
        'And RoleP.type = ''R''' + CHAR(10) +
        'And CharIndex(''' + @Machine + '\'', LoginP.name) = 0;';
    
    Insert Into @Roles (RoleName, LoginName)
    Exec sp_executesql @SQL;
    
    -- Get all explicitly granted permissions
    Set @SQL = 'Select P.name Collate database_default,' + CHAR(10) +
        '   SP.state_desc, SP.permission_name, SP.class, SP.class_desc, SP.major_id,' + CHAR(10) +
        '   SubP.name Collate database_default,' + CHAR(10) +
        '   SubEP.name Collate database_default' + CHAR(10) +
        'From '/* + QUOTENAME(@PartnerServer) + '.*/ + ' master.sys.server_principals P' + CHAR(10) +
        'Inner Join '/* + QUOTENAME(@PartnerServer) + '.*/ + ' master.sys.server_permissions SP' + CHAR(10) +
        CHAR(9) + 'On SP.grantee_principal_id = P.principal_id' + CHAR(10) +
        'Left Join '/* + QUOTENAME(@PartnerServer) + '.*/ + ' master.sys.server_principals SubP' + CHAR(10) +
        CHAR(9) + 'On SubP.principal_id = SP.major_id And SP.class = 101' + CHAR(10) +
        'Left Join '/* + QUOTENAME(@PartnerServer) + '.*/ + ' master.sys.endpoints SubEP' + CHAR(10) +
        CHAR(9) + 'On SubEP.endpoint_id = SP.major_id And SP.class = 105' + CHAR(10) +
        'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
        'And P.name <> ''sa''' + CHAR(10) +
        'And P.name Not Like ''##%''' + CHAR(10) +
        'And P.name Not Like ''NT SERVICE%''' + CHAR(10) +
        'And CharIndex(''' + @Machine + '\'', P.name) = 0;'
    
    Insert Into @Perms (LoginName, PermState, PermName, Class, ClassDesc, MajorID, SubLoginName, SubEndPointName)
    Exec sp_executesql @SQL;
    
    --select * from @Logins;
    --select * from @Roles;
    --select * from @perms;
    
    
    Select @MaxID = Max(LoginID), @CurrID = 1
    From @Logins;
    
    While @CurrID <= @MaxID
    Begin
    Select @LoginName = Name,
        @IsDisabled = IsDisabled,
        @Type = [Type],
        @SID = [SID],
        @PasswordHash = PasswordHash
    From @Logins
    Where LoginID = @CurrID;
    
    --    If Not Exists (Select 1 From sys.server_principals
    --              Where name = @LoginName)
    Begin
    
        set @sql = char(10);
        set @sql += 'If Not Exists (Select 1 From sys.server_principals Where name = ''' + @LoginName + ''')' + char(10);
        set @sql += 'begin' + char(10) + '    ';
    
        Set @SQL += 'Create Login ' + quotename(@LoginName)
        If @Type In ('U', 'G')
        Begin
            Set @SQL = @SQL + ' From Windows;'
        End
        Else
        Begin
            Set @PasswordHashString = '0x' +
                Cast('' As XML).value('xs:hexBinary(sql:variable("@PasswordHash"))', 'nvarchar(300)');
    
            Set @SQL = @SQL + ' With Password = ' + @PasswordHashString + ' HASHED;  --, ';
    
            Set @SIDString = '0x' +
                Cast('' As XML).value('xs:hexBinary(sql:variable("@SID"))', 'nvarchar(100)');
            Set @SQL = @SQL + 'SID = ' + @SIDString + ';' + char(10);
        End
    
        set @sql += char(10) +
            '    print ''Created Login ' + @loginName  + ''';' + char(10) +
            'end' + char(10) +
            'else' + char(10) +
            convert(nvarchar(max), '    print ''Login ' + @loginName + ' already existed. '';') + char(10);
    
        If @Debug = 0
        insert into #sqlOut select @SQL;                      
        Else
        Print @SQL;
    
        If @IsDisabled = 1
        Begin
            Set @SQL = 'Alter Login ' + quotename(@LoginName) + ' Disable;'
            If @Debug = 0
                insert into #sqlOut select @SQL;                              
            Else              
                Print @SQL;              
        End
        End
    Set @CurrID = @CurrID + 1;
    End
    
    
    insert into #sqlOut select char(10) + 'use Master;' + char(10);
    
    Select @MaxID = Max(RoleID), @CurrID = 1
    From @Roles;
    
    While @CurrID <= @MaxID
    Begin
    Select @LoginName = LoginName,
        @RoleName = RoleName
    From @Roles
    Where RoleID = @CurrID;
    
    /*  If Not Exists (Select 1 From sys.server_role_members RM
                Inner Join sys.server_principals RoleP
                    On RoleP.principal_id = RM.role_principal_id
                Inner Join sys.server_principals LoginP
                    On LoginP.principal_id = RM.member_principal_id
                Where LoginP.type In ('U', 'G', 'S')
                And RoleP.type = 'R'
                And RoleP.name = @RoleName
                And LoginP.name = @LoginName)*/
    Begin
        If @Debug = 0
        Begin          
            insert into #sqlOut select 'Exec sp_addsrvrolemember @rolename = ''' + @RoleName + ''', @loginame = ''' + @LoginName + ''';';
        End
        Else
        Begin
            Print 'Exec sp_addsrvrolemember @rolename = ''' + @RoleName + ''',';
            Print '     @loginame = ''' + @LoginName + ''';';
        End
    End
    
    Set @CurrID = @CurrID + 1;
    End
    
    
    insert into #sqlOut select char(10) + 'use Master;' + char(10);
    
    
    Select @MaxID = Max(PermID), @CurrID = 1
    From @Perms;
    
    While @CurrID <= @MaxID
    Begin
    Select @PermState = PermState,
        @PermName = PermName,
        @Class = Class,
        @LoginName = LoginName,
        @MajorID = MajorID,
        @SQL = PermState + space(1) + PermName + SPACE(1) +
            Case Class When 101 Then 'On Login::' + QUOTENAME(SubLoginName)
                    When 105 Then 'On ' + ClassDesc + '::' + QUOTENAME(SubEndPointName)
                    Else '' End +
            ' To ' + QUOTENAME(LoginName) + ';'
    From @Perms
    Where PermID = @CurrID;
    
    /*If Not Exists (Select 1 From sys.server_principals P
                Inner Join sys.server_permissions SP On SP.grantee_principal_id = P.principal_id
                Where SP.state_desc = @PermState
                And SP.permission_name = @PermName
                And SP.class = @Class
                And P.name = @LoginName
                And SP.major_id = @MajorID)*/
    Begin
        If @Debug = 0
                insert into #sqlOut select @sql;                      
        Else          
            Print @SQL;          
    End
    
    Set @CurrID = @CurrID + 1;
    End
    
    
    select Command from #sqlOut as SqlOut order by Row;
    go
    
    
    --
    -- (6) Generate a script to Re-link all users to logins based on current state (before shutdown)
    --
    
    use Master;
    
    if object_id('tempdb..#sqlOut') is not null
    drop table #sqlOut;
    
    create table #sqlOut
    (
        Command nvarchar(max) not null,
        Row int identity(1,1) not null primary key
    );
    
    insert into #sqlOut select char(10) + '-- RELINK USERS TO LOGINS' + char(10);
    
    insert into #sqlOut select char(10) + char(10) + '/* ---------------------------------------------------------------------------------------------' + char(10) + 
    'ServerName: ' + @@servername + char(10) + 'ServiceName: ' + @@servicename + char(10) + 'Version: ' + @@version + 
    '--------------------------------------------------------------------------------------------- */';
    
    declare @dbCmd varchar(8000) = '
    use ?;
    
    insert into #sqlOut select char(10) + ''use ?;'' + char(10);  
    
    with links as
    (
    select u.name as UserName,
        l.loginname as LoginName
        from sysusers u 
        join master..syslogins l
        on u.sid = l.sid        
    where u.name != ''dbo''
        and u.isSqlUser = 1 or l.isNtName = 1 or l.isNtGroup = 1
    )
    insert into #sqlOut 
    select ''alter user ['' + UserName + ''] with name = ['' + UserName + ''], login = ['' + LoginName + '']''
    from links
    ';    
    
    exec sp_MSforeachdb @dbCmd;
    
    select Command from #sqlOut order by Row;
    
    go

5) Komut dosyasını, sistem (master, msdb, model) dahil olmak üzere tüm DB'leri harici sürücüye yedekle'ye çalıştırın.

6) Tüm DB'leri Ayırmak için komut dosyasını çalıştırın

7) C Sürücü yeniden formatlanacak. LDF / MDF'leri, C üzerinde DEĞİL ise, koruyun

8) Windows Server 2012 C’de yüklü

9) Orijinal sistem dosyaları için LDF / MDF'yi, C Sürücüsünde olmasalardı şekilde çekip çıkarın.

10) SQL Server 2012 yeniden yüklenecek ve SP3'e yayacak. Sistem Kullanıcı / Grup hesaplarını yeniden oluşturun

11) Sistem DB'lerini YENİ bir konuma veya dosya adına yedekleyin (orijinallerin üzerine yazmamaya dikkat edin!).

12) Yeniden yaratma rolleri pasajını çalıştırın. Gibi bir şey:

USE [master]
CREATE SERVER ROLE [SomeServerRole]
--ALTER SERVER ROLE [dbcreator] ADD MEMBER [SomeServerRole]
--ALTER SERVER ROLE [bulkadmin] ADD MEMBER [SomeServerRole]
-- ALTER SERVER ROLE [SomeServerRole] ADD MEMBER [SomeMemberOrRole]

13) Yeniden başlat giriş komut dosyasını çalıştırın (girişler geri yüklendiyse hiçbir şey yapmaz)

14) SQL AJAN'ı durdurun.

(Master'ı burada geri yükleyebilir miyiz, tavştık).

15) Yukarıdaki betiği kullanarak mdf / ldf'yi ekleyin. a. Başarısız olursa, yukarıdaki betiği kullanarak bak komutundan manuel olarak geri yükleyin.

16) Modelin Geri Yüklenmeye Çalışması

17) SQL Agent'ın durdurulduğundan emin olun. MSDB'yi geri yükleme (bağlantı) a. Başarısız olursa, işleri + bakım planını + posta yapılandırmasını + işleçleri yeniden oluşturmanız gerekir

18) Kullanıcı To Login komut dosyasını açın ...

    a. If there are master users (rare?) then First Re-Create users for master since it was not restored:
        use master;       
        CREATE USER [ABC] FOR LOGIN [machine\ABC]

    b. Run the rest of the script

19) Hizmet aracısını, orijinal SELECT adıyla eşleşecek şekilde etkinleştirin, is_broker_enabled FROM sys.databases;

    alter database MSDB set single_user with rollback immediate;
    ALTER DATABASE [MSDB] SET ENABLE_BROKER;
    alter database MSDB set multi_user;

20) SQL Agent'ı başlatın

21) Paralellik eşiğini orijinal değerine ayarla

22) Herhangi bir veritabanı ayarını orijinal değerlerine ayarlayın:

 declare @dbCmd varchar(8000) = '
      use ?;
      if db_name() not in (''master'', ''model'', ''tempdb'', ''msdb'')
      begin
             print ''Adjusting [?]...'';    
            alter database [?] set single_user with rollback immediate;
             aLTER AUTHORIZATION ON DATABASE::[?] to [sa];
            -- alter database [?] set trustworthy on;
            ALTER DATABASE [?] SET AUTO_CLOSE OFF WITH NO_WAIT;     
            alter database [?] set multi_user;
      end     
      else
             print ''Skipping [?]...'';
    ';    

    exec sp_MSforeachdb @dbCmd;

23) İş sahipliğini kontrol edin:

select s.name as JobName, l.name as login, SUSER_SNAME(s.owner_sid) AS login2
from  msdb..sysjobs s 
left join master.sys.syslogins l on s.owner_sid = l.sid

SQL Server Sürümü de yükseltilmiş olsaydı, model ve msdb veritabanlarının geri yüklenebileceğine inanmıyorum, bu nedenle işler https://support.microsoft.com/en-us/kb/264474 nedeniyle kaybedilmiş olabilir.

Ne kayıp:

  • Ana veritabanındaki orignal kullanıcılar (nadir?)
  • Sunucu Rolleri
  • ?

0

Her iki yaklaşımda da hiçbir şey yanlış değildir - ikisini de yaptım ve sonuçların ikisi de genellikle iyi.

Göç yaklaşımında bir sorun varsa, teknik değil: tembellik. Sıklıkla, bir şirketin henüz xxxx sürümüne tam olarak gitmemesinin sebebi, salıncak geçişi seçtikleri ve tamamen hareket etmek için zor işleri yapmak için asla uğraşmadıklarıdır. Şimdi bir yerine iki veya daha fazla sunucu setine sahipler.

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.