Tuesday, November 23, 2010

Oracle - PGA explained

Oracle Database allocates a program global area (PGA) for each server process. The PGA is used to process SQL statements and to hold logon and other session information. For the purposes of memory management, the collection of all PGAs is known as the instance PGA. Using an initialization parameter, you set the size of the instance PGA, and the database distributes memory to individual PGAs as needed.

Background processes also allocate their own PGAs. This discussion focuses on server process PGAs only.
Content of the PGA
The content of the PGA memory varies, depending on whether or not the instance is running the shared server option. 

Session Memory
Session memory is the memory allocated to hold a session's variables (logon information) and other information related to the session. For a shared server, the session memory is shared and not private.

Private SQL Area
The private SQL area contains data such as bind variable values, query execution state information, and query execution work areas. Each session that issues a SQL statement has a private SQL area. Each user that submits the same SQL statement has his or her own private SQL area that uses a single shared SQL area. Thus, many private SQL areas can be associated with the same shared SQL area.
The location of a private SQL area depends on the type of connection established for a session. If a session is connected through a dedicated server, private SQL areas are located in the server process's PGA. However, if a session is connected through a shared server, part of the private SQL area is kept in the SGA.


Cursors and SQL Areas
The application developer of an Oracle Database precompiler program or OCI program can explicitly open cursors, or handles to specific private SQL areas, and use them as a named resource throughout the execution of the program. Recursive cursors that Oracle Database issues implicitly for some SQL statements also use shared SQL areas.

The management of private SQL areas is the responsibility of the user process. The allocation and deallocation of private SQL areas depends largely on which application tool you are using, although the number of private SQL areas that a user process can allocate is always limited by the initialization parameter OPEN_CURSORS. The default value of this parameter is 50.
A private SQL area continues to exist until the corresponding cursor is closed or the statement handle is freed. Although Oracle Database frees the run-time area after the statement completes, the persistent area remains waiting. Application developers close all open cursors that will not be used again to free the persistent area and to minimize the amount of memory required for users of the application.

Private SQL Area Components
The private SQL area of a cursor is itself divided into two areas whose lifetimes are different:
  • The persistent area—This area contains bind variable values. It is freed only when the cursor is closed.
  • The runtime area—Oracle Database creates this area as the first step of an execute request. It contains the following structures:
    • Query execution state information
For example, for a full table scan, this area contains information on the progress of the scan
    • SQL work areas
These areas are allocated as needed for memory-intensive operations like sorting or hash-joins. More detail is provided later in this section.
  • For DML, the run-time area is freed when the statement finishes running. For queries, it is freed after all rows are fetched or the query is cancelled.
SQL Work Areas
SQL work areas are allocated to support memory-intensive operators such as the following:
  • Sort-based operators (order by, group-by, rollup, window function)
  • Hash-join
  • Bitmap merge
  • Bitmap create
For example, a sort operator uses a work area (sometimes called the sort area) to perform the in-memory sort of a set of rows. Similarly, a hash-join operator uses a work area (also called the hash area) to build a hash table from its left input. If the amount of data to be processed by these two operators does not fit into a work area, the input data is divided into smaller pieces. This enables some data pieces to be processed in memory while the rest are spilled to temporary disk storage to be processed later. Although bitmap operators do not spill to disk when their associated work area is too small, their complexity is inversely proportional to the size of their work area. Thus, these operators run faster with larger work area.

The size of a work area can be controlled and tuned. The database automatically tunes work area sizes when automatic PGA memory management is enabled.

Generally, bigger work areas can significantly improve the performance of a particular operator at the cost of higher memory consumption. Optimally, the size of a work area is big enough to accommodate the input data and auxiliary memory structures allocated by its associated SQL operator. If not, response time increases, because part of the input data must be spilled to temporary disk storage. In the extreme case, if the size of a work area is far too small compared to the input data size, multiple passes over the data pieces must be performed.

Oracle - SGA Explained

The System Global Area (SGA) is a group of shared memory areas that are dedicated to an Oracle “instance” (an instance is your database programs and RAM). 

All Oracle processes use the SGA to hold information. The SGA is used to store incoming data (the data buffers as defined by the db_cache_size parameter), and internal control information that is needed by the database. You control the amount of memory to be allocated to the SGA by setting some of the Oracle “initialization parameters”.  These might include db_cache_size, shared_pool_size and log_buffer.
In Oracle Database 10g you only need to define two parameters (sga_target and sga_max_size) to configure your SGA. If these parameters are configured, Oracle will calculate how much memory to allocate to the different areas of the SGA using a feature called Automatic Memory Management (AMM). As you gain experience you may want to manually allocate memory to each individual area of the SGA with the initialization parameters. 

We have already noted that the SGA was sub-divided into several memory structures that each have different missions. The main areas contained in the SGA that you will be initially interested in have complicated names, but are actually quite simple:

* The buffer cache (db_cache_size)
* The shared pool (shared_pool_size)
* The redo log buffer (log_buffer)

Here is a simple view of the SGA:


Oracle - Data Buffer Cache

The Buffer Cache (also called the database buffer cache) is where Oracle stores data blocks.  With a few exceptions, any data coming in or going out of the database will pass through the buffer cache.
The total space in the Database Buffer Cache is sub-divided by Oracle into units of storage called “blocks”. Blocks are the smallest unit of storage in Oracle and you control the data file blocksize when you allocate your database files. 

An Oracle block is different from a disk block.  An Oracle block is a logical construct -- a creation of Oracle, rather than the internal block size of the operating system. In other words, you provide Oracle with a big whiteboard, and Oracle takes pens and draws a bunch of boxes on the board that are all the same size. The whiteboard is the memory, and the boxes that Oracle creates are individual blocks in the memory. 
Each block inside a file is determined by your db_block_size parameter and the size of your “default” blocks are defined when the database is created. You control the default database block size, and you can also define tablespaces with different block sizes.  For example, many Oracle professionals place indexes in a 32k block size and leave the data files in a 16k block size.

When Oracle receives a request to retrieve data, it will first check the internal memory structures to see if the data is already in the buffer. This practice allows to server to avoid unnecessary I/O. In an ideal world, DBAs would be able to create one buffer for each database page, thereby ensuring that Oracle Server would read each block only once. 

The db_cache_size and shared_pool_size parameters define most of the size of the in-memory region that Oracle consumes on startup and determine the amount of storage available to cache data blocks, SQL, and stored procedures. 

The default size for the buffer pool (64k) is too small. It is recommended that you set this to a value of 1m when you configure Oracle.

SQL - Top15 biggest tables

Using this SQL you will be able to get a list of the top 15 biggest tables in MB and GB.
You can replace the 15 with any number depending on how many results you would like to see.


SQL:

SELECT NAME, size_mb, size_gb
  FROM (SELECT   segment_name NAME,
                 SUM (BYTES) / 1024 / 1024 size_mb,
                 SUM (BYTES) / 1024 / 1024 / 1024 size_gb
        FROM dba_segments
        GROUP BY segment_name
        ORDER BY SUM (BYTES) / 1024 / 1024 DESC)
 WHERE ROWNUM <= 15

SQL - Tablespace Sizing

Here is a easy way to manage your tablespace sizing and availability.

SQL:

select  a.tablespace_name,
       round(a.bytes_alloc / 1024 / 1024, 2) megs_alloc,
       round(nvl(b.bytes_free, 0) / 1024 / 1024, 2) megs_free,
       round((a.bytes_alloc - nvl(b.bytes_free, 0)) / 1024 / 1024, 2) megs_used,
       round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_Free,
       100 - round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_used,
       round(maxbytes/1048576,2) Max
from  ( select  f.tablespace_name,
               sum(f.bytes) bytes_alloc,
               sum(decode(f.autoextensible, 'YES',f.maxbytes,'NO', f.bytes)) maxbytes
        from dba_data_files f
        group by tablespace_name) a,
      ( select  f.tablespace_name,
               sum(f.bytes)  bytes_free
        from dba_free_space f
        group by tablespace_name) b
where a.tablespace_name = b.tablespace_name (+)
union all
select h.tablespace_name,
       round(sum(h.bytes_free + h.bytes_used) / 1048576, 2) megs_alloc,
       round(sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / 1048576, 2) megs_free,
       round(sum(nvl(p.bytes_used, 0))/ 1048576, 2) megs_used,
       round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2) Pct_Free,
       100 - round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2)
pct_used,
       round(f.maxbytes / 1048576, 2) max
from   sys.v_$TEMP_SPACE_HEADER h, sys.v_$Temp_extent_pool p, dba_temp_files f
where  p.file_id(+) = h.file_id
and    p.tablespace_name(+) = h.tablespace_name
and    f.file_id = h.file_id
and    f.tablespace_name = h.tablespace_name
group by h.tablespace_name, f.maxbytes
ORDER BY 1


This is what the results should look like: