2011年10月26日 星期三

SQL Server - 資料誤刪救援方式

        近日遇到一個客戶詢問的問題,由於他們的資料庫中有一個資料表的資料意外的被刪除,所以尋求我們協助還原資料,但可惜的是在進一步詢問後,客戶竟然完全沒有備份,所以只好透過內建的方法進行還原,大家一定會想到可以透過 DBCC LOG 或  fn_dblog 來觀察吧,但可惜的是這二個的資訊還是無法讓使用者比較直接又簡單的方式進行還原的動作,後來我終於找到方式解決,大家可以參考下列的步驟進行。
     
1、如果你有完整備份時,您可以透過交易記錄檔還原被 update 或 delete 的記錄。

還原到某個時間點

1-1. 使用 NORECOVERY 選項執行 RESTORE DATABASE 陳述式。
附註
如果部分還原順序排除任何FILESTREAM 檔案群組,則不支援時間點還原。您可以強制還原順序,以繼續進行。但是,絕對無法還原 RESTORE 陳述式中省略的 FILESTREAM 檔案群組。若要強制時間點還原,請指定 CONTINUE_AFTER_ERROR 選項,連同 STOPAT、STOPATMARK 或 STOPBEFOREMARK 選項,而且您也必須在後續的 RESTORE LOG 陳述式中指定這些項目。如果您指定 CONTINUE_AFTER_ERROR,則部分還原順序會成功,而 FILESTREAM 檔案群組則會變成無法復原。

1-2. 執行 RESTORE LOG 陳述式以套用每一個交易記錄備份,並指定:

  • 要套用交易記錄檔的資料庫名稱。
  • 要從其還原交易記錄備份的備份裝置。
  • RECOVERY 及 STOPAT 選項。如果交易記錄備份中不含所要求的時間 (例如,指定的時間超出交易記錄的結束時間),則會產生警告訊息,且此資料庫會維持未復原狀態。

範例
下列範例會將資料庫還原至 April 15, 202012:00 AM 時的狀態,並顯示含有多個記錄備份的還原作業。在備份裝置 AdventureWorks2008R2Backups 上,要還原的完整資料庫備份是裝置上的第三個備份組 (FILE = 3),第一個記錄備份是第四個備份組 (FILE = 4),而第二個記錄備份是第五個備份組 (FILE = 5)。

重要事項
AdventureWorks2008R2 資料庫使用簡單復原模式。若要允許記錄備份,在執行完整資料庫備份之前,請使用 ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL 將該資料庫設定為使用完整復原模式。

RESTORE DATABASE AdventureWorks2008R2
FROM AdventureWorks2008R2Backups
WITH FILE=3, NORECOVERY;
go;

RESTORE LOG AdventureWorks2008R2
FROM
AdventureWorks2008R2Backups
WITH FILE=4, NORECOVERY,
STOPAT = 'Apr 15, 2020 12:00 AM';
go;

RESTORE LOG AdventureWorks2008R2
FROM
AdventureWorks2008R2Backups
WITH FILE=5, NORECOVERY,
STOPAT = 'Apr 15, 2020 12:00 AM';
RESTORE DATABASE AdventureWorks2008R2 WITH
RECOVERY;
go;

參考資料:
如何:還原到某個時間點 (Transact-SQL)
http://msdn.microsoft.com/zh-tw/library/ms179451.aspx

2、若沒有做過完整備份,我們沒有提供直接從交易記錄檔的方式,提供third-party 工具給您參考。 LiteSpeed http://www.quest.com/litespeed-for-sql-server/ 您可以用LiteSpeed找出所有資料後,再透過undo log的方式找回被誤刪的資料即可。

在下列的測試程式碼中,會建立資料庫,然後新增二筆紀錄,再刪除名稱為 'cary' 的紀錄,然後後再透過 LiteSpeed 的軟體救回資料。

測試程式碼:
CREATE TABLE dbo.cary_member (
sn smallint NOT NULL IDENTITY (1, 1),
name varchar(50) NULL
) ON [PRIMARY] go;

insert dbo.cary_member(name) values('cary'); go;

insert dbo.cary_member(name) values('sky'); go;

delete from dbo.cary_member where name = 'cary' go;


2-1. 啟動 LiteSpeed 之後,連線到資料庫,然後在左半邊的最下方,點選 Log Reader,然後就可以列出目前在Log Files中有的記錄。

2-2. 選取被刪除的記錄,然後選擇 [Undo/Redo Transaction]

2-3此時會跳出 [Undo/Redo Wizard],將你選擇的紀錄轉成DML語法。

2-4完成後系統會統計你進行的筆數與執行結。

2-5這時候再到資料庫中進行查詢,你就會發生資料已被救回來了。

2-6然後再回到 LiteSpeed的 Log Reader之中,確認Log 的紀錄,此時你會發現又多現一筆了,也就是新增後寫回的紀錄。



3、另外如果您要查詢是那一位使用者刪除的話,您可以透過下列的方式進行。

