Pythian Blog: Technical Track

asmcmd> a better "du"

I discovered ASM with a 10.1.0.3 RAC running on Linux Itanium and that was a big adventure. At this time there was no asmcmd. In 2005, Oracle released Oracle 10gR2 and asmcmd came into the place and we figured out how to make it work with a 10gR1 ASM. We were very excited to have a command line for ASM until... we tried it ! let's call a spade a spade, it was very poor... 10 years after, Oracle has released 11gR1, 11gR2, 12cR1, asmcmd has been improved but the "ASM shell" remains very weak and specially the "du" command : [code] ASMCMD> du Used_MB Mirror_used_MB 556178 556178 ASMCMD> du . Used_MB Mirror_used_MB 556178 556178 ASMCMD> du * Used_MB Mirror_used_MB 556265 556265 ASMCMD> ls ASM_CONFIG/ DATA/ FRA/ LOG/ ASMCMD> [/code] Why "du *" does not act as it acts in any Unix shell ? How do I know the size of each subdirectory in my current directory ?   Nowadays, we use to have dozens of instances running on the same server sharing the same ASM : [code] [oracle@higgins ~]$ ps -ef | grep pmon | wc -l 30 [oracle@higgins ~]$ [/code] so should I use one "du" per database (directory) to know the size used by each database ? what if I keep one month of archivelogs in my FRA ? should I wait for the month of February to have only 28 "du" to perform if I want to know the size of archivelogs generated each day (if this is a non-leap year !) ?   This is why I wrote this piece of code to have a "du" under ASM that makes my life easier everyday : [code] [oracle@higgins ~]$ cat asmdu.sh #!/bin/bash # # du of each subdirectory in a directory for ASM # D=$1 if [[ -z $D ]] then echo "Please provide a directory !" exit 1 fi (for DIR in `asmcmd ls ${D}` do echo ${DIR} `asmcmd du ${D}/${DIR} | tail -1` done) | awk -v D="$D" ' BEGIN { printf("\n\t\t%40s\n\n", D " subdirectories size") ; printf("%25s%16s%16s\n", "Subdir", "Used MB", "Mirror MB") ; printf("%25s%16s%16s\n", "------", "-------", "---------") ;} { printf("%25s%16s%16s\n", $1, $2, $3) ; use += $2 ; mir += $3 ; } END { printf("\n\n%25s%16s%16s\n", "------", "-------", "---------"); printf("%25s%16s%16s\n\n", "Total", use, mir) ;} ' [oracle@higgins ~]$[/code]
Let's see it in action with some real life examples :
[code][oracle@higgins ~]$. oraenv ORACLE_SID = [+ASM] ? +ASM The Oracle base remains unchanged with value /oracle [oracle@higgins ~]$./asmdu.sh DATA DATA subdirectories size Subdir Used MB Mirror MB ------ ------- -------- DB01/ 2423 2423 DB02/ 2642 2642 DB03/ 321201 321201 DB04/ 39491 39491 DB05/ 180753 180753 DB06/ 4672 4672 DB07/ 1431 1431 DB08/ 2653 2653 DB09/ 70942 70942 DB10/ 96001 96001 DB11/ 57322 57322 DB12/ 70989 70989 DB13/ 4639 4639 DB14/ 40800 40800 DB15/ 13397 13397 DB16/ 15279 15279 DB17/ 19020 19020 DB18/ 8886 8886 DB19/ 4671 4671 DB20/ 14994 14994 DB21/ 502245 502245 DB22/ 4839 4839 DB23/ 10169 10169 DB24/ 7772 7772 DB25/ 7828 7828 DB26/ 112109 112109 DB27/ 5564 5564 DB28/ 16895 16895 ------ ------- --------- Total 1639627 1639627 [oracle@higgins ~]$ [/code]  
Another one with many archivelogs directories :
[code][oracle@higgins ~]$./asmdu.sh FRA/THE_DB/ARCHIVELOG/ FRA/THE_DB/ARCHIVELOG/ subdirectories size Subdir Used MB Mirror MB ------ ------ --------- 2015_02_19/ 114 114 2015_02_20/ 147 147 2015_02_21/ 112 112 2015_02_22/ 137 137 2015_02_23/ 150 150 2015_02_24/ 126 126 2015_02_25/ 135 135 2015_02_26/ 130 130 2015_02_27/ 129 129 2015_02_28/ 119 119 2015_03_01/ 146 146 2015_03_02/ 150 150 2015_03_03/ 128 128 2015_03_04/ 134 134 2015_03_05/ 44 44 2015_05_27/ 28 28 2015_05_28/ 95 95 2015_05_29/ 76 76 2015_05_30/ 187 187 2015_05_31/ 78 78 2015_06_01/ 111 111 2015_06_02/ 105 105 2015_06_03/ 43 43 2015_06_04/ 142 142 2015_06_05/ 42 42 2015_06_06/ 84 84 2015_06_07/ 70 70 2015_06_08/ 134 134 2015_06_09/ 77 77 2015_06_10/ 143 143 2015_06_11/ 2 2 2015_06_21/ 14 14 2015_06_22/ 14918 14918 ------ ------- --------- Total 18250 18250 [oracle@higgins ~]$ [/code] This example is a very nice one as it shows us that 2015 is not a leap year and that some archivelogs are still on disk even if they probably shouldn't and that's a good information as v$log_history do not contain these information anymore : [code] SQL> select trunc(FIRST_TIME), count(*) from v$log_history group by trunc(FIRST_TIME) order by 1 ; TRUNC(FIR COUNT(*) --------- ---------- 22-JUN-15 402 SQL> [/code] Hope it will also makes your life easier, Have a good day :)

No Comments Yet

Let us know what you think

Subscribe by email