SQL問題與解答-數據庫移動、性能優化、備份和鏡像
新陣列移動日
問:我們當前的 RAID 很快就填滿了,因此需要將一些 SQL Server 2005 數據庫移到其他位置。新陣列已準備就緒,并且我一直在為移動數據庫作準備。我剛剛發現其中一個數據庫是事務復制發布服務器,我知道這表示我不能移動該數據庫。我應怎樣做?
答:對您來說有一個好消息 - 只有 SQL Server 2000(和更早版本)具有以下局限性:限制在未重新初始化事務復制或直接更改各種系統表的情況下移動發布數據庫。
對于 SQL Server 2005 和 SQL Server 2008,有一個記錄下來的過程,您可以按照它移動數據庫,而不必對事務復制執行任何操作,但要求數據庫保持連接到同一 SQL Server 實例。移動時必須停機一段時間,因為當數據庫文件仍處于聯機狀態時無法將其移動。過程如下:
首先,使用下面的代碼使數據庫脫機。如果有用戶連接到數據庫,則需要先斷開這些用戶的連接,此過程才能成功:
- ALTER DATABASE MyDatabaseName SET OFFLINE;
接著,將數據文件復制到新位置。使用復制而不是移動,可在發生任何錯誤時進行快速回滾(否則,必須執行還原)。然后,使用以下代碼告知 SQL Server 每個文件的新位置
- ALTER DATABASE MyDatabaseName
- MODIFY FILE
- (NAME = N'LogicalFileName',
- FILENAME = N'pathname\filename');
物理上復制了所有文件并更新了 SQL Server 中的文件位置后,使用以下代碼使數據庫恢復聯機狀態:
- ALTER DATABASE MyDatabaseName SET ONLINE;
關閉頁鎖存
問:我在理解一些性能優化相關概念時存在疑問。我幾次讀到需要防止“頁鎖存”問題。我不知道“頁”或“鎖存”是什么意思,或者說為什么頁鎖存甚至是一個問題。您能解釋所有這些疑問嗎?
答:SQL Server 數據庫中的所有數據都存儲在數據文件中。在內部,這些文件組織成大小為 8 KB 的數據塊序列,稱為頁。頁是 SQL Server 可以管理的基本存儲和 I/O 單位。頁通常位于磁盤上的數據文件中,并且在處理任何查詢之前,需要 SQL Server 的緩存(稱為緩沖池)來進行讀取。
SQL Server 使用各種頁來存儲不同類型的關系數據(例如,表中的行、非群集索引中的行或者文本/LOB 數據)。還有一些頁存儲 SQL Server 組織和訪問存儲關系數據的頁所需的內部數據結構部分。
鎖存 是一種輕量級內部機制,SQL Server 使用它來同步對緩存內的某個頁的訪問。您需要注意兩種類型的頁鎖存 - 常規頁鎖存 和頁 I/O 鎖存。如果 SQL Server 線程必須等待獲取其中一個鎖存,則表示出現性能問題。
當 SQL Server 正等待從磁盤中讀取數據文件的某部分時,則可能會導致頁 I/O 鎖存等待。如果頁 I/O 鎖存持續很長時間,則通常表明底層磁盤子系統出現性能問題(即,該子系統過載)。
當 SQL Server 中的多個線程嘗試訪問內存中的相同 8 KB 數據文件頁時,就存在對該頁訪問權的爭用,這可能會導致頁鎖存等待。最常見的這種情況涉及大量使用 tempdb 數據庫中的臨時小對象。
有關如何監視和減少頁鎖存等待的更深入說明不屬于本專欄文章的范圍,但您可以在以下資料中找到更多信息:
SQL Server 2008 聯機叢書中的“SQL Server Wait Statistics 對象”部分,它說明如何使用系統監視器監視等待統計數據。
SQL Server 2008 聯機叢書中的“sys.dm_os_wait_stats”部分,它列出了常見的 SQL Server 等待類型及其含義,并說明如何從 SQL Server 內部監視等待統計數據。
白皮書《SQL Server 2008 中的性能問題故障排除》,它提供各種故障排除查詢和技術,包括等待統計數據。
通查數據庫快照
問:我剛剛發現了數據庫快照。現在,我考慮將它們用作完全恢復模式和日志備份的替代方法。我將大約每小時創建一次快照,這樣當出現錯誤時,我可以拉回損壞的數據。這似乎是一種更省事且更快的還原方法。您認為進行這種更改會產生任何問題嗎?
答:會產生問題,數據庫快照不是全面的災難恢復策略的實用或可行替代方法。在從災難完全恢復方面,數據庫快照不具備與事務日志備份相同的功能。數據庫快照不包含數據庫中所有頁的副本,它只包含自***次創建數據庫后更改過的頁的副本。這意味著,如果數據庫有任何損壞,則沒有底層數據庫的數據庫快照將沒有任何用處。它只是數據庫中不同頁的集合,不能用于恢復。
您可以通過數據庫快照拉回不小心從數據庫中刪除的數據,但前提是數據庫本身仍可用。例如,如果從數據庫中刪除的表仍存在于快照中,則可以使用快照重新創建該表。
也就是因為潛在的性能問題,創建太多數據庫快照(作為每一個半小時的事務日志備份的替代方法)不是一個好主意。在可以交換數據庫頁之前(請參閱“關閉頁鎖存”部分中的答案說明),必須先將頁同步地復制到尚未包含該頁版本的所有現有數據庫快照中。隨著創建的數據庫快照越來越多,要生成的頁副本也越來越多,從而導致性能下降。
不要創建太多數據庫快照的另一個原因是每個數據庫快照將包含數據庫頁更改前的副本。每個副本將隨著數據庫中更改的內容增多而增大。這可能會導致磁盤空間問題和性能問題。
數據庫快照不是為了替代頻繁日志備份而設計的。您可以在白皮書 Database Snapshot Performance Considerations Under I/O-Intensive Workloads 中閱讀關于數據庫快照的性能影響的更深入研究。
此外,如果您要使用完全恢復模式和事務日志備份,則很明顯您對最多能夠恢復到災難點和/或使用時間點還原感興趣。(有關恢復到災難點和時間點還原的說明,請分別參閱我于 2009 年 7 月和 2009 年 11 月發布的文章“了解 SQL Server 備份”和“SQL Server:利用備份進行災難恢復”。)
鏡像,鏡像
問:我被要求為數據庫設置數據庫鏡像,但我擔心數據庫鏡像不能幫助解決我們的問題。我們的 SAN 存在一些損壞問題,因此打算通過數據庫鏡像防止我們受到損壞。損壞不會自動發送到鏡像嗎?數據庫鏡像如何幫助我們解決此問題?
答:這是一個會引起大量混淆的問題。任何提供冗余數據庫副本的技術看起來似乎都容易受到從主體傳播到鏡像數據庫(以使用數據庫鏡像術語)的損壞的影響,但實際上這種情況不會發生。
問題的關鍵在于理解鏡像數據庫的維護方式。如果底層同步機制將完整數據庫頁從主體復制到鏡像數據庫,則損壞肯定會傳播到鏡像。然后,主體中損壞的頁將被放置在鏡像中。
但是,數據庫鏡像專門避免了這種情況,因為它不將一個數據庫中的數據庫頁復制到另一個數據庫。數據庫鏡像過程是將事務日志記錄從主體數據庫復制到鏡像來完成的。事務日志記錄說明對數據庫頁所做的物理更改,它們不包含實際頁本身。(有關事務日志記錄、日志記錄和恢復的完整說明,請參閱我于 2009 年 2 月發布的文章:“了解 SQL Server 中的日志記錄和恢復功能。”)
即使數據庫頁被主體數據庫的底層 I/O 子系統損壞,該損壞也不可能直接傳播到鏡像數據庫。可能出現的最壞情況是如果 SQL Server 未檢測到頁面損壞(由于未啟用頁面校驗和),將使用已損壞的列值來計算存儲在數據庫中的值。生成的不正確結果將傳播到鏡像數據庫,從而產生二級損壞效果。如前所述,如果啟用了頁面校驗和,則從磁盤中讀取頁面時,這種損壞仍將檢測不到,從而不會出現二級損壞。
此行為還說明了為什么對主體數據庫運行一致性檢查不會生成關于鏡像數據庫的一致性狀態的任何信息,反之亦然。它們是通過傳送對數據庫而不是實際數據庫頁的物理更改的說明來保持同步的兩個不同數據庫。
本文來源:微軟TechNet中文站