select [Current LSN], [Transaction ID], [Transaction Name],
[Begin Time], bb.name
from ::fn_dblog (null, null) aa inner join
master.sys.syslogins bb
on aa.[Transaction SID] = bb.sid
where [Transaction Name] LIKE '%DELETE%'


最後還是建議大家在資料庫的維護上,還是要有完整的備份規畫,要不然日後如果還有資料誤刪或毀損時,可不是每一次都可以這麼幸運的,建議大家可以參考下列的連結進行備份的規畫。

參考連結:
Introduction to Backup and Restore Strategies in SQL Server
http://msdn.microsoft.com/en-us/library/ms191239.aspx

關鍵字:SQL ServerData RecoveryDBCC LOGfn_dblogLiteSpeed

2011年10月24日 星期一

SQL Server 2008 R2 安裝問題排除

        由於之前已有安裝SQL Server 2008 R2 Express,但由於工作需要,又另外裝了SQL Server 2008 R2,但是在安裝的過程中遇到了下列的問題,但是後來解決方法還真是簡單,只要將Microsoft_Corporation的下檔案夾刪除即可,再次重新啟動安裝程式即可。

路徑:
C:\Users\caryhsu\AppData\Local\Microsoft_Corporation\LandingPage.exe_StrongName_ryspccglaxmt4nhllj5z3thycltsvyyx

錯誤訊息:
建立 userSettings/Microsoft.SqlServer.Configuration.LandingPage.Properties.Settings 的組態區段處理常式時發生錯誤:無法載入檔案或組件 'System. Version=4.0.0.0, Culture=neutral, PublicKey Token=b77a5c561934e089' 或其相依性的其中之一。系統找不到指定的檔案。
(C:\users\caryhsu\AppData\Local\Microsoft_Corporation\LandingPage.exe_StrongName_ryspccglaxmt4nhllj5z3thycltsvyyx\10.0.0.0\user.config

詳細錯誤資料:
如需叫用 Just-In-Time (JIT) 偵錯的詳細資料,
請參閱本訊息結尾處 (而非這個對話方塊) 的資訊。

************** 例外狀況文字 **************
System.Configuration.ConfigurationErrorsException: 建立 userSettings/Microsoft.SqlServer.Configuration.LandingPage.Properties.Settings 的組態區段處理常式時發生錯誤: 無法載入檔案或組件 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 或其相依性的其中之一。 系統找不到指定的檔案。 (C:\Users\caryhsu\AppData\Local\Microsoft_Corporation\LandingPage.exe_StrongName_ryspccglaxmt4nhllj5z3thycltsvyyx\10.0.0.0\user.config line 5) ---> System.IO.FileNotFoundException: 無法載入檔案或組件 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 或其相依性的其中之一。 系統找不到指定的檔案。
檔案名稱: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
   於 System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
   於 System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.Init(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
   於 System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.InitWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
   於 System.Configuration.RuntimeConfigurationRecord.CreateSectionFactory(FactoryRecord factoryRecord)
   於 System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)

警告: 組件繫結記錄切換為 OFF。
若要記錄組件繫結失敗,請將登錄值 [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) 設為 1。
注意: 與組件繫結失敗記錄相關的效能會有部分負面影響。
若要關閉此功能,請移除登錄值 [HKLM\Software\Microsoft\Fusion!EnableLog]。

   --- 內部例外狀況堆疊追蹤的結尾 ---
   於 System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
   於 System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   於 System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   於 System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   於 System.Configuration.ConfigurationManager.GetSection(String sectionName)
   於 System.Configuration.ClientSettingsStore.ReadSettings(String sectionName, Boolean isUserScoped)
   於 System.Configuration.LocalFileSettingsProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
   於 System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider)
   於 System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName)
   於 System.Configuration.SettingsBase.get_Item(String propertyName)
   於 System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName)
   於 System.Configuration.ApplicationSettingsBase.get_Item(String propertyName)
   於 Microsoft.SqlServer.Configuration.LandingPage.LandingPageForm.OnLoad(EventArgs e)
   於 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   於 System.Windows.Forms.Control.CreateControl()
   於 System.Windows.Forms.Control.WmShowWindow(Message& m)
   於 System.Windows.Forms.Control.WndProc(Message& m)
   於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   於 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** 已載入的組件 **************
mscorlib
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4963 (win7RTMGDR.050727-4900)
    程式碼基底: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
mscorlib.resources
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4963 (win7RTMGDR.050727-4900)
    程式碼基底: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
LandingPage
    組件版本: 10.0.0.0
    Win32 版本: 10.50.1600.1 ((KJ_RTM).100402-1539 )
    程式碼基底: file:///E:/x64/LandingPage.exe
----------------------------------------
System.Windows.Forms
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4961 (win7RTMGDR.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4962 (win7RTMGDR.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Microsoft.SqlServer.Configuration.Sco
    組件版本: 10.0.0.0
    Win32 版本: 10.50.1600.1 ((KJ_RTM).100402-1539 )
    程式碼基底: file:///E:/x64/Microsoft.SqlServer.Configuration.Sco.DLL
----------------------------------------
LandingPage.resources
    組件版本: 10.0.0.0
    Win32 版本: 10.50.1600.1 ((KJ_RTM).100402-1539 )
    程式碼基底: file:///E:/x64/zh-CHT/LandingPage.resources.DLL
----------------------------------------
Microsoft.SqlServer.Chainer.Infrastructure
    組件版本: 10.0.0.0
    Win32 版本: 10.50.1600.1 ((KJ_RTM).100402-1539 )
    程式碼基底: file:///E:/x64/Microsoft.SqlServer.Chainer.Infrastructure.DLL
----------------------------------------
System.Xml
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
Accessibility
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/Accessibility/2.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
Microsoft.SqlServer.Management.Controls
    組件版本: 10.0.0.0
    Win32 版本: 10.50.1600.1 ((KJ_RTM).100402-1539 )
    程式碼基底: file:///E:/x64/Microsoft.SqlServer.Management.Controls.DLL
----------------------------------------
System.Configuration
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
SYSTEM.CONFIGURATION.resources
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration.resources/2.0.0.0_zh-CHT_b03f5f7f11d50a3a/System.Configuration.resources.dll
----------------------------------------
System.Windows.Forms.resources
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.4927 (NetFXspW7.050727-4900)
    程式碼基底: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms.resources/2.0.0.0_zh-CHT_b77a5c561934e089/System.Windows.Forms.resources.dll
----------------------------------------

************** JIT 偵錯 **************
若要啟用 Just-In-Time (JIT) 偵錯功能,則必須在
此應用程式或電腦的 .config 檔案中,設定
system.windows.forms 區段內的 jitDebugging 值。
且該應用程式也必須在啟用偵錯的狀態下進行
編譯。

例如:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

當 JIT 偵錯功能啟用後,會將所有未處理的例外
狀況傳送給電腦上已註冊的 JIT 偵錯工具進行處
理,而不是使用這個對話方塊來處理。



關鍵字:SQL ServerSQL Server 2008 R2LandingPage

2011年10月23日 星期日

硬碟修復心得分享

        之前我一直將檔案儲存在本機與行動碟中,也因為行動碟容量很大,而又非常的方便,所以我就將很多的重要檔案(不好的習慣)放在此行動碟中,然後在固定的時間備份回另一顆硬碟中,但在一次的意外中,我的隨身碟竟然完全無法讀取,透過不同的電腦嘗試,最後還是徒勞無功,後來只好先送修,其實在送修前我已有大概的心理打算,因為我的情況滿嚴重的,所以我想沒個上萬元是修不好的。

        因為這是我的行動碟第一次壞掉,所以基本上我也沒有什麼想法,就只是先找廠商估價,但由於有某些大公司的報價會貴一點點,所以作了一個錯誤的決定,就是拿到一間在台中市中正路上的一間公司修理,結果也是花了快一萬五,原本預估一個月就好,但是中間對方一拖再拖,最後我竟然花了七個多月的等待,然後對方才回給我他們因為設備不足,所以搶救不太順利,但是他們又表示最近因為買了新設備,所以問我要不要等,結果又等了快一個月後,雖然最後有我的部份心血救回了,但是我的重要資料都已經變成不重要了,而且重要的資料我也大部份改寫完成,所以建議大家還是自已評估資料的重要性與時效性,而且大公司的報價也不一定會比較貴,但至少時效性與專業度真的是可以信賴的,經過這一次的經驗,與等待期間找到的資訊,整理如下,

  1. 由於最近一直都沒有動過行動碟與相關裝置,所以初步排除硬體裝置。
  2. 如果你的行動碟還可以在系統中捉的到,但是卻無法讀取時,可以透過下列的三套軟體進行嘗試讀取的動作。

    2-1 easyrecovery (Free):http://www.ontrack.com/
          ftp://ftp.isu.edu.tw/pub/Windows/softking/soft/en/e/ERPERFUS.EXE
    2-2 final data (Free):http://www.finaldata.com/
          ftp://ftp.isu.edu.tw/pub/Windows/softking/soft/cpatch/f/FDENT20.rar
    2-3 r-studio (Shareware):http://www.r-tt.com/
          http://www.r-tt.com/downloads/rsd_en_5.exe
    2-4 badcopy (Shareware):http://www.jufsoft.com/   
          ftp://ftp.isu.edu.tw/pub/Windows/softking/soft/en/b/badcopy-setup.exe 

          上述的軟體在嘗試救援時會花非常久的時間,可能會花快10個小時,所以要耐心的等待。
  3. 如果上面的方法也讀取不到你的資料時,而你的硬碟也還在保固中,建議你可以先拿回原廠詢問是否有修復的可能,而且需確認修復後是否資料會不見,因為送廠修復,大部份他是不會管你的資料是否遺失,所以你要先有心理準備。
  4. 如果你的行動碟完全無法讀取時,有時候可能只是裝置的介面壞掉,所以你可以先找一顆與你目前行動碟相同的型號,然後再拆開後,將壞掉的硬碟,更換到新的硬碟上嘗試進行讀取,據說此方法可以修復大部份的問題,但此方式還是有可能造成硬碟損壞,所以在更換上,還是請注意。上述的作法都不行時,只好找資料救援的廠商,通常都是送修後,如果要確認是否可以修復都需要先收一次工本費,然後再估價,建議大家可以多找幾間進行估價,而且如果可以也確認有修復的環境與裝置,因為通常修復硬碟要在無塵室的環境中,所以也參考多樣條件後再決定,要不然跟我一樣你就會後悔了。
資碟救援是一種最後的手段,還是建議大家平時要作好完整的備份,因為不是每一次檔案都可以救回,而且救回的檔案也不一定能使用,所以千萬不要讓你的懶惰與疏忽,造成你日後資料補救上的痛。

關鍵字:HDDData Recovery資料救援磁碟修復

2011年10月21日 星期五

SQL Server 2008 Service Pack 3 開放下載

        期待已久的SQL Server 2008 SP3終於推出了,本次除了修正許多已知的問題外,也將SP2之後的累積更新 1~4也包其中,再請大家盡快更新。


版本編號:10.00.5500.00
發行日期:2011/10/6


增強功能清單:
  • 從舊版 SQL Server 升級到 SQL Server 2008 SP3 的增強型體驗。此外,我們也提升了安裝體驗的效能與可靠性。 
  • 在 SQL Server Integration Services 記錄檔中,現在會顯示在資料流程中傳送的資料列總數。 
  • 如果啟用 [壓縮資料庫] 選項,建立維護計畫時會產生增強型警告訊息。 
  • 在啟用透明資料加密時解決資料庫問題,即使在卸除憑證時依然可以使用資料庫。 
  • 當 DTA (Database Tuning Advisor) 參考索引空間資料類型資料行時的最佳化查詢結果。 
  • 在平行執行計畫中具有序列函數 (例如 Row_Numbers()) 的優質使用者體驗。

參考連結:
SQL Server 2008 Service Pack 3 http://www.microsoft.com/downloads/zh-tw/details.aspx?FamilyID=757bca07-7b52-46fb-ab92-476be9339442

SQL Server 2008年服務套件 3 中所修正的 bug 清單
http://support.microsoft.com/kb/2546945

關鍵字:SQL ServerService Pack

2011年10月20日 星期四

容錯移轉叢集中多個節點切換順序的設定

        容錯移轉叢集(Cluster)是許多企業在HA架構上的首選,但是許多的企業在叢集環境中,可能會有兩個以上的節點,而節點切換的順序,依照預設值為安裝節點的先後,如果節點之間硬體設備不同,想要指定切換的順序時,你可以依照下列的方法進行節點切換順序的設定。

作業系統支援最大的叢集節點數:
Windows Server 2003 or 2008 標準版 - 支援2個節點
Windows Server 2003 企業版以上 - 支援8個節點
Windows Server 2008 企業版以上 - 支援16個節點

PS:此切換順序是當三個節點以上時才需特別設定。

相關文章:
  1. SQL Server 2008 R2 容錯移轉叢集環境架設 - 利用 VM 與 Windows Storage Server - Part I
  2. SQL Server 2008 R2 容錯移轉叢集環境架設 - 利用 VM 與 Windows Storage Server - Part II
  3. SQL Server 2008 R2 容錯移轉叢集環境架設 - 利用 VM 與 Windows Storage Server - Part III(終)

設定流程:
1、打開容錯叢集管理員
2、點選 [服務與應用程式]
3、點選 [SQL Server],然後再點選滑鼠右鍵


4、開啟內容之後,看到 [慣用擁有者] ,這個就是節點切換時的順序,預設如下列的順序。

1. SQL2008R2-Clu-1
2. SQL2008R2-Clu-2
3. SQL2008R2-Clu-3


5、接下來我們來實驗,當改變順序時,是否會如同我們的設定,我將順序更改如下:

1. SQL2008R2-Clu-3
2. SQL2008R2-Clu-2
3. SQL2008R2-Clu-1


6、設定完成後,請看到下圖,目前的 [節點擁有者] 為 [SQL2008R2-Clu-1],接下來我們進行模擬測試,請點選 [容錯叢集管理員] -> [SQL Server]  -> [將此服務或應用程式移動到另一個節點] -> [1(1) - 最佳的可能選擇] 。

7、此時會跳出切換動作的確認,請再選擇第一個即可。

8、切換完成後,你可以看到 [目前擁有者] 已切換成到第三個節點了。

參考資源:


關鍵字:SQL ServerFailover ClusterCluster慣用擁有者High Availability

2011年10月18日 星期二

SQL Server 2008 R2 安裝 Service Pack 1 錯誤排除

        最近接到一個Case,客戶在安裝SQL Server 2008 R2 Service Pack 1的時候發生問題,錯誤訊息如下,經過多步的確認後,發現可能是系統中其他的軟體安裝移除後,造成登錄值的不同步所影響,而且特別 ProcessMonitor 追踨之後,發現主要是登錄值所造成,後來透過登錄值的修改之後,問題就解決了,方法如下:

操作步驟:

  1. 點選 [開始] -> 執行 -> regedit
  2. 點選 HKEY_Local_Machine\Software\Microsoft|Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\ConfigurationState\ 的目錄,然後先行備份。
  3. 請將 HKEY_Local_Machine\Software\Microsoft|Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\ConfigurationState\ 底下的四個登錄值改變為1即可。
    1. MPT_AGENT_CORE_CNI
    2.  SQL_Engine_Core_Inst
    3.  SQL_FullText_Adv
    4.  SQL_Replication_Core_Inst
  4. 請將 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\ConfigurationState\底下SQL開頭的值也更改為1。
  5. 重新啟動電腦
  6. 再次重新安裝 Service Pack 1
  7. 確認是否安裝完成。


錯誤訊息:
Exception type: Microsoft.SqlServer.Chainer.Infrastructure.ChainerInvalidOperationException
    Message:     
        A failure was detected for a previous installation, patch, or repair during configuration for features [SQL_BIDS_Full,]. In order to apply this patch package (KB2528583), you must resolve any issues with the previous operation that failed. View the summary.txt log to determine why the previous operation failed.
    Data:
      ChainerInvalidOperationExceptionData = ProductInstallProperty
      DisableUpload = true
      DisableWatson = true

關鍵字:SQL ServerService Pack 1SQL Server 2008 R2SP1SQL_BIDS_Full

2011年10月17日 星期一

SQL CLR的介紹與範例說明

        傳統的SQL語法由於只有定義簡單的DDL (data definition language) and DML (data manipulation languages)等,但是使用者對SQL的要求卻是日與聚增,所以各家廠商粉粉自行擴展SQL語法,如Microsoft的T-SQL、Oracle的PL/SQL等,但是這些擴展的SQL還是與程式語言有些差距,而Microsoft為了改善這個問題,在SQL Server 2005以後推出了SQL CLR,讓開發者可以透過.NET  Framework設計出各種資料庫的物件,其中包括預存程式、使用者自訂函式、觸發程式、使用者自訂型別以及使用者自訂彙總函式等功能。

SQL CLR架構


在這我透過一個簡單的範例來介紹,希望大家可以透過這個範例獲得一些啟發。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.Read)]
public static SqlString QueryVersion()
{
string tmp = "";
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
SqlCommand cmd = new SqlCommand("select @@VERSION", conn);
SqlDataReader dr = cmd.ExecuteReader();

if (dr.Read())
tmp = dr[0].ToString();

dr.Close();
}
return new SqlString(tmp);
}
};


