DAC(Dedicated Admin Connection)是SQL Server 2005引入的一個東西,目的是在SQL Server發生嚴重性能問題的時候仍保留有限的資源保證管理員能夠執行一些簡單的命令用於問題診斷、釋放資源、殺死肇事進程等。微軟官方對DAC的說明:使用專用管理員連接。對於DA ...
DAC(Dedicated Admin Connection)是SQL Server 2005引入的一個東西,目的是在SQL Server發生嚴重性能問題的時候仍保留有限的資源保證管理員能夠執行一些簡單的命令用於問題診斷、釋放資源、殺死肇事進程等。微軟官方對DAC的說明:使用專用管理員連接。對於DAC使用的一般情況,有兩個不錯的Blog值得推薦:
http://www.cnblogs.com/kerrycode/p/3344085.html
http://www.cnblogs.com/lyhabc/archive/2012/09/23/2698702.html
上面的兩篇blog涉及到的基本是DAC訪問單機單實例的情況。本文試圖對DAC訪問單機多實例的情況也做個探討。
1)單機單SQL Server實例,且SQL Server實例使用預設埠(1433)
--以下的形式都可以訪問 sqlcmd -S myServer -U myUser -P myPassword -A sqlcmd -S ADMIN:myServer -U myUser -P myPassword sqlcmd -S myServer,1434 -U myUser -P myPassword sqlcmd -S xxx.xxx.xxx.xxx -U myUser -P myPassword -A sqlcmd -S xxx.xxx.xxx.xxx,1434 -U myUser -P myPassword
說明: a) sqlcmd命令行中參數與參數值之間可以有空格也可以沒有;如果你的密碼中有空格,你可以用雙引號把你的密碼引起來; b) sqlcmd命令中的“-S”其實也可以用"/S",其它參數也一樣; c) 1434是SQL Server連接的預設埠號; d) 在伺服器前加"ADMIN:"也是為了指定進行DAC連接; e) “-A”是在sqlcmd命令行中指定DAC連接的參數; f) "-A","ADMIN:",",1434"不能在一條命令中出現兩個或以上,否則會報錯; g) 不在命令行中加入這3個參數("-A","ADMIN:",",1434")的任何一個,登錄也能成功,差別在於你使用的連接是普通連接,不是DAC連接。一般來說,普通連接能用的資源更多,但是當系統性能出現嚴重問題的時候普通連接可能沒法建立,這也是引入DAC的初衷;再就是DAC連接下能看到一些有助於診斷的秘密視圖(參見上面推薦的第一個blog)。
2)單機單SQL Server實例,SQL Server實例使用非預設埠
我通過測試得到的結論是:對於單機單SQL Server實例,使用非預設埠時候的DAC訪問跟使用預設埠1433時候完全一樣。網上的一些論壇說要確保“SQL Server Browser”在運行,似乎不是必要的,至少我測試(用的SQL Server 2008 R2 SP3)過程中“SQL Server Browser”是不是在運行不影響訪問。
3)單機多SQL Server實例
通過DAC來訪問單機多SQL Server實例的情況要複雜一些。上面的幾條命令行在這種情況下都會失效。原因在兩個: a) DAC訪問是實例級別的,服務端得有辦法知道你要訪問的是哪個實例; b) 在單機多實例的情況下監視DAC訪問的是隨機埠,而不再是預設的1434 --怎麼破? 我們在訪問資料庫引擎的時候,碰到單機多實例的情況有兩種辦法,一種是在配置S參數的時候加上實例名,一種是加實例埠號。命令行的形式類似下麵: sqlcmd -S myServer\InstanceName -U myUser -P myPassword sqlcmd -S xxx.xxx.xxx.xxx\InstanceName -U myUser -P myPassword sqlcmd -S myServer,6xxx -U myUser -P myPassword sqlcmd -S xxx.xxx.xxx.xxx,6xxx -U myUser -P myPassword 先從實例名著手: sqlcmd -S myServer\InstanceName -U myUser -P myPassword -A sqlcmd -S xxx.xxx.xxx.xxx\InstanceName -U myUser -P myPassword -A sqlcmd -S ADMIN:myServer\InstanceName -U myUser -P myPassword sqlcmd -S ADMIN:xxx.xxx.xxx.xxx\InstanceName -U myUser -P myPassword 經測試確認,以上4種連接方式都是OK的。註意一點,對於InstanceName的解析是伺服器上的“SQL Server Browser”進行的,如果這個服務不在運行,DAC的訪問是要失敗的。流程是:Browser根據“myServer\InstanceName”或者“xxx.xxx.xxx.xxx\InstanceName”找到你要訪問的實例,然後根據“-A”或者“ADMIN:”找到你要訪問的埠。 既然這樣可以進行DAC訪問,那用類似訪問資料庫引擎的方式,把上面命令中的“\InstanceName”改成",xxxx"格式的埠號是不是也行呢? sqlcmd -S myServer,xxxx -U myUser -P myPassword -A sqlcmd -S xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword -A sqlcmd -S ADMIN:myServer,xxxx -U myUser -P myPassword sqlcmd -S ADMIN:xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword 如果你在幾個命令行中配的埠號跟訪問資料庫引擎時候配置的埠號是一樣的話,答案是不行。原因在哪裡呢?那個埠是資料庫引擎的訪問埠,並不是被監聽的DAC埠,因為不在一個頻道上DAC還不知道你想訪問。我的理解,在命令行中指定了埠號的情況下,Browser認為那就是你想訪問的埠,結果因為它並不是那個隨機的DAC埠而導致了失敗。 DAC訪問偵聽跟資料庫引擎一樣,從根本上來說也是一個tcp服務(關於這一點你可以查看sys.endpoints來確認)。是服務,我們如果能知道它偵聽的埠號就應該能解決問題。但不幸也在這兒,如上面b)所說,在單機多實例的情況下這個被監聽的埠是隨機的。視圖sys.endpoints是能查到當前SQL Server實例上的tcp服務信息的,每個endpoint都有一條記錄,比如你就能在這裡查到用於鏡像的5022,但遺憾的是對於DAC,埠那一列卻顯示的是0.通過埠訪問的這條路我沒能走通。
4)DAC訪問與防火牆
如果有人通過我上面提到的有效的方式進行DAC訪問卻不幸失敗了,也請不要奇怪。拋開埠劫持等特殊情況,DAC訪問失敗最常見的就是受到防火牆設置的攔截。對於上面提到的兩種單機單實例的情況,只要確認服務端配置了允許對tcp1434埠的訪問,DAC連接應該是沒有問題的;複雜的情況仍然是單機多實例。 對於單機多實例的情況,由於DAC偵聽的埠是隨機的,不能指定,所以我們沒法在防火牆上給它開口子,除非關閉防火牆。事實上,我在測試的時候就是讓伺服器上的Windows防火牆對域範圍內的訪問不起作用(關閉針對域內部訪問的攔截)的。那要想從外網訪問怎麼辦?總不能為了一個DAC連接把這台伺服器赤裸裸的暴露出來(給它配外網IP)或者關掉公司的級別的防火牆吧?這倒不必,可以用VPN或者埠映射從防火牆上開個小口子,這樣你就能連接到區域網,從那進行DAC訪問。
5)如何確認當前是DAC連接還是普通連接
可以使用下麵的SQL: select s.session_id, s.login_time, s.login_name, s.host_name, p.endpoint_id, p.protocol_desc, p.name from sys.dm_exec_sessions s inner join sys.endpoints p on s.endpoint_id = p.endpoint_id 你可以從login_time,login_name,host_name來判斷出哪一個是你當前的連接session,如果是DAC連接的話,你能從name列看到“Dedicated Admin Connection”。