天天看點

The Accidental DBA

本文大意:

     全篇主要講硬體選擇和伺服器成本的考慮,包括記憶體的開銷,cpu開銷,以及sql server的收費方式。

     存儲在sql server中占了很重要的角色,存儲子系統配置的不對就會讓server性能很爛。

     磁盤比較多的性能往往比磁盤少的性能好,因為磁盤多吞吐量大。

     關于容量的評估,可以更具,評估檔案大小,tempdb大小,備份大小

     關于性能的評估,可以評估,順序,随機的讀寫性能

性能測試工具:CrystalDiskMark

     關于SSD磁盤的使用,首先要看傳統的磁盤和SSD的差別,通過測試傳統的磁盤,順序讀寫性能遠遠高于随機讀寫。而SSD除了順序讀寫性能不俗之外,随機讀寫性能遠遠的提升。那麼很顯然了,如果傳統的磁盤為了适應伺服器性能需求,花費比使用SSD要大的時候,那麼就可以考慮使用SSD來代替。一般适用的場景:1.單執行個體多資料庫,随機io過大,可以考慮把log放入ssd中,2.tempdb io過大可以考慮把tempdb放ssd中。

     sql server的安裝配置最佳實踐從還未裝之前就已經開始,在決定要cpu,伺服器,io子系統之後,

     1.先保持bios,os版本最新。配置專用的域賬号。

     2.在bios的電源控制中是否選擇了關閉或者OS控制。windows上的電源控制是否選擇了高性能。

     3.是否開啟超線程,是否經過了測試。

     4.raid級别,需要的空間,是否需要多個邏輯盤,使用CrystalDiskMark,SQLIO測試性能,raid的cache大小,cache政策是否設定成需要的

     5.啟動Windows instant File Initialization和Page Lock

     6.把sql server更新到最新版本

     7.設定最大服務記憶體

     8.Optimize for ad hoc workloads是否配置

     9.tempdb多檔案考慮

     10.啟動T3226關閉,當備份成功後往errorlog寫入資訊

額外閱讀:

     使用虛拟化的原因:因為虛拟化便宜

     缺點:1.io達不到要求。2.VMWare下,VM會過渡使用記憶體。3.過渡使用cpu問題

     IO達不到要求:

          作者使用6個1T的7200-RPM在NetApp SAN的磁盤和5400-RPM的usb2.0的磁盤做了性能對比:

     發現2個性能差不多,對于SQL Server來所這樣的io性能是不夠的,并且如果出現io size的問題SAM并沒有好的解決方案,SQL Server對磁盤的要求不單單是空間,還有性能

     記憶體問題:

     記憶體大了可以減少io,VMWare和hyper-v記憶體的配置設定方式不同,VMWare預設可以超過設定的記憶體,但是hyper-v啟動時會檢查可以使用的記憶體數量,不會超過這個數量,但是當有壓力時,有一個最小可用記憶體保證了記憶體的需求。VMware也可以靜态的保留記憶體以免VM過渡的使用記憶體。

     CPU問題:

     VM是通過共享cpu片段來實作并發問題,當一個host配置設定為一個寬VM一個窄VM就很容易出現排程的問題。對于4個虛拟處理器的VM,當其他VM發生并發時,可以調用的cpu時間片并不是4個cpu。為了解決這個問題引入了協作排程(co-schedule)

     在虛拟環境下經常會碰到特殊的workload導緻cpu性能問題,表現在VM的cpu使用率高,增加vcpu反而加重問題。減少vcpu反而性能編号。說明協同排程有問題,要不是過度的送出,要不就是寬,窄混合,導緻排程問題。

     RTO:恢複時間需求,RPO:允許丢失的資料

     不管對資料庫做了什麼修改都會産生日志,日志的去向就2中1.送出,2.復原。

     管理事務日志,不能讓日志檔案過大,妨礙資料庫正常使用。

     恢複模式:

     完全:日志全部記錄,在日志備份時被截斷

     大容量日志:某些日志被最小化記錄,在日志備份時截斷

     簡單:某些日志最小化記錄,checkpoint被截斷

     備份類型:

     全備,日志備份,差異備份,檔案組備份,檔案備份,檔案差異備份,檔案組差異備份

     全備:備份所有資料和一部分日志,允許一緻性事務點,全備不會截斷日志,全備的備份日志量:從備份讀取資料時最早的活動日志到,備份讀取結束的日志

     事務日志:備份所有日志,要在全備之後才能使用,第一次全備之後,全備和日志備份将不再有任何關系

     差異備份:從你上次全備後的所有修改,差異備份是累計的,不是遞增的

     還原最主要的2個問題:1.要多久,2.可以接受多少資料的丢失

     根據以上的2個點來設定還原政策,進而設計備份政策

     比如,如果資料丢失可以接受在15分鐘,那麼就日志的備份至少是15分鐘一次,若無法承受,那麼最後還要恢複尾日志。當然還可以使用同步進制如鏡像

     恢複時間,需要同個各種恢複政策的測試,保證恢複時間在指定時間内。