程式碼設定完成後,請透過DOC Command視窗輸入下列的指令:
C:\Windows\Microsoft.NET\Framework\v3.5> csc.exe /t:library /out:QueryVersion.dll c:\QueryVersion.cs

完成後你就會在 [C:\Windows\Microsoft.NET\Framework\v3.5] 的目錄下得到一個dll

PS:注意事項
1、在上述的語法上,原始檔 [QueryVersion.cs] 放在C磁碟機下。
2、v3.5只要看你安裝的版本而定,再請自行修正。

指令語法:
--啟用CLR
EXEC sp_configure 'clr enabled', 1 
GO 
RECONFIGURE 
GO
--啟用Trustworthy
Use test_db
ALTER DATABASE master SET TRUSTWORTHY ON
Go
--建立Assembly
Use test_db
Create ASSEMBLY CARY_CLR_1
FROM 'C:\QueryVersion.dll'
WITH PERMISSION_SET = SAFE
GO
--建立SQL Function
CREATE FUNCTION QueryVersion()
RETURNS NVARCHAR(4000) WITH EXECUTE AS CALLER
AS EXTERNAL NAME CARY_CLR_1.UserDefinedFunctions.QueryVersion
--執行SQL Function
select dbo.queryversion()



執行結果:



看到上述的執行結果,就代表你已成功設計出一個SQL CLR,當然SQL CLR其實還有其他許多強大的功能,如字串切割、不同語系的字元碼轉換等,後續我再將不同的CLR功能分享上來,也希望大家多多分享,謝謝了。

參考連結:
Introduction to SQL Server CLR Integration (ADO.NET)
http://msdn.microsoft.com/en-us/library/ms254498(v=VS.90).aspx
CLR User-Defined Functions
http://msdn.microsoft.com/en-us/library/ms254508(v=vs.90).aspx
How to: Create a SQL Server Project
http://msdn.microsoft.com/en-us/library/84b1se47(v=vs.90).aspx
How to: Create and Run a CLR SQL Server User-Defined Function
http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.90).aspx
How to: Create and Run a CLR SQL Server User-Defined Type
http://msdn.microsoft.com/en-us/library/a8s4s5dz(v=vs.90).aspx
TRUSTWORTHY Database Property
http://msdn.microsoft.com/en-us/library/ms187861.aspx

關鍵字:SQL Server、SQL CLR

2011年10月15日 星期六

如何修復一個 Suspect Database

        最近接到一個Case,由於客戶的資料庫清單開啟後,就看到其中的一個資料庫 cary_db (匿名) 的狀態有問題,變成 Suspect,而且資料庫也打不開,所以請我們協助,當然最先的動作還是先了解客戶資料庫備份計畫,因為在這種情況下,應該沒有人可以100%的保證資料可以完全的還原,所以至少先確認如果修復失敗後,還有檔案可以還原,在這個Case中,很可惜的,也是什麼都沒有,當然我想這是最差的情況了,所以接下來只好進行修復,動作如下。

