Thursday, November 12, 2015

Oracle Rac Global Cache Service

Now before going into Cache Fusion – first let’s first memorize once again how actually a normal database instance behaves when there is a request for data block.Let us suppose a user process is requesting a data block, and since this process cannot directly read from the disk, first the requested block must be read(Physical Read) into Buffer Cache of SGA. Once it is read into buffer cache it will remains in the Buffer Cache for further requests. Whenever there is a request for the same data block, since it is already in the buffer, it can be directly read (Buffer Read) from the buffer, thus avoiding another Physical Read. If a data block is found in buffer cache it is called a ‘Cache Hit’ and if it is not found, then it is called a ‘Cache Miss’.
In RAC, there are 2 or more instances accessing same database files that are residing in shared storage area. Each instance has its own SGA and background processes, which means each instance has its own buffer cache .These buffer cache’s act individually at instance level.
(Global Cache) so as to share the data blocks between instances.This is what we called ‘Cache Fusion’. Cache Fusion uses a high-speed IPC interconnect to provide cache-to-cache transfers of data blocks between instances in a cluster.
in a RAC environment, if there are concurrent requests for the same data block – Here too Oracle uses locking and queuing mechanisms to coordinate lock resources, data and inter-instance data requests.Cache Fusion was implemented by a controlling mechanism called Global Cache Service (GCS), which is responsible for block transfers between instances. The Global Cache Service is implemented by various background processes, such as
    Global Cache Service Processes (LMSn)
    Global Enqueue Service Daemon (LMD)
Global Cache Service Daemon (LMSn)
Upon a request from an Instance GCS organizes the block shipping to other instances by retaining block copies in memory. Each such copy is called a past image (PI), which in the event of a node failure, Oracle can reconstruct the current version of a block by using a saved PI.
Global Enqueue Service Daemon (LMD)
The global enqueue service (GES) tracks the status of all Oracle enqueuing mechanisms. The GES performs concurrency control on dictionary cache locks, library cache locks, and transactions. It performs this operation for resources that are accessed by more than one instance. The GES controls access to data files and control files but not for the data blocks. 
The resources managed by the GES include the following:
Transaction locks – It is acquired in the exclusive mode when a transaction initiates its first row level change. The lock is held until the transaction is committed or rolled back.
Library Cache locks – When a database object (such as a table, view, procedure, function, package, package body, trigger, index, cluster, or synonym) is referenced during parsing or compiling of a SQL, DML or DDL, PL/SQL, or Java statement, the process parsing or compiling the statement acquires the library cache lock in the correct mode.
Dictionary Cache Locks – Global enqueues are used in the cluster database mode. The data dictionary structure is the same for all Oracle instances in a cluster database, as it is for instances in a single-instance database. However, in real application clusters, Oracle synchronizes all the dictionary caches throughout the cluster. Real application clusters use latches to do this, just as in the case of a single-instance Oracle database.
Table locks – These are the GES locks that protect the entire table(s). A transaction acquires a table lock when a table is modified. A table lock can be held in any of several modes: null (N), row share (RS), row exclusive (RX), share lock (S), share row exclusive (SRX), or exclusive (X).
GCS (LMSn + LMD) keeps track of the resources, location and their statuses (mode, role) and this information is recorded in Global Resource Directory (GRD). Each instance maintains its own GRD and manages a portion of the directory. Whenever a block is transferred out of a local cache to another instance’s cache the GRD is updated. A GRD knows where exactly a recent version of the data block is available.
To perform any operation on a data block we need to know the current state of the particular data block. To know its current state, it requires 3 things:
1. What is its current role?(Local(L) or Global(G))
2. What is its current mode?(Null (N) or Shared (S) or Exclusive (E))
3. Whether the requesting block has any Past Images (PI)? (0 or 1)
But where can you get this information from? Yes – you are right – from GRD.
Now let me show the different scenarios of data block transfer –
1. Reading the data block from the disk – In this scenario, initially a data block is read (disk read) from the data file, since no copy of this data block is currently available in any of the instances. Once the block is read into the buffer cache, it is in the state of SL0. This indicates that the block now is in shared mode with local role and doesn’t have any past images. The resource information will be updated accordingly in GRD.
2. Reading the data block from the cache – In this scenario, a data block is currently available in one of the instances buffer cache, so there is no need to read from the disk, thus avoiding a physical read. Let us say, Instance 2 request for a data block, in that regard it sends a request to GCS. GCS in turn passes the request to the owning instance (instance 1). Upon receiving the request, instance 1 forwards the data block to the requesting instance (instance 2) keeping the data block in shared mode and also retains its Local role. No past image is created on instance 1 as the data block was not dirtied yet. Now the state of the data block in instance 2 is SL0 (similar to that of reading from a disk).
3. Modifying the data block – In this scenario, Instance 2 requests for a block to modify, and pass the request to GCS. GCS in turn pass the request to the Instance 1 (owner of that data block). Instance 1 modified this data block, but not committed yet. Upon receiving the request, instance 1 sends the data block to instance 2. Before sending, the resource is downgraded to NULL mode and keeps a copy of current version of the block (PI). Now the role becomes Global, since it is dirtied. It also informs Instance 2 that it retained a PI copy and a NULL resource, which specifies that instance 2 can held the block in exclusive mode (X) with a global role (G). Upon receipt of the block, instance 2 informs GCS about the mode and role of the block (X, G).
4. Writing dirty buffers to disk – In this scenario, Instance 1 wants to write the buffer to disk, so a request is send to GCS. GCS forwards the request to instance 2(current holder of block). Upon receiving the request, instance 2 writes the block to the disk and informs GCS. Instance 2 also informs GCS that the resource role now become local because the instance has completed write of the current block. Upon receiving the message GCS orders all PI holders to discard their PI’s and they no longer need for recovery as the current block is written and buffer is released.



No comments:

Post a Comment