Category Archives: Rittman Mead

Becky’s BI Apps Corner: Installing on Windows Server 2012

Recently I was installing Oracle BI Apps on a VM for a custom training, as mentioned in a previous post. I setup the VM with Windows Server 2012 after verifying in the certification matrix that the Oracle BI Apps version (11.1.1.9.2) was certified to run on Windows Server 2012.

As I was going along, I was getting errors during some of the installs on the pre-requisite checks for the operating system (OS), as can be the case when the OS gets certified after the initial release of that version of software. The workaround is available for that error in MOS Doc ID 1577652.1, and involves adding the OS to an .xml file… Okay, I admit it. I didn’t actually update the .xml file. I just clicked Continue past the pre-requisite check. Since there didn’t seem to be any repercussions and the installs completed successfully, I continued on my merry way through the installation instructions.

When I was running OBIEE’s configuration (config.bat), it failed at 35% on the step Setting Up BI Publisher. The install_DATE_TIME.log file didn’t have enough information, so I dug into the install_DATE_TIME.out file. In it, there was the following error:

updateBIPConfigFiles: OSError: (0, 'Failed to execute command (['sh', '-c', 'java -classpath C:\\Oracle\\Product\\BI_11.1\\Oracle_BI1\\clients\\bipublisher\\xdo-server.jar oracle.xdo.install.UpdateConfigFiles 9704 9703 9710 jdbc/mds/owsm C:\\Oracle\\Product\\BI_11.1\\user_projects\\domains\\bifoundation_domain']): java.io.IOException: Cannot run program "sh": CreateProcess error=2, The system cannot find the file specified')

I left the config.bat open (It only takes one time to learn not to cancel during the config.bat or configApps.bat) and I took a trip over to my friendly neighborhood support.oracle.com where I found MOS Doc ID 1580583.1. Essentially, it says to dig into and update a Jar file, and then directs you to Oracle’s Java Tutorials to learn how. I decided to do just that and post the steps here.

Forays into Java

The MOS doc says I need to update a file called javashell.py by adding the string “Windows Server 2012” to the list of os.names. This javashell.py file is archived inside a jar file located: commonwlstmodulesjython-modules.jar.

A jar file is simply a package of a bunch of files. To view content of a jar file, the command is:
jar tf jar-file

In my command window, I navigated to the folder where the jython-modules.jar was. For this particular jar, the number of files was bigger than my command window would show, so I sent it to a text file.

The command I used was:

C:appproductfmwwlserver_10.3commonwlstmodules>c:javajdk1.7.0_85binjar
tf jython-modules.jar >log.txt

In the jython-modules.jar, there was a Libjavashell.py. Now that I found my file, I needed to extract the file from the jar. To do that, the command is:
jar xf jar-file [archived-file(s)]

Since I was still in the same directory, I used the following command:

C:appproductfmwwlserver_10.3commonwlstmodules>c:javajdk1.7.0_85binjar
xf jython-modules.jar Lib/javashell.py

The file is now extracted and can be edited. I opened the javashell.py file in Notepad++. You can open/edit it in your editor of choice. Not too far into the python script, I found the os.name and the list of other operating systems. I’m not particularly skilled in python, but the change seemed pretty straight forward. As you can see from the screenshot, I just added a comma, and the ‘Windows Server 2012’ at the end of the “nt” operating systems. I am certain this would work for other operating systems added to the certification matrix after the software was released.

Once I’ve saved my changes, I need to get this javashell.py file back into the python-modules.jar.

The command to update a file inside of a jar is:
jar uf jar-file input-file(s)

I used:

C:appproductfmwwlserver_10.3commonwlstmodules>c:javajdk1.7.0_85binjar
uf jython-modules.jar Lib/javashell.py

With everything in order, I went back to the config.bat window, which was still running. I scrolled to the top, checked the box next to the first line, clicked Retry.

The install completed without any further errors! We got to play with Java Jar files and a python script to resolve an error with the config.bat installer. These steps will allow you to update for any OS, which can come in handy for any that are certified after the initial release of a version of software. Let me know in the comments all the different Operating Systems where you have installed BI Apps. So far, I’ve installed on RHEL 5 and 6, Solaris 10, Windows Server 2008, and Windows Server 2012, each with interesting little quirks. Also, if you have training needs, check out our new trainings for 2016, and contact us! And of course, keep an eye out for more Becky’s BI Apps Corner coming soon.

The post Becky’s BI Apps Corner: Installing on Windows Server 2012 appeared first on Rittman Mead Consulting.

Kickstart Your 2016 with Rittman Mead’s Data Integration Training

Happy Holidays and a Happy New Year to all! As you begin your 2016 this January, it’s time to start planning your team’s data integration training. Look no further than Rittman Mead’s Oracle Data Integrator training course! We offer a 4 day Oracle Data Integrator 12c Bootcamp for those looking to take advantage of the latest and greatest features in ODI 12c. We also still teach our 5 day Oracle Data Integrator 11g Bootcamp, as we know sometimes it can be difficult to upgrade to the latest release and new data warehouse team members need to be brought up to speed on the product. ODI 11g is also still very much alive in Oracle Business Intelligence Applications, being the ETL technology for the 11g release of the product suite.

ODI12c training

Customized Data Integration Training

BI Apps 11g training has been a hot topic from the data integration perspective over the last couple of years. Rittman Mead have delivered custom BI Apps training for ODI developers several times just within the last year, prompting us to add a new public training course specific to this topic to our public schedule. This course walks attendees through the unique relationship between OBIEE and ODI 11g as the data integration technology, including configuration, load plan generation, and ETL customization. If you have an Oracle Business Intelligence Applications 11g team looking to enhance their ODI 11g skills, take a look at the new ODI for BI Applications course description.

The customization of training does not just apply to BI Applications, but to all aspects of Oracle Data Integration. Whether adding more details around Oracle GoldenGate installation and maintenance to the ODI 12c course, or learning about Oracle EDQ integration, the Rittman Mead data integration team of experts can work to deliver the course so your team gains the most value from its investment in Oracle Data Integration technologies. Just ask! Reach out and we can work together to create a custom course to fit your needs.

Public or Onsite Training?

Rittman Mead has several dates for each course, scheduled to be delivered out of our offices in either Atlanta, GA or Brighton, UK. Take a look here for our ODI 12c bootcamp, ODI 11g bootcamp, and ODI for BI Apps Developers offerings in the US. Look here for the same in the UK/Europe (Note: as of the writing of this blog post, the 2016 UK/Europe schedule had not been released). We also offer the same courses for delivery onsite at your company’s office, allowing our experts to come to you! Quite often our clients will combine consulting and training, ensuring they get the most out of their investment in our team of experts.

Why Rittman Mead?

Many folks in the Business Intelligence and Data Integration profession who are looking for a consulting company might think Rittman Mead only work on extremely challenging projects based on the depth of knowledge and type of problems (and solutions) we offer via our blog. The fact is, most of our projects are the “standard” data warehouse or business intelligence reporting implementations, with some of these additional challenges coming along the way. Why do I bring that up? Well, if you’re looking for the experts in Oracle Data Integration technology, with experience in both project implementation and solving challenging technical problems, then you’ve come to the right place to learn about ODI.

Unlike many other companies offering training, we don’t have a staff of educators on hand. Our trainers are the same folks that deliver projects, using the technology you’re interested in learning about, on a day-to-day basis. We offer you real world examples as we walk through our training slide deck and labs. Need to know why Oracle GoldenGate is an integral part of real-time data integration? Let me tell you about my latest client where I implemented GoldenGate and ODI. Want to know what to look out for when installing the JEE Agent in ODI 12c? We’ve done that many times – and know the tricks necessary to get it all working.

Our experts, such Jérôme Françoisse, Becky Wagner, Mark Rittman, myself, and many others, all have multiple years of experience with Oracle Data Integration implementations. Not only that, but we here at Rittman Mead truly enjoy sharing our knowledge! Whether posting to this blog, speaking at Oracle conferences, or on the OTN forums, Rittman Mead experts are always looking to teach others in order to better the Oracle Data Integration community.

If you or your company are in need of Oracle Data Integration training, please drop us a line at training@rittmanmead.com. As always, feel free to reach out to me directly on Twitter (@mRainey), LinkedIn, or via email (michael.rainey@rittmanmead.com) if you have any direct questions. See you all next year!

The post Kickstart Your 2016 with Rittman Mead’s Data Integration Training appeared first on Rittman Mead Consulting.

Action Links in OBIEE 12c – Part 2

Introduction and Scenario

Part 1 of this series on Action Links had us creating a simple navigate action and left us in suspense with the promise of a new means by which to filter one report from another. Now time to deliver! The scenario: say we’ve got a company dashboard that is pretty locked down in terms of adding any new user-facing content, and as a developer you occupy more of an analyst role where you can build analyses all day, but dashboards are a no go. So how then can we drive some of our own detail analyses from dashboard selections? The answer? Hidden driving documents! In a nutshell, these documents store selected dashboad values and act as a filter for our detail analyses, utilizing OBIEE’s “filter on the results of another analysis” filter option. It should be noted that we could simply set the target analysis’s filters to be equal to the presentation variables generated by the source dashboard prompt. However, the following technique is simply to illustrate a possible technique, say when you’re going between two different subject areas, that might be applicable in your current situation or at least spark an idea to get you headed in the right direction towards a possible solution. So, let’s start by getting the pieces to our puzzle together.

Start with the dashboard and prompt. We are going to navigate from a monthly sales trend to a detail report displaying product sales detail.

The Solution

Now that we’ve determined the dashboard analysis from which we want to navigate, we can set up our driving document. Again, the overall concept of a driving document is to act as an intermediary container for selected values that then get passed from one report to another. So let’s set this up. Given that our trend is prompted on Year, Company, Region, we need to place three dummy columns on our driving report to store the presentation variables generated by each prompt. I used the same three columns in my driving report for consistency, however any column will do. Note that the columns in the picture have custom names already are not the native columns from their respective tables.

Edit each column to store the presentation variables generated by your dashboard prompt. If the dashboard prompt does not have a presentation variable for each column prompt, go ahead and get those set up before completing this step. My year column variable in this example is appropriately titled SALES_YEAR. Be sure to put single quotes around your variable as in ‘@{SALES_YEAR}’ when entering it in the Edit Column dialogue.

You can now save your driving report and place it on your dashboard. Right away you should see that your driving report picks up the values in each column prompt. Note the use of a default value {2012}. Using these is ideal so that if we want to edit our driving document, we at least have some values to pass it, as opposed to it throwing an error on the Results tab.

 

Now for some bad news. You might have noticed an obvious limitation to this approach, which is the driving report’s limited selection of only one column value from each column prompt. Nevertheless, let’s run this thing through to the end and see what happens. The next piece of the puzzle is setting up your target analysis.

Our analyst in this scenario wants to set up two reports to be driven off of our dashboard selection. The first will be a top 10 report for products based on the selected month. The second will be another top 10, but for sales reps instead. Navigating to our desired subject area, let’s bring over the needed columns, formatting as needed. In this example, we’re going to include a custom calc which gives us the percent variance to the prior period which has also been conditionally formatted to indicate positive or negative growth.
We have placed the columns necessary to build each report and also added filters, as seen in the proceeding picture.

Now comes the crux of this neat trick. We need to add the proper filters to the analysis so that any values we pick from both the dashboard prompt and the source analysis itself will drive our target analysis.

In the target report, we added a filter for each column that we’d like our analysis filtered on and likewise, comes from our source report.

To set this filter, simply apply the ‘is based on results of another analysis’ filter to each column. Then, browse for the driving report we made and apply the ‘is equal to any’ Relationship option. As our driving report values will only have one value for each of the filtered columns, our target report columns should filter on each of these. Lastly, use the drop down to choose the corresponding column from the source analysis. In the following pic we are selecting the  Region column from our driving report so that our target report will be filtered on whatever Region is selected on our source dashboard.

As the last steps in our target analysis, make sure you’ve set all the filter columns to respond to the driver analysis and that you select the ‘is prompted’ filter for any additional dimension columns on your report that are not driven by a dashboard prompt. In the example, this is going to be the Month column. This will ensure that our target analysis “listens” to whatever month is selected in our source analysis, that is, our sales trend.

Don’t worry if your Results tab shows no values as this is expected behavior (we haven’t sent any values over yet!). If you’d like to set it up so that your target report actually yields results without clicking on the action link, simply apply default values to the presentation variables in your driving document, as described above in the Year example. The last piece of this puzzle is finally assigning the action link to our respective column. Follow the instructions outlined in the first part of this post in order to navigate to our target analysis. In our example, this is going to be our Sales column.

Now that we’ve got all the pieces of the puzzle, let’s put it all together and see what happens. Clicking on any sales point on our trend line, we should be taken to the target analysis which should be filtered on both our dashboard prompt values as well as our Month. In this example, I’ve applied a filters object to the target analysis to make sure the target analysis responded to all applied filters.

Looks like everything works great! At this point you can hide the driver report on your dashboard and get rid of the filters object on your target analysis. I’d like to hear about some neat ways people have used this technique or modified it to suit their particular business/use case. Feel free to post in the comments! Stay tuned for part three of this series on Action Links where we go in depth about the GoURL syntax and how it can be a powerful and customizable tool in navigating to web pages and OBIEE 12c content.

The post Action Links in OBIEE 12c – Part 2 appeared first on Rittman Mead Consulting.

Using Linux Control Groups to Constrain Process Memory

Linux Control Groups (cgroups) are a nifty way to limit the amount of resource, such as CPU, memory, or IO throughput, that a process or group of processes may use. Frits Hoogland wrote a great blog demonstrating how to use it to constrain the I/O a particular process could use, and was the inspiration for this one. I have been doing some digging into the performance characteristics of OBIEE in certain conditions, including how it behaves under memory pressure. I’ll write more about that in a future blog, but wanted to write this short blog to demonstrate how cgroups can be used to constrain the memory that a given Linux process can be allocated.

This was done on Amazon EC2 running an image imported originally from Oracle’s OBIEE SampleApp, built on Oracle Linux 6.5.

$ uname -a  
Linux demo.us.oracle.com 2.6.32-431.5.1.el6.x86_64 #1 SMP Tue Feb 11 11:09:04 PST 2014 x86_64 x86_64 x86_64 GNU/Linux

First off, install the necessary package in order to use them, and start the service. Throughout this blog where I quote shell commands those prefixed with # are run as root and $ as non-root:

# yum install libcgroup  
# service cgconfig start

Create a cgroup (I’m shamelessly ripping off Frits’ code here, hence the same cgroup name ;-) ):

# cgcreate -g memory:/myGroup

You can use cgget to view the current limits, usage, & high watermarks of the cgroup:

# cgget -g memory:/myGroup|grep bytes  
memory.memsw.limit_in_bytes: 9223372036854775807  
memory.memsw.max_usage_in_bytes: 0  
memory.memsw.usage_in_bytes: 0  
memory.soft_limit_in_bytes: 9223372036854775807  
memory.limit_in_bytes: 9223372036854775807  
memory.max_usage_in_bytes: 0  
memory.usage_in_bytes: 0

For more information about the field meaning see the doc here.

To test out the cgroup ability to limit memory used by a process we’re going to use the tool stress, which can be used to generate CPU, memory, or IO load on a server. It’s great for testing what happens to a server under resource pressure, and also for testing memory allocation capabilities of a process which is what we’re using it for here.

We’re going to configure cgroups to add stress to the myGroup group whenever it runs

$ cat /etc/cgrules.conf  
*:stress memory myGroup

[Re-]start the cg rules engine service:

# service cgred restart

Now we’ll use the watch command to re-issue the cgget command every second enabling us to watch cgroup’s metrics in realtime:

# watch --interval 1 cgget -g memory:/myGroup  
/myGroup:  
memory.memsw.failcnt: 0  
memory.memsw.limit_in_bytes: 9223372036854775807  
memory.memsw.max_usage_in_bytes: 0  
memory.memsw.usage_in_bytes: 0  
memory.oom_control: oom_kill_disable 0  
        under_oom 0  
memory.move_charge_at_immigrate: 0  
memory.swappiness: 60  
memory.use_hierarchy: 0  
memory.stat: cache 0  
        rss 0  
        mapped_file 0  
        pgpgin 0  
        pgpgout 0  
        swap 0  
        inactive_anon 0  
        active_anon 0  
        inactive_file 0  
        active_file 0  
        unevictable 0  
        hierarchical_memory_limit 9223372036854775807  
        hierarchical_memsw_limit 9223372036854775807  
        total_cache 0  
        total_rss 0  
        total_mapped_file 0  
        total_pgpgin 0  
        total_pgpgout 0  
        total_swap 0  
        total_inactive_anon 0  
        total_active_anon 0  
        total_inactive_file 0  
        total_active_file 0  
        total_unevictable 0  
memory.failcnt: 0  
memory.soft_limit_in_bytes: 9223372036854775807  
memory.limit_in_bytes: 9223372036854775807  
memory.max_usage_in_bytes: 0  
memory.usage_in_bytes: 0

In a separate terminal (or even better, use screen!) run stress, telling it to grab 150MB of memory:

$ stress --vm-bytes 150M --vm-keep -m 1

Review the cgroup, and note that the usage fields have increased:

/myGroup:  
memory.memsw.failcnt: 0  
memory.memsw.limit_in_bytes: 9223372036854775807  
memory.memsw.max_usage_in_bytes: 157548544  
memory.memsw.usage_in_bytes: 157548544  
memory.oom_control: oom_kill_disable 0  
        under_oom 0  
memory.move_charge_at_immigrate: 0  
memory.swappiness: 60  
memory.use_hierarchy: 0  
memory.stat: cache 0  
        rss 157343744  
        mapped_file 0  
        pgpgin 38414  
        pgpgout 0  
        swap 0  
        inactive_anon 0  
        active_anon 157343744  
        inactive_file 0  
        active_file 0  
        unevictable 0  
        hierarchical_memory_limit 9223372036854775807  
        hierarchical_memsw_limit 9223372036854775807  
        total_cache 0  
        total_rss 157343744  
        total_mapped_file 0  
        total_pgpgin 38414  
        total_pgpgout 0  
        total_swap 0  
        total_inactive_anon 0  
        total_active_anon 157343744  
        total_inactive_file 0  
        total_active_file 0  
        total_unevictable 0  
memory.failcnt: 0  
memory.soft_limit_in_bytes: 9223372036854775807  
memory.limit_in_bytes: 9223372036854775807  
memory.max_usage_in_bytes: 157548544  
memory.usage_in_bytes: 157548544

Both memory.memsw.usage_in_bytes and memory.usage_in_bytes are 157548544 = 150.25MB

Having a look at the process stats for stress shows us:

$ ps -ef|grep stress  
oracle   15296  9023  0 11:57 pts/12   00:00:00 stress --vm-bytes 150M --vm-keep -m 1  
oracle   15297 15296 96 11:57 pts/12   00:06:23 stress --vm-bytes 150M --vm-keep -m 1  
oracle   20365 29403  0 12:04 pts/10   00:00:00 grep stress

$ cat /proc/15297/status

Name:   stress  
State:  R (running)  
[...]  
VmPeak:   160124 kB  
VmSize:   160124 kB  
VmLck:         0 kB  
VmHWM:    153860 kB  
VmRSS:    153860 kB  
VmData:   153652 kB  
VmStk:        92 kB  
VmExe:        20 kB  
VmLib:      2232 kB  
VmPTE:       328 kB  
VmSwap:        0 kB  
[...]

The man page for proc gives us more information about these fields, but of particular note are:

  • VmSize: Virtual memory size.
  • VmRSS: Resident set size.
  • VmSwap: Swapped-out virtual memory size by anonymous private pages

Our stress process has a VmSize of 156MB, VmRSS of 150MB, and zero swap.

Kill the stress process, and set a memory limit of 100MB for any process in this cgroup:

# cgset -r memory.limit_in_bytes=100m myGroup

Run cgset and you should see the see new limit. Note that at this stage we’re just setting memory.limit_in_bytes and leaving memory.memsw.limit_in_bytes unchanged.

# cgget -g memory:/myGroup|grep limit|grep bytes  
memory.memsw.limit_in_bytes: 9223372036854775807  
memory.soft_limit_in_bytes: 9223372036854775807  
memory.limit_in_bytes: 104857600

Let’s see what happens when we try to allocate the memory, observing the cgroup and process Virtual Memory process information at each point:

  • 15MB:

    $ stress --vm-bytes 15M --vm-keep -m 1  
    stress: info: [31942] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
    
    # cgget -g memory:/myGroup|grep usage|grep -v max  
    memory.memsw.usage_in_bytes: 15990784  
    memory.usage_in_bytes: 15990784
    
    $ cat /proc/$(pgrep stress|tail -n1)/status|grep VmVmPeak:    21884 kB  
    VmSize:    21884 kB  
    VmLck:         0 kB  
    VmHWM:     15616 kB  
    VmRSS:     15616 kB  
    VmData:    15412 kB  
    VmStk:        92 kB  
    VmExe:        20 kB  
    VmLib:      2232 kB  
    VmPTE:        60 kB  
    VmSwap:        0 kB

  • 50MB:

    $ stress --vm-bytes 50M --vm-keep -m 1  
    stress: info: [32419] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
    
    # cgget -g memory:/myGroup|grep usage|grep -v max  
    memory.memsw.usage_in_bytes: 52748288  
    memory.usage_in_bytes: 52748288     
    
    $ cat /proc/$(pgrep stress|tail -n1)/status|grep Vm  
    VmPeak:    57724 kB  
    VmSize:    57724 kB  
    VmLck:         0 kB  
    VmHWM:     51456 kB  
    VmRSS:     51456 kB  
    VmData:    51252 kB  
    VmStk:        92 kB  
    VmExe:        20 kB  
    VmLib:      2232 kB  
    VmPTE:       128 kB  
    VmSwap:        0 kB

  • 100MB:

    $ stress --vm-bytes 100M --vm-keep -m 1  
    stress: info: [20379] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd        
    # cgget -g memory:/myGroup|grep usage|grep -v max  
    memory.memsw.usage_in_bytes: 105197568  
    memory.usage_in_bytes: 104738816
    
    $ cat /proc/$(pgrep stress|tail -n1)/status|grep Vm  
    VmPeak:   108924 kB  
    VmSize:   108924 kB  
    VmLck:         0 kB  
    VmHWM:    102588 kB  
    VmRSS:    101448 kB  
    VmData:   102452 kB  
    VmStk:        92 kB  
    VmExe:        20 kB  
    VmLib:      2232 kB  
    VmPTE:       232 kB  
    VmSwap:     1212 kB

Note that VmSwap has now gone above zero, despite the machine having plenty of usable memory:

# vmstat -s  
     16330912  total memory  
     14849864  used memory  
     10583040  active memory  
      3410892  inactive memory  
      1481048  free memory  
       149416  buffer memory  
      8204108  swap cache  
      6143992  total swap  
      1212184  used swap  
      4931808  free swap

So it looks like the memory cap has kicked in and the stress process is being forced to get the additional memory that it needs from swap.

Let’s tighten the screw a bit further:

$ stress --vm-bytes 200M --vm-keep -m 1  
stress: info: [21945] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

The process is now using 100MB of swap (since we’ve asked it to grab 200MB but cgroup is constraining it to 100MB real):

$ cat /proc/$(pgrep stress|tail -n1)/status|grep Vm  
VmPeak:   211324 kB  
VmSize:   211324 kB  
VmLck:         0 kB  
VmHWM:    102616 kB  
VmRSS:    102600 kB  
VmData:   204852 kB  
VmStk:        92 kB  
VmExe:        20 kB  
VmLib:      2232 kB  
VmPTE:       432 kB  
VmSwap:   102460 kB

The cgget command confirms that we’re using swap, as the memsw value shows:

# cgget -g memory:/myGroup|grep usage|grep -v max  
memory.memsw.usage_in_bytes: 209788928  
memory.usage_in_bytes: 104759296

So now what happens if we curtail the use of all memory, including swap? To do this we’ll set the memory.memsw.limit_in_bytes parameter. Note that running cgset whilst a task under the cgroup is executing seems to get ignored if it is below that currently in use (per the usage_in_bytes field). If it is above this then the change is instantaneous:

  • Current state

    # cgget -g memory:/myGroup|grep bytes  
    memory.memsw.limit_in_bytes: 9223372036854775807  
    memory.memsw.max_usage_in_bytes: 209915904  
    memory.memsw.usage_in_bytes: 209784832  
    memory.soft_limit_in_bytes: 9223372036854775807  
    memory.limit_in_bytes: 104857600  
    memory.max_usage_in_bytes: 104857600  
    memory.usage_in_bytes: 104775680

  • Set the limit below what is currently in use (150m limit vs 200m in use)

    # cgset -r memory.memsw.limit_in_bytes=150m myGroup

  • Check the limit – it remains unchanged

    # cgget -g memory:/myGroup|grep bytes  
    memory.memsw.limit_in_bytes: 9223372036854775807  
    memory.memsw.max_usage_in_bytes: 209993728  
    memory.memsw.usage_in_bytes: 209784832  
    memory.soft_limit_in_bytes: 9223372036854775807  
    memory.limit_in_bytes: 104857600  
    memory.max_usage_in_bytes: 104857600  
    memory.usage_in_bytes: 104751104

  • Set the limit above what is currently in use (250m limit vs 200m in use)

    # cgset -r memory.memsw.limit_in_bytes=250m myGroup

  • Check the limit – it’s taken effect

    # cgget -g memory:/myGroup|grep bytes  
    memory.memsw.limit_in_bytes: 262144000  
    memory.memsw.max_usage_in_bytes: 210006016  
    memory.memsw.usage_in_bytes: 209846272  
    memory.soft_limit_in_bytes: 9223372036854775807  
    memory.limit_in_bytes: 104857600  
    memory.max_usage_in_bytes: 104857600  
    memory.usage_in_bytes: 104816640

So now we’ve got limits in place of 100MB real memory and 250MB total (real + swap). What happens when we test that out?

$ stress --vm-bytes 245M --vm-keep -m 1  
stress: info: [25927] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

The process is using 245MB total (VmData), of which 95MB is resident (VmRSS) and 150MB is swapped out (VmSwap)

$ cat /proc/$(pgrep stress|tail -n1)/status|grep Vm  
VmPeak:   257404 kB  
VmSize:   257404 kB  
VmLck:         0 kB  
VmHWM:    102548 kB  
VmRSS:     97280 kB  
VmData:   250932 kB  
VmStk:        92 kB  
VmExe:        20 kB  
VmLib:      2232 kB  
VmPTE:       520 kB  
VmSwap:   153860 kB

The cgroup stats reflect this:

# cgget -g memory:/myGroup|grep bytes  
memory.memsw.limit_in_bytes: 262144000  
memory.memsw.max_usage_in_bytes: 257159168  
memory.memsw.usage_in_bytes: 257007616  
[...]  
memory.limit_in_bytes: 104857600  
memory.max_usage_in_bytes: 104857600  
memory.usage_in_bytes: 104849408

If we try to go above this absolute limit (memory.memsw.max_usage_in_bytes) then the cgroup kicks in a stops the process getting the memory, which in turn causes stress to fail:

$ stress --vm-bytes 250M --vm-keep -m 1  
stress: info: [27356] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd  
stress: FAIL: [27356] (415) <-- worker 27357 got signal 9  
stress: WARN: [27356] (417) now reaping child worker processes  
stress: FAIL: [27356] (451) failed run completed in 3s

This gives you an indication of how careful you need to be using this type of low-level process control. Most tools will not be happy if they are starved of resource, including memory, and may well behave in unstable ways.


Thanks to Frits Hoogland for reading a draft of this post and providing valuable feedback.

The post Using Linux Control Groups to Constrain Process Memory appeared first on Rittman Mead Consulting.

Becky’s BI Apps Corner: Oracle BI Applications, where art thou?

Hello! I would like to take a moment to introduce myself. My name is Becky Wagner and I’ve been working with Rittman Mead America since the beginning of the year. I have a background in data warehousing and ETL with a state government agency, where I was part of a project upgrading from DataStage to ODI 11g with Oracle Golden Gate in Oracle’s early adopter program for Oracle BI Apps 11g. Since coming to Rittman Mead, I’ve taught several ODI 12c bootcamps, designed and delivered custom trainings for BI Apps and ODI and been involved in ODI 11g, ODI 12c projects, and OBIA 11g projects.

 

Recently, I was putting together a BI Apps for Oracle Data Integrator (ODI) custom training for a client who is upgrading BI Apps and will be using ODI for the first time. On the Virtual Machine I was building for the training, I wanted the version of Oracle BI Applications to match the client’s installation. I found that Oracle’s recent website facelifts changed the way I was used to getting older versions of software. Oracle’s Downloads and Technetwork sites both have the most recent version of Oracle BI Apps available (currently 11.1.1.10.1) but no earlier versions any longer. Edelivery has the earlier versions as well as the current version, but the site has changed enough that it took me a bit to understand how to get to the Oracle BI Apps software files to download.

 

Downloading Oracle BI Apps from Edelivery

 

From your favorite browser, go to https://edelivery.oracle.com and sign in.

Accept the Export Restrictions (of course, only after you have read, understand and agree to them.)

 

Fill in the Product* box with ‘Business Intelligence Applications’. You won’t see Business Intelligence Applications in the dropdown that appears as you start typing. What you do see are other Products that your company would have purchased to allow you to have a license of Oracle Business Intelligence Applications, such as Oracle Financial Analytics or Oracle Human Resources Analytics. Select the product (or one of the products) that was purchased by your company.

Click on the Select Platform button and check the box for your appropriate platform, such as Linux x86-64 or Microsoft Windows x64 (64-bit). Then click the Select button.

Once the Product you selected is displaying in the window, click on the Continue button.

 

Now Oracle Business Intelligence 11.1.1.10.1 is showing. Interestingly, it doesn’t say Oracle Business Intelligence Applications, but currently OBIEE doesn’t have a version of 11.1.1.10.1, so we can be confident this is actually Oracle BI Apps. However, this still isn’t the Oracle BI Apps that you are looking for. Below the Available Release, you will see the option to Select Alternate Release.

This will allow you to drop down the box to select an earlier version.

With any version of Oracle BI Apps, there are several different components to download, which you can see by clicking on the triangle to the left of the Available Release. Once you have selected your desired version of Oracle BI Apps, click on the continue button to begin the download.

Please don’t forget to read the license agreements carefully and if you agree, check the box and click Continue.

 

At this point, you can now see the files to download. You can click on each blue link individually, or click the Download All button to use Oracle’s downloader tool. Also, for the Linux, Red Hat, and Solaris folks, notice at the bottom the WGET Options.

Downloading ODI for Oracle BI Apps from Edelivery

 

Get the downloads started for these files. We aren’t quite finished yet, though. ODI needs to be downloaded as well. Return to the Products page. Please note that to get the correct version of ODI, you must type in ‘Oracle Data Integrator for Oracle Business Intelligence’ (again, it probably means Oracle BI Apps, but points here for consistency at least). Select a Platform. Then click Continue.

Notice we are showing Oracle Business Intelligence 11.1.1.10.1 again. You will want to click on Select Alternate Release, and pick the same version you selected above. This will save you from interesting OPatch errors later during the install process, but I will leave those fun errors for another blog post. Then click Continue.

Rinse and repeat.

And that is how you navigate the new Oracle EDelivery site to get Oracle BI Apps download files and previous versions. I would love to hear your thoughts if you found this helpful or confusing. Also, please leave comments below if you found other alternatives for downloading earlier versions of Oracle BI Apps, and/or your suggestions for ways to rename the V#####-##.zip files to something more descriptive that better identifies the zip file. Keep an eye out for more Becky’s BI Apps Corner coming soon and if you’re interested in OBIEE or ODI training (or even a custom Oracle BI Applications course), give us a shout at training@rittmanmead.com!

The post Becky’s BI Apps Corner: Oracle BI Applications, where art thou? appeared first on Rittman Mead Consulting.