資料庫版本:SQL Server 2005

底下以cary_db為卻修復的資料庫為列:

1、如果可以的話請先停止服務並進行資料庫(cary_db.mdf與cary_db_log.ldf)的備份。

預設目錄:
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\

2、由於資料庫狀態為 Suspect ,所以可以透過將資料庫切換成 Emergency,讓資料庫可以進行唯讀存取與修復。

Use master
go
Alter database cary_db set emergency
go

3、由於需要進行資料庫修復,所以先將資料庫切換成單人模式。

Alter database cary_db set single_user
go

4、再來就是透過checkdb來進行資料庫修復,在參數上有兩種常用的方法,建議大家可以先用 [REPAIR_REBUILD] 指令來修復,如果執行完成後仍然有錯時,才會使用[REPAIR_ALLOW_DATA_LOSS] 的指令來執行,因為此指令可能會造成資料的遺失,所以千萬注意,而執行完成後,需確認是否有錯誤訊息顯示。

DBCC checkdb(cary_db ,REPAIR_REBUILD ||  REPAIR_ALLOW_DATA_LOSS)
go

5、由於已修復完成,所以將資料庫的狀態切回原本的正常狀態。

Alter DATABASE cary_db SET ONLINE
go

6、再將資料庫切換回多人使用模式
Alter DATABASE cary_db SET multi_user
go

最後,在這次的修復過程中,運氣算是還滿好的,因為也沒有任何的錯誤訊息,算是完整修復,而且也沒有資料遺失,但坦白說不是每一次的運氣都會這麼的好,還是建議大家設定好你的備份計畫,這才是上上之策。

資料庫狀態
狀態定義
ONLINE資料庫可供存取。主要檔案群組是在線上,雖然可能尚未完成復原的恢復階段。
OFFLINE資料庫是無法使用的。明確的使用者動作可使資料庫變成離線狀態,並且在採取其他的使用者動作之前都是離線狀態。例如,可以將資料庫設成離線,好讓檔案移到新的磁碟中。在完成移動後,就會將資料庫重新啟動為線上狀態。
RESTORING在離線狀態還原主要檔案群組的一或多個檔案,或還原一或多個次要檔案。資料庫是無法使用的。
RECOVERING資料庫復原中。復原程序是暫時性的狀態;如果復原成功,資料庫就會自動變成線上狀態。如果復原失敗,資料庫就會變成有疑問的狀態。資料庫是無法使用的。
RECOVERY PENDINGSQL Server 在復原期間發生資源相關的錯誤。資料庫並未損毀,但是檔案有可能遺失或系統資源限制有可能造成它無法啟動。資料庫是無法使用的。需要使用者執行其他動作以解決錯誤並讓復原處理得以完成。
SUSPECT至少主要檔案群組為有疑問的,而且有可能會損毀。資料庫在 SQL Server 啟動期間無法復原資料庫。資料庫是無法使用的。需要使用者執行其他動作來解決問題。
EMERGENCY使用者已變更資料庫並將狀態設為 EMERGENCY。資料庫是在單一使用者模式下,而且可以進行修復或還原。資料庫是標示為 READ_ONLY、記錄已停用並限定只有系統管理員 (sysadmin) 固定伺服器角色的成員才可存取。EMERGENCY 主要是做為疑難排解的用途。例如,標示為有疑問的資料庫可以設為 EMERGENCY 狀態。這將可允許系統管理員唯讀存取資料庫。只有系統管理員 (sysadmin) 固定伺服器角色的成員,可以將 資料庫設定為 EMERGENCY 狀態。

相關文章:
SQL Server 最佳案例 - 如何修復一個有問題的資料庫 (Suspect Database) http://caryhsu.blogspot.com/2011/07/sql-server-suspect-database.html
有效維護資料庫的最佳秘訣
http://caryhsu.blogspot.com/2011/04/blog-post.html

參考資源:
資料庫狀態
http://msdn.microsoft.com/zh-tw/library/ms190442.aspx

關鍵字:SQL ServerSuspectEmergencyRecoveryDatabase State、REPAIR_REBUILDREPAIR_ALLOW_DATA_LOSS

2011年10月6日 星期四

