Getting Oracle.DataAccess “Working” on x64
Note: Please read to the end of the article before starting—results may vary.
We recently moved one of our applications off an older server to a shiny, speedy new server. In that transition, however, the new server was loaded with 64–bit Windows Server 2003 R2. That’s fine—run .NET in 64–bit mode and kick along—my libraries are already set to run under ‘Any CPU’.
Wrong. BadFormatExceptions from Oracle.DataAccess.
Unfortunately, even the 64–bit versions of the Oracle 11g ODP returns a x86 Oracle.DataAccess.dll. For me, setting the project to ‘x86’ (under the CPU build type) didn’t resolve the issue—it still couldn’t load the Oracle library. A bit of hunting turned up that the x86 version of .NET isn’t installed by default.
To enable 32–bit access on a 64–bit platform, a few command lines are required:
First, a quick script to enable support on the system:
cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 True
Second, actually install the 32–bit version of ASP.NET onto IIS:
Finally, enable 32–bit ASP.NET inside the Web Server Extensions (IIS Management Console):
Now, that works—but we have a 64–bit server downgrading everything to 32–bit. Why can’t we find and get this crackin’ at 64–bit? We just need a 64–bit version of Oracle.DataAccess, right?
Right. ~~~ Like most thing, the challenge is in the details.
If you look at the GAC on a machine with ODP 64–bit installed (I’m using 18.104.22.168.21 for 11g), there isn’t a x64 image available. To find the 64–bit edition, you need the 11g Release 1 Client (it’s release 1 today). Unfortunately, it’s 22.214.171.124.0–-a different version. GAH. Okay, go ahead and install!
It should install a x64 image library with the following properties:
Now, in the web.config for the application, we need to add an assembly redirection.
<assemblyIdentity name=“Oracle.DataAccess“ publicKeyToken=“89b483f429c47342“/>
<bindingRedirect oldVersion=“0.0.0.0-126.96.36.199“ newVersion=“188.8.131.52“/>
Also, in the /bin directory of your project (or where ever your referenced libraries are), make sure that the 32–bit edition is not available so that the compiler will read from the GAC.
Start up the application and go.
Too easy, right? Yeah, I’m afraid it is. After all this work, performance under the 64–bit environment was atrocious. A load test of about 1000 users (using the Visual Studio Web Test tools).
Here’s the graph (click for details—it’s big so the detail is available):
The bouncing green line in the top graph is the JIT compiler recycling over and over while the red in the bottom is the CPU pegged… and not pegged after 1000 users, but after about 15 at :15 seconds into the run. Ugh. I finally cut it off at 7:15 as the system was getting unstable.
So, I removed the 64–bit calls, rolled back to calling 32–bit ODP, and ran the EXACT same load tests.
In 32–bit mode, the CPU is running as expected (the spikes are the system generating 50–100 page PDF reports on the fly using DataDynamics ActiveReports) and we hit our full 1000+ concurrent users without any real issues or memory seepage.
As a quick test, I removed the references and the few lines that are accessing Oracle databases in the application and just used the 64–bit libraries for SQL Server 2005 and my own framework libraries—and performance screamed. I’m pretty confident that this is within Oracle.DataAccess, but more investigation is required to nail down which objects/calls. There may be more value of simply populating the few bits of data I’m pulling out of Oracle within our SQL environment and updating it daily—like psuedo, remove materialized views.🙂
So… while it’s good to know how to get the 64–bit libraries working, I’m VERY interested in why the performance was so poor. I haven’t tossed ANTS at it yet in 64–bit mode, though that is the next test on a 64–bit development box that I’m building up.