筆者意見:

     用備份來做災難性恢複,随着資料庫越來越大,已經有點不太現實了,一般的做法還是使用資料庫備援,鏡像,故障轉移等手段。備份如果隻是用來做容災,那麼已經有點落伍了。

<a href="http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-9-of-30-backups-essential-backup-options/">The Accidental DBA (Day 9 of 30): Backups: Essential BACKUP Options</a>

     壓縮:可以讓備份更快,更小,但是費cpu

     Copy_only:隻複制,對日志備份中,不會對日志鍊産生影響

     Description和File Names:加入一些描述性的東西到備份檔案中。

     Checksum:1.驗證從資料檔案中過來的page,如果checksum對不上,預設備份失敗,并且報出現資料頁錯誤。2.對整個備份計算checksum并放入備份檔案頭

     Status:用來表示backup的進度

<a href="http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-10-of-30-backups-backup-testing-for-validation/">The Accidental DBA (Day 10 of 30): Backups: Backup Testing for Validation</a>

     驗證備份,不單單是驗證備份的檔案是否可用,而且還要驗證是不是在備份恢複的時間内,DBA不單單要保證備份的正确性,而且要驗證備份。保證随着時間的推移不會造成備份檔案錯誤,備份驗證比較簡單隻需要做恢複就可以了。如果要驗證備份内容的正确性,那麼在備份的時候使用checksum,在恢複的時候也使用checksum,用來驗證存在備份頭裡面的checksum是否正确。同時需要考慮備份儲存的問題,儲存在哪裡,儲存時間多長。

<a href="http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-11-of-30-backups-backup-storage-and-retention/">The Accidental DBA (Day 11 of 30): Backups: Backup Storage and Retention</a>

     關于備份的儲存有2個重大問題:1.不要儲存在和資料庫同一個io子系統下,2.隻保留一份最新的backup

     如果資料庫突然crash,那麼在異地有一份就可以迅速還原上來,但是 往往是本地的一台機器crash,其他機器沒事兒,是以不但要在異地保留一份,要在本地異機也保留一份。

     如果隻保留一份最新的備份,如果剛好,全備出錯,那麼就無法恢複了。是以,備份的保留時間也是一個問題。本地至少要保留一個月的備份,異地至少3個月。除非沒周都測試。可以适當減少。

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-12-of-30-backups-vm-snapshots/">The Accidental DBA (Day 12 of 30): Backups: VM Snapshots</a>

     關于VM快照的備份,作者說了很多,但是關鍵點是,VM快照備份有些地方不給力,如不能根據日志鍊恢複,隻能恢複到快照的點。好處,可以恢複到某個檔案,甚至是某一個對象。還可以幫忙截斷事務日志。

<a href="http://www.sqlskills.com/blogs/erin/the-accidental-dba-day-13-of-30-consistency-checking/">The Accidental DBA (Day 13 of 30): Consistency Checking</a>

     對于大的資料庫,可以先運作checkfilegroup,然後執行checkcatlog來分解。checkdb,檢查盡早的排除資料錯誤的問題。如果出現問題,可以使用錯誤日志發現問題。發現問題後需要恢複,就要考慮2個問題:1.可以丢失多少資料,2.會當機多久。可以先通過備份履歷測試,通過測試發現是否在可以接受的範圍,然後再處理。當dbcc checkdb恢複後,是不管限制的,是以之後要使用dbcc checkident和dbcc checkconstraints善後。

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-14-of-30-index-maintenance/">The Accidental DBA (Day 14 of 30): Index Maintenance</a>

     是以維護主要是維護索引碎片的問題。定期重建或者重組。碎片2個壞處:1.造成io量大,2.造成記憶體,空間浪費。

     對于腳本維護有一下建議1.少于1000頁不用處理,2.碎片少于10%不用處理,3.10-30%重組,4.30%以上重建。

     對于統計資訊維護,sql server會自動維護的規則:若 &lt;500,累計500行更新,重新統計,&gt;500則500+20%更新。

     統計資訊是以BLOB方式存放在資料庫中,一般自己不維護,而是更具優化器的需要自動建立,一般隻有大的表需要做手動的統計資訊維護。統計資訊主要是包含了key的資料分布。統計資訊分為3個部分:1.頭,2.密度向量,3.直方圖。

     統計資訊的準确性,有很多因素,其中比較重要的是:表的大小,表是否頻繁被修改。注意:索引重建會更改統計資訊,但是索引重組不會。

<a href="http://www.sqlskills.com/blogs/kimberly/category/statistics/">http://www.sqlskills.com/blogs/kimberly/category/statistics/</a>

<a href="http://www.sqlskills.com/blogs/kimberly/database-maintenance-best-practices-part-i-clarifying-ambiguous-recommendations-for-sharepoint/">Database Maintenance Best Practices Part I – clarifying ambiguous recommendations for SharePoint</a>

<a href="http://www.sqlskills.com/blogs/kimberly/auto-update-statistics-and-auto-create-statistics-should-you-leave-them-on-andor-turn-them-on/">Auto update statistics and auto create statistics – should you leave them on and/or turn them on??</a>

<a href="http://www.sqlskills.com/blogs/kimberly/what-caused-that-plan-to-go-horribly-wrong-should-you-update-statistics/">What caused that plan to go horribly wrong – should you update statistics?</a>

<a href="http://www.sqlskills.com/blogs/kimberly/filtered-indexes-and-filtered-stats-might-become-seriously-out-of-date/">Filtered indexes and filtered stats might become seriously out-of-date</a>

<a href="http://www.sqlskills.com/blogs/kimberly/statistics-query-plans-and-are-you-reading-conors-blog/">Statistics, query plans, and are you reading Conor’s blog?</a>

<a href="http://www.sqlskills.com/blogs/erin/category/statistics/">http://www.sqlskills.com/blogs/erin/category/statistics/</a>

<a href="http://www.sqlskills.com/blogs/erin/understanding-when-statistics-will-automatically-update/">Understanding When Statistics Will Automatically Update</a>

<a href="http://www.sqlskills.com/blogs/erin/sql-server-maintenance-plans-and-parallelism-index-rebuild/">SQL Server Maintenance Plans and Parallelism – Index Rebuilds</a>

<a href="http://www.sqlskills.com/blogs/erin/new-statistics-dmf-in-sql-server-2008r2-sp2/">New Statistics DMF in SQL Server 2008R2 SP2</a>

<a href="http://www.sqlskills.com/blogs/paul/category/statistics/">http://www.sqlskills.com/blogs/paul/category/statistics/</a>

<a href="http://www.sqlskills.com/blogs/paul/easy-automation-of-sql-server-database-maintenance/">Easy automation of SQL Server database maintenance</a>

<a href="http://www.sqlskills.com/blogs/paul/index-rebuilds-depend-on-stats-which-are-updated-by-index-rebuilds/">Index rebuilds depend on stats, which are updated by index rebuilds?!?</a>

<a href="http://www.sqlskills.com/blogs/paul/how-are-per-column-modification-counts-tracked/">How are per-column modification counts tracked?</a>

<a href="http://www.sqlskills.com/blogs/paul/how-are-auto-created-column-statistics-names-generated/">How are auto-created column statistics names generated?</a>

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-16-of-30-general-security/">The Accidental DBA (Day 16 of 30): General Security</a>

<a href="http://www.sqlskills.com/blogs/glenn/the-accidental-dba-day-17-of-30-configuring-alerts-for-high-severity-problems/">The Accidental DBA (Day 17 of 30): Configuring Alerts for High Severity Problems</a>

     使用Agent alert可以用來反映嚴重錯誤的資訊。通過配置agent alert 和操作員來完成。

     并且作者分享了一段代碼

<a href="http://www.sqlskills.com/blogs/erin/the-accidental-dba-baselines/">The Accidental DBA (Day 18 of 30): Baselines</a>

     談到基線,就有4個問題:1.為什麼要有基線,2.怎麼擷取基線,3.什麼時候抓資料,4.怎麼分析

     為什麼要有基線:在出問題之間,提前發現問題;可以主動去調整;通過直方圖發現其中變法,排查問題;資料和環境的變化;制定資源和能力計劃

     怎麼擷取基線:通過抓取DMV,性能計數器

     什麼時候抓資料:有些可以一天一次,比如可用空間,有些需要間隔幾分鐘一次比如性能名額。

     怎麼分析:通過分析資料的變化來預測未來将要發生的情況

<a href="http://www.sqlskills.com/blogs/erin/the-accidental-dba-tools-for-on-going-monitoring/">The Accidental DBA (Day 19 of 30): Tools for On-Going Monitoring</a>

     主要介紹一些用來做監控的工具:

     1.性能計數器,比較全面,系統自帶相容性好。

     2.PAL,也是收集性能名額的,有統一的套件,不需要再自己配置了

     3.cleartrace,RML是用來分析sql trace的工具,有被擴充事件代替的趨勢

     4.SQL Nexus是用來分析,SQLDiag和PSSDiag的結果

     5.DMV監控

我覺得在使用工具之前必須要了解是幹什麼用的,怎麼分析的,才能用的得心應手

<a href="http://www.sqlskills.com/blogs/kimberly/the-accidental-dba-day-20-of-30-are-your-indexing-strategies-working-aka-indexing-dmvs/">The Accidental DBA (Day 20 of 30): Are your indexing strategies working? (aka Indexing DMVs)</a>

     索引是個很頭痛的問題,如果不合适造成性能問題,如果沒有select有性能問題。如果太多更改有性能問題。空間又浪費

     沒有用的索引需要删除:

            1.完全重複的索引,可以使用通過DMV找出完全一樣的索引幹掉

            2.超出沒用的索引,通過sys.dm_db_indes_usage_stats超出,幹掉,注意,視圖中的user_update是以語句個數來計算的

            3.相似的索引,索引相似一般分為幾種情況,1.key相似 2.key的左邊相似。 如果合并,會讓io變大,可能會造成另外一個語句變爛,但是減少了空間,減少了維護成本,如果不合并浪費空間,浪費記憶體,更改性能可能會有潛在變化,并且便随死鎖的出現。這些還是要看語句是否需要窄的索引。

     檢查已存在的索引:

          1.主要是碎片的維護,2.填充因子的設定

     添加新的索引:

          添加新的索引是比較有難度的,因為需要分析已經存在的索引,如果隻是單純的添加索引,那麼隻會讓索引越來越多,越來越臃腫,可以以miss index為指導建立索引。如果有miss index提示,那麼把語句放到DTA上面,分析這樣會比miss index更為全面,miss index 是為每個索引找最合适的索引,是以有時候需要考慮索引合并問題

     讨論常用的一些性能名額的意義,性能計數器可以通過PAL進行統計,好處可以減少配置的時間,壞處是閥值是被寫死的。

     CPU相關統計資訊:

Processor

%Processor Time

%Privileged Time

Process (sqlservr.exe)

     處理器有多少cpu時鐘被使用,有多少被用在核心模式,程式占用了多少cpu,有多少使用與核心模式

     記憶體相關統計資訊:

Memory

Available Mbytes    可用記憶體

SQL Server:Buffer Manager

Lazy writes/sec             Lazy write 次數

Page life expectancy    頁生命周期

Page reads/sec             每秒頁讀取次數

Page writes/sec            每秒頁寫入次數

SQL Server:Memory Manager

Total Server Memory (KB)            總共服務記憶體

Target Server Memory (KB)          目标服務記憶體

    磁盤相關統計資訊:

Physical Disk

Avg. Disk sec/Read                   讀取延遲

Avg. Disk Bytes/Read               讀取位元組數

Avg. Disk sec/Write                   寫入延遲

Avg. Disk Bytes/Write               寫入位元組數

Paging File

%Usage                                         page file使用率

SQL Server:Access Methods

Forwarded Records/sec              順序記錄數

Full Scans/sec                              掃描次數

Index Searches/sec                      查詢次數

       對讀取和寫入延遲有一個推薦值來确定io是否正常:

        &lt; 8ms: excellent

&lt; 12ms: good

&lt; 20ms: fair

&gt; 20ms: poor

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-22-of-30-determining-a-high-availability-strategy/">The Accidental DBA (Day 22 of 30): Determining a High-Availability Strategy</a>

     決定使用高可用的政策:

     1.确定會使用到什麼技術,并且是否有某些高可用會對這些技術排斥

     2.選擇高可用技術

     3.測試高可用性,是否能夠達到高可用的需要,并且對性能造成的影響可以在接受的範圍内

<a href="http://www.sqlskills.com/blogs/erin/sql-server-hadr-features/">The Accidental DBA (Day 23 of 30): SQL Server HA/DR Features</a>

     最不想聊的,就是說一些高可用和災難恢複的一些技術,而且很淺。新人可以以此為切入點深入

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-24-of-30-virtualization-high-availability/">The Accidental DBA (Day 24 of 30): Virtualization High Availability</a>

<a href="http://www.sqlskills.com/blogs/erin/the-accidental-dba-day-25-of-30-wait-statistics-analysis/">The Accidental DBA (Day 25 of 30): Wait Statistics Analysis</a>

<a href="http://www.sqlskills.com/blogs/erin/the-accidental-dba-monitoring-disk-io/">The Accidental DBA (Day 26 of 30): Monitoring Disk I/O</a>

      對于dba來說,不單單是存儲空間,還有性能,吞吐量,sys.dm_io_vaitual_file_stats擷取資料庫io資訊。裡面的值都是累加的,隻有重新開機時才會重置。這個dmv不但有io延遲,還有讀寫次數和讀寫的位元組數,用來标記讀寫做多的檔案。

     io的延遲使用avg disk sec/write 和 avg disk sec/read,磁盤緩存,控制卡,存儲系統都會影響延遲。延遲不單單是和host和磁盤相關,是從host到磁盤的整個路徑,如總線,交換機,SAN控制器,磁盤。一般資深的存儲管理者都會知道這個路徑。

     avg disk bytes/read和avg disk bytes/write用來表示吞吐量,要測試吞吐量的極限可以簡單的建立索引,來增大io的量。

     對sys.dm_io_vaitual_file_stats建立極限可以有詳細的資訊,說服存儲管理者給予性能上的支援。還可以幫助預測将要發生的問題。如果io是漸變的,那麼考慮是否在預期的範圍内。SAN是共享存儲,是以也需要考慮是否有可能是這個原因造成io上升,可以在資料庫性能惡化錢給SAN管理者一個參考值。

<a href="http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/">The Accidental DBA (Day 27 of 30): Troubleshooting: Tempdb Contention</a>

     tempdb沖突時一個典型的沖突,大量的查詢使用tempdb,當建立時,要配置設定page,中繼資料,處理FPS,GAM,SGAM等,為了優化,sql server對做了一個cache,更多資訊可以看tempdb的白皮書。

     根據以下sql可以檢視sql server中所有的堵塞:

     SELECT

    [owt]. [session_id],

    [owt]. [exec_context_id],

    [owt]. [wait_duration_ms],

    [owt]. [wait_type],

    [owt]. [blocking_session_id],

    [owt]. [resource_description],

    CASE [owt].[wait_type]

        WHEN N'CXPACKET' THEN

                RIGHT ( [owt].[resource_description] ,

                CHARINDEX ( N'=', REVERSE ( [owt].[resource_description] )) - 1)

            ELSE NULL

        END AS [Node ID],

        [es].[program_name] ,

        [est].text ,

        [er].[database_id] ,

        [eqp].[query_plan] ,

        [er].[cpu_time]

     FROM sys .dm_os_waiting_tasks [owt]

     INNER JOIN sys. dm_exec_sessions [es] ON

        [owt].[session_id] = [es].[session_id]

     INNER JOIN sys. dm_exec_requests [er] ON

        [es].[session_id] = [er].[session_id]

     OUTER APPLY sys. dm_exec_sql_text ( [er].[sql_handle] ) [est]

     OUTER APPLY sys. dm_exec_query_plan ( [er].[plan_handle] ) [eqp]

     WHERE

        [es].[is_user_process] = 1

     ORDER BY

        [owt].[session_id] ,

        [owt].[exec_context_id] ;

     GO

若大量出現FPS,GAM,SGAM堵塞,一般是2:1:1,2:1:2,2:1:3(fps間隔8088個頁,GAM/SGAM間隔 7988*8頁,頁可以使用dbcc page 檢視pagetype确定是否是GAM/SGAM/FPS)。

若出現沖突解決方法:1.減少臨時表的使用,2.開啟1118,3.建立多個資料檔案。方法1比較簡單,隻要減少tempdb的使用就可以了,方法2:如果還出現沖突,啟動1118,當表一上來就直接在專用區配置設定,而不是在混合區,這個trace是全局的,不單單是tempdb生效。方法3:也是現在用的比較多的方法,被認為是最佳實踐,建立多個檔案,檔案個數=min(8,邏輯核心)+4*N

<a href="http://www.sqlskills.com/blogs/kimberly/the-accidental-dba-day-28-of-30-troubleshooting-blocking/">The Accidental DBA (Day 28 of 30): Troubleshooting: Blocking</a>

     一般導緻鎖堵塞的情況:1.無效的更新字段,2.update 沒有相關index幫助,3.事務存在使用者互動問題。

     通過對wait stats建立等待baseline,可以及時的發現問題。也可以使用sys.dm_os_waiting_tasks監控堵塞問題。

     解決方法:1.是否可以通過調整索引解決,2.是否考慮使用行版本

<a href="http://www.sqlskills.com/blogs/jonathan/the-accidental-dba-day-29-of-30-troubleshooting-deadlocks/">The Accidental DBA (Day 29 of 30): Troubleshooting Deadlocks</a>

     死鎖的資訊可以通過1222,1204,1205trace flag,寫入到錯誤日志中。

     除了以上的方法,還可以使用SQL Trace,消息通知,WMI和擴充事件收集消息。

     然後通過等待和已獲得的資源的資訊,分析死鎖,調整死鎖。可能的解決方案:1.建立索引。2.使用行版本

<a href="http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-30-of-30-troubleshooting-transaction-log-growth/">The Accidental DBA (Day 30 of 30): Troubleshooting: Transaction Log Growth</a>

     對于新手來說,往往會出現日志檔案很大,但是資料檔案相對來說很小。造成這個問題一般,除了程式bug之外,1.使用了完全恢複模式,但是沒有日志備份,2.全備後被手動切換到完全模式,但是沒有日志備份。

     SELECT [log_reuse_wait_desc] FROM sys.databases;

     使用這個sql檢視到底是什麼原因造成的如果是LOG_BACKUP那麼就是日志沒有備份的問題。

     每次日志增長都會帶來一些問題:

     1.日志檔案初始化,讓寫入操作暫停

     2.日志增長,日志塊頁會增長(應該指的是虛拟日志檔案),會對性能造成影響(特别是olap負荷)

     3.日志大,恢複時間長