網路負載平衡 - Reporting Service 與 NLB 的結合

        在許多的企業中為了讓系統的服務不中斷,所以採取了許多 High Availability的架構,在Windows 的架構中,最常見的就是Cluster,並將SQL Server安裝在此叢集上,詳細的作法可以參考我的另一篇文章 [SQL Server 2008 R2 容錯移轉叢集環境架設 - 利用 VM 與 Windows Storage Server - Part I],但是特別強調,並非所有的在SQL Server下的服務都可以掛到Cluster之中,而Reporting Service就是其中一個,我收到許來網友的來信詢問到,為何他們將Reporting Service安裝在Cluster上之後,在容錯叢集管理員還是看不到,而且在第二台為何沒有看到Reporting Service,原因在於Reporting Service本身不支援容錯轉移,雖然可以安裝,但是並不會像SQL Server Service一樣,可以在發生錯誤時容錯轉移到另一個節點,而第二台的Reporting Service如果要安裝,也不能裝在預設的 Instance上面,必須安裝在另一個 Instance上面即可。

看到上面大家也別灰心,雖然Reporting Service不能設定容錯轉移,但可以進行負載平衡的設定,這也是本篇的重點,在設定上有點複雜,我參考官網的步驟整理如下:
  1. 在 NLB 叢集的伺服器節點上安裝 Reporting Services 之前,請先檢查向外延展部署的需求
  2. 設定 NLB 叢集並確認它是否正常運作。
    請務必將主機標頭名稱對應至 NLB 叢集的虛擬伺服器 IP。此主機標頭名稱會用於報表伺服器 URL 中,而且比 IP 位址更容易記得和輸入。
  3. 在僅限檔案模式中,於已經屬於 NLB 叢集之一部分的節點上安裝 Reporting Services,並設定報表伺服器執行個體來進行向外延展部署
  4. 設定檢視狀態驗證
    為了獲得最佳結果,請在您設定向外延展部署之後,而在將報表伺服器執行個體設定為使用虛擬伺服器 IP 之前,執行這個步驟。先設定檢視狀態驗證,就可以在使用者嘗試存取互動式報表時,避免發生有關狀態驗證失敗的例外狀況。
  5. 將 Hostname 和 UrlRoot 設定為使用 NLB 叢集的虛擬伺服器 IP。
  6. 確認伺服器可透過您指定的主機名稱存取。
環境說明:
軟體:
Reporting Server 2008 R2 Enterprise + 向外延展部署

Node 1:
IP -1 :192.168.1.150
IP -2 :10.0.0.150

Node 2:
IP -1 :192.168.1.151
IP -2 :10.0.0.151

PS:在NLB的架構中建議每一個節點要有兩張網卡,以免在透過遠端連線管理時,造成連線的問題。



1、規劃向外延展部署

1-1 詳細的功能說明請參照下列的列表或是官網的說明。
需求說明
版本需求
下列版本支援向外延展部署:Enterprise、Developer 和 Evaluation。
Standard、Workgroup 和 Express 版本不支援向外延展部署。
版本需求
所有報表伺服器都必須是相同的主要版本,而且這些版本必須擁有相同的更新與 Service Pack。
網域需求
所有的報表伺服器必須在同一個網域中,或在受信任的網域中。
參考說明:規劃向外延展部署

2、設定 NLB 叢集

2-1 NLB 說明
NLB全名為 [Network Load Balancing],他是Windows所提供的兩種叢集技術之一,你可以透過 NLB 進行網路負載平衡,將需要分配管理的電腦架設在網路負載平衡叢集上,當有網路需求時,NLB就可以平均的分配給在此叢集上的每一台電腦。


參考說明:網路負載平衡主要功能

2-2 安裝與設定第一個節點的 NLB

2-2-1 由於我是透過 Hyper-V進行 NLB 的架設,原本架設怎麼都架不起來,後來終於找到,必須在Hyper-V的網卡設定中啟用 [Enable spoofing of MAC addresses] 這樣你設定好的 NLB才不會有問題。

2-2-2 新增伺服器功能 -> 網路負載平衡


2-2-3 安裝完成後,選擇 [網路負載平衡管理員]。

2-2-4 開啟後點選 [網路負載平衡叢集] -> [新增叢集]

2-2-5 在連線的地方,請先將第一台的節點加入即可。

2-2-6 設定該節點在此負載平衡上叢集上的優先順序,此值在後面仍然可以進行變動。

2-2-7 針對此負載平衡叢集新增一組IP。



2-2-8 針對此叢集參數,其中最重要的就是 [完整網際網路名稱] 此值日後就不可以更改而且必須在此網路上是唯一的,所以名稱的設定再請多加注意,而叢集操作的模式,可以使用預設值 [單點傳播],關於此操作模式的說明,可以參考下列的說明:


參考文章:網路負載平衡 (NLB):單點傳播 (Unicast) 與 多點傳送 (Multicast) 的差異

2-2-9 連接埠規則設定,也請使用預設值即可,詳細說明請參考:建立新的網路負載平衡連接埠規則。


2-2-10 建立完成後,你就可以新的叢集與加入的節點就顯示出來了。

2-3 將第二個節點加入負載平衡叢集之中。

2-3-1 選擇已新增的叢集名稱,選擇 [新增主機到叢集]。

2-3-2 在 [主機]的地方輸入第二個節點的電腦名稱,然後選擇連線。

