Monitoring PCM Locking

Several dynamic views are available to monitor PCM locking activity. Some of these views provide ping statistics at the instance level, while other views provide information about ping activity at the block level. Table 10.1 lists all the V$ views that provide PCM locking statistics and tells you the level at which each view is useful. Statistics for some of the views (e.g., V$PING, V$FALSE_PING, and V$CACHE) are derived from the V$BH view. They contain the same columns as V$BH but provide additional database object information.

Table 10-1. Views with PCM Lock Contention Statistics

Dynamic View

Description

V$LOCK_ACTIVITY

GV$LOCK_ACTIVITY

Instance-level lock activity

Return the cumulative number of lock conversions performed by the instance. One row is returned for each type of conversion such as X to NULL, X to S, NULL to X, and so forth.

V$FILE_PING

GV$FILE_PING

Lock activity by datafile

Return the number of lock conversions for each datafile. One row is returned for each datafile. This view can be used to identify datafiles with a high amount of ping activity.

V$BH

GV$BH

Block-level statistics

Buffer header views. Return one row for each block in the buffer cache and show buffer status, forced reads, forced writes, and so forth.

V$CACHE

GV$CACHE

Block- and object-level lock activity

Like V$BH, return one row for each block in the buffer cache. The view provides the name and owner of the database object that contains the block.

V$CACHE_LOCK

Block- and object-level lock activity

Like V$CACHE but with two operating system-specific columns.

V$PING

GV$PING

Block- and object-level lock activity

Same as V$CACHE but return a list of only those blocks that have been pinged at least once.

V$CLASS_PING

GV$CLASS_PING

Lock activity by block class

Show the number of lock conversions for each block class. Block classes include data blocks, undo blocks, segment headers, and so forth. One row is returned for each block class. Can be used to identify block classes having a high amount of ping activity.

V$FALSE_PING

GV$FALSE_PING

False ping activity

Return one row for each buffer in the buffer cache that is likely experiencing false pings.

V$LOCKS_WITH_COLLISIONS

GV$LOCKS_WITH_COLLISIONS

Locks with high collisions

Return one row on each lock that protects multiple buffers, each of which has been pinged at least 10 times.

V$LOCK_ELEMENT

GV$LOCK_ELEMENT

Information on PCM locks

Return information on each PCM lock that is protecting a buffer in the buffer cache.

One approach to monitoring OPS ping activity is to determine at the instance level and at the datafile level if a lot of pinging is taking place. After you determine this fact, you can identify the specific objects and blocks that are causing the most pings. You also can investigate false pinging. After identifying the objects responsible for most of the pings, you should focus on tuning PCM lock allocation, restructuring tablespaces, and repartitioning the application as required.

Important V$ View Columns

Some of the columns in the dynamic performance views are found in many of the views. This section explains the meaning of the common columns and their significance, along with values of the column where appropriate.

The XNC column

The XNC column is present in the V$BH, V$CACHE, V$PING, and V$FALSE_PING dynamic performance views, as well as in the corresponding GV$ views. The XNC column shows the number of X-to-NULL lock conversations for the block. Each X-to-NULL lock conversion represents a ping. However, this statistic captures only part of the pinging activity for a block. Pinging also is caused by other lock conversions, such as X-to-S changeovers.

This column is now obsolete. It is present in Oracle7 and has been retained in Oracle8 to provide backward compatibility. We recommend that you use the FORCED_READS and FORCED_WRITES statistics to measure ping activity.

The FORCED_WRITES column

The FORCED_WRITES column is present in the V$BH, V$CACHE, V$PING, and V$FALSE_PING dynamic performance views. It’s also present in the corresponding global dynamic (GV$) performance views. FORCED_WRITES shows the number of times a block has been written to disk because another instance needed the lock on that block in a conflicting mode. Forced writes entail the following lock conversions:

X to NULL
X to S
X to SSX

The FORCED_READS column

The FORCED_READS column is present in the same views as the FORCED_WRITES column. It shows the number of times a block has to be reread from disk because of a previous forced write. Together, the FORCED_WRITES and FORCED_READS values represent extra I/O that is performed by an OPS instance as a result of PCM lock conflicts. This extra I/O would not be necessary in a standalone instance configuration.

The STATUS column

The STATUS column shows the status of the blocks in the database buffer cache. This column is present in the V$BH, V$CACHE, V$PING, and V$FALSE_PING dynamic performance views. Buffer status also is referred to as the buffer state, and it corresponds to the lock modes. For example, when an instance acquires an exclusive lock on a block, the buffer state changes to XCUR. Table 10.2 shows the buffer state codes along with any applicable corresponding lock modes.

