Windows systems write blocks of data to underlying storage – the size of these blocks is given various terms, for example –
- Block size
- Allocation unit
- Cluster size
The important thing to consider is that this unit of allocation can have an impact on the performance of systems. By default Windows will format a disk with a standard 4KB block size. Microsoft Exchange server for example, recommends the unit size be 64KB. Microsoft recommend this for SQL server and virtual machines as well. By not setting the value correctly on an underlying disk we can generate performance problems for our system. Aligning block size with the data set being written can help to ensure efficient IO processing. If we consider SQL server which uses a 64KB extent (which is it’s basic unit, made up of eight, 8KB pages) we can most effectively format the disk with a 64KB block size. Assuming this is a locally attached disk we can then have Windows write the extent as one contiguous block rather than having to split it up into say 4KB default sized blocks. Imagine taking that 64KB extent and having to split that single IO into 16 smaller IO writes – not very efficient.
If we are writing to SAN storage we also want to make sure the block size (or whatever the vendor calls it) is also appropriate, again to try and avoid split IO writes and to ensure performance. It’s a big topic to discuss but I will end here and move on to how we can retrieve this information from our servers.
PowerShell Commands
Microsoft are deprecating the Get-wmiObject cmdlet in favour of the Get-cimInstance cmdlet. I have provided both as a reference in case you are doing this on older systems. Note that the value is described as ‘BlockSize’.
PS C:\> Get-WmiObject -Class Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize
PS C:\> Get-CimInstance -ClassName Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize
Example output –
PS C:\> Get-CimInstance -ClassName Win32_Volume | Select-Object Label, BlockSize | Format-Table -AutoSize Label BlockSize ----- --------- 4096 bsa_sqlinfra01_db_vv 4096 bsa_sqlinfra01_logs_vv 4096 bsa_sqlsp_db_vv 65536 bsa_sqlsp_logs_vv 65536 Recovery 4096
DOS Commands
We can make use of the fsutil amd DiskPart commands. Note that in fsutil the value is ‘Byte Per Cluster’ with a 64KB value while in DiskPart it is called ‘Allocation Unit Size’.
PS C:\> fsutil fsinfo ntfsinfo p: NTFS Volume Serial Number : 0x5840d42e40d4151a NTFS Version : 3.1 LFS Version : 2.0 Number Sectors : 0x000000007ffbefff Total Clusters : 0x0000000000fff7df Free Clusters : 0x0000000000459424 Total Reserved : 0x0000000000000000 Bytes Per Sector : 512 Bytes Per Physical Sector : 512 Bytes Per Cluster : 65536 Bytes Per FileRecord Segment : 1024 Clusters Per FileRecord Segment : 0 Mft Valid Data Length : 0x000000000e840000 Mft Start Lcn : 0x000000000000c000 Mft2 Start Lcn : 0x0000000000000001 Mft Zone Start : 0x0000000000cf4180 Mft Zone End : 0x0000000000cf4c80 Resource Manager Identifier : 0C567257-18F9-11E5-80CE-00155DAEB03C
I will use the DiskPart utility to list all of the volumes attached to this server, then I will select a volume and use the ‘filesystems’ command to display the required information. As mentioned the value is now described as ‘Allocation Unit Size’.
DISKPART> list vol Volume ### Ltr Label Fs Type Size Status Info ---------- --- ----------- ----- ---------- ------- --------- -------- Volume 0 C NTFS Partition 59 GB Healthy Boot Volume 1 Recovery NTFS Partition 300 MB Healthy Hidden Volume 2 FAT32 Partition 99 MB Healthy System Volume 3 P bsa_sqlsp_d NTFS Partition 1023 GB Healthy Volume 4 Q bsa_sqlsp_l NTFS Partition 199 GB Healthy Volume 5 F bsa_sqlinfr NTFS Partition 499 GB Healthy Volume 6 G bsa_sqlinfr NTFS Partition 199 GB Healthy DISKPART> select vol 3 Volume 3 is the selected volume. DISKPART> filesystems Current File System Type : NTFS Allocation Unit Size : 64K Flags : 00000000 File Systems Supported for Formatting Type : NTFS (Default) Allocation Unit Sizes: 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K (Default) Type : REFS Allocation Unit Sizes: 64K (Default) DISKPART>
As you can see Microsoft lack consistency in describing this attribute which is rather frustrating but such is the way of the IT world. It’s always important to check that you are formatting storage with the correct block size to avoid split IO and misalignment issues. I have seen some vendors (especially all flash array sellers) telling administrators not to worry because their system is ‘so fast’ any overhead or inefficiencies caused can be compensated for by the systems speed. Personally I hate this notion and fully believe everything should be optimised and deployed according to best practices to get the most out of the system.