What is finally the primary objective of a database? Storing Data 😀
The question is, how Oracle makes it. For many beginners, a confusing topic is to get the picture between physical storage and logical one. So how does it work?

The storage in an Oracle database can be seen from 2 points of view:

  • Database users
  • System Administrators

On one hand you have users who see tables, indexes and so on. This could be summarized has objects or, so called in Oracle, Segments. On the other hand you have system adminitrators (Unix or Windows, doesn’t matter…), who see files and blocks.
As DBA you are the missing link between these 2 points of view 🙄
So, how do we go down from an Object, Segment, to the files and OS blocks? Take a look down there.

logical_physical_Storage

As we already said, data are stored in Segments (Tables, Indexes…). Segments are stored in Tablespaces and these are the bridge between logical storage and physical storage.

On one side, tablespaces are physical collection of data files, which are made of operating system blocks. On the other side, tablespaces are logical collection of Segments (Tables, indexes…). You could almost compare them to folders where you organize your data in.

Segments are composed of Extents, which are pieces of data. As Segments will most probably grow over time, Extents are added to follow the Segments’ size increase. Extents are made of Oracle Blocks.

Finally we reach the lowest level, where Oracle Blocks are groups of Operating System Blocks. The Oracle block size is defined on database level but can also be customized per tablespace. The Oracle block size must be greater or equal and a multiple of the OS blocks. This is basis while speaking about Oracle performances. Many best practices can be found on Internet about it.

Let’s take a small example:

1 Database with 8KB Oracle Blocks on File Systems of 4KB blocks.
==> 1 Oracle Block = 2 OS Blocks
Now we can have a look a little bit deeper in all these elements

Tablespaces and Data Files

As seen, Tablespaces are logical containers composed of one or more datafiles.

tablespaces

Oracle provides 2 types of tablespaces:

  • Smallfile tablespaces – most commonly used
  • Bigfile tablespaces

The Smallfile tablespaces are composed of several datafiles, while Bigfiles are composed of a single data file. One of the reasons why Oracle introduced big file tablespaces was the limitation on the number of data file composing a database (usually 64k). In Bigfile tablespaces, the data files max size limit is much higher than for small file tablespaces.

How does it work? You may have already heard about ROWID, which is a unique ID for each row in a database. In fact the ROWID is more than just an ID, it is also the pointer to the row location. Between Smallfiles and Bigfiles tablespaces, the ROWID is slightly different.

rowid

As by definition Bigfile tablespaces are made of a single file, there is no File Nb needed within the ROWID. Therefore the Block Nb is coded on 4GB instead of 4kB.

If we take our example of a 8kB database again, we have the following:
Smallfile max size: 4kB blocks X 8kB (size of each block) = 32 GB per file
Bigfile max size: 4GB blocks X 8kB (size of each block) = 32 TB per file

The tablespace management can be done either in the Oracle Data Dictionary or, since 10g, be Locally Managed. Nowadays almost all tablespaces are configured as Locally Managed TableSpace (LMTS). This means that the space management is done in a bitmap stored in the Segment Header of the tablespace. The LMTS has the advantage to reduce – but not avoid – fragmentation and improve DDL performances.

While creating data files, 2 solutions are possible. You can either create them with fix size which will be allocated at file creation, or you can create them in autoextend mode. Autoextend data files are created with an initial size and will then grow up automatically until the defined max size. If no max size is given at data file creation, then the limit defined by the Oracle Block Size (see above about ROWID and max data file size) will be applied.

Here are the 2 main views in oracle to get information on tablespaces and data files: dba_tablespaces, dba_data_files

SQL> desc dba_tablespaces;
Name                       Null?         Type
-------------------------- ------------- ------------------------------------
TABLESPACE_NAME            NOT NULL      VARCHAR2(30)
BLOCK_SIZE                 NOT NULL      NUMBER
INITIAL_EXTENT                           NUMBER
NEXT_EXTENT                              NUMBER
MIN_EXTENTS                NOT NULL      NUMBER
MAX_EXTENTS                              NUMBER
MAX_SIZE                                 NUMBER
PCT_INCREASE                             NUMBER
MIN_EXTLEN                               NUMBER
STATUS                                   VARCHAR2(9)
CONTENTS                                 VARCHAR2(9)
LOGGING                                  VARCHAR2(9)
FORCE_LOGGING                            VARCHAR2(3)
EXTENT_MANAGEMENT                        VARCHAR2(10)
ALLOCATION_TYPE                          VARCHAR2(9)
PLUGGED_IN                               VARCHAR2(3)
SEGMENT_SPACE_MANAGEMENT                 VARCHAR2(6)
DEF_TAB_COMPRESSION                      VARCHAR2(8)
RETENTION                                VARCHAR2(11)
BIGFILE                                  VARCHAR2(3)
PREDICATE_EVALUATION                     VARCHAR2(7)
ENCRYPTED                                VARCHAR2(3)
COMPRESS_FOR                             VARCHAR2(12)
SQL> desc dba_data_files;
 Name                       Null?    Type
 -------------------------- -------- -------------------------------
 FILE_NAME                           VARCHAR2(513)
 FILE_ID                             NUMBER
 TABLESPACE_NAME                     VARCHAR2(30)
 BYTES                               NUMBER
 BLOCKS                              NUMBER
 STATUS                              VARCHAR2(9)
 RELATIVE_FNO                        NUMBER
 AUTOEXTENSIBLE                      VARCHAR2(3)
 MAXBYTES                            NUMBER
 MAXBLOCKS                           NUMBER
 INCREMENT_BY                        NUMBER
 USER_BYTES                          NUMBER
 USER_BLOCKS                         NUMBER
 ONLINE_STATUS                       VARCHAR2(7)

Segments and Extents

Segment is the generic name used in Oracle databases to represent objects like tables, indexes or partitions. These are stored in Data Files in pieces called Extents.

The Segments can be either in MANUAL mode or in AUTO mode – Automatic Segment Space Management (ASSM)
In earlier Oracle version, the MANUAL mode managed free blocks and free space in a Free List stored the Data Dictionary, which overloaded System tablespace. Since Oracle 10g and ASSM the free blocks and the free space are managed in a bitmap in the Segment Header of each Tablespace.

segments

The 2 main views to find segments and extents information are: dba_segments and dba_extents

SQL> desc dba_segments
Name                       Null?           Type
-------------------------- --------------- -----------------------------------
OWNER                                      VARCHAR2(30)
SEGMENT_NAME                               VARCHAR2(81)
PARTITION_NAME                             VARCHAR2(30)
SEGMENT_TYPE                               VARCHAR2(18)
SEGMENT_SUBTYPE                            VARCHAR2(10)
TABLESPACE_NAME                            VARCHAR2(30)
HEADER_FILE                                NUMBER
HEADER_BLOCK                               NUMBER
BYTES                                      NUMBER
BLOCKS                                     NUMBER
EXTENTS                                    NUMBER
INITIAL_EXTENT                             NUMBER
NEXT_EXTENT                                NUMBER
MIN_EXTENTS                                NUMBER
MAX_EXTENTS                                NUMBER
MAX_SIZE                                   NUMBER
RETENTION                                  VARCHAR2(7)
MINRETENTION                               NUMBER
PCT_INCREASE                               NUMBER
FREELISTS                                  NUMBER
FREELIST_GROUPS                            NUMBER
RELATIVE_FNO                               NUMBER
BUFFER_POOL                                VARCHAR2(7)
FLASH_CACHE                                VARCHAR2(7)
CELL_FLASH_CACHE                           VARCHAR2(7)
SQL> desc dba_extents
Name                       Null?           Type
-------------------------- --------------- ------------------------------------
OWNER                                      VARCHAR2(30)
SEGMENT_NAME                               VARCHAR2(81)
PARTITION_NAME                             VARCHAR2(30)
SEGMENT_TYPE                               VARCHAR2(18)
TABLESPACE_NAME                            VARCHAR2(30)
EXTENT_ID                                  NUMBER
FILE_ID                                    NUMBER
BLOCK_ID                                   NUMBER
BYTES                                      NUMBER
BLOCKS                                     NUMBER
RELATIVE_FNO                               NUMBER

Another important concept to understand, in case of Table segments, is the “High Watermark” (HWM). It defines the position of the last formated block for the segment. It means that in case of a Full table scan (FTS – i.e. select * from table1;) Oracle will go through all the segment’s blocks up to the HWM position.

hwm

The key here is to keep in mind that deleting data, which means free blocks, does NOT move the HWM position. This can have a quite huge impact on requests performances.
The only ways to move down the HWM is either to truncate the table, but this also means losing all data, or to make a table reorganization. However this quite beyond our current topic 😀

So here we are with this introduction into Oracle data storage.
Have fun with Oracle 😀