Automatic Storage Management (ASM) is essentially a volume manager and a file system for exclusive use by ORACLE instances. The volume management capabilities include mirroring and striping. ASM implements the S.A.M.E. (stripe and mirror everything)2 approach. ASM uses a number of raw devices,3 concatenates them into a large pool of storage, and offers the storage space as a kind of file system to ORACLE instances. Raw disks (e.g., LUNs in a SAN) are grouped into disk groups. ASM can rely on RAID storage arrays for mirroring (external redundancy) or it can do its own mirroring (normal/high redundancy). If necessary, disks in a disk group may 1. The format in which the UNIX command ls displays permissions, is {r|-}{w|-}{x|-}. This sequence of
characters is repeated three times. The left part applies to the owner of the file, group permissions are in the middle, and permissions for anyone (a.k.a. world) are on the right. A minus sign means that the permission represented by the position in the string is not granted. For example, rwxr-xr-x means that the owner may read, write, and execute, the group may read and execute and anyone may read and execute.
2. See http://www.oracle.com/technology/deploy/availability/pdf/OOW2000_same_ppt.pdf
3. Oracle10g Release 2 on Linux supports block devices too. These are opened with O_DIRECT to eliminate caching by the Linux operating system kernel as with raw devices. Performance is the same as that of raw devices, which have been deprecated on the Linux platform.
Debes_1952-1C02.fm Page 31 Thursday, May 7, 2009 9:22 AM
be assigned to failure groups, which indicate the storage system topology to ASM, such that mirrored copies can be placed on different storage arrays or may be accessed using different host bus adapters.
For readers who would like to familiarize themselves with ASM, but do not have access to a SAN or cannot create raw devices on a local disk due to space constraints or lack of privileges, this chapter demonstrates how to set up a test environment for automatic storage management on Windows with cooked files and _ASM_ALLOW_ONLY_RAW_DISKS. Old school UNIX jargon distin- guished raw files from cooked files. Cooked files are simply the opposite of raw devices—files in a file system. After all, something that’s not raw has to be cooked, right?
ASM Hidden Parameters
Undocumented parameters pertaining to ASM may be retrieved by running the following query as user SYS:
SQL> SELECT x.ksppinm name, y.ksppstvl value, x.ksppdesc description FROM x$ksppi x, x$ksppcv y
WHERE x.inst_id = userenv('Instance') AND y.inst_id = userenv('Instance') AND x.indx = y.indx
AND x.ksppinm LIKE '\_asm%' ESCAPE '\' ORDER BY name;
NAME VALUE DESCRIPTION
--- --- --- _asm_acd_chunks 1 initial ACD chunks created
_asm_allow_only_raw_disks TRUE Discovery only raw devices _asm_allow_resilver_corruption FALSE Enable disk resilvering for external redundancy
_asm_ausize 1048576 allocation unit size _asm_blksize 4096 metadata block size
_asm_disk_repair_time 14400 seconds to wait before dropping a failing disk
_asm_droptimeout 60 timeout before offlined disks get dropped (in 3s ticks)
_asm_emulmax 10000 max number of concurrent disks to emulate I/O errors
_asm_emultimeout 0 timeout before emulation begins (in 3s ticks)
_asm_kfdpevent 0 KFDP event
_asm_libraries ufs library search order for discovery _asm_maxio 1048576 Maximum size of individual I/O request
_asm_stripesize 131072 ASM file stripe size _asm_stripewidth 8 ASM file stripe width
_asm_wait_time 18 Max/imum time to wait before asmb exits
_asmlib_test 0 Osmlib test event _asmsid asm ASM instance id
C H A P T E R 2 ■ H I D D E N I N I T I A L I Z A T I O N P A R A M E T E R S 33
These parameters unveil some of ASM’s inner workings. The default settings indicate that ASM divides an allocation unit (_ASM_AUSIZE) into 128 KB chunks (_ASM_STRIPESIZE) and places each of those chunks on up to eight different disks (_ASM_STRIPEWIDTH). Very large databases may benefit from increasing _ASM_AUSIZE, but this is beyond the scope of this book.4 This chapter merely addresses _ASM_ALLOW_ONLY_RAW_DISKS.
Setting Up Oracle Clusterware for ASM
To start an ASM instance, a stripped down version of Oracle Clusterware must be running on the same system. This is accomplished with the command %ORACLE_HOME%\bin\localconfig add, which creates an ORACLE cluster registry (OCR) in %ORACLE_HOME%\cdata\localhost\
local.ocr. It also creates a new Windows service for the OCSSD Clusterware daemon. OCSSD logging goes to the file %ORACLE_HOME%\log\<host name>\cssd\ocssd.log.
C:> localconfig add
Step 1: creating new OCR repository
Successfully accumulated necessary OCR keys.
Creating OCR keys for user 'ndebes', privgrp ''..
Operation successful.
Step 2: creating new CSS service successfully created local CSS service successfully added CSS to home
The service that implements OCSSD is called OracleCSService. You can verify that the service is functional by running the command net start in a Windows command interpreter.
This command lists all running services.
C:> net start
…
OracleCSService
OracleDB_10_2TNSListener
…
The Clusterware command for checking OCSSD’s status is crsctl check css.
C:> crsctl check css CSS appears healthy
By running crsctl check crs, it becomes apparent that only a subset of Clusterware daemons are active in a local-only configuration. The CRS and EVM daemons required for RAC are not needed.
C:> crsctl check crs CSS appears healthy
Cannot communicate with CRS Cannot communicate with EVM
4. See http://h20331.www2.hp.com/ERC/downloads/4AA0-9728ENW.pdf and Metalink note 368055.1.
Debes_1952-1C02.fm Page 33 Thursday, May 7, 2009 9:22 AM
ASM Instance Setup
Next, we will create some cooked files for ASM storage. ASM will use these files instead of raw disks. On Windows, the undocumented switch -create of the asmtool command is used to create cooked files for use by ASM. The syntax is as follows:
asmtool -create <file_name> <file_size_mb>
We will use the asmtool command to create four files which will serve as “disks”. Each file has a size of 512 MB.
C:\> mkdir C:\oradata
C:\> asmtool -create C:\oradata\ARRAY1_DISK1 512
Repeat the asmtool command with the file names ARRAY1_DISK2, ARRAY2_DISK1, and ARRAY2_DISK2 to create three more files. On UNIX, the dd command is available to accomplish the same task as asmtool -create. Following is an example for creating a file with a size of 512 MB:
$ dd if=/dev/zero bs=1048576 count=512 of=ARRAY1_DISK1
The above dd command reads 512 blocks with a size of 1 MB each from the device special file /dev/zero. Since reading from /dev/zero returns nothing but binary zeros, the resulting file is zeroed out as required by ASM. The dd command is available for Windows systems by installing Cygwin (http://www.cygwin.com). The dd option conv=notrunc is interesting in that it may be used to zero out a section within a file to simulate a failure or induce a block corruption.
The four files will be used to simulate two disk arrays (ARRAY1 and ARRAY2) with two logical units (LUNs) each. We will then set up ASM to mirror across the two arrays. Striping occurs within the array boundaries.
C:\oradata>ls -l total 2463840
-rw-rw-rw- 1 ndebes mkpasswd 536870912 Nov 2 13:34 ARRAY1_DISK1 -rw-rw-rw- 1 ndebes mkpasswd 536870912 Nov 2 13:38 ARRAY1_DISK2 -rw-rw-rw- 1 ndebes mkpasswd 536870912 Nov 2 13:40 ARRAY2_DISK1 -rw-rw-rw- 1 ndebes mkpasswd 536870912 Nov 2 13:38 ARRAY2_DISK2
To start an ASM instance, a parameter file that contains INSTANCE_TYPE=ASM is required.
The parameter ASM_DISKSTRING is used to indicate where ASM should search for disks. Create a file called pfile+ASM.ora with the following contents in %ORACLE_HOME%\database:
instance_type = ASM
asm_diskstring = 'c:\oradata\*'
Next, create a Windows service for the ORACLE ASM instance with oradim:
C:> oradim -new -asmsid +ASM -syspwd secret -startmode manual -srvcstart demand Instance created.
The command oradim creates and starts a Windows service called OracleASMService+ASM.
You may verify that the service is running with net start.
C:> net start | grep -i asm OracleASMService+ASM
Now we are ready to start the ASM instance.
C H A P T E R 2 ■ H I D D E N I N I T I A L I Z A T I O N P A R A M E T E R S 35
C:> set ORACLE_SID=+ASM C:> sqlplus / as sysdba
SQL*Plus: Release 10.2.0.3.0 - Production on Tue Aug 14 16:17:51 2007 Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to an idle instance.
SQL> STARTUP NOMOUNT PFILE=?\database\pfile+ASM.ora ASM instance started
Total System Global Area 79691776 bytes Fixed Size 1247396 bytes Variable Size 53278556 bytes ASM Cache 25165824 bytes
Next, we create a server parameter file (SPFILE), such that ASM will be able to store disk group names it should mount at instance startup in the SPFILE.
SQL> CREATE SPFILE FROM PFILE='?\database\pfile+ASM.ora';
File created.
This creates an SPFILE called spfile+ASM.ora. Let’s see whether ASM recognizes the cooked files as disks.
SQL> SELECT path, header_status FROM v$asm_disk;
no rows selected
ASM does not see any disks that it might use. This is not surprising, since the default setting of the parameter _ASM_ALLOW_ONLY_RAW_DISKS is TRUE. We need to shut down the instance and restart it before we can change the parameter in the SPFILE that we created.
SQL> SHUTDOWN IMMEDIATE
ORA-15100: invalid or missing diskgroup name ASM instance shutdown
SQL> STARTUP NOMOUNT ASM instance started
…
SQL> SHOW PARAMETER SPFILE NAME TYPE VALUE
--- --- --- spfile string C:\ORACLE\PRODUCT\DB10.2\DATABASE\SPFILE+ASM.ORA
Since _ASM_ALLOW_ONLY_RAW_DISKS is a static parameter, another instance restart is required after changing it.
SQL> ALTER SYSTEM SET "_asm_allow_only_raw_disks"=FALSE SCOPE=SPFILE SID='*';
System altered.
SQL> SHUTDOWN IMMEDIATE
ORA-15100: invalid or missing diskgroup name ASM instance shutdown
SQL> STARTUP NOMOUNT ASM instance started
…
Debes_1952-1C02.fm Page 35 Thursday, May 7, 2009 9:22 AM
SQL> SELECT path, header_status, library, total_mb, free_mb FROM v$asm_disk;
PATH HEADER_STATUS LIBRARY TOTAL_MB FREE_MB --- --- --- --- --- C:\ORADATA\ARRAY1_DISK1 CANDIDATE System 512 0 C:\ORADATA\ARRAY2_DISK2 CANDIDATE System 512 0 C:\ORADATA\ARRAY2_DISK1 CANDIDATE System 512 0 C:\ORADATA\ARRAY1_DISK2 CANDIDATE System 512 0
This time ASM did recognize the cooked files as disks for use in a disk group, so we may go ahead and create a disk group with external redundancy. By assigning the failure group array1 to the disks in the first disk array (files ARRAY1_DISK1 and ARRAY1_DISK2) and the failure group array2 to the second disk array (files ARRAY2_DISK1 and ARRAY2_DISK2), ASM is instructed to mirror across the two disk arrays. It will automatically stripe the data within each disk array.
SQL> CREATE DISKGROUP cooked_dg NORMAL REDUNDANCY FAILGROUP array1
DISK
'C:\ORADATA\ARRAY1_DISK1' NAME array1_disk1, 'C:\ORADATA\ARRAY1_DISK2' NAME array1_disk2 FAILGROUP array2
DISK
'C:\ORADATA\ARRAY2_DISK1' NAME array2_disk1, 'C:\ORADATA\ARRAY2_DISK2' NAME array2_disk2;
Diskgroup created.
The disks that were formerly candidates are now members of a disk group.
SQL> SELECT path, header_status, library, total_mb, free_mb FROM v$asm_disk;
PATH HEADER_STATUS LIBRARY TOTAL_MB FREE_MB --- --- --- --- --- C:\ORADATA\ARRAY1_DISK1 MEMBER System 512 482 C:\ORADATA\ARRAY1_DISK2 MEMBER System 512 489 C:\ORADATA\ARRAY2_DISK1 MEMBER System 512 484 C:\ORADATA\ARRAY2_DISK2 MEMBER System 512 487
As you can see by comparing the columns TOTAL_MB and FREE_MB, ASM uses quite a bit of space for internal purposes. The view V$ASM_DISKGROUP gives access to information on disk groups.
If you have read the overview of hidden ASM parameters at the beginning of this chapter atten- tively, you will recognize the settings of two hidden parameters in the following output:
SQL> SELECT name, block_size, allocation_unit_size, state, type, total_mb, usable_file_mb
FROM v$asm_diskgroup;
NAME BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB USABLE_FILE_MB --- --- --- --- --- --- --- COOKED_DG 4096 1048576 MOUNTED NORMAL 2048 715
The value in column BLOCK_SIZE is derived from the parameter _ASM_BLKSIZE, while ALLOCATION_UNIT_SIZE is derived from _ASM_AUSIZE. You may now use DBCA to create a database in the disk group. Make sure you choose ASM storage for all data files.
C H A P T E R 2 ■ H I D D E N I N I T I A L I Z A T I O N P A R A M E T E R S 37
Disk Failure Simulation
Chances are high that you have never had to deal with disk failure in an ASM environment. To prepare yourself for such a case, you may wish to use the environment set up in this chapter to simulate disk failure and gain experience with repairing an ASM setup. Disk failure may be simulated by placing cooked files on an external FireWire disk drive, USB disk drive, or USB stick, and pulling the cable to the disk or the stick. In a SAN environment, disk failure might by simulated by pulling cables, changing the zoning configuration, or removing logical unit number (LUN) access rights in a storage array. The term zoning is used to describe the config- uration whereby a storage area network administrator separates a SAN into units and allocates storage to those units. Each disk or LUN in a SAN has a unique identification called a worldwide number (WWN). If a WWN is made invisible to a system by changing the zoning configuration, neither ASM nor RDBMS instances will be able to use the LUN.
Source Code Depot
Table 2-1 lists this chapter’s source files and their functionality.
Table 2-1. Hidden Parameters Source Code Depot
File Name Functionality
10g_hidden_parameters.html Complete list of undocumented parameters in Oracle10g with default values and descriptions
11g_hidden_parameters.html Complete list of undocumented parameters in Oracle11g with default values and descriptions
9i_hidden_parameters.html Complete list of undocumented parameters in Oracle9i with default values and descriptions
hidden_parameters.sql SELECT statement for retrieving all hidden parameters with their values and descriptions
hidden_parameter_value.sql SELECT statement for retrieving the value of a single hidden parameter
Debes_1952-1C02.fm Page 37 Thursday, May 7, 2009 9:22 AM
Debes_1952-1C03.fm Page 39 Friday, April 24, 2009 9:43 AM
P A R T 2
Data Dictionary Base Tables
41
■ ■ ■
C H A P T E R 3
Introduction to Data Dictionary Base Tables
Each ORACLE database contains a data dictionary that holds metadata, i.e., data about the database itself. Data dictionary objects are mostly clusters, tables, indexes, and large objects.
The data dictionary is like the engine of a car. If it doesn’t ignite (or rather bootstrap using SYS.BOOTSTRAP$), then all the other fancy features are quite useless. Traditionally, all data dictionary objects were stored in the tablespace SYSTEM. With the release of Oracle10g, the additional tablespace SYSAUX was introduced. This new tablespace contains the Workload Repository base tables (WRI$* and WRH$* tables) and other objects.
Knowing how to leverage data dictionary base tables allows a DBA to accomplish tasks that cannot be completed by accessing data dictionary views built on top of dictionary base tables. This includes scenarios where dictionary views lack required functionality as well as workarounds for defects in data dictionary views.
The data dictionary is created behind the scenes when the SQL statement CREATE DATABASE is executed. It is created by running the script $ORACLE_HOME/rdbms/admin/sql.bsq. Except for some placeholders, sql.bsq is a regular SQL*Plus script. Oracle9i contains 341 data dictionary base tables, Oracle10g 712, and Oracle11g 839.
Database administrators and users seldom access the data dictionary base tables directly.
Since the base tables are normalized and often rather cryptic, the data dictionary views with prefixes DBA_*, ALL_* and USER_* are provided for convenient access to database metadata.
Some data dictionary views do not have one of these three prefixes (e.g., AUDIT_ACTIONS). The well-known script catalog.sql creates data dictionary views. By looking at view definitions in catalog.sql, it becomes apparent which base table column corresponds to which dictionary view column.
For optimum performance, data dictionary metadata are buffered in the dictionary cache.
To further corroborate the saying that well-designed ORACLE DBMS features have more than a single name, the dictionary cache is also known as the row cache. The term row cache stems from the fact that this cache contains individual rows instead of entire blocks like the buffer cache does. Both caches are in the SGA. The dictionary cache is part of the shared pool, to be precise.
The role DBA includes read-only access to data dictionary base tables through the system privilege SELECT ANY DICTIONARY. This privilege should not be granted frivolously to non-DBA users. This is especially true for Oracle9i where the dictionary base table SYS.LINK$ contains unencrypted passwords of database links, whereas the dictionary view DBA_DB_LINKS, which is accessible through the role SELECT_CATALOG_ROLE, hides the passwords. Passwords for database
Debes_1952-1C03.fm Page 41 Friday, April 24, 2009 9:43 AM
links are encrypted during the upgrade process to Oracle10g. Table 3-1 lists some dictionary tables that are related to prominent database objects.
Of course, dictionary base tables should never be changed directly, as this may easily cause database corruption. Querying dictionary base tables should be considered when data dictionary views do not expose enough information to solve a task. Sometimes dictionary views have bugs, which can be worked around by accessing the base tables directly. The script sql.bsq is well commented, such that reading this script may aid in understanding the struc- ture of the dictionary base tables.
Large Objects and PCTVERSION vs. RETENTION
An example of leveraging direct access to dictionary base tables is an issue with the data dictionary view DBA_LOBS in Oracle9i and Oracle10g Release 1. The view fails to correctly report the versioning setting for LOB segments. Since Oracle9i, multiversion read consistency for LOBs is done either by setting aside a certain percentage of storage in the LOB segment (SQL keyword PCTVERSION;
old approach) or with undo segments (SQL keyword RETENTION; new approach). The default for an Oracle9i database with automatic undo management is PCTVERSION. For an Oracle10g data- base in automatic undo management mode, the default is RETENTION. The setting of RETENTION cannot be specified with SQL syntax and is copied from the parameter UNDO_RETENTION. Here’s an example that uses both approaches within a single table:
Table 3-1. Data Dictionary Base Tables Object Data Dictionary
Base Table
Associated DBA_* View(s)
Clusters CLU$ DBA_CLUSTERS, DBA_SEGMENTS
Database links LINK$ DBA_DB_LINKS
Data files FILE$ DBA_DATA_FILES, DBA_FREE_SPACE
Free extents FET$ DBA_FREE_SPACE
Indexes IND$ DBA_INDEXES
Large objects LOB$ DBA_LOBS
Database objects OBJ$ DBA_OBJECTS, DBA_LOBS, DBA_TYPES
Segments SEG$ DBA_SEGMENTS
Tables TAB$ DBA_TABLES, DBA_LOBS
Tablespaces TS$ DBA_TABLESPACES, DBA_DATA_FILES, DBA_LOBS
Types TYPE$ DBA_TYPES
Used extents UET$ DBA_SEGMENTS, DBA_FREE_SPACE
Users USER$ DBA_USERS, DBA_DB_LINKS, DBA_LOBS
C H A P T E R 3 ■ I N T R O D U C T I O N T O D A T A D I C T I O N A R Y B A S E T A B L E S 43
SQL> CREATE TABLE blog ( username VARCHAR2(30), date_time DATE, text CLOB, img BLOB)
LOB (text) STORE AS blog_text_clob (RETENTION), LOB (img) STORE AS blog_img_blob (PCTVERSION 10);
Table created.
SQL> SELECT pctversion, retention FROM user_lobs WHERE table_name='BLOG';
PCTVERSION RETENTION --- --- 10 10800 10 10800
SQL> SHOW PARAMETER undo_retention
NAME TYPE VALUE
--- --- --- undo_retention integer 10800
The result of querying the data dictionary view USER_LOBS is obviously incorrect. Looking at sql.bsq, there’s unfortunately no comment that says which column is used to discern PCTVERSION and RETENTION, though it appears likely that the column FLAGS holds the required information. Here’s the relevant excerpt of sql.bsq:
create table lob$ /* LOB information table */
( obj# number not null, /* object number of the base table */
…
lobj# number not null, /* object number for the LOB */
…
pctversion$ number not null, /* version pool */
flags number not null, /* 0x0000 = CACHE */
/* 0x0001 = NOCACHE LOGGING */
/* 0x0002 = NOCACHE NOLOGGING */
…
retention number not null, /* retention value = UNDO_RETENTION */
The PCTVERSION setting is stored in the column PCTVERSION$ and the undo retention setting is stored in the column RETENTION. Since LOB$.LOBJ# corresponds to DBA_OBJECTS.OBJECT_ID (see definition of DBA_LOBS in the file catalog.sql), we can query LOB$.FLAGS for our table by joining DBA_OBJECTS and LOB$:
SQL> SELECT object_name, flags FROM sys.lob$ l, dba_objects o WHERE l.lobj#=o.object_id
AND o.object_name IN ('BLOG_TEXT_CLOB', 'BLOG_IMG_BLOB');
OBJECT_NAME FLAGS --- --- BLOG_IMG_BLOB 65 BLOG_TEXT_CLOB 97
Debes_1952-1C03.fm Page 43 Friday, April 24, 2009 9:43 AM