By William Sescu
User and group quotas do exist for quite a while for all kind of file systems, like ext4 or vxfs and maybe many others.
However, for my use case, I do need quotas for different directories on the same file system. My mount point is /u01 and in that file system, I do have different Oracle Homes which belong to the same user, oracle. However, I do not want that my 11.2.0.4 Oracle Home influences my 12.1.0.2 Oracle Home in respect of file system usage. e.g. if the 11.2.0.4 home is core dumping, it should not fill up the space of the 12.1.0.2 home, and the other way around. But how can I do that?
The idea is to create XFS project quotas, and this is how it works.
First of all, we need to enable project quotas on the XFS file system. /u01 is currently mounted with XFS default options, which are (rw,relatime,attr2,inode64,noquota). As you can see, the default is “noquota”.
[root@dbidg01 ~]# mount | grep u01 /dev/mapper/vg_ora_u01-lv_ora_u01 on /u01 type xfs (rw,relatime,attr2,inode64,noquota)
We can enable project quotas by adding the “prjquota” mount option to the /etc/fstab and afterwards remounting the file system.
[root@dbidg01 ~]# mount | grep u01 /dev/mapper/vg_ora_u01-lv_ora_u01 on /u01 type xfs (rw,relatime,attr2,inode64,noquota)
Unfortunately, the remount option does not work with the XFS filesystem. Meaning, I can remount the file system, but my new option “prjquota” is not reflected.
[root@dbidg01 ~]# mount -o remount,rw,relatime,attr2,inode64,prjquota /u01 [root@dbidg01 ~]# mount | grep u01 /dev/mapper/vg_ora_u01-lv_ora_u01 on /u01 type xfs (rw,relatime,attr2,inode64,noquota)
So I have to do a umount, mount. Not a good thing from my point of view, because it means that I cannot enable project quotas online for my /u01 directory, where I have different Oracle homes located. In other words, I need to shutdown all Oracle databases.
[root@dbidg01 ~]# umount /u01 [root@dbidg01 ~]# mount /u01 [root@dbidg01 ~]# mount | grep u01 /dev/mapper/vg_ora_u01-lv_ora_u01 on /u01 type xfs (rw,relatime,attr2,inode64,prjquota)
Ok. Now it looks better. The next step is to define unique project id’s for the different directory hierarchies in the /etc/projects file.
For example, to set a project ID of 11 for the directory hierarchy /u01/app/oracle/product/11.2.0, and the project ID of 12 for the directory hierarchy /u01/app/oracle/product/12.1.0 we can do the following.
# echo "11:/u01/app/oracle/product/11.2.0" >> /etc/projects # echo "12:/u01/app/oracle/product/12.1.0" >> /etc/projects [root@dbidg01 ~]# cat /etc/projects 11:/u01/app/oracle/product/11.2.0 12:/u01/app/oracle/product/12.1.0
If you don’t want to work with ID’s, you have the possibility to map project names to the project ID’s in your /etc/projid file. It is much easier in regards of reporting quota usage, which we will see later.
For example, to map the project name oracle11gR2 to the project with ID 11 or to map the project name oracle12cR1 to 12 do the following.
# echo "oracle11gR2:11" >> /etc/projid # echo "oracle12cR1:12" >> /etc/projid
Now use the project subcommand of xfs_quota to define a managed tree in the XFS file system for the different projects.
For example, to define a managed tree in the /u01 file system for the project oracle11gR2, which corresponds to the directory hierarchy /u01/app/oracle/product/11.2.0, do the following.
# xfs_quota -x -c 'project -s oracle11gR2' /u01 [root@dbidg01 etc]# xfs_quota -x -c 'project -s oracle11gR2' /u01 Setting up project oracle11gR2 (path /u01/app/oracle/product/11.2.0)... xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/bin/lbuilder xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/jdk/jre/lib/amd64/server/libjsig.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/libagtsh.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/libodm11.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/libclntsh.so.10.1 xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/libocci.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/libclntsh.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/liborasdk.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/lib/liborasdkbase.so xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/sqlnet.ora xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/tnsnames.ora xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/ldap.ora xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/precomp/public/SQLCA.H xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/precomp/public/ORACA.H xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/precomp/public/SQLDA.H xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/precomp/public/SQLCA.COB xfs_quota: skipping special file /u01/app/oracle/product/11.2.0/dbhome_1/precomp/public/ORACA.COB Processed 1 (/etc/projects and cmdline) paths for project oracle11gR2 with recursion depth infinite (-1).
The same applies to project oracle12cR1.
# xfs_quota -x -c 'project -s oracle12cR1' /u01 [root@dbidg01 etc]# xfs_quota -x -c 'project -s oracle12cR1' /u01 Setting up project oracle12cR1 (path /u01/app/oracle/product/12.1.0)... xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/bin/lbuilder xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/admin/classes.bin xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/admin/cbp.jar xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/admin/libjtcjt.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/security/US_export_policy.jar xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/security/cacerts xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/security/java.security xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/security/local_policy.jar xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/jce.jar xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/javavm/lib/sunjce_provider.jar xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/jdk/bin/ControlPanel xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/jdk/jre/bin/ControlPanel xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/jdk/jre/javaws/javaws xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/jdk/jre/lib/amd64/server/libjsig.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libagtsh.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libjavavm12.a xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libodm12.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libocci.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libclntshcore.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.10.1 xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.11.1 xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/listener.ora xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/sqlnet.ora xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/ldap.ora xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/tnsnames.ora xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/precomp/public/SQLCA.H xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/precomp/public/ORACA.H xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/precomp/public/SQLDA.H xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/precomp/public/SQLCA.COB xfs_quota: skipping special file /u01/app/oracle/product/12.1.0/dbhome_1/precomp/public/ORACA.COB Processed 1 (/etc/projects and cmdline) paths for project oracle12cR1 with recursion depth infinite (-1).
Now the fun part begins, and we can start using the limit subcommand to set the limits on the disk usage for the different projects. My 11.2.0.4 Oracle home is currently 5.7G in size, and the 12.1.0.2 Oracle home is 7.1G big. I want to configure for the 11g home a soft limit of 8G and a hard limit of 12G, and for the 12c home a soft limit of 10G and a hard limit of 16G.
oracle@dbidg01:/u01/app/oracle/product/ [rdbms112] du -hs 11.2.0 5.7G 11.2.0 oracle@dbidg01:/u01/app/oracle/product/ [rdbms112] du -hs 12.1.0 7.1G 12.1.0 # xfs_quota -x -c 'limit -p bsoft=8g bhard=12g oracle11gR2' /u01 # xfs_quota -x -c 'limit -p bsoft=10g bhard=16g oracle12cR1' /u01 [root@dbidg01 ~]# xfs_quota -x -c 'report -p' /u01 Project quota on /u01 (/dev/mapper/vg_ora_u01-lv_ora_u01) Blocks Project ID Used Soft Hard Warn/Grace ---------- -------------------------------------------------- #0 8776636 0 0 00 [--------] oracle11gR2 5883604 8388608 12582912 00 [--------] oracle12cR1 7415292 10485760 16777216 00 [--------] [root@dbidg01 ~]# xfs_quota -x -c 'report -h -p' /u01 Project quota on /u01 (/dev/mapper/vg_ora_u01-lv_ora_u01) Blocks Project ID Used Soft Hard Warn/Grace ---------- --------------------------------- #0 8.4G 0 0 00 [------] oracle11gR2 5.6G 8G 12G 00 [------] oracle12cR1 7.1G 10G 16G 00 [------]
The quotas are immediately seen by the df command. The df on the /u01 shows the full filesystem size, which is 50G, however, if I navigate to my 11g or 12c home, I see the soft limit which I have configured beforehand.
[root@dbidg01 product]# df -h /u01 Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_ora_u01-lv_ora_u01 50G 22G 29G 43% /u01 [root@dbidg01 ~]# cd /u01/app/oracle/product/11.2.0 [root@dbidg01 11.2.0]# df -h . Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_ora_u01-lv_ora_u01 8.0G 5.7G 2.4G 71% /u01 [root@dbidg01 ~]# cd /u01/app/oracle/product/12.1.0 [root@dbidg01 12.1.0]# df -h . Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_ora_u01-lv_ora_u01 10G 7.1G 3.0G 71% /u01
Conclusion
The project quotas with XFS are a quite cool feature. Limiting file system usage per projects gives you a huge flexibility. Setting quotas on individual Oracle homes is one thing, but you could also limit filesystem usage for your Oracle databases in the DIAG directory based on ORACLE_SID, so that /u01/app/oracle/diag/rdbms/<SID1> can never fill up /u01/app/oracle/diag/rdbms/<SID2>. The only drawback I see, is that enabling project quotas is not an online operation. You need to umount and mount the file system to activate this feature.
Have fun with XFS quotas.
Cheers,
William