SQLServer DBA 三十問(第1~20題)

首先聲明:這是本人的答案,並非官方答案,不要盲目追捧,因爲覺得這問題很具有代表性,很多人想了解,所以記下,順便讓廣大園友也來給本人打打分。因爲本人平時用sqlserver2000,所以大多基於sql2000回答。

原帖地址 http://www.cnblogs.com/fygh/archive/2011/10/18/2216166.html 

問題如下: 

1. char、varchar、nvarchar之間的區別(包括用途和空間佔用);xml類型查找某個節點的數據有哪些方法,哪個效率高;使用存儲

   過程和使用T-SQL查詢數據有啥不一樣;

答:char 是定長的字符類型,若長度不夠自動在後面補足夠的空格 ;varchar是可變長度的字符類型,具長度體根據存入的數據而定;nvarchar可理解爲unicode的可變長度字符類型;

xml類型的字段沒用過,因爲感覺xml用不上索引; 

 

2. 系統DB有哪些,都有什麼作用,需不需要做備份,爲什麼;損壞了如何做還原(主要是master庫);

答:master 主要保存系統級的信息,比如本數據庫實例都有哪些數據庫 ,都有哪些賬號等,需備份;

model 模板,每創建一個數據庫 ,都會根據這個庫的結構來創建,如果改過此庫,建議備份;

msdb 保存計劃任務,作業之類的信息,需備份,否則會丟失作業和備份計劃;

tempdb 用戶對sqlserver操作時產生的臨時數據依賴於此庫,最常見的是臨時表,不許備份;

resource 這個是sqlserver2005新增的只讀數據庫,保存了sqlserver的系統對象,如sys.objects,建議備份,磁盤損壞時需要; 

master的還原要依賴於sqlcmd,估計很少人經常幹這事,所以這時候應該查下資料; 

 

3. 有哪些操作會使用到TempDB;如果TempDB異常變大,可能的原因是什麼,該如何處理;

 答:每個sqlserver運行時所產生的臨時數據都會用到tempdb,最常見的是執行sql腳本需要返回的記錄集;

異常變大的原因是執行的操作返回的記錄集過大造成,找出該語句優化,減少數據範圍,或者分批操作這些數據; 

 

4. Index有哪些類型,它們的區別和實現原理是什麼,索引有啥優點和缺點;如何爲SQL語句創建合適的索引,索引創建時有哪些需要

    注意的項,如何查看你創建的索引是否被使用;如何維護索引;索引損壞如何檢查,怎麼修復;T-SQL有更好的索引存在,但是運行

    時並沒有使用該索引,原因可能是什麼;

答:聚集索引,非聚集索引;聚集索引只能有一個,非聚集可有多個,數據依賴於聚集索引來保存,如果沒有聚集索引,數據是一個亂序的堆;

優點:合適的索引可有效提高查詢效率;缺點:過多的索引,在insert、update 和 delete 的時候增加索引的維護成本,降低併發量;

一般索引的創建要依賴於 where 和 order by 這兩個關鍵字,執行計劃可以看出是否用到了索引;

還沒遇到過索引損壞的情況,如果損壞,重建之;

用不到索引可能是索引碎片過多 ,可進行碎片整理,若不行可加強制索引with(index( 索引名 ))

  

5. 視圖上我們能建索引嗎,如果能建的話,會啥好處和壞處;視圖上建索引和表上建索引有啥區別;

答:有索引視圖,不過本人從來不用, 因爲視圖被定義爲一個虛擬表,如果對其創建索引,需要具備一些苛刻的條件,也不易維護,所以從來不用;

 

6. Job信息我們可以通過哪些表獲取;系統正在運行的語句可以通過哪些視圖獲取;如何獲取某個T-SQL語句的IO、Time等信息;

答:sql2000下是通過 master.dbo.sysjobs 來查看作業信息;系統正在運行的語句可通過 master.dbo.sysprocesses 結合 dbcc inputbuffer 來查看,一般查堵塞這個很管用(關於堵塞的定位可看我的另外一篇博客,sqlserver阻塞定位  ); 

IO,在sql2000下我本人都是通過profiler看reads,duration,sql2005下有了動態視圖(dmv); 

 

7. 在線系統,一個表有五千萬記錄,現在要你將其中的兩千萬條記錄導入到另一臺服務器的某個表中,導完後,需要將這兩千萬數據刪

   除,你預備如何處理,優缺點是什麼;

答:這個的我之前專門寫了一篇博客,在這裏  SQLServer DBA 三十問之我答(第7題)

 

8. 數據庫服務器報磁盤空間不足,你將如何應對,要求儘快恢復;

答:如果是日誌文件太大,備份日誌,sqlserver會自動截斷日誌;