2-3-3 選擇此台主機的優先順序

2-3-4 連接埠規則請與第一個節點的設定相同,所以依照預設值即可。

2-3-5 新增完成後,你就可以在下列的地方看到第二個節點加入到網路負載平衡叢集中了。

2-3-6 設定完成請確認在兩台電腦中的狀態必須為 [已交集],然後PING的指令確認新增的網路名稱與 IP 是正常的。

PING cary-nlb
PING 192.168.1.149

3、設定與安裝 Reporting Service向外延展部署

3-1 詳細的設定細節,請參考我的另一篇說明 [設定報表伺服器執行個體來進行向外延展部署]。

4、設定檢視狀態驗證

4-1 由於我們透過 NLB 與 Reporting Service 進行負載平衡處理,所以接下來就必須產生一個MachineKey讓兩台在加解密上的動作都是使用相同的方法進行,你可以透過下列的網站先產生一組Key。

MachineKey WebSite:

MachineKey說明:設定金鑰,用以進行表單驗證 Cookie 資料及檢視狀態資料的加密和解密,並驗證跨處理序 (Out-Of-Process) 工作階段的狀態識別。

 4-2 打開 "\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\Web.config" 的檔案,找到 <system.web> 的區段,然後貼上去,之後再存檔即可。



4-3 重新啟動 Reporting Service 的服務

4-4 重新上述的動作在此NLB中的每一個節點。


5、將 Hostname 和 UrlRoot 設定為使用 NLB 叢集的虛擬伺服器 IP

5-1 打開 "\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\rsreportserver.config" 的檔案。

5-2 找到 <Service> 的區段,然後將剛剛 1-8節的中新增的NLB對外名稱加入到<Hostname>cary-nlb</Hostname>。

PS:預設Hostname的標籤是不存在的,需自行新增。

5-3 在 <Service> 的區段,尋找 <UrlRoot>的標籤值變更成下列的值即可 。
<UrlRoot>http://cary-nlb/reportserver</UrlRoot>

5-4 重新啟動Reporting Service的服務

5-5 重新上述的動作在此NLB中的每一個節點。

修改完成後的設定檔

6 報表測試與問題排除

6-1 解決 HTTP 401 Unauthorized的問題
首先在測試上你不必從本機上進行測試,因為NLB的關係,所以你必須透過第三台來測試,測試的網址可以透過下列二種,但是很可惜的我卻遇到了 HTTP 401 Unauthorized 的問題,解決方法為下列二個步驟。

6-1-1 打開第一個節點中 C:\Windows\System32\drivers\etc\hosts 的檔案,在最後一行中加入下列的位置對照。

192.168.1.150    cary-nlb


6-1-2 同樣地的打開第二個節點中 C:\Windows\System32\drivers\etc\hosts 的檔案,在最後一行中加入下列的位置對照。

192.168.1.151    cary-nlb

6-1-3 新增 [DisableStrictNameChecking] 的登錄值。
  • 按一下 [開始]、 按一下 [執行]、 輸入 regedit,然後按一下 [確定]]。
  • 在 [登錄編輯程式] 中,找出並按一下下列登錄機碼:
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
  • 在登錄值上按一下滑鼠右鍵,指向 [新增],然後再按一下 [DWORD 值]。
  • 鍵入 DisableLoopbackCheck,並按下 ENTER。
  • 在DisableLoopbackCheck 上按一下滑鼠右鍵,然後按一下 [修改]。
  • 選擇 [數值資料] 方塊中鍵入 1,再按 [確定]。
  • 結束 「 登錄編輯程式 」,然後重新啟動您的電腦。
參考網址:
瀏覽的網站,使用 「 整合式驗證 」 且裝載在 IIS 5.1 或更新版本上時,收到 401.1 錯誤

6-2 報表與 NLB 的結合測試
在測試不管是進入 Reports 或是 ReportServer的目錄,網址名稱皆是使用 cary-nlb ,但是要如何知道目前的主機是在第一台還是第二台,本來想透過 Reporting Service 中的內建欄位來完成,但是很可惜沒有這種功能,後來我想到一個方法,由於都是連接到同一個資料庫,所以可以透過資料庫中得到登入的電腦名稱與使用者帳號,所以我就作了一個報表,透過下列的語法進行,一試就完成。

SQL 語法:
SELECT HOST_NAME() as HostName,
SUSER_NAME() LoggedInUser

第一台連線測試:

第二台連線測試:
PS:請特別注意,由於 NLB 會盡量將同一個 Client 導向同一台電腦,所以第二台測試請利用不同的電腦進行測試即可。

最後終於完成這個艱辛的任務,接下來再請大家自行測試,其實安裝上真的我自已也遇到許多的問題,所以如果有遇到任何問題,歡迎大家來信詢問。

參考資源:
如何:在網路負載平衡叢集上設定報表伺服器
Reporting Service 2008 R2 - 如何設定向外延展部署的功能

關鍵字:Network Load Balancing ClustersNLBClusterHigh AvailabilityHAReporting Service向外延展部署