SQL問題與解答:行溢出、差異備份及更多內容

來源: technet  發布時間: 2010-12-20 23:01  閱讀: 661 次  推薦: 0   原文鏈接   [收藏]  
摘要:今天我們將討論的是行溢出、差異備份及更多內容,希望對大家的工作有所幫助。

  問: 我最近升級了一個應用程序,使其可以在 SQL Server 2005 上運行。我利用了允許行長度超出 8,060 個字節這項功能,以便用戶可以創建較長的數據字段而不會收到從 SQL Server 返回的錯誤。現在,將這個應用程序應用到實際環境之后,一些掃描查詢開始出現性能問題,在架構更改之前,這些查詢運行正常。我也檢查過各種索引的碎片,一切正常。那為什么查詢在 SQL Server 2005 上運行時速度比較慢呢?

  答: 您所利用的“行溢出”功能,對于在特定情況下允許行長度大于 8,060 個字節效果很好,但卻不適合大多數長度過大的行,而且可能使查詢性能大打折扣,正如您所遇到的情況那樣。

  發生這種情況的原因是,當某行的長度開始變得過大時,該行中的其中一個可變長度列會被“推出行”。這意味著該列會在數據或索引頁上從行中移到文本頁中。至于原來列中的值,會由指針取代,指向該列中的值在數據文件中的新位置。

  這與用來存儲 XML、文本、圖像或 varchar(max) 等常規 LOB(大型對象)列的機制完全相同。請注意,如果表架構包含多個可變長度列,就無法保證在多個行的長度變得過大時推出的會是同一列。

  這種機制可能會產生性能問題。如果查詢從一個表格行中檢索的可變長度列已被推出該行,可能突然之間需要額外的 I/O 來讀取內含行外位置的值的文本頁。如果有多個行的長度過大,從多個行中檢索相同的可變長度列的查詢,可能產生無法預料的性能問題,嚴重程度取決于被推出行的值的數量。

  在您遇到的情況中,對包含可變長度列的選擇列表執行范圍掃描或表掃描的查詢,正是因行溢出及其影響而導致性能下降。這與索引是否執行過完全的碎片整理無關,當可變長度列被推出行時,因為必須使用隨機 I/O 讀取內含行外的值的文本頁,所以之前有效的掃描作業已基本中斷。

  雖然行溢出在特定的情況下對于長度過大的行仍然很有用,但如果查詢的性能至關重要,則不應該在您的設計里面過度利用。

  問: 我們剛在兩個故障轉移群集之間引入了數據庫鏡像,作為以低于存儲區域網絡 (SAN) 復制的成本獲得地理冗余的方法。因為數據中心位于同一個城市,所以我們能夠使用同步鏡像。問題在于當本地群集上發生故障轉移時,鏡像數據庫會故障轉移到遠程群集,而這并不是我們希望發生的情況。我們該如何避免出現這種情況?我們只希望在本地群集無法使用的時才進行故障轉移。

  答: 為了提高可用性,鏡像會安裝一個見證服務器,以便在主體服務器無法使用時自動發生故障轉移。其理論基礎是:如果整個本地群集出現故障,數據庫鏡像將故障轉移到第二個群集,這樣應用程序就可以繼續執行了。

  此問題出現在群集故障轉移期間。故障轉移所花的時間超過了數據庫鏡像的默認超時設置,而見證服務器和鏡像服務器(即第二個群集上活動的 SQL Server 實例)均認為它們看不到主體服務器,于是鏡像服務器便開始將鏡像故障轉移到第二個群集。

  預防這種現象最簡單的方法是刪除見證服務器,以便數據庫鏡像在本地群集出現故障時不會自動進行故障轉移。當然,這種做法會降低可用性,因為這樣一來就需要人為啟動故障轉移。

  第二種方法是更改數據庫鏡像的默認超時設置,也就是更改確定主體服務器不可用之前,它響應“ping”信息(每秒一次)失敗的次數。這種設置稱為“伙伴超時”(Parnter Timeout),默認值為 10。可使用下列代碼找到數據庫當前的超時值:

 
1. SELECT mirroring_connection_timeout
2. FROM master.sys.database_mirroring
3. WHERE database_id = DB_ID ('mydbname');
4. GO

  可使用下列代碼更改超時值:

 
