2016年1月21日 星期四

電腦主機或虛擬機無法啟動進入作業系統時,如何進行問題排除。

        一般當主機無法啟動時,我們會進行二種簡單的判斷,確認當下是否可以進入作業系統,如果可以進的話,基本上我們會有比較多的方式可以進行處理,但如果遇到無法進入Windows時,除非是硬體問題,進行更換後可能可以進入,否則你也沒有相關的Log可以得知資訊,通常往往只能透過重灌的方式進行解決,本篇提出幾個不同的作法,如Registry Hive、RegBack等觀念與方法,希望可以進一步的進行處理,或許可以讓你的主機恢復生機。

PS:在無法進入作業系統時,其實你還是可以透過Live Kernel-Mode Debugging來進行處理,但可惜就算連結成功了,但如果沒有熟悉底層作業系統的運作,你可能還是無法查出問題為何,所以本篇也不詳加說明,關於設定的詳細說明可以參考下列的網址。

Live Kernel-Mode Debugging Using WinDbg
https://msdn.microsoft.com/en-us/library/windows/hardware/hh451166(v=vs.85).aspx
How to Setup a Live Debug Using Physical Machines
http://blogs.technet.com/b/askcore/archive/2013/07/08/how-to-setup-a-live-debug-using-physical-machines.aspx

一開始我們先簡單的說明一下Registry Hive是什麼,如同底下的截取說明,你可以把他當作一個儲存登錄檔資訊的檔案結構,其實簡單的說也就是登錄檔存放的位置,當問題發生時,我們可以嘗試從登錄檔中找出可能的問題點,另外也可以嘗試進行登錄檔的手動還原。

A hive is a logical group of keys, subkeys, and values in the registry that has a set of supporting files containing backups of its data.

Registry Hives
https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms724877(v=vs.85).aspx


另外通常如果電腦有問題時,我們也通常會先參考Windows中的事件檢示器看系統到底發生了什麼事,但是當系統無法正常開機時,通常也無從下手,所以下列我們就來看如何進行處理。

當電腦無法進入作業系統時,我們可以嘗試進行下列的動作。

a. 透過Live Kernel-Mode Debugging,但是難度太高,跳過。
b. 透過登錄檔修復還原與事件檢示器進行問題排除。


問題排除:

1、掛載虛擬機至本機磁碟
其實當作業系統無法進入時,如果是實體機,我們可以將硬碟取下,然後裝到另一台主機上確認問題,如果是虛擬機的話,也很簡單,只需將硬碟掛上Host主機上即可進一步處理,下列我們就以虛擬機掛載的方式進行

掛載VM Disk至本機磁碟上(掛載前請確認為關機的狀態)。

點選 Administrative Tools -> Computer Management -> Attach VHD。

選擇你要掛載的VHD。

掛載完成後,即可以透過檔案的方式進行存取。

2、下載雲端虛擬機磁碟至本機
另外這個方法也可以同樣的運用在雲端系統上,以Azure為例,我們可以透過下列的方式將VHD檔從雲端下載到本地端進行。

先確認VM放在那一個儲存體上,點選虛擬機器(傳統) -> 磁碟 -> 選擇你要磁碟 -> VHD位置

選擇目的儲存體帳戶

進入目的儲存體後即可找到你的VHD的檔案,然後再點選下載即可。


3、檢查問題磁碟上的事件檢示器
預設事件檢示器上有二個常進行確認的事件,對應到的登錄檔分別為:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System

對應到的實際路徑位址:
%SystemRoot%\system32\winevt\Logs\Application.evtx
%SystemRoot%\system32\winevt\Logs\System.evtx

How to move Event Viewer log files to another location in Windows 2000 and in Windows Server 2003
https://support.microsoft.com/en-us/kb/315417

4、還原備份的登錄檔
在很多的情況下,可能是由於使用者安裝了軟體或登錄檔毀損所造成,但通常的情況下只能嘗試從之前的還原點或是透過系統進行自動修復,所以我們來介紹一個內建自動進行備份登錄的方機制。

Registry Marriage
http://blogs.technet.com/b/mrsnrub/archive/2010/03/01/registry-marriage.aspx

在預設的情況下,系統會自動進行備份,名稱為RegBack,不同的作業系統有不同的備份行為,如在Windows 2003是在你進行ntbackup時進行,如果是Windows 2008/Vista則是每12個小時進行一次,到了Windows 2008 R2/Windows 7則是每10天進行一次,所以當有問題發生其實我們是可以透過此機制進行手動還原。

路徑位址:
C:\Windows\System32\config\RegBack

工作排程器資訊:

手動還原登錄檔程序:
a. 手動備份C:\Windows\System32\config下的所有檔案
b. 將所有C:\Windows\System32\config\RegBack底下的檔案還原到C:\Windows\System32\config的目錄下。

5、手動掛載Registry Hive到本機登錄檔上:
5-1 開啟regedit.exe -> 請先點選一個根節點(HKLM為例) -> File -> Load Hive,然後選擇已掛載磁碟上的登錄檔。

掛載磁碟:Disk M
掛載位址:M:\Windows\System32\config


5-2 輸入掛載後的暫時名稱。

5-3 完成後,你就可以看到在選擇的根目錄上即有一個暫時新增的登錄節點。


關鍵字:Registry Hiveunable to start vm instance

2016年1月10日 星期日

如何在AlwaysOn建立Partition Table與自動進行資料平均分配

自從SQL Server 2005,本身就有加入Partition Table的功能,也就是可以將一個資料表的資料分散到其他的磁碟上,藉以加快讀寫速度,但可惜的事,由於SQL Server只有支援Range Partition的功能,也就是將特定資料範圍的部份放在特定的磁上,但使用起來感覺還像只有封存的作用,而且特定時間後就要再進行一次封存,不像Oracle本身就有支援四種分割的方法好用,所以為了解決這個問題我整理了這篇分享出來,也希望大家可以參考。

另外說明我的測試是在AlwaysOn上的主要節點進行的,其實在AlwaysOn上只需特別注意在建立Data File時的路徑每一個節點都需要相同,其他的部份與在單機上進行皆相同


1、加入Data File and File Group
在建立上由於我的主要是四核心,所以我就建立四個File Group,而其中各File Group也各自有一個Data File。

PS:如需進一步了解核心數與Data File的關係,可以參考我的另一篇文章。
SQL Server 儲存設備 (Storage) 最佳調整作業
http://caryhsu.blogspot.tw/2011/02/sql-server-io.html

1-1 建立的方式可以透過GUI進行設定,或是透過T-SQL進行。



1-2 透過T-SQL進行
USE [master]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILEGROUP [ag_group_1]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILEGROUP [ag_group_2]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILEGROUP [ag_group_3]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILEGROUP [ag_group_4]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILE ( NAME = N'fg_1', FILENAME = N'C:\sql_data\fg_1.ndf' , SIZE = 51200KB , FILEGROWTH = 1024KB ) TO FILEGROUP [ag_group_1]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILE ( NAME = N'fg_2', FILENAME = N'C:\sql_data\fg_2.ndf' , SIZE = 51200KB , FILEGROWTH = 1024KB ) TO FILEGROUP [ag_group_2]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILE ( NAME = N'fg_3', FILENAME = N'C:\sql_data\fg_3.ndf' , SIZE = 51200KB , FILEGROWTH = 1024KB ) TO FILEGROUP [ag_group_3]
GO
ALTER DATABASE [AdventureWorks2012] ADD FILE ( NAME = N'fg_4', FILENAME = N'C:\sql_data\fg_4.ndf' , SIZE = 51200KB , FILEGROWTH = 1024KB ) TO FILEGROUP [ag_group_4]
GO

2、加入平均計算函數
前面有說過,由於Partition Table目前只有Range Partition,所以內建的方法並無法達到平均分配,所以我在這邊提供了一個方式,就是在表格中加入一個實體的計算欄位(Persisted),然後透過此欄位來進行分配。

因為我是透過 AdventureWorks2012 中的TransactionHistory進行,而因為此表是透過流水號當主鍵,所以我就以此TransactionID當成計算參數之一,設定如下。


PS:
a. 當然如果沒有流水號可以選擇的話,你也可以透過 row_number 的參數進行。
b. 上述的計算欄位的(Is Persisted)一定要是Yes,否則會發生下列的錯誤。

Msg 7724, Level 16, State 1, Line 23
Computed column cannot be used as a partition key if it is not persisted. Partition key column 'pf_val' in table 'Production.TransactionHistory' is not persisted.

3、建立Partition Table
3-1 選擇要建立的Table Name -> Storage -> Create Partition


3-2 下一步

3-3 選擇要進行分配的欄位參考,我們這裡以新增的計算欄位進行。

3-4 設定Partition Function名稱

3-5 設定Partition Scheme名稱

3-6 這一頁要特別注意不要被騙了,這個部份我作了好多次,雖然你看到第一欄只有分配到一筆,但是做完後即可完平均分配。

另外最後一列由於雖然我們會分成四個區塊,但由於系統設計因素,所以必須提供另外一個區塊存放(但不會有資料),所以我們就選預設的File Group。

3-7 選擇立即執行

3-8 點選完成

3-9 執行完成

3-10 執行完成後,我們可以透過DMV來查平均分配的結果,如下所示,的確如我們預期進行,後續上的資料新增後也會依照我們的規劃循序放置,這樣一來就不需要固定時間後又進行一次調整,建議大家可以參考看看。

執行語法:
--查詢所有Partition Table資訊
select     object_schema_name(i.object_id) as [schema],  
object_name(i.object_id) as [object_name],    t.name as [table_name],  
i.name as [index_name],    s.name as [partition_scheme]
from sys.indexes i    join sys.partition_schemes s on
i.data_space_id = s.data_space_id    join sys.tables t on
i.object_id = t.object_id

--查詢特定Partition Table的分配情況
SELECT
OBJECT_Name(object_id),
row_count,
(used_page_count * 8.0 / 1024) usedMB
FROM sys.dm_db_partition_stats
where OBJECT_Name(object_id) = 'TransactionHistory'
and index_id = 0



參考連結:
Computed Columns
https://technet.microsoft.com/en-us/library/ms191250(v=sql.105).aspx
Partitioning
https://technet.microsoft.com/en-us/library/ms178148(v=sql.105).aspx
Partitioned Tables and Indexes
https://docs.oracle.com/html/A96524_01/c12parti.htm


關鍵字:Partitioning MethodsHash PartitioningRange PartitioningPartition Table資料分割

2016年1月7日 星期四

Windows上不同Block Size的效能測試 - 以AWS EC2為例

在我之前的文章中有特別介紹到透過SQLIO來進行磁碟機在不同Block Size的存取效能,但很可惜的是,此軟體目前已無法使用,但取而帶之的是另一個新的軟體,名稱為DiskSpd,但其實二者在使用上的方法非常的接近,我在下列整理使用的方法。

測試環境:
Amazon EC2
Instance Types - m4.xlarge

參考連結:
DiskSpd: http://aka.ms/diskspd
EC2 Instance Types: https://aws.amazon.com/tw/ec2/instance-types/

先前文章介紹:
SQL Server IO 測試工具 - SQLIO的使用與不同Block Size下的效能測試


參數說明:
-b  -> Block Size
-d  -> 測試時間(秒)
-t   -> 模擬的執行緒數量
-o  -> overlapped IOs
-L -> 關閉所有硬體或軟體式快取
-c  -> 產生檔案

執行範例:
diskspd.exe -b4k -d60 -t4 -o8 -L -r -w40 -c100m test_io_4k.dat

下列我分別針對4、16、32、64、128、256等不同的Block Size進行測試,數據如下,可以看出其實在Block Size越高的情況,其實是會有助於IO的傳輸。


另外一提在SQL Server上,由於Data File與Log File的磁碟在建議上也是擺放在較大的Block Size上也會有較佳的效能,但文中有提到,在許多的情況可能32K會是較佳的選擇,建議大家可以在設計規劃前可以再進行測試,藉以確認情況。

截取文字:
An appropriate value for most installations should be 65,536 bytes (that is, 64 KB) for partitions on which SQL Server data or log files reside. In many cases, this is the same size for Analysis Services data or log files, but there are times where 32 KB provides better performance. To determine the right size, you will need to do performance testing with your workload comparing the two different block sizes.

Disk Partition Alignment Best Practices for SQL ServerDisk Partition Alignment Best Practices for SQL Server
https://technet.microsoft.com/en-us/library/dd758814(v=sql.100).aspx


輸出範例:
Command Line: diskspd -b64k -d60 -t4 -o8 -L -r -w40 -c100m -c100m test_io_64k.dat

Input parameters:

timespan:   1
-------------
duration: 60s
warm up time: 5s
cool down time: 0s
measuring latency
random seed: 0
path: 'test_io_64k.dat'
think time: 0ms
burst size: 0
using software and hardware write cache
performing mix test (write/read ratio: 40/100)
block size: 65536
using random I/O (alignment: 65536)
number of outstanding I/O operations: 8
thread stride size: 0
threads per file: 4
using I/O Completion Ports
IO priority: normal

Results for timespan 1:
*******************************************************************************

actual test time: 60.00s
thread count: 4
proc count: 4

CPU |  Usage |  User  |  Kernel |  Idle
-------------------------------------------
   0|  97.84%|   2.66%|   95.18%|   2.16%
   1|  98.10%|   5.34%|   92.76%|   1.90%
   2|  97.42%|   3.93%|   93.49%|   2.58%
   3|  98.23%|   5.13%|   93.10%|   1.77%
-------------------------------------------
avg.|  97.90%|   4.26%|   93.63%|   2.10%

Total IO
thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |  file
-----------------------------------------------------------------------------------------------------
     0 |     56763678720 |       866145 |     902.23 |   14435.69 |    0.484 |     0.983 | test_io_64k.dat (100MB)
     1 |     60673949696 |       925811 |     964.38 |   15430.12 |    0.453 |     0.988 | test_io_64k.dat (100MB)
     2 |     60541894656 |       923796 |     962.28 |   15396.54 |    0.454 |     0.937 | test_io_64k.dat (100MB)
     3 |     61227008000 |       934250 |     973.17 |   15570.77 |    0.449 |     0.952 | test_io_64k.dat (100MB)
-----------------------------------------------------------------------------------------------------
total:      239206531072 |      3650002 |    3802.07 |   60833.13 |    0.459 |     0.965

Read IO
thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |  file
-----------------------------------------------------------------------------------------------------
     0 |     34065874944 |       519804 |     541.46 |    8663.37 |    0.469 |     1.076 | test_io_64k.dat (100MB)
     1 |     36373069824 |       555009 |     578.13 |    9250.11 |    0.438 |     0.995 | test_io_64k.dat (100MB)
     2 |     36226596864 |       552774 |     575.80 |    9212.86 |    0.439 |     0.993 | test_io_64k.dat (100MB)
     3 |     36731944960 |       560485 |     583.84 |    9341.38 |    0.434 |     0.958 | test_io_64k.dat (100MB)
-----------------------------------------------------------------------------------------------------
total:      143397486592 |      2188072 |    2279.23 |   36467.72 |    0.445 |     1.005

Write IO
thread |       bytes     |     I/Os     |     MB/s   |  I/O per s |  AvgLat  | LatStdDev |  file
-----------------------------------------------------------------------------------------------------
     0 |     22697803776 |       346341 |     360.77 |    5772.33 |    0.507 |     0.823 | test_io_64k.dat (100MB)
     1 |     24300879872 |       370802 |     386.25 |    6180.01 |    0.475 |     0.977 | test_io_64k.dat (100MB)
     2 |     24315297792 |       371022 |     386.48 |    6183.68 |    0.475 |     0.845 | test_io_64k.dat (100MB)
     3 |     24495063040 |       373765 |     389.34 |    6229.39 |    0.470 |     0.942 | test_io_64k.dat (100MB)
-----------------------------------------------------------------------------------------------------
total:       95809044480 |      1461930 |    1522.84 |   24365.40 |    0.481 |     0.901


  %-ile |  Read (ms) | Write (ms) | Total (ms)
----------------------------------------------
    min |      0.129 |      0.131 |      0.129
   25th |      0.326 |      0.358 |      0.338
   50th |      0.395 |      0.431 |      0.409
   75th |      0.482 |      0.522 |      0.499
   90th |      0.587 |      0.632 |      0.607
   95th |      0.676 |      0.728 |      0.699
   99th |      1.114 |      1.211 |      1.155
3-nines |      5.509 |      5.694 |      5.579
4-nines |     21.156 |     21.259 |     21.195
5-nines |    165.139 |    165.020 |    165.061
6-nines |    268.805 |    259.394 |    259.702
7-nines |    271.001 |    259.702 |    271.001
8-nines |    271.001 |    259.702 |    271.001
    max |    271.001 |    259.702 |    271.001


關鍵字:DiskSpdBlock SizeIOPS