Oracle ASMLib: Physical and Logical Blocksize
February 27, 2014 4 Comments
This article is about the use of Advanced Format devices on Oracle’s ASMLib kernel library for Linux. For background, read this page on 4k sector sizes first, otherwise it might all sound like nonsense. Mind you, it mind sound like nonsense anyway, I can’t guarantee anything here. By the way, a big hello to my buddy Nate who asked for this information: you rock, dude.
In more recent versions of ASMLib, Oracle introduced a new parameter into the /etc/sysconfig/oracleasm file:
[root@half-server4 mapper]# tail -5 /etc/sysconfig/oracleasm # ORACLEASM_USE_LOGICAL_BLOCK_SIZE: 'true' means use the logical block size # reported by the underlying disk instead of the physical. The default # is 'false' ORACLEASM_USE_LOGICAL_BLOCK_SIZE=false
To understand what this parameter does, consider this device which I am presenting from a Violin array:
[root@half-server4 ~]# ls -l /dev/mapper/testlun lrwxrwxrwx 1 root root 8 Feb 27 15:33 /dev/mapper/testlun -> ../dm-19 [root@half-server4 ~]# fdisk -l /dev/mapper/testlun Disk /dev/mapper/testlun: 34.4 GB, 34359738368 bytes 255 heads, 63 sectors/track, 4177 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 524288 bytes
The important bit there is highlighted in red. This device has a 4k physical blocksize (as all Violin devices do, as well as many other modern storage systems) but has a 512 byte logical blocksize. Essentially, this LUN is pretending to be a 512 byte based.
Now that’s all well and good. Operating systems and applications that cannot support 4k block sizes (e.g. Red Hat 5 and Oracle Linux 5) will happily use this, because they believe it to be 512 byte. But later versions of ASMLib have started being too clever for their own good.
Don’t Look Behind The Curtain
Let’s create an ASMLib label on this device:
root@half-server4 ~]# oracleasm createdisk TESTLUN /dev/mapper/testlun Writing disk header: done Instantiating disk: done
And now we can attempt to put an ASM diskgroup on it:
SQL> CREATE DISKGROUP TEST EXTERNAL REDUNDANCY DISK 'ORCL:TESTLUN' ATTRIBUTE 'sector_size'='512', 'compatible.asm' = '11.2', 'compatible.rdbms' = '11.2'; CREATE DISKGROUP TEST EXTERNAL REDUNDANCY * ERROR at line 1: ORA-15018: diskgroup cannot be created ORA-15038: disk '' mismatch on 'Sector Size' with target disk group  
What happened? Well, ASMLib has looked behind the smoke and mirrors and decided that this is actually a 4k device. It’s therefore presenting this to Oracle ASM as 4k, which causes the problem (because I explicitly asked for sector size to be 512 byte on this diskgroup).
One possible solution is to change the ASM_DISKSTRING from it’s default value of NULL (meaning ‘ORCL:*’) to ‘/dev/oracleasm/disks/*’, i.e. the location where ASMLib creates its own block devices. We can test this theory with fdisk:
[oracle@half-server4 ~]$ ls -l /dev/oracleasm/disks/TESTLUN brw-rw---- 1 oracle dba 252, 19 Feb 27 15:38 /dev/oracleasm/disks/TESTLUN [oracle@half-server4 ~]$ fdisk -l /dev/oracleasm/disks/TESTLUN | grep "Sector size" Sector size (logical/physical): 512 bytes / 4096 bytes
So that would work. But it would lose many of the claimed benefits of ASMLib such as reduced file descriptors and context switching. Also, it feels like a hack.
The answer, as you probably guessed, is to set this new parameter. It defaults, wrongly in my opinion, to using the physical block size. We can either edit the value in the file to be true in order to use the logical blocksize, or preferably use the oracleasm configure command:
root@half-server4 ~]# oracleasm configure -b Writing Oracle ASM library driver configuration: done [root@half-server4 ~]# oracleasm configure | grep ORACLEASM_USE_LOGICAL_BLOCK_SIZE ORACLEASM_USE_LOGICAL_BLOCK_SIZE="true"
It can be set back to using the physical blocksize with the following command:
[root@half-server4 ~]# oracleasm configure -p Writing Oracle ASM library driver configuration: done [root@half-server4 ~]# oracleasm configure | grep ORACLEASM_USE_LOGICAL_BLOCK_SIZE ORACLEASM_USE_LOGICAL_BLOCK_SIZE="false"
Finally, a word of warning. If you are like me, then you are a bit stupid and can’t follow instructions properly. I set the value of the parameter to TRUE in upper case and then spent hours wondering why it didn’t work. The answer, to my embarrassment, is that it’s case sensitive. TRUE is not a valid value so it defaults to false. Doh.