如果是數據文件過大,趕緊轉移到一個足夠大的硬盤上,然後再想辦法拆分庫,一般一個庫100G應該差不多,如果太大備份還原什麼的都不是很方便,至於拆分方案那不可一概而論; 

 

9. 臨時表、表變量、CTE(公用表表達式)有啥區別和聯繫,保存位置有啥不一樣,使用時如何決定選哪種;

答:臨時表,保存在 tempdb中,

表變量 保存在內存中,他和臨時表的區別是 一個是保存在tempdb,一個保存在內存中,

cte是sqlserver2005新增的,是把一個記錄集當做一個變量來使用,他跟表變量的區別是不需要insert數據,所以應該比表變量更高效;

如果只使用一次cte應該是最好的,如果要重複多次使用同一個記錄集,我個人認爲還是表變量,

如果你還需要用到truncate語句來清除臨時的數據,那最好用臨時表,因爲表變量不支持truncate,可參考我的另一篇 本質:sqlserver爲什麼表變量不能truncate

 

 

10. SQLServer有哪些隔離級別,默認級別是哪個;數據庫有哪些主要的鎖類型;行版本控制是如何實現的;

答: 隔離級別: read uncommitted,相當於給每個select 加with(nolock), 會產生髒讀,爲提高併發量可設置此選項;

read committed 不允許髒度,默認級別;repeatable read 鎖定select的數據集;serializable 相當於在select的表上加 with(holdlock),從來沒用過;

books online 裏查 set transaction isolation level 可查到。 

 

 

後語:剛開始看這題目的時候,感覺都經常用到,應該很easy,但是真正要回答的時候發現不知道該怎麼表示,最後還是花了不少時間來查一些資料,也算是對自己知識的再鞏固。可能有些回答的不一定準確,如果哪位仁兄另有高見,不妨賜教一二,也可經常切磋切磋,共同進步。從本人招聘的經歷來看,做asp.net開發的能答對第1、第4題已經算是很不錯的了,從這點可以看到sql是廣大的程序員的弱項。

 

 

11. 死鎖如何跟蹤;阻塞如何跟蹤和查找;發現有問題的語句後,如何進行處理;用Profile做跟蹤時,一般我們需要跟蹤哪些事件;

答:dbcc traceon(1204) 可以開打跟蹤死鎖的標記,sqlserver2005新增了1222跟蹤標誌,就是格式更詳細,死鎖的信息會記錄在errlog文件裏,順便說下errlog一共有errlog,errlog1~errlog6共7個文件,關於這些可以看看books online,如果覺得books online太乏味,可以看看徐海蔚的《Microsoft SQLServer企業級平臺管理實踐》;

相對來說,阻塞的問題比死鎖要嚴重,死鎖只是犧牲部分進程,阻塞的話會導致整個系統癱瘓,阻塞的定位我有一篇專門的博客介紹:sqlserver阻塞定位

要跟蹤死鎖的話,當然是選擇“鎖”事件,不過我一般用profiler都是做性能調優的,選 常規——》模板名——》SQLProfileTuning 就ok了,死鎖很少跟蹤,因爲我們的sqlserver降低了事務隔離級別,基本不會產生死鎖,有的話也在可接受的範圍內,都是凌晨運行作業時產生的,也不會太多。

 

12. Windows日誌主要有哪幾種,SQLServer日誌一般保留幾個,什麼情況下會產生新的SQL日誌;數據庫日誌恢復模式有哪幾種,區別是什麼;數據庫日誌突然變得很大,而且你無法收縮,可能的原因是什麼,怎麼查找原因,分別將如何處理;

 答:windows的日誌可以自己看iis就明白了,我一般只看應用程序,一次發現asp.net拋出的錯誤和異常,解決之;sqlserver的日誌一般保留7個,errlog,errlog1~errlog6,每次數據庫重啓都會產生新的日誌,新的日誌命名爲errlog,舊的日誌也會跟着改名,之前老的errlog改爲errlog1,老的errlog1 改成 errlog2,直到 errlog5 改成 errlog6, 之前的errlog6會被刪除,所以如果數據庫出錯千萬不要盲目充能更新啓動,可以先看看錯誤日誌,多次重啓之後可能就丟失了最原始的錯誤信息;

應該是數據庫恢復模式吧,簡單,大容量,完全;用哪個要視情況而定,不重要的業務可以用簡單,重要業務就要用完整;

完整模式支持最完善的備份和還原方案,可以還原到某個時間點,簡單模式只能還原到該備份裏面的數據,無法還原到時間點,大容量模式一般只在需要進行批量數據導入的時候才使用; 

日誌突然很大而且無法收縮,其實有很多種可能,不過不管是哪一種可能,都離不開一個現象,有一個更新(insert,update)動作工作正在執行,而且短時間內不會停止,既然短時間內不會停止,那麼我們就應該想到master.dbo.sysprocesses這個表,可以通過 select spid from master.dbo.sysprocesses where open_tran > 0 查看當前運行時間比較長的進程,看看到底有什麼動作,我們還可以通過 dbcc inputbuffer(@spid) 找到語句;

     

13. 分區表和分區視圖是什麼概念,一般是在什麼情況下使用,有啥好處;

答:先說分區視圖,這個在sql2000就已經支持,他其實還是一個視圖;

分區表是sql2005新提供的功能,邏輯上他就是一個表,物理上它可以把數據保存在多個磁盤,以此提高io,提高併發量;

2005下應該都是用分區表了,數據量龐大的時候可以按分區函數把數據分開,對於查詢性能有很大的提升,不過我無論如何都認爲太大的表不好,2000下我一般都是分表的,比如歷史表,或者按自己業務需求制定分表方案。

 

14. 如何比較兩個同結構的表數據的差異;如果表損壞了,如何修復;如何在備份文件有問題的情況下儘量還原數據;如何將一個表

     的Identity屬性歸零;

答:要比較兩個表所有字段的值,光通過sqlserver可能實現不了,可能需要藉助第3方工具,但如果數據量很大,什麼工具都很難完美實現,提出這個問題,應該是想找到部分丟失的數據,如果是這樣,我一般是通過找到出問題的那段時間開始,把那之後的數據比較一下,然後通過join 把數據update成想要的;

如果表壞了,有個dbcc checktable的命令,不過我至今沒遇到過;

一般備份文件有問題,但是可以還原成功,不過會報些錯誤,可能導致數據庫不穩定,可以嘗試dbcc checkdb命令,之後再新建一個庫,把數據導入新庫中;

identity屬性的問題,delete並不會歸零,因爲在結構中還保存了最大值,truncate table就可以 

 

15. CheckPoint和LazyWriter區別;DDL Trigger 和 DML Trigger有啥用,區別是啥;

答:在sqlserver2000只有checkpoint,lazywriter 是 sql2005以後加入的,可以簡單認爲他們是sqlserver系統內部的進程;

checkpoint 需要達到一定條件纔會觸發,觸發之後會強制把髒頁寫入磁盤;

lazywriter 是每隔一段時間啓動一次,然後檢查free list,看看是否低於某個閥值,如果低於這個閥值,他就幹活,把髒頁數據放入free list,同時寫入磁盤;  

可以打一個形象的比喻:lazywriter是個懶漢,他每隔一會兒就睡(定時啓動),睡醒了就看看自己的錢包(free list),如果他認爲錢包的錢少了,他就拿錢(髒頁放入free list)幹活(髒頁寫入磁盤),checkpoint是一個很賣力的夥計,只有有事情通知他一聲,他立馬一聲不吭的把把活幹完(髒頁寫入磁盤),不會在乎自己的錢包(free list);  

 

DDL Trigger是針對結構的觸發器,比如新建表,修改表,刪除表;

DML Trgger是針對數據的觸發器,比如insert,delete,update表數據;

 

16. Mirroring 和Logshipping 的區別和使用場景;SQLServer的Mirroring與Oracle的哪像技術比較接近,它們的區別是啥;

答:Mirroring,即數據庫鏡像,一般用作高可用性的故障轉移集羣,需要 主服務器,鏡像服務器,見證服務器3臺,當見證服務器檢測到主服務器出現故障時,會自動把數據庫連接指向鏡像服。實現的基本流程如下,用戶訪問主庫,並提交數據,主庫會把日誌傳送到鏡像服務器,做鏡像的時候也有些麻煩,必須首先保證主庫和鏡像庫數據一致才能建立鏡像關係,所以如果你的主庫時刻在產生數據,那鏡像做起來估計就費神了;其實我還有個疑問,要是見證服務器掛了怎麼辦,ms貌似沒給出方案;

LogShipping,即日誌傳送,也有主庫-輔助庫,沒有見證庫了,他定時把事務日誌傳送到輔助庫,其實就是不斷做back log 和 restore 的操作,他有個缺陷,輔助庫每次restore都需要斷開所有連接,所以輔助庫並不適合讓用戶訪問,這個方案都是可以作爲容災備份的一個方案,當主庫出現故障的時候,馬上手工切換到輔助庫即可恢復。

相比之下我覺得logshipping更合適一些,做的時候沒有那麼多條件限制; 

對Oracle不瞭解,所以無法比較; 

 

17. Mirroring的搭建步驟,Mirroring三種模式區別,Mirroring 中同步和異步的原理和要求,搭建了Mirroring後,需要對數據庫日誌做

     什麼處理;

答:這個搭建步驟還是查資料比較可靠。 

三種模式,高安全(帶自動故障轉移)同步傳輸 ,高安全(不帶自動故障轉移)同步傳輸,高性能,異步傳輸數據,同步就是主庫要等待鏡像庫的迴應消息纔會提交事務,異步就是不等待迴應消息就已經提交日誌,因爲等待消息需要時間,所以不等待性能會更高,但不是很安全,鏡像數據庫的數據有可能和主庫的數據不一致。

需要對數據庫日誌做什麼處理?沒看懂這句; 

 

18. Replication配置和使用場景;Replication有哪幾種模式;PUSH和PULL有啥區別;搭建Replication後會產生一個什麼庫;報錯時

     用什麼來查看報錯的具體語句,清理掉某個庫的Replication使用什麼語句,查看同步鏈信息主要通過哪些表;

答:配置的步驟足夠寫一篇博客,大概的步驟如下:1. 標識分發服務器;2. 在此分發服務器上創建分發數據庫;3. 啓用將使用此分發服務器的發佈服務器;4. 啓用發佈數據庫;5. 啓用將接收發布數據的訂閱服務器;其實裏面很多細節要注意,可以google得到不錯的教程,然後手動操作一遍就知道了,沒什麼難度。

場景:一般都是作爲數據同步用;有推和拉模式,分發代理程序在分發服務器上運行即推,在訂閱服務器上運行即拉;

會產生一個distribution庫;

報錯的話,一般監視器裏面都有優紅X的,如果覺得這樣看太麻煩,可以直接查 distribution庫的dbo.MSdistribution_history表,所有分發相關的信息都保存在了distrition庫;

清理replication看似簡單,其實還分很多情況的,比如push,pull模式,還是日誌,快照,合併模式,因這些不同,都需要執行不同的系統存儲過程,既然ms給我們提供的好用的企業管理器,我們大可以用他來簡化我們的工作,如果一定要腳本,那就找吧,系統存儲過程一般以 sp_ 打頭,清楚一般包含 "del","drop","remove" 等關鍵字,比如我通過 select * from master..sysobjects 

 

where xtype = 'p' and name like '%repl%' and name like '%remove%',sql2000下可以查到相關的過程和用法;說實話誰也不能保證自己什麼都會,不會應該保證在遇到問題的時候能馬上找到解決的辦法,這比死記硬背答案要來的有效些;
在distribution.dbo.MSarticles 可以查看同步鏈; 

 

 

19. Replication發佈端的表能truncate嗎,爲什麼;Replication Identity列如何處理、缺失字段錯誤如何處理、主鍵衝突錯誤如何處

     理、如何跳過指定的錯誤、訂閱端表被刪除了如何處理、大規模改動數據如何處理;某條同步鏈因爲其中的某個表一次性改動數據很

     大造成同步鏈的嚴重延時,要求儘快恢復同步鏈,如何處理。

答:不能truncate,具體見我的另外一篇:DBA之問:Replication發佈端的表能truncate嗎,爲什麼;

發佈的時候默認情況下,目標表不會建立identity字段,也的確不該建立;

缺失字段這種情況不應該發生,如果發生了是技術人員的操作失敗,如果此列不許發佈,去掉就可以了,如果要在發佈之後再對列進行添加或者刪除,可以參考 sp_repladdcolumn , sp_repldropcolumn 這兩個系統存儲過程;

主鍵衝突,首先忽略,然後再檢查兩個表數據量是否一樣,發生這種問題可能是有技術人員違規在訂閱庫上修改了表,這是不被允許的,訂閱庫的庫只適合做查詢用,不應該人爲手動更新;

訂閱端表被刪除,這樣監視器是會提示錯誤的,應該重新初始化數據;

不建議同事進行大規模的數據改動,因爲這會導致同步太頻繁,而沒一個同步動作都需要等待發布端服務器的確認,如果生產數據庫需要不斷的等待確認,那等於降低了併發量,如果等待隊列和時間都太長有可能導致數據庫太慢而停止服務,我們遇到過類似情況。

 

20. SSB(Service Broker)使用場景,如何創建,都會創建些什麼對象,有啥優缺點,主要通過什麼方式實現不同服務器之間的消息

     傳遞;可以通過哪些方式排錯;

答:這是sql2005以後新增的功能,一直用的2000,對這個還沒認真研究過,只知道可以用來做分佈式的數據同步,而且是異步實現的。

 

-----------------------------------------------

後語: 這中間的10題比之前的10題難度提高了不少,有些問題在這之前我只是用他們來幹活,並沒具體研究他們怎麼幹活的,通過這10題我對sqlserver的瞭解又加深了一步,而且很多問題,都是抱着追究本質的態度。在這些題目裏面,有些是sqlserver2005新增的功能,因爲本人實在沒用過,所以不敢妄給答案,以免誤人子弟。知識無限,能力有限,文中難免存在不對的地方,本人秉承着相互交流的態度,若哪位仁兄發現不對,敬請指出,本人也很樂意和從事sqlserver工作的兄弟們交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章