Table 10-2. Buffer States

Buffer State

Description

PCM Lock Mode

XCUR

Instance has an exclusive lock on the buffer.

X

SCUR

Instance has a shared lock on the buffer.

S

CR

Instance has a NULL lock on the buffer.

N

READ

Instance is reading from disk to the buffer.

N/A

MREC

Buffer is in media recovery mode.

N/A

IREC

Buffer is in instance recovery mode.

N/A

FREE

Buffer is currently not used.

N/A

The KIND column

The KIND column tells you the type of database object represented by the data in a particular block. KIND is present in the V$BH, V$CACHE, V$PING, and V$FALSE_PING views, as well as in the corresponding global dynamic performance views. Table 10.3 shows the possible values for this column.

Table 10-3. Object Type Codes for the KIND Column

Value

Object Type

1

INDEX

2

TABLE

3

CLUSTER

4

VIEW

5

SYNONYM

6

SEQUENCE

7

PROCEDURE

8

FUNCTION

9

PACKAGE

10

NON-EXISTENT

11

PACKAGE BODY

12

TRIGGER

13

TYPE

14

TYPE BODY

19

TABLE PARTITION

20

INDEX PARTITION

21

LOB

22

LIBRARY

The V$LOCK_ACTIVITY View

The V$LOCK_ACTIVITY view provides statistics on the number of overall lock mode conversions in an instance. These statistics are cumulative from the time that the instance was started. The query in the following example reports on the lock conversions in instance 1:

SQL> SELECT * 
  2  FROM gv$lock_activity
  3  WHERE inst_id = 1;


FROM_VAL TO_VAL  ACTION_V                                COUNTER
-------- ------  -------------------------------------- --------
NULL      S      Lock buffers for read                     45595
NULL      X      Lock buffers for write                   139115
S         NULL   Make buffers CR (no write)                50625
S         X      Upgrade read lock to write                87555
X         NULL   Make buffers CR (write dirty buffers)    108366
X         S      Downgrade write lock to read              94261
                 (write dirty buffers)        
X         SSX    Write transaction table/undo blocks       11142
SSX       X      Rearm transaction table write mechanism   11142

8 rows selected.

Rate of change

When you look at V$LOCK_ACTIVITY, you can’t just query the view once and look at the raw numbers. The statistics are cumulative, and if you’re looking at the statistics a few weeks after you start your instance, the numbers may indeed look high. The point to focus on is the rate at which the lock conversions are taking place. To determine the rate, you need to query V$LOCK_ACTIVITY twice and note the difference in the COUNTER values between the two queries.

As an example, assume that in instance 1 the count of X-to-NULL conversions increases from 108,400 to 120,400 between two queries against V$LOCK_ACTIVITY. The net number of X-to-NULL lock conversions during the time period is then 12,000. This indicates that instance 1 is forced to write many modified blocks to disk because another instance needs the corresponding locks in exclusive mode. This represents pinging. If you run the same query while connected to the other instance, you would notice a large number of lock conversions from NULL to X, as the second instance is acquiring those same locks in exclusive mode.

Lock-related disk writes

Lock downgrades from exclusive (X) modes to other modes such as NULL, shared (S), or subshared exclusive (SSX) involve disk writes. The following list describes the implications of these downgrades:

X to NULL

An instance is modifying a block and is holding the corresponding lock in exclusive mode. Another instance needs the same lock in exclusive mode in order to modify a block covered by the same lock. The instance holding the lock has to write the data to disk and then downgrade the lock from X to NULL. The other instance then upgrades its lock from NULL to X.

X to S

An instance is modifying a block and is holding the corresponding lock in exclusive mode. Another instance needs the same lock in shared mode in order to read a block covered by the lock. The instance holding the lock has to write the data to disk and then downgrade the lock mode from X to S. The other instance then upgrades its lock from NULL to S.

X to SSX

SSX locks are used for undo blocks in the rollback segment. One instance is modifying blocks and is holding the corresponding locks in exclusive mode. The instance also acquires exclusive locks on the undo blocks as these blocks also are modified when recording the rollback entries. Another instance is running a query that needs data from undo blocks. The first instance has to write the undo blocks to disk. The locks covering the undo blocks then are downgraded from X to SSX. After the consistent read operation is performed by the second instance, the lock mode changes back from SSX to X. In any instance, the number of X-to-SSX conversions will be the same as the number of SSX-to-X conversions.

As an example of how to look at lock-related disk writes, say that we queried the V$LOCK_ACTIVITY view and found the following lock mode conversion numbers:

X   to  NULL    108366
X   to  S       94261
X   to  SSX     11142

Adding the number of all X-to-NULL, X-to-S, and X-to-SSX conversions together, we get a total of 213,769 lock conversions. These lock mode conversions result in disk writes. Now, let’s find the total number of blocks that are written to disk because of these lock conversions. The “DBWR cross instance writes” statistic in the V$SYSSTAT view provides the total number of blocks written to disk because of lock mode conversions. You can query for that information as shown in this example:

SQL> SELECT * FROM v$sysstat 
                     WHERE statistic# = 'DBWR cross instance writes';

STATISTIC# NAME                                CLASS      VALUE
---------- ------------------------------ ---------- ----------
        77 DBWR cross instance writes             40    417,143

The ping rate shows the average number of blocks written to disk for each lock downgrade. The ping rate is computed as follows:

Ping rate = DBWR cross instance writes
              /Lock operations resulting in disk writes
          = 417,143/213,769
          = 1.95

The ping rate provides an indication as to whether false pings are occurring. The following paragraphs explain how to interpret the ping rate:

Ping rate < 1

A ping rate of less than 1 indicates a high degree of soft ping activity. Typically, each X-to-NULL, X-to-S, and X-to-SSX lock conversion causes at least one block write to disk. However, in some situations, no disk write occurs if the blocks covered by the lock have already been written to disk as a result of a normal checkpoint operation. This scenario is referred to as a soft ping. In this case, a lot of soft ping activity in the instance is bringing down the overall ping rate to less than 1.

Ping rate > 1

A ping rate of greater than 1 indicates a high degree of false ping activity. In other words, on average, each lock operation is causing more than one block to be written to disk. In this chapter’s example, the ping rate is 1.95. This number indicates that false pings are definitely occurring. The goal is to bring down the ping rate to 1 by reducing the occurrence of false pings. You can compute the percentage of disk writes due to false pings using the following formulas and query:

Percentage of disk writes due to false pings
    = ((DBWR cross instance writes - Lock operations resulting in disk write)
              /DBWR cross instance writes) * 100
    = (417,143-213,769) / 417,143
    = 48.754024
 
SQL> SELECT ((s.value - ( a.counter + b.counter + c.counter)) / s.value )* 100
  2  "PERCENTAGE FALSE PING"
  3  FROM  v$sysstat s, v$lock_activity a, v$lock_activity b, v$lock_activity 
  4  WHERE a.from_val ='X' AND a.to_val ='NULL' 
  5  AND   b.from_val ='X' AND b.to_val ='S' and  
  6  AND   c.from_val ='X' AND c.to_val ='SSX'
  7* AND   s.name = 'DBWR cross instance writes'

PERCENTAGE FALSE PING
---------------------
            48.754024

In this example, more than 48% of the blocks written to disk are due to false pings. False pings occur when one lock covers more than one block, and you can allocate additional PCM locks to reduce the occurrence of false pings.

Ping rate = 1

A ping rate of 1 indicates that, on average, each lock operation is causing one block to be written to disk. Either soft pings and false pings are not occurring, or they are occurring together in a way that masks each other’s effects on the ping rate statistic. Unfortunately, it isn’t possible to reach any definite conclusion.

You also should monitor lock activity in all OPS instances using the GV$LOCK_ACTIVITY view. Once you know that in general there is high ping activity in the instance, you then should monitor the V$FILE_PING view to find out which specific datafiles have high ping activity.

The V$FILE_PING View

The V$FILE_PING view tells you the amount of lock activity for each file in your database. This view returns one row for each datafile and is very useful in identifying files that incur a high number of pings. Once you identify files with high ping rates, you can further investigate to find out which specific objects and blocks in those files are being pinged the most. You also can investigate to find out which instances are contending for those resources. Here’s an example of a query against the GV$FILE_PING view:

SQL> SELECT file_number, x_2_null, X_2_S, S_2_NULL
  2* FROM v$file_ping                                                                   

FILE_NUMBER   X_2_NULL      X_2_S   S_2_NULL
----------- ---------- ---------- ----------
          1     134198     187545     165542
          2       3094       2700       4838
          3        512      17858       4202
          4      40569         65        175

This report indicates that datafile 1 has the greatest amount of lock activity. Because these statistics are cumulative since instance startup, you should run this query repeatedly in order to determine the rate of lock activity for each file. If a table has high lock activity, particularly X_2_NULL and X_2_S lock mode conversions, this fact also implies high ping activity. Further monitor V$FALSE_PING and other views to find out if the pings are false pings or true pings.

The V$BH and V$CACHE Views

The V$BH view returns buffer header information. For every buffer in the database buffer cache, it returns the buffer status and the number of X-to-NULL lock conversions, forced reads, and forced writes. It also provides the block number and the file number for the block that is in the buffer. V$BH does not contain any information on the database object associated with the block that is in the buffer. However, you can join this view with the OBJ$ view in order to identify the objects corresponding to V$BH’s blocks. The V$BH view is defined internally in the server, and other views such as V$CACHE and V$PING are based on the V$BH view.

The V$CACHE view returns one row for each block in the buffer cache, except for those blocks that do not have a lock element associated with them. Temporary blocks, for example, do not have locks. V$CACHE contains many of the same columns as the V$BH view, including XNC, FORCED_READS, and FORCED_WRITES. In addition, this view maps blocks to their respective database objects and also indicates the type and owner of those objects.

The V$PING View

The V$PING view contains a subset of rows from the V$CACHE view. It shows only those blocks in the buffer cache that have experienced at least one forced read or one forced write. Query V$PING to find out which blocks and objects have a high number of forced reads and forced writes. You may limit the query to a particular datafile that you have identified as a result of querying V$FILE_PING. Run the same query on other instances to identify all the instances involved in pinging the objects in question, for example:

SQL> SELECT name, block#, kind, forced_writes, 
  2          forced_reads, lock_element_addr
  3  FROM v$ping
  4  WHERE forced_writes > 10 AND forced_reads > 10
  5  AND file# = 4
  6* ORDER BY name

NAME            BLOCK# KIND     FORCED_WRITES FORCED_READS LOCK_ELE
----------- ---------- -------- ------------- ------------ --------
CUST_INFO        13631 TABLE             3170         2180 34E054CC
CUST_INFO        13643 TABLE              150          268 34E0578C
CUST_INFO        13633 TABLE              170          180 34E0550C
.                .     .                  .            .   .       
.                .     .                  .            .   .       
.                .     .                  .            .   .       
PK_CUST_INFO     53691 INDEX             1176          200 64E0638C
PK_CUST_INFO     53759 INDEX              756          636 64E0748C
PK_CUST_INFO     53758 INDEX              756          636 64E0744C

This sample report shows the tables and indexes that have encountered high forced read and forced write activity. In this example, CUST_INFO is a “hot” object. Note the block number for each hot object. Then query the GV$BH view to find out if the same block numbers also show up in other OPS instances. Query GV$BH instead of V$BH, because you want to see this information for all instances. With respect to the example shown here, we need to query GV$BH for block number #13631, because the number of forced writes and forced reads is high for that block. If the same block number does not show up in other instances, there is contention for locks, implying false pings. If you see the same block number in other instances, then there is contention for the block, and true pings are occurring.

If the lock activity is due to true pings, check to see whether access to this object can be localized to only one instance. Investigate the various application partitioning strategies described in Chapter 11. If the object is a small object, consider using a high PCTFREE value for the object so that the data is spread out among more blocks. This reduces the likelihood of block contention.

If identifying the specific blocks of an object that are experiencing high amounts of ping activity isn’t enough to help you reduce that activity, you can further drill down to find out which rows are in those blocks. To identify the rows contained in a hot block, start by converting the block number to hexadecimal. Once you’ve done that, you can take advantage of the fact that the first part of the database rowid is the block number. In Oracle7, you can issue a query such as the following to identify the rows contained in a hot block:

SELECT * 
FROM trans_log
WHERE ROWID LIKE '%372A%'

This query will return all rows in which the ROWID contains the block number of interest. Note that Oracle8 and Oracle8i use a new ROWID format. You still can use this technique under Oracle8 and Oracle8i, but you need to use a conversion function in your query in order to convert the new ROWIDs back into the old format, for example:

SELECT * 
FROM trans_log
WHERE DBMS_ROWID.ROWID_TO_RESTRICTED(rowid,1) like '%372A%'

Drilling down to the row level and identifying the rows in a “hot” block may provide some insight as to the data for which multiple instances may be contending.

The V$LOCKS_WITH_COLLISIONS and V$FALSE_PING Views

There is always the possibility that false pings will occur whenever a single PCM lock covers more than one block. Even when two instances are modifying different blocks, pinging still can occur because of lock conflicts.

The V$LOCKS_WITH_COLLISIONS view identifies locks that protect more than one block in cases in which the number of forced reads and forced writes for each block exceeds 10. Since each such lock is protecting more than one block with a high degree of ping activity, it is likely that false pings are occurring. The locks are identified by their address, which is returned by the LOCK_ELEMENT_ADDR column. LOCK_ELEMENT_ADDR is the only column returned by the view.

The V$FALSE_PING view shows the blocks that are protected by the locks identified by the V$LOCKS_WITH_COLLISIONS view. These are the blocks most likely to be experiencing false pings. The following query retrieves a list of these blocks that includes their respective object names and file numbers:

SELECT name, kind, file#, block, forced_reads, forced_writes 
FROM v$false_ping 
ORDER BY name, file#;

If a query of the V$FALSE_PING view returns a large number of blocks, then note the file IDs for those blocks and consider allocating additional hashed PCM locks to those datafiles. Doing so will reduce the granularity (the number of blocks covered by a lock) for all objects in the datafile, consequently reducing the number of false pings. If the file is very large and contains many other objects, it may not be possible to allocate enough locks to significantly reduce the granularity for the object you are interested in. In that case, consider placing the object in a separate tablespace and hence in its own datafile. The new datafile will contain fewer blocks than the original datafile, so the same incremental allocation of locks to the new datafile will greatly reduce granularity, which will more effectively reduce false pings. Alternatively, you also might consider using releasable fine-grained locks for those datafiles.

The V$CLASS_PING View

The V$CLASS_PING view summarizes ping activity by block class for the blocks in the database buffer cache. Here’s an example of the output that you’ll get when querying this view:

SQL> SELECT class, X_2_NULL, X_2_S, X_2_SSX, SSX_2_X,  S_2_NULL, S_2_X
  2  FROM v$class_ping;

CLASS              X_2_NULL   X_2_S X_2_SSX SSX_2_X S_2_NULL  S_2_X
------------------ -------- ------- ------- ------- -------- ------
                          0       0       0       0        0      0
data block           570139 1017442       0       0   238738 356407
sort block                0       0       0       0        0      0
save undo block           0       0       0       0        0      0
segment header        27842     393       0       0      258    439
save undo header          0       0       0       0        0      0
free list                 0       0       0       0        0      0
extent map                0       0       0       0        0      0
bitmap block              0       0       0       0        0      0
bitmap index block        0       0       0       0        0      0
unused                    0       0       0       0        0      0
undo header               0    2183   24705   24705     2531   2197
undo block                0       0    5335    5335        0      0

13 rows selected.

The data in this report shows that most of the lock conversion takes place for data blocks and segment headers. Segment headers contain information on free data blocks. Segment header contention occurs when more than one instance is inserting data into an object at the same time. Chapter 9, describes some techniques that you can use to reduce segment header contention.

Also notice the values for the X_2_SSX and SSX_2_X columns in this example. These represent X-to-SSX and SSX-to-X conversions, respectively. These conversions occur only for undo headers and undo blocks. The counts for X-to-SSX and SSX-to-X conversions will always be the same because each X-to-SSX conversion is followed by a corresponding SSX-to-X conversion.

The V$LOCK_ELEMENT View

A lock element is a data structure in an Oracle instance that stores information on a PCM lock. There is one lock element for each PCM lock allocated. The V$LOCK_ELEMENT view contains one row for each lock element and has information such as the lock element name, the lock element address, the number of blocks protected by the lock, and so forth. Using this view, you can get an idea of how many blocks are protected by locks and the average number of blocks protected by one lock. The following two queries provide this information:

SELECT block_count, COUNT(*) 
FROM v$lock_element
GROUP BY block_count;

SELECT AVG(block_count)
FROM v$lock_element;

Using this view, you also can confirm that the number of PCM locks allocated matches what you think you asked for using the GC_ initialization parameters. For example, with the following GC_FILES_TO_LOCKS and GC_RELEASABLE_LOCKS parameter settings, the total number of PCM locks in the instance will be 11,000:

GC_FILES_TO_LOCKS = "1=2000:2-5=1000EACH"
GC_RELEASABLE LOCKS = 5000

You can query V$LOCK_ELEMENT to find out the overall number of PCM locks that have been allocated. You also can query for the number of fixed and releasable PCM locks that have been allocated. The following query, for example, returns the total number of PCM locks allocated to each instance. This total includes both fixed and releasable PCM locks:

SQL> SELECT COUNT(*) FROM v$lock_element;

Count(*)
---------
11,0000

To count up the number of fixed PCM locks that have been allocated, use the FLAGS column in the WHERE clause as follows:

SQL> SELECT COUNT(*) FROM v$lock_element
                  WHERE BITAND(flags,4) != 0;

Count(*) 
--------
6,000

You can use a similar query to count up the number of releasable PCM locks. You only need to change the WHERE clause so that the query counts lock elements where BITAND(flags,4) = 0. Once you have the values returned by these queries, you then can verify that they correspond to your GC_ parameter settings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.132.99