Pythian goodies: the answer to free memory, swap, oracle, and everything
I gave this talk at the UKOUG, and I have received a few requests to post the slides online. Instead of just posting the PowerPoint I took some time to give the presentation again (internally here at Pythian) and this time we recorded the session and we are posting it here in a variety of formats. This is a bit of a departure from the typical Pythian Goodies, in that it is scripted, and there is a lot of content here in the whitepaper, but there hasn't been a Goodie in a while so why not! I'd love to hear from you, so please feel free to ask any follow-up questions to this post in the comments.
Abstract
Do I have enough memory? Why is my free memory so low? Am I swapping to disk? Can I increase my SGA (db cache) size? Can I add another instance to this server? Are my system resources used optimally? These are all questions that often haunt DBAs. This presentation is The Answer. It covers, in detail, the different types of memory, how to monitor memory, and how to optimally use it with Oracle. Multiple examples in the presentation demonstrate how certain actions on the database side cause different memory areas to be allocated and used on the OS side. Key underlying differences in operating systems approaches to managing memory will be highlighted, with special attention given to Linux, Solaris, and Windows. Using Linux as an example throughout, this presentation explains how to effectively use tools such as "top", "vmstat" and "/proc/meminfo" to look into into a system's allocation and use of memory. Below you should see a flash video with me giving the session. Download this presentation! Powerpoint IPod video (right-click and Save As . . .) MP3 audio only And below you will find the complete contents of the whitepaper. This is intended to be a good overall reference resource for how memory works in Oracle, using Linux as an example.What is memory?
Memory in the computer world is the same as storage shelves in the real world. Its purpose is to store items (data) and allow easy access to them. Computers are all about manipulating data based on a predefined set of rules. The efficiency of a computer is a function of how fast it can manipulate the data (CPU speed) and how fast it can retrieve and store that data (CPU cache, RAM, Disk). In this paper I will concentrate only on the data-access component. I will refer to it as 'memory' and I will go into some practical details of how to make the most of it with Oracle.Types of Memory in a Modern Computer
Building a computer to perform involves putting the fastest CPU unit (or units) available and the fastest memory possible. Unfortunately, building such a computer would be expensive, and as human beings we always look for more cost-efficient ways of accomplishing what we need. Welcome to the world of compromises. There are three main properties of memory:- Latency: how much time it takes between making a request and receiving the data requested
- Capacity: how much it can hold (remember)
- Throughput: how fast can this data be retrieved or stored
- CPU registers – this is were the CPU manipulates the data – no latency, very low capacity
- CPU cache – memory direct access to the CPU unit – some latency for requesting memory
- RAM (main memory) – some noticeable latency associated with accessing this memory but in the same time, significantly larger capacity
- Disk – significant latency – very large capacity (in database world). This is also sometimes referred to as 'main storage' as it is the only non-volatile memory. That is memory that does not get reset on computer shutdown
Virtualization and 32bit vs 64bit
In order to save programmers from recoding the same idea over and over again, the operating system (OS) provides certain abstractions. The most significant one is memory virtualization. To understand that, you must first understand how memory is accessed. Memory is used to store data. The smallest unit of memory is a byte, which represents 8 bits. Memory capacity is measured in bytes. In today's large-capacity servers, "gigabyte" is more often used. A gigabyte is1024*1024*1024*1024
bytes. 1 Gb (gigabyte) is approximately 1 billion bytes. When storing and retrieving data, an offset is used to determine the location in which the data is stored. For example a data request would be "retrieve 8 bytes of data starting at offset 8100". This is similar to saying "give me the fifth binder from the second row" in the real world. Currently, the world is slowly in transition from 32-bit computers to 64-bit computers. The "bits" number of a computer represents how big the memory offset number can be. For example a 32 bit computer can "address" up to 4 Gb of memory. In contrast, a 64-bit computer can represent 17,179,869,184 Gb. That's not an error, it truly is a 11-digit number in Gb. Current 32-bit computers use some workarounds to be able to address more than 4Gb of RAM by adding extra registers and extra bits into the addressing portion. This, however, still does not allow for processes (running programs) to be able to freely address more than 4Gb of RAM. Modern operating systems run processes in "protected mode". What this mean is that a process can only "see" its own memory. It cannot interfere with other processes – memory or with kernel memory (memory used by the OS). This is accomplished by mapping the offsets of the memory used by a process to real memory. This mapping is maintained by mapping tables. The whole process is managed behind the scenes by the OS. For example, a process may request the value at offset 5000, but the OS translates this to offset 134000 in real memory and retrieves the data from there. The results is that each process has its own "addressing space" which it can use as it likes. The only limitation imposed is by the 32-bit or 64-bit mode of the process. A 64-bit OS can execute both 32-bit and 64-bit programs. A 32-bit OS can only execute 32-bit programs.
Virtual Memory Management
As a very complicated structure, virtual memory requires management. For kernel developers there's a numbers of very good articles at https://linux-mm.org/LinuxMMDocumentation. In this document, I will discuss only the structures that concerns us. Virtual memory is managed in pages. This means that memory is split into chunks. Each chunk can have different states such as "empty", "in memory", or "on disk". In Linux, those chunks are typically 4Kb. The chunk mappings and states are managed by sophisticated memory structure. Part of this structure is "page table entries" or PTEs. Each memory page is described by 1 PTEs. PTEs are similar to primary key indexes in Oracle. They describe the location of "this" page. The PTE memory structure is organized in a similar way as an Oracle index. It has three layers, and up to three pointers need to be accessed to find where a given page is located. This can be a very time-consuming operation, so each modern CPU has a fixed number of Cache entries called the "TLB cache" (Translation Lookaside Buffer). Each PTE entry also takes some small amount of memory. If you have many processes, consuming a lot memory, the memory needed for PTEs can be significant.Virtual Memory Benefits
Having this virtual memory abstraction allows the OS to provide some advanced services to applications. Some of them are:- Swapping: the ability to use the disk to extend the amount of RAM available. This is accomplished by temporary writing out some of the less-needed memory pages to disk
- Memory-mapped files: reading files as if they were fully loaded in memory and the OS performing reads behind the scene
- Shared memory: the ability for multiple processes to have access to the same memory. Modifications to this shared memory are immediately visible for all processes. This is extensively used by Oracle.
Virtual Memory Simplified
Simplifying all the above information, conceptually speaking, there are only three types of memory:- Kernel memory: memory needed by the OS to manage itself
- Private memory: memory used by user programs
- Shared memory: memory that can be used by multiple programs simultaneously
- in RAM or not in RAM
- on disk or not on disk (here, disk also could be swap)
- shared or not shared
Oracle Memory Types
The Oracle database has two main memory areas"- PGA – Process Global Area. This memory is private for each Oracle process. It is not shared, and it is dynamically allocated during runtime.
- SGA – Shared Global Area. This memory is shared amongst all Oracle processes. The two major sections of this memory are the "db cache" and the "pools" (shared pool, large pool etc.)
Linux Memory Areas
Many of the Linux memory areas are similar to other OSes, such as Solaris and AIX. They may be called or displayed differently, but in essence, it is the same concept.Direct user-dependant types of memory
Consumption of memory in these areas is directly related to user activities.- Buffers (shared) - raw buffers. Usually the biggest consumer is meta-data blocks of an ext3 file system
- Cached (shared) - files cached at a logical level. This includes the data portion of '"file system cache", including binary files "cached" for execution.
- Anonymous (private or shared) - memory allocated by programs. This includes stack, private variables, etc.
- HugePages - locked in memory, 2mb pages (chunks), usable only by special users via modified system calls.
Indirect (system) managed areas
Memory in these structures is a result of allocating memory in the above structures, or based on user activity, number of processes, etc.- Slab - kernel structures. This is an optimized memory allocation structure for small objects. The biggest consumers are
inode_cache
(file entity cache),dentry_cache
(directory entry cache) andbuffer_head
(headers of buffers, any type). - PageTables, the "leaf" objects of the PTE tables. These can consume a lot of large memory.
Virtual Memory, Oracle and the Filesystem Cache
When an Oracle instance is started , the first process allocates a relatively large shared memory segment. The size of this segment depends on multiple parameters. This segment is called the SGA -- shared global area. Each following process "attaches" to this memory segment by mapping it into its own addressing space. This allows each process to manipulate the SGA. This also includes shadow processes that are a direct result of a user connecting to the database. The SGA memory is reported into the "cached" section for Linux. The Oracle SGA does not have a disk representation, it is anonymous.Monitoring Memory Usage -- vmstat
Vmstat is one of the most commonly used tools for monitoring of virtual memory usage and file system activity. It is available on almost all Unix platforms. When running, vmstat prints a line everyx
seconds, containing information about the current state of key memory and disk statistics. The command
vmstat 2
means one line every two seconds. Example output:
vmstat 2 procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 3631424 11096 120204 0 0 35 31 255 20 0 0 99 0 0 0 0 3631488 11096 120204 0 0 0 0 1014 18 0 0 100 0 0 0 0 3631488 11096 120204 0 0 0 0 1012 16 0 0 100 0A quick overview of the columns.
- r - run queue: how many processes currently waiting for or running on the CPU
- b: how many processes waiting (blocking), usually waiting on IO
- swpd: swap memory usage in Kb
- free: free memory in Kb
- cache: file system cache size in Kb
- si/so: swap in / out - in Kb/sec
- bi/bo: bytes in / out - in Kb/sec
- cs: context switches
- us/sy/id/wa: user/system/idle/wait time for CPUs in percents.
Monitoring Memory Usage -- top
One of the most common tools for monitoring a *nix OS is the tool called "top". Almost all OSes have top or similar (it's topas on AIX). This tool uses information from the/proc
filesystem to gather overall and per-process information. top is also the most misunderstood tool. Its output can be confusing, as it presents information explained in documentation with single words or at most single sentences. This makes it open for free interpretation. Since top takes all its information from the
/proc
filesystem, specifically
/proc/meminfo
and
/proc/pid/statm
, I will be covering
/proc/meminfo
in detail further in this paper. Sample output of top:
top - 22:03:11 up 3:19, 2 users, load average: 2.98, 1.22, 0.52 Tasks: 89 total, 1 running, 88 sleeping, 0 stopped, 0 zombie Cpu0 : 0.7% us, 0.8% sy, 0.0% ni, 0.3% id, 98.0% wa, 0.2% hi, 0.0% si Cpu1 : 0.0% us, 0.8% sy, 0.0% ni, 97.6% id, 1.4% wa, 0.2% hi, 0.0% si Cpu2 : 0.0% us, 0.2% sy, 0.0% ni, 99.7% id, 0.2% wa, 0.0% hi, 0.0% si Cpu3 : 0.2% us, 0.2% sy, 0.0% ni, 33.6% id, 66.1% wa, 0.0% hi, 0.0% si Mem: 8310308k total, 8049068k used, 261240k free, 36620k buffers Swap: 7823644k total, 572k used, 7823072k free, 3395900k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8494 oracle 16 0 1662m 1.6g 1.5g D 2.0 19.8 0:03.15 oracletest(LOCAL=YE 4796 oracle 16 0 1626m 1.5g 1.5g S 1.0 19.5 0:03.91 ora_dbw1_test 4794 oracle 15 0 1626m 1.5g 1.5g S 0.7 19.5 0:12.23 ora_dbw0_test 4798 oracle 16 0 1626m 1.5g 1.5g S 0.7 19.5 0:03.97 ora_dbw2_test 4800 oracle 16 0 1626m 1.5g 1.5g S 0.7 19.5 0:04.09 ora_dbw3_test 1 root 16 0 2384 600 512 S 0.0 0.0 0:00.86 init [3] 2 root RT 0 0 0 0 S 0.0 0.0 0:00.00 [migration/0] 3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 [ksoftirqd/0]NOTE: This is only a sample output. I do not recommend running multiple dbwriter processes. top has two sections: the overall statistics and the process list. The overall statistics display:
- the load average
- per-CPU usage (toggled with the key "1")
- memory summaries (discussed in next section)
- PID - the process ID of that process. A unique identifier for the process.
- USER - the user executing that process. You can press '“u†and type in a user to filter the process list.
- PR - current priority of the process. A lower number indicates a higher priority
- NI - nice value, the priority modifier for that process. Allows you to raise or lower priority for the process.
- VIRT - the virtual memory size of the process. How much memory the process can address in its private addressing space.
- RES - resident size. The amount of memory currently in RAM. NOTE: shared memory can be resident for multiple processes. In the example above, each dbwriter process has 1.5gb resident.
- SHR - the amount of memory shared. Usually matches the SGA size
- S - state. This is sampled and not overall for the interval monitored. The states are:
- is sleeping (an oracle process is sleeping while waiting for a lock for example)
- waiting on disk io (actively reading)
- currently running on CPU
- %CPU – percent CPU usage, relatively to a single CPU (toggle with Shift-I). Note that this number can go above 100% if the process is multi-threaded, as each thread can leverage a different CPU.
- %MEM – percentage of memory taken, counting the RES column. Note: shared memory is counted multiple times.
- TIME+ - how much overall CPU time this process has consumed in its lifetime
- COMMAND – name of the process running. By default displays only the binary file name. I always switch it to display the actual command by pressing '“Câ€Â. This allows me to see which Oracle process is running (background, shadow).
Reading /proc/meminfo
The
/proc
file system is a text-file interface to kernel structures. It represents both read-only and modifiable settings.
/proc/meminfo
is one of the read-only text files. It is user friendly, meaning that each line has its own description. Some files are intended for automated read by other programs. To read
meminfo
issue
cat /proc/meminfo
. Here's sample output:
cat /proc/meminfo MemTotal: 8310308 kB MemFree: 93448 kB Buffers: 132036 kB Cached: 3413324 kB SwapCached: 0 kB Active: 1658252 kB Inactive: 1942032 kB HighTotal: 7470528 kB HighFree: 8768 kB LowTotal: 839780 kB LowFree: 84680 kB SwapTotal: 7823644 kB SwapFree: 7823072 kB Dirty: 100 kB Writeback: 0 kB Mapped: 82500 kB Slab: 92028 kB Committed_AS: 490700 kB PageTables: 3952 kB VmallocTotal: 106488 kB VmallocUsed: 5964 kB VmallocChunk: 99900 kB HugePages_Total: 2200 HugePages_Free: 1088 Hugepagesize: 2048 kBHere is the explanation of the significant values.
MemTotal
The total memory visible by the OS. If it's not what you've put in the machine, probably you have a bad SIM/DIMM.MemFree
Memory that is currently unoccupied and available to use immediately. This is not the maximum amount of memory available at the moment. If this value goes low, do not panic. Every bit of memory in this section is currently unused. You can even call it wasted. Some tools offer checks, and can page you, if "free memory" goes too low. You can remove those checks because in most cases all you need is a very small amount of memory free to allow programs to quickly allocate memory without the OS having to free some additional memory. In some rare cases, you may need to have more free memory available for some rare, spiky memory-hungry applications. The amount of memory that Linux will target to keep free can be controlled by (Linux RH4)/proc/sys/vm/min_free_kbytes
. Note that this is only a target. The idea behind free memory is to have asynchronous memory management, i.e. not to cause programs to wait for resources to be deallocated. Instead, the OS deallocates some resources in anticipation of memory needs.
grep MemFree /proc/meminfo MemFree: 26568 kB echo 900000 > /proc/sys/vm/min_free_kbytes grep MemFree /proc/meminfo MemFree: 210056 kB
Buffers
The cache of raw disk blocks. Do not confuse it with filesystem cache (next). Usually occupied with ext3 data pointers (extent management data). Generally, if you have a large and active database, there's 1 Mb of metadata associated with each 1 Gb of data. Not all of it needs to be buffered, but the active portion does. The ext3 pointers, depending on the file size, are direct, indirect, and double indirect. On large files, when accessing the tail end of the file, up to 2 additional disk reads may be required. It does not matter whether you use DirectIO for your datafiles or not -- buffers are still needed. ASM (Oracle's Automatic Storage Manager) manages data in much larger chunks, so it requires less memory. Its metadata is in the shared pool. If you have a large database, it may make sense to have a larger shared pool for the ASM metadata.Cached
Often referred to as filesystem cache. This is the actual data of the files. Each block is associated with a file (or inode). Thus the file cache is logical. For example: when removing a file, its associated cached pages are removed. Note that removing the "file" portion of the file, does not necessary free up the inode immediately. If the file is opened by an application, the inode (and "the file") will remain open and its cache will not be released. This file system cache is also used for executing binary files. For example: if you copy a binary executable file and run it immediately, it will already be in memory and will not need to be loaded. For reference, the "Oracle" binary is 100 Mb. Usually, at least 50% of it is cached. Also a number of binary libraries end up in this area. On systems with large amounts of RAM, file system cache would be the largest area, unless DirectIO is used. If you do not have DirectIO enabled in your database and you use a normal file system to store your data (ASM implies DirectIO), then your cache will be polluted with database activity. The same data will be cached both in the database and in the OS cache. Usually the result is the system "feels" sluggish, as any rare activity will require its data to be re-read from disk. The Oracle SGA is also in this area, when not using HugePages. This can be quite confusing. Especially since 10g, the SGA is allocated slowly on a touch basis. An example of this behavior is in the case studies section further below. Here are a few examples of filesystem cache usage behaviour. The machine is freshly started, lots of free memory will be consumed by file system cache. The test case involves reading a few large files and observing memory behavior.[root@ ~]# cat /proc/meminfo ... MemFree: 8232512 kB Buffers: 9328 kB Cached: 28372 kB ... du -smc indx01_* 1714 indx01_01.dbf 1761 indx01_02.dbf 1722 indx01_03.dbf 5197 total ... cat indx01_* > /dev/null [root@ ~]# vmstat 2 procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 8093888 10808 163392 0 0 0 0 1012 17 0 0 100 0 0 0 0 8093952 10808 163392 0 0 0 0 1012 16 0 0 100 0 0 1 0 7956736 10948 300272 0 0 68602 0 1567 1126 0 2 76 22 0 1 0 7808576 11092 448068 0 0 73992 80 1623 1210 0 2 75 23 ... 0 1 0 2847616 16104 5397616 0 0 65792 0 1542 1076 0 2 75 23 0 0 0 2766272 16180 5479180 0 0 40698 0 1341 675 0 1 85 14 0 0 0 2766208 16192 5479168 0 0 0 114 1033 22 0 0 100 0 cat /proc/meminfo ... MemFree: 2766464 kB Buffers: 16192 kB Cached: 5479168 kB ...The next test case, reads the same files (cached in memory) and writes them to a new file replicating a number of datablocks. Then I remove the newly created file, and its cache is released, resulting in a lot of free memory.
cat indx01_* >newfile vmstat 2 procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 2765312 17044 5479356 0 0 0 0 1012 17 0 0 100 0 0 3 0 2405376 17428 5833612 0 0 16 36866 1324 144 1 18 76 6 0 2 0 2143616 17688 6091532 0 0 4 111748 2000 213 0 16 50 34 ... 0 1 0 16832 6784 8198556 0 0 8556 26684 1942 1267 0 2 74 24 1 1 0 16832 6856 8198744 0 0 12518 20720 2130 1767 0 3 74 23 ... cat /proc/meminfo ... MemFree: 16768 kB Buffers: 2192 kB Cached: 8196908 kB ... Dirty: 277468 kB Writeback: 0 kB ... cat /proc/meminfo ... MemFree: 20672 kB Buffers: 3300 kB Cached: 8191900 kB ... Dirty: 0 kB Writeback: 0 kB ... rm newfile procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 23296 3380 8189480 0 0 0 28 1015 18 0 0 100 0 0 1 0 3257472 3948 4996372 0 0 284 0 1084 160 0 14 78 8 0 1 0 3255552 5828 4996572 0 0 940 0 1247 485 0 1 75 24 0 1 0 3253696 7616 4996344 0 0 884 96 1237 470 0 2 75 23 0 0 0 3253440 7988 4996492 0 0 186 0 1061 112 0 0 95 4 0 0 0 3253440 7988 4996492 0 0 0 0 1012 14 0 0 100 0
SWAP
The swap section displays summary about less-used data that has been written to disk. Only anonymous data requires a swap file since it does not have an already existing on disk representation, i.e. it is not associated with any inode. There are three values in the swap section:- SwapTotal – the total amount of swap space available
- SwapFree – unused amount of swap space
- SwapCached – data that has been swapped out to disk, but still remains in memory.
SwapTotal - SwapFree - SwapCachedIt is perfectly fine to have data swapped out and cached. This means that some application has requested and used some memory, but has not been using it for a long period of time. For example, the Oracle Clusterware tends to do that.
Active/Inactive
These values can be used to determine whether you have sufficient memory for your workload. If "active" is very close to your total amount of memory, you would probably benefit from extra memory. However these are not long-term numbers. They refer to a very recent state of the system. Having a low '“active†does not mean that overnight your "active" will be very high and could cause some swapping.High/Low Free
In 32-bit systems, there are limitations on what memory the Linux kernel can address directly or indirectly. High memory in 32-bit systems is the memory above 1 Gb. Linux needs to do extra work when using high memory. Some of the Linux kernel structures cannot reside in high memory. The newer 2.6 kernel does a very good job in managing high memory and reserving low memory for kernel structures. On 64-bit systems there is no high memory, and meminfo will show 0 for high total and high free. All the memory can be accessed directly without any additional overhead.Dirty & Writeback
Dirty memory is cache/buffers that need to be written to disk. Writeback – memory actively being written to disk. This can reach high values with asynchronous writes with a large queue.Committed and mapped
Committed_AS - Total memory requested by all running applications . Note that this is requested memory, not actually used memory. A process may "request" a large amount of memory and never use it. There is no need to allocate it to that process until it actually uses it. If every process in the system is to touch and use the memory it has requested, the total memory usage would be Committed_AS. Mapped - memory used for in-memory mapped files. Anonymous, and committed and touched memories are also counted here. Here is a small test case demonstrating the difference between committed (requested) and used (touched). This small C program requests 1 Gb of memory, but free memory remains the same -- committed increases by 1 Gb.cat grab.c main() {void *p; p=malloc(1073741824); sleep(60);} cat /proc/meminfo ... MemFree: 3230592 kB ... Committed_AS: 49972 kB ./grab cat /proc/meminfo ... MemFree: 3230464 kB ... Committed_AS: 1098808 kB
SLAB
Slab is special type of memory. It is a way to manage a large number of small objects that are constantly allocated and de-allocated. Most of the objects are a direct result of kernel structure allocated as part of process activity. In a way it is similar to Oracle's shared pool. Details about the content of the "slab" can be obtained from the user un-friendly file/proc/slabinfo
. A more user-friendly interface is provided
slabtop
. It's similar to the "top" for processes but only displays stats about slabs by type. slabtop sample output (ordered by size, by pressing the C key):
Active / Total Objects (% used) : 88874 / 139343 (63.8%) Active / Total Slabs (% used) : 5839 / 5846 (99.9%) Active / Total Caches (% used) : 90 / 132 (68.2%) Active / Total Size (% used) : 17286.03K / 23311.27K (74.2%) Minimum / Average / Maximum Object : 0.01K / 0.17K / 128.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 32382 24900 76% 0.27K 2313 14 9252K radix_tree_node 56925 40013 70% 0.05K 759 75 3036K buffer_head 364 363 99% 4.00K 364 1 1456K size-4096 2485 2471 99% 0.54K 355 7 1420K ext3_inode_cache 2376 413 17% 0.50K 297 8 1188K size-512 256 256 100% 3.00K 128 2 1024K biovec-(256) 4576 4481 97% 0.15K 176 26 704K dentry_cache 10248 4548 44% 0.06K 168 61 672K size-64 4340 1215 27% 0.12K 140 31 560K size-128 1980 316 15% 0.25K 132 15 528K size-256
Share this
Previous story
← Oracle Grid Control: The Importance of Deleting the emkey
You May Also Like
These Related Stories
How to Enable RAM Cache in Oracle Exadata
How to Enable RAM Cache in Oracle Exadata
Oct 8, 2020
8
min read
Performance Tuning: HugePages in Linux
Performance Tuning: HugePages in Linux
Nov 10, 2008
6
min read
Enabling large pages on Oracle Database 11g running on IBM AIX
Enabling large pages on Oracle Database 11g running on IBM AIX
Apr 4, 2016
3
min read
No Comments Yet
Let us know what you think