1. ALTER DATABASE mydbname
2. SET PARTNER TIMEOUT <timeoutvalue>;
3. GO

  對于這種情況,設置的伙伴超時值必須大于在本地群集上進行群集故障轉移的常規時間值。在鏡像數據庫上進行群集故障轉移時確定運行恢復所需的時間變化,可能有些困難,不過您應該可以判斷出上限。這種方法的缺點在于超時值可能必須以分鐘為單位,不適合在發生真正的災難時使用。

  問: 我使用的備份策略包括完整備份和日志備份,但有人建議我應該加入差異備份來縮短還原時間。我每周進行一次完整備份,每個小時進行一次日志備份。我試過每天添加差異備份,但我注意到一個異常現象:每個星期結束時的差異備份與每周的完整備份大小差不多。我記得差異備份與日志備份一樣都屬于增量備份啊!難道是我記錯了嗎?
  答: 這是對差異備份的本質有所誤解造成的。差異備份與日志備份不同,不屬于增量備份。差異備份包含自上次完整備份后所有更改的數據文件范圍(這適用于數據庫、文件組和文件級別備份)。

  如果范圍(包含八個連續數據文件頁的邏輯組)有任何更改,都會標記在稱為差異圖的特殊位圖頁中。每個數據文件的每 4GB 就有一個差異圖。進行差異備份時,備份子系統會掃描所有差異圖,并復制所有已更改的范圍,但不會重置差異圖。這表示連續的差異備份之間更改的范圍越大,后者的備份會越大。只有在執行完整備份時才會重置差異圖。

  如果應用程序工作負載太大,以至于數據庫內容在短時間(假設在一個星期)內進行了大量更改,那么每周的完整備份大小幾乎會與在下一個完整備份前進行的差異備份的大小相同。這也解釋了您看到的現象。

  另外,差異備份確實提供了一種在災難恢復的情況下縮短還原時間的方法。如果您采用的備份策略是每周進行一次完整備份,每小時進行一次日志備份,那么您必須執行下列操作才能最迅速地實現還原:

  運行尾日志備份(自最近的日志備份后生成的所有日志)。

  還原最近的完整數據庫備份。

  按順序還原自最近的完整數據庫備份后的所有日志備份。

  還原尾日志備份。

  可能需要還原大量日志備份,尤其是在災難剛好發生在進行下次完整備份之前。(最糟的情況是需要還原 24 + 24 + 24 + 24 + 24 + 24 + 23 個日志備份!)在此策略中每天添加差異備份,還原的順序會變成這樣:

  運行尾日志備份(自最近的日志備份后生成的所有日志)。

  還原最近的完整數據庫備份。

  還原最近的差異備份。

  按順序還原自最近的差異備份后的所有日志備份。

  還原尾日志備份。

  這樣就不必還原大量的日志備份了,因為還原差異備份與還原差異備份涵蓋期間內的所有日志備份基本相同。

  在每天執行差異備份的情況下,即使是在該周的最后一天,最糟的情況也不過是 23 個日志備份。差異備份不屬于增量備份,它的一個缺點是它們可能會占用更多的空間,但與縮短還原時間相比,這是值得的。

  問: 我有一個兩節點的故障轉移群集,每個節點都運行一個 SQL Server 2005 實例。我按照通常的要求,將每個實例設置為只使用 50% 的可用內存。現在我遇到了一些問題,因為兩個實例上的工作負載都需要更多的內存才能維持相同的性能級別。如果我刪除內存限制,或是增加內存,我想我會碰到這樣的問題:其中一個實例故障轉移,然后兩個實例都只在一個節點上運行。您有什么建議?

  答: 我會針對兩節點、雙實例的情況來解答這個問題,但下列內容也適用于其他多實例設置(N-1 故障轉移群集,其中有 N 個節點和 N-1 個 SQL Server 實例)。

  許多人在兩個實例上都遇到過高工作負載的情況(占用的服務器內存超過 50%),而沒有考慮到兩個實例在發生故障轉移后最后會在一個節點上運行對工作負載的影響。如果沒有特殊的配置,實例之間的內存分配很可能會不成比例,結果一個工作負載正常運行,而另一個卻慢得不行。

  對于 SQL Server 2000,建議將每個實例限制為最多使用 50% 的群集節點內存。這是因為 SQL Server 2000 中的內存管理器并不會對內存不足做出響應 — 假如 SQL Server 占用了節點 80% 的內存,它并不會降低內存使用量。這表示在故障轉移的情況下,另一個剛啟動的實例只有 20% 的內存可用。通過將兩個實例限制為最多使用節點 50% 的內存,可保證每個故障轉移實例有 50% 的內存。不過,這種方法產生的問題是每個實例上的工作負載也會限制為使用 50% 的內存。

  而對于 SQL Server 2005(和 SQL Server 2008),內存管理器可以響應內存不足,因此 50% 的上限不再適用。但是沒有這類限制,如果兩個實例都在一個群集節點上運行,它們可能會爭用內存直到產生不成比例的內存分配。

  答案是將每個實例設置為最低內存量,這樣一來,它們就不會被迫釋放過多的內存。對于兩節點、雙實例的情況,最常見的設置是為每個實例至少配置 40% 的內存。這表示當每個實例在不同的節點上運行時,它們可以占用任意內存量。而當發生故障轉移時,會保證每個實例有特定的內存量,以保持固定的工作負載性能級別,并留一些內存在兩者之間共享。雖然這意味著兩個工作負載的性能在發生故障轉移時可能會下降(在意料之中),但是每個實例在不同的群集節點上運行的大多數時間完全不會受到限制。

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()