顯示具有 MSDTC 標籤的文章。 顯示所有文章
顯示具有 MSDTC 標籤的文章。 顯示所有文章

2009年2月10日

如何分析 MSDTC Trace Log (Windows SDK: tracefmt.exe Utility)

咳咳,今天要紀錄的是如何分析 MSDTC Trace Log,MSDTC 這東西真的是很難馴服,
雖然已經整理出一套設定方式(這篇是 Google「MSDTC」第一頁的最後一筆耶!)
但是 MSDTC 的可怕之處不在於「不會通」,而是「有時候通,有時候不會通」,
而且由於全世界受 MSDTC 之苦的前輩們長久下來累積了豐富的 troubleshooting 資料,因此當不同客戶的環境中 MSDTC 出現問題時,用該客戶環境當作關鍵字去搜尋解答,
往往每次都會得到不同的答案!Darkthread 是個尋找 MSDTC 疑難排解的好地方)
例如,在「日文 XP SP1 + MS A 產品 + Oracle DB」或是「英文 Win2k3 SP2 + IE6」,
或者「中文 Win2k3 SP1 + IE7 + Office 2003 + MS Project 2007」等等的環境因素,
綜合起來可能就會導致 MSDTC 產生不同的異常狀況!導致真正的原因始終搞不清楚 Orz
所以,有時候還是得分析 MSDTC 的 Trace Log,以檢視一段時間內 MSDTC 服務運作的狀況(MSDTC.LOG / DTCAXTM.LOG 是 MSDTC 內部使用的,沒辦法用來分析)。

首先要啟用 MSDTC Trace,設定方法請參考 Microsoft KB ,還蠻簡單的,
要注意的地方是開啟 Trace 會造成系統效能下降(運氣不好的話還會嚴重下降),
所以 Debug 完畢後請務必把 Trace 關閉,以免影響 Production 環境的系統效能。
(預設應該是停用 Trace 的,但我發現我使用的好幾台 VM 都已經有開啟 Trace 了,應該沒有特別去設定,感覺預設應該是啟用@@”)


設定好 Enable Trace 之後,在 Windows 2003 上看起來應該會類似這樣:
MSDTC_Trace_Win2k3

在 Windows 2008 上看起來則是這樣(跟設定的時候一樣,元件服務的內容有變):
MSDTC_Trace_Win2k8

Update: 發布前一個手滑就抓了 Win7 (Build 7000) 的圖(正式版應該也差不多):
MSDTC_Trace_Win7(Build 7000)

看起來果然是預設會 Trace Aborted & Long-Lived Transactions.
之後就繼續執行系統正常的操作,過一段時間再去檢查位於「C:\WINDOWS\system32\MsDtc\Trace」下的 Log 即可,檔名應該叫做「dtctrace.log / tracetx.log」。

好不容易叫 MSDTC 老老實實的記錄下來它到底都幹了甚麼好事之後,由於 log 是 binary 的格式,因此肉眼是無法閱讀的,這時候就輪到「tracefmt.exe」工具上場了!
「tracefmt.exe」是 Windows SDK提供的一個 Utility,
顧名思義應該是要將 Windows 內部使用的一些 binary log 重新 format 為人可以閱讀的格式,以 MSDTC Trace Log 來講就會被轉換為 csv 格式。

很不幸的,網路上似乎很難直接找到 tracefmt.exe 的下載點(其實就算找到也感覺蠻恐怖的,執行檔不知道會不會有病毒之類的),因此必須先下載完整的 Windows SDK 安裝檔,
官方下載點在這裡,稍微看了一下說明文件後會發現,這個 Windows SDK 版本可支援 Win XP、Vista、2003、2008(事實上 Win2003 SDK 的下載頁面也會導向這裡),大小約 1.3G, 若不想要裝一大堆有的沒的,只要選擇安裝「Development Tool」即可。

接下來依序執行以下步驟:
  1. 將 tracefmt.exe 從 {Windows SDK Folder}\bin 下複製到 Trace Log 所在的目錄中。
    並確認除目錄中除了 dtctrace.log 外,必須要有「msdtctr.mof」和「msdtcvtr.bat」兩個檔案。
    (.mof 要幹嘛我不太清楚,msdtcvtr.bat 內含呼叫 tracefmt.exe 執行 format 的 vb script)
  2. 在 Command Line 模式中,執行「msdtcvtr.bat -tracelog tracetx.log」,最後一個參數請換成 log 檔的檔名。
    (執行過程中產生的錯誤會紀錄在「errortrace.txt」中 <-- 所以我才知道沒有 msdtcctr.mof 就跑不下去)
  3. 執行完畢後 Windows 會自動用 notepad 打開 tracefmt.exe 產生的 trace.csv,此檔案中的內容就是 Trace 過程中紀錄到的各種 event,接下來就可以根據 event 的內容開始分析了。若檔案內容一片空白表示沒有紀錄到任何 event。
    (既然是 csv 格式,有需要的話也可以用 excel 開起來作進一步處理)
  4. 除了 trace.csv 檔案外,還會另外產生一個 errortrace.txt 說明檔,內有一些統計資料。不管你把「dtctrace.log」、「msdtctr.mof」、「msdtcvtr.bat」、「tracefmt.exe」複製到哪個資料夾執行,「trace.csv」和「errortrace.txt」的預設位置都會在:C:\WINDOWS\system32\MsDtc\Trace
    (應該可以透過 tracefmt.exe 指定輸出位置,不過這也不太重要…)
以上就是完整的步驟啦,最後補上一張完整的抓圖:
MSDTC_LogParse

2009年2月8日

What’s ThreadLocalStorage (aka TLS)?

最近開始試圖解決公司底層元件的宿疾陳痾 -- 惡名昭彰的 MSDTC
以使用 TransactionScope 來說,為了確保系統中全程採用 Local Transaction,
重點在於在交易過程中必須使用單一的 connection,且不可以有開開關關的動作
 
(關於 MSDTC 的說明請參考附註中 Darkthread 大大的.NET分散式交易程式開發FAQ)

但是很不幸的,舊的底層元件(Entity)為了簡化外部程式的寫法, 主動把 connection 物件給包了起來,並且在每個 public 的 CRUD Method 中去 open & close connection,因此只要在 TransactionScope 中使用多個 Entity, 或者先呼叫某個 Entity 的 Select 再呼叫 Save(造成 connection 開關多次), 就會導致該交易從 Local Transaction 被 automatic escalate 為 MSDTC, 進而造成 MA 時莫大的痛苦

(幾乎每次 MSDTC 出錯時,根據當時的 System Configuration 都可以在網路上找到相對應的案例。也就是說,各種可能導致 MSDTC 出錯的環境組合幾乎是無窮盡的 =.=”)


為了在「避免舊系統大幅改寫」的前提下,修改底層元件的寫法以設法避免 MSDTC,
我們需要一個 Global 的地方以存放共用的 connection (以及相關的交易控制資料),
在一番討論 & survey 之後,決定採用 ThreadLocalStorage (簡稱 TLS) 這個技術。

以下是 TLS 的基本介紹:
  • TLS 的技術可以回溯到 Win32 multi-threaded programming,在 .NET 的世界中也有一套相對應的作法。
  • TLS 的基本原理是,在每個 thread 中分配一塊可以用來儲存資料的地方,只要在該 thread 中執行的 method 均可存取這些資料。
  • TLS 的一個好用之處,在於可在不修改現有程式碼(不管是改不動還是根本就沒有 source code)的情況下,在系統中增加(效能分析)用的 tracking information(有一點 AOP 的感覺)。對我目前面臨的問題來說,剛好可以當作 Global Data Storage 來儲存 connection 物件。
  • 在 TLS 中,一份資料對於某一組「thread + AppDomain」來說是 unique 的。TLS 不能像 .NET Remoting 技術那樣的 cross AppDomain boundary。
    (.NET Remoting 還蠻複雜的,看來沒時間仔細研究。不過以後會被 WCF 取代)
    image
  • 儲存於 TLS 的資料一律是 Object 的資料型態,因此必須自己 handle 轉型。
TLS 的基本程式寫法很簡單,可以參考這裡。雖然目前這個方法還沒有實際驗證過,
但根據手上的資料來看應該是可以解決 MSDTC 的問題。

我的小小 TLS 範例程式可以在這裡下載。

PS. 關於 MSDTC 的說明,可參考 Darkthread 大大在 Run!PC 上發表的文章,如果忘記這個連結位置的話,可以 google「darkthread TransactionScope」,在第二個 result「Browse by Tags - Darkthread」中就可以找到「.NET分散式交易程式開發FAQ」。

2008年9月1日

如何在Windows Server 2008上設定MSDTC

隨著Windows Server 2008的正式上市,最近也利用一些時間來測試公司底層的.NET 1.1元件(還有最近升級到.NET 2.0的元件),由於在微軟的平台上,舊的元件不可避免的大量依賴MSDTC(微軟的分散式交易服務,參考MSDN文件,在黑暗執行緒也有很多troubleshooting資料),又因為MSDTC可能出錯的狀況幾乎是有上千種(連某些特殊語系的OS都可能會有詭異的bug),因此隨著新版Windows Server OS的推出,也必須要更新舊有的MSDTC Troubleshooting Manual。

在最近的測試中,大致上都相當順利(不管是X86 or X64版),Win2008除了底層架構更為模組化,效能表現更加突出之外(這在UI上感受不到),最明顯感受到的差異就是管理介面的改變,不過對於用習慣Vista Business的人來說,應該會比較容易上手(若是Vista Home Premium以下,則還是有相當的差異,就像WinXP vs. Win2003的差異一樣)。

廢話不多說,以下是最general的設定步驟(這些步驟會將安全性原則設定到最寬鬆的狀態,實際上還是應該經過測試,開放最小限度的安全設定即可):
  1. 確認 AP Server 以及 DB Server 上的 Distributed Transaction Coordinator 服務都有開。

    除了透過「系統管理工具」-->「服務」的  GUI 來啟動 DTC 服務之外,也可以在 command prompt 中用「net stop msdtc」和「net start msdtc」來啟動/停止 DTC 服務。
  2. 確認 AP Server 與 DB Server 間能互相以 NetBIOS / DNS 的方式來解析電腦名稱。

    這裡的重點是一定要兩台 Server 間彼此互相都能解析,在 Win2008 上,預設會把 ping 所使用的 ICMP Protocol 關閉,可以在 command prompt 中執行「netsh firewall set icmpsetting 8」指令,或者從Firewall的Inbound Rules中,將「File and Printer Sharing (Echo Request – ICMPv4-In)」設定為Enabled。(參考資料)
  3. 調整關於 RPC 的安全性設定 

    DTC 必須使用RPC,因此需要設定相關的安全性設定。直接修改 Registry 的方式請參考這裡
  4. 其他安全性設定(含允許網路 DTC)

    (1)在Control Panel中,進入Component Services
    clip_image001

    (2)依序展開Computers > My Computer > Distributed Transaction Coordinator > Local DTC,檢視 Properties。參考下圖的設定。
    image

    (3)上途中在「Allow Inbound」和「Allow Outbound」下面的三個驗證選項,由於通常AP Server和DB Server會位於相同的Security Zone中,因此最寬鬆的設定是完全不要驗證,以免產生不必要的麻煩,相關安全性的問題應該在request進入AP Server前就處理好,或者在AP Server就把惡意的程式碼給擋下來,不要牽涉到DB Server。

    根據實際經驗,如果 AP Server 和 DB Server 都位於相同的 AD Domain,那麼其實設定開啟驗證也不會有什麼問題。

    最後一個「Enable XA Transactions」的選項就目前的情況也都可以不要允許,XA應該是另一套做 two-phase commit 的機制,不太熟 .... O.o

  5. Basic Windows Firewall Exception Program settings

    (1)到Control Panel > Windows Firewall,點選左方的「Allow a program through Windows Firewall」連結,以設定 Exception Program:
    image

    (2)設定允許DTC和File and Printer Sharing(參考資料):
    image

  6. Advanced Windows Firewall Policy Settings

    (1)在Control Panel > Administrative Tools 中,找到 Windows Firewall with Advanced Security:
    clip_image001[13]

    (2)展開「Inbound Rules」後,在中間的Rules詳細內容區塊中可以找到「Distributed Transaction Coordinator (RPC)」、「Distributed Transaction Coordinator (RPC-EPMAP)」、「Distributed Transaction Coordinator (TCP-In)」等規則,預設都是disabled的(灰色),把他們通通 Enable。
    clip_image002

  7. 設定完畢之後,一定要利用DTC Tester來測試(更早以前還有一個DTC Ping工具,但是可能會產生false positive的結果,工具說通了,但實際就是不work),這個工具是利用ODBC來連線,在target DB Server上啟動一個分散式交易,建立一個temp table(只有一個欄位),然後塞入一筆亂數的資料,若是MSDTC有通的話,最後會要求你按一個鍵來commit transaction,如果看到志個訊息就表示「基本上」MSDTC的設定已經成功了! (參考:如何使用 DTC Tester)

    曾經公司有些SE到客戶端裝完機器,按照手冊設定好MSDTC之後,居然拿最基本的ping DNS和telnet來測試連線,然後反應說系統掛了,結果看exception的訊息很明顯就是MSDTC不通。總之重點就是,沒有用DTC tester這個工具來測試的話,一切都是假的,聽說還會有DTC Tester測試通過,但MSDTC還是無法正常運作的案例呢!(幸好我沒遇過)

    好消息是微軟因為知道MSDTC這東西太難搞了,所以釋出一些測試工具,壞消息是這些工具在大部分的情況下只會吐出非常general的錯誤訊息(e.g. Invalid Cursor State),還有四個預設的安全性檢查建議,因此除非剛好看到非常明顯的錯誤訊息(例如MSDTC服務根本沒開),否則還是只能無奈的看著「Invalid Cursor State」,然後靠著Google瞎子摸象找解法了。
以上的圖主要是針對Win2008抓的,若SQL Server是架在Win2003上,基本上步驟都一樣(只是可以不要管Windows Firewall with Advanced Security的部份),主要是畫面長的不太一樣,主要還是參考微軟的這份文件(2007.12.5)

MSDTC這東西真的是很麻煩,常常發現出錯的時候,都會Google到新的scenario(OS Setting + MS Product + .NET Version + Firewall Setting + Registry Setting),可能出錯的狀況真的是有千百種,即使到了最新的LINQ or ADO.NET Entity Framework似乎也還是無法擺脫它(NHibernate / Spring 是怎麼弄的我就不清楚了)。

事實上,根據公司資深ASE的前輩的觀察,其實相當少的系統需要做到realtime的two-phase commit,大部分的系統做到near realtime就可以了,或者以Enterprise Application來講,配合DB Server的設定,可以做到高階主管(或者頂級尊爵客戶)看到的系統畫面是真的realtime,其他一般小職員或者普通user看到的系統畫面則是near realtime,delay個1分鐘其實都還不會怎樣的。(不過 ... 效能還是應該無所不用其極的盡量調校才對,效能好也是可以節能減碳的)在near realtime的情況下,可以用暫存table來自己處理two-phase commit,更可以精準的控制retry的機制,把critical的交易通通交給像MSDTC這樣的black box來處理,未必是最明智的作法。

Anyway,短期內還是必須要跟MSDTC這東西相處好一陣子,有空再把之前處理過的更詭異情況寫一下囉~~

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D