SYSASM 角色
自动存储管理 (ASM) 是在 Oracle 数据库 10g 中引入的,它在某种程度上打破了 DBA 和系统管理员之间在存储分配功能上的界限。ASM 实例由 DBA 管理,正如常规的 DBA 工作需要以 SYSDBA 角色进行连接一样。但是随着时间的推移,角色变得更加清楚,我们看到发生了基本的分工。因此,一些 ASM 操作返还给系统管理员。在某些情况下,会出现单独的一类“ASM 管理员”,他们只进行 ASM 管理,并不涉及数据库管理。
然而,这个新角色的出现引发了一个冲突:需要用 SYSDBA 角色来管理 ASM 实例,但运行在同一台服务器上的生产数据库的许多 DBA 感觉很难共享该角色。
Oracle 数据库 11g 消除了这个冲突。有一个新角色 SYSASM,只用于管理 ASM 实例。这类似于针对 ASM 实例的 SYSDBA 角色。下面将演示如何连接到 ASM 实例:
$ sqlplus / as sysasm
SQL*Plus: Release 11.1.0.6.0 - Production on Fri Sep 28 20:37:39 2007
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining
and Real Application Testing options
SQL>
注意连接子句“as sysasm”。在 Oracle 数据库 11g 第 1 版中,该 SYSASM 角色被授予具有 SYSDBA 权限的操作系统组(大多数情况下为“dba”)。换言之,Unix 中属于 dba 组的用户也可以作为 SYSASM 进行连接。(今后的版本会更改这种安排;sysdba 和 sysasm 角色将分成不同的 OS 组。)
以 sys 用户身份连接到 ASM 实例后,您可以更新在口令文件中更新的 SYS 口令:
SQL> alter user sys identified by oracle
2 /
User altered.
尽管这个 ASM 实例不带数据库,您仍然可以创建用户:
SQL> create user asmoper identified by dumboper
2 /
User created.
现在,您可以将 SYSASM 角色授予该用户:
SQL> grant sysasm to asmoper;
Grant succeeded.
进行授权之后,asmoper 用户(而非 SYS 用户)可以执行所有 ASM 管理功能。该用户可以通过子句 as sysasm 进行连接,该子句类似于常规数据库中的“as sysdba”子句。
$ sqlplus asmoper/dumboper as sysasm
这个特性实现了迫切需要的 ASM 和 DBA 职权分离。
可变的区大小
ASM 存储中结构最小的元素是分配单元 (AU),与 Oracle 数据库块的概念类似。创建表和索引之类的数据库段时,分配的最小单元不是一个块,而是一个包含多个块的区。您可以更改段的区大小。
ASM 中有一个非常类似的概念:在 ASM 磁盘组上创建文件时,最小的可寻址单元是区,而不是 AU.在 Oracle 数据库 10g 中,AU 和区是可互换的;一个区只包含一个 AU.
10g 兼容的磁盘组需要共享池为每个区提供内存。对于大型数据库,这又需要大量内存。因此,如果 AU 大小为 1MB(默认值),1TB 的数据库需要在共享池中管理超过一百万个区。
在 Oracle 数据库 11g 中,区大小不再等于 AU 大小。创建文件时,区大小从 1MB 开始。文件达到某个阈值时,区大小增加至 4MB,然后是 16MB,最后当达到某个阈值后,区大小为 64MB.您不必担心大小;ASM 实例会自动分配合适的区大小。由于较少数量的区即可容纳大量数据,因此可以大大减少共享池中的区总数,从而将性能提高数倍。
当文件急剧扩大和缩小时,可变的区大小可能会产生一些碎片。如果需要进行碎片整理,ASM 将自动解决该问题。
可变的 AU 大小
正如我在前面提到的,AU 的默认大小为 1MB.对许多数据库而言,这可能足够大了,但请考虑一个大小超过 10TB 的大型数据库。对象可能超过 1MB,因此您可能希望扩大 AU 大小以减少 AU 数量。在 Oracle 数据库 10g 中,您可以设置一个底线参数来更改 AU 大小。然而,这会影响这之后创建的所有磁盘组,而且还需要一个 ASM 实例周期来设置该参数。
在 Oracle 数据库 11g 中,只需在创建 DG 期间设置一个磁盘组属性 au_size 即可轻松完成此任务,如下所示:
create diskgroup dg6
external redundancy
disk
'/dev/raw/raw13'
attribute 'au_size' = '2M'
AU_SIZE 应为 1M、2M、4M、8M、16M、32M 或 64M(M 代表 MB)。您还可以将该值设成一个绝对值(单位为字节):
attribute 'au_size' = ' 2097152'
创建磁盘组之后,您可以通过以下查询来查看 AU 大小:
select name, allocation_unit_size
from v$asm_diskgroup
/
NAME ALLOCATION_UNIT_SIZE
------- --------------------
DG1 1048576
DG3 1048576
DG6 2097152
DG5 1048576
DG4 1048576
DG2 1048576
注意各个磁盘组名称的 AU 大小。现在,您可以创建具有合适 AU 大小的磁盘组,以满足每个应用程序的需要。
磁盘组属性
ASM 是一个适用于从 10g 到当前版本的 Oracle 数据库的存储平台。因此,11g 上的 ASM 实例可以保存 10g 第 1 版、10g 第 2 版以及 11g 第 1 版(以及更高版本)的数据库。只要 ASM 版本与 RDBMS 的版本相同或者更高,就可以在该 ASM 实例上创建数据库。如果 ASM 和 RDBMS 实例的版本不同,它们将如何通信呢?很简单:ASM 将消息转换成适合 RDBMS 的版本。
默认情况下,ASM 实例可以支持 10g 数据库。但如果您希望在该 ASM 实例上仅放置 11g RDBMS,该怎么办?无需进行消息转换来支持版本差异。但如果可以告诉 ASM 实例唯一支持的数据库是 11g 第 1 版,该怎么办?这将消除,至少可以减少消息转换。在 Oracle 数据库 11g 中,可以使用 ASM 兼容性和 RDBMS 兼容性磁盘组属性实现。
首先,我们将检查磁盘组的当前属性:
SQL> select compatibility, database_compatibility
2 from v$asm_diskgroup
3 where name = 'DG1'
4 /
COMPATIBILITY DATABASE_COMPATIBILITY
---------------------- ----------------------
10.1.0.0.0 10.1.0.0.0
如您所见,ASM 兼容性(由 COMPATIBILITY 显示)设置为 10.1.0.0.0,这意味着该磁盘组最高可支持 10.1 ASM 结构。因此,该磁盘组可以具有任意 RDBMS 结构。另一列 DATABASE_COMPATIBILITY 显示 RDBMS 兼容性设置为 10.1.这意味着,ASM 磁盘组 DG1 可用于 10.1 版的任何 RDBMS.
由于您只希望创建 11g ASM 和 RDBMS 结构,因此无需拥有 10g 元素。要将该磁盘组的 ASM 兼容性属性设置为 11.1,您可以执行以下语句(在 ASM 实例中):
SQL> alter diskgroup dg1 set attribute 'compatible.asm'='11.1';
现在,如果您检查磁盘组的属性:
COMPATIBILITY DATABASE_COMPATIBILITY
---------------------- ----------------------
11.1.0.0.0 10.1.0.0.0
ASM 兼容性设置为 11.1;但 RDBMS 兼容性仍然设置为 10.1.要将它也更改为 11.1,请使用:
SQL> alter diskgroup dg1 set attribute 'compatible.rdbms'='11.1';
需要特别注意的是:兼容性是针对磁盘组设置的,而不是针对整个 ASM 实例。使用该特性,您只需使用一个 ASM 实例即可满足所有数据库版本类型的需要。根据所使用的版本,您可以相应地设置属性,从而减少版本间通信。
首选的镜像读取
在 Oracle RAC 数据库中,多个节点可能指向同一个 ASM 实例。如果您在一个 ASM 磁盘组中使用正常镜像,访问磁盘的行为可能并不像您预想的那样。
假设您有一个名为 DG2 的磁盘组,它包含两个 failgroup(DG2_0000 和 DG2_0001),每个具有一个单独的磁盘,如下图所示:
向磁盘组 DG2 写入某些内容时,会以循环方式写入区中:第一个进入 DG2_0000,副本进入 DG2_0001,第二个进入 DG2_0001,副本在 DG2_0000 上,第三个进入 DG2_0000,副本在 DG2_0001 上,依此类推。ASM 以这种方式在一个磁盘上维护另一个磁盘的备份。
但是在读取这些区时,始终从主 failgroup(在本例中为 DG2_0000)中读取,而不是从辅助 failgroup (DG2_0001) 中读取。仅当主 failgroup 不可用时才读取辅助 failgroup.
这在大多数情况下可以正常工作,但有时可能不是所希望的。在 Oracle 数据库 11g 中,您可以将一个节点配置为从特定 failgroup 中读取。例如,在上面的示例中,如果您希望将实例 1 配置为从 failgroup DG2_0000 中读取,将实例 2 配置为从 DG2_0001 中读取,您可以设置这些磁盘组的首选读取组。在实例 1 中执行的以下命令导致磁盘组 DG2 和 DG3 中的 failgroup DG2_0000 和 DG3_0000 分别是实例 1 上的首选磁盘:
SQL> alter system set asm_preferred_read_failure_groups = 'DG2.DG2_0000','DG3.DG3_0000'
同样,在另一个实例上,您可以执行以下命令使其他 failgroup 成为首选磁盘:
SQL> alter system set asm_preferred_read_failure_groups = 'DG2.DG2_0001','DG3.DG3_0001'
执行这些语句后,当来自实例 1 的某个会话希望从磁盘组 DG2 中读取时,将读取磁盘 DG2_0000.如果该磁盘不可用,则读取另一个磁盘 DG2_0001.同样,当某个连接到实例 2 的会话读取数据时,将读取磁盘 DG2_0001.
如果您要检查磁盘组中不同磁盘的使用情况,可以参考一个新的字典视图 V$ASM_DISK_IOSTAT,它模拟了 UNIX 系统中的 IOSTAT 实用程序:
select
instname,
dbname,
group_number,
failgroup,
disk_number,
reads,
writes
from v$asm_disk_iostat
order by 1,2,3,4,5,6
/
示例输出如下:
INSTNAM DBNAME GROUP_NUMBER FAILGROUP DISK_NUMBER READS WRITES
------- -------- ------------ ---------- ----------- ---------- ----------
PRONE31 PRONE3 2 DG2_0000 0 4450 910
PRONE32 PRONE3 2 DG2_0001 1 2256 910
PRONE31 PRONE3 3 DG3_0000 0 300 29
PRONE32 PRONE3 3 DG3_0001 1 560 29
该输出显示了实例 PRONE31 和 PRONE32 的首选 failgroup 分别为 DG2_0000 和 DG2_0001.注意 WRITES 列;它们在 910 处相同。这是因为统一写入到两个磁盘中。现在,注意 READS 列。针对实例 PRONE31 和 PRONE32 分别为 4450 和 2256.为什么?因为实例 PRONE3 发出多次读取命令,这些读取均来自于其首选 failgroup DG2_0000.对于磁盘组 DG3,实例 PRONE32 发出多次来自于其首选 failgroup (DG3_0001) 的读取命令,因此该磁盘显示更多读取。
首选读取在“拉伸”集群(节点之间地理距离较远的集群)中尤为有用。首选读取通过将读取隔离到特定磁盘,加快了读取速度。
Drop Diskgroup Force
当一个磁盘不再可用时(损坏到无法修复的程度)会发生什么?您希望完全删除该磁盘组然后重新创建,或者将该磁盘组的磁盘添加到其他磁盘组。该磁盘组尚未挂载。由于其中一个磁盘缺少,您甚至无法挂载它。要删除该磁盘组,您必须挂载它,但由于缺少磁盘,您无法进行挂载 — 绝对是一个“无法摆脱的困境”。您应该做些什么?
在 Oracle 数据库 10g 中,您可以使用一种变通方法 — 使用 dd 命令擦除磁盘表头:
$ dd if=/dev/zero of=/dev/raw/raw13 bs=1024 count=4
这将在磁盘 /dev/raw/raw13 的表头中放入零,擦除所有信息。如果该方法生效,它将完全擦除磁盘表头的信息,并删除用作磁盘组一部分的磁盘。
在 Oracle 数据库 11g 中,您不必求助于该变通方法。您只需执行带 force 选项的 drop 命令:
SQL> drop diskgroup dg7 force including contents;
使用该命令,即使没有挂载磁盘,也可以删除磁盘组。可用的磁盘显示为 FORMER;即,它们用作某个磁盘组的一部分。(注:您必须使用“including contents”子句。)
元数据备份和恢复
许多人将 ASM 看作一个具有自己的存储的数据库。事实并非如此,ASM 并不存储数据,而是由数据库进行存储。但 ASM 实例需要维护磁盘组名称、其中的磁盘、目录等元数据。这些元数据存储在磁盘表头中。
假设所有磁盘都损坏且表头信息消失,您该怎么办?当然,您已经使用 RMAN 对数据库进行了备份,因此可以恢复。但您只有在创建了所有磁盘组和目录后才能进行恢复。希望您保留了所有记录。(对吗?)即使您进行了备份,这个过程也需要时间。
如果您进行了备份,该怎么办呢?在 Oracle 数据库 11g 中,您可以使用 md_backup 命令通过 ASM 命令行选项 (ASMCMD) 备份 ASM 实例的元数据。
$ asmcmd -p
ASMCMD [+] > md_backup
该命令将创建一个名为 ambr_backup_intermediate_file 的文件。以下是该文件从顶部开始的一部分:
@diskgroup_set = (
{
'DISKSINFO' => {
'DG1_0000' => {
'DG1_0000' => {
'TOTAL_MB' => '103',
'FAILGROUP' => 'DG1_0000',
'NAME' => 'DG1_0000',
'DGNAME' => 'DG1',
'PATH' => '/dev/raw/raw5'
}
}
},
'DGINFO' => {
'DGTORESTORE' => 0,
'DGCOMPAT' => '10.1.0.0.0',
'DGNAME' => 'DG1',
'DGDBCOMPAT' => '10.1.0.0.0',
'DGTYPE' => 'EXTERN',
'DGAUSZ' => '1048576'
},
'ALIASINFO' => {},
'TEMPLATEINFO' => {
'6' => {
'DGNAME' => 'DG1',
'STRIPE' => 'COARSE',
'TEMPNAME' => 'ASM_STALE',
'REDUNDANCY' => 'UNPROT',
'SYSTEM' => 'Y'
... and more ...
为了节省空间,此处没有显示整个文件。它记录了所有磁盘组、磁盘、目录、磁盘属性,等等。默认情况下,该文件会记录所有磁盘组。如果您希望仅备份特定磁盘组,可以使用 -g 选项。此外,您还可以使用 -b 选项创建特定的命名文件。
ASMCMD [+] > md_backup -g dg1 -b prolin3_asm.backup
这会将磁盘组 DG1 的元数据备份到一个名为 prolin3_asm.backup 的文件,而不是默认的 ambr_backup_intermediate_file.该文件必须是新建的,如果在生成前该文件已存在,您必须删除它。
现在,让我们看看恢复操作是如何工作的。恢复有不同的类型。最简单的用法是恢复一个以前删除的磁盘组及其目录。首选,在磁盘组上创建一个目录:
ASMCMD [+] > cd DG7
ASMCMD [+DG7] > mkdir TEST
ASMCMD [+DG7] > ls
TEST/
该磁盘组有一个名为 TEST 的目录。现在,备份该磁盘组:
ASMCMD [+] > md_backup -g dg7 -b g7.backup
备份之后,假设您删除该磁盘组来模拟一次意外删除:
SQL> drop diskgroup dg7;
Diskgroup dropped.
现在,磁盘组 DG7 已从 ASM 实例删除,您希望使用以前的备份恢复它。可以使用 md_restore 命令恢复它:
$ asmcmd md_restore -b dg7.backup -t full
Current Diskgroup being restored: DG7
Diskgroup DG7 created!
System template TEMPFILE modified!
System template FLASHBACK modified!
System template ARCHIVELOG modified!
System template BACKUPSET modified!
System template XTRANSPORT modified!
System template DATAGUARDCONFIG modified!
System template CONTROLFILE modified!
System template AUTOBACKUP modified!
System template DUMPSET modified!
System template ONLINELOG modified!
System template PARAMETERFILE modified!
System template ASM_STALE modified!
System template CHANGETRACKING modified!
System template DATAFILE modified!
Directory +DG7/TEST re-created!
看看输出;它创建了该磁盘组以及模板和目录。如果以前有任何数据,当然,这些数据将丢失。md_backup 不是数据的备份,而是 ASM 实例元数据的备份。表面上,数据是由 RMAN 备份的。创建磁盘组和所有目录之后,您可以将 RMAN 备份恢复到该磁盘组。
另一个选项 -f 使您可以将命令放在一个脚本文件中,而不是执行这些命令:
ASMCMD [+] > md_restore -b dg7.backup -t full -f cr_dg7.sql
它会创建一个名为 cr_dg7.sql 的 SQL 脚本,该脚本用于创建磁盘组以及所有其他对象。您可以在 ASM 实例中手动运行该脚本。该文件如下所示:
create diskgroup DG7 EXTERNAL redundancy disk '/dev/raw/raw14' name DG7_0000 size 100M ;
alter diskgroup /*ASMCMD AMBR*/DG7 alter template TEMPFILE attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template FLASHBACK attributes (UNPROTECTED FINE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template ARCHIVELOG attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template BACKUPSET attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template XTRANSPORT attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template DATAGUARDCONFIG attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template CONTROLFILE attributes (UNPROTECTED FINE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template AUTOBACKUP attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template DUMPSET attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template ONLINELOG attributes (UNPROTECTED FINE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template PARAMETERFILE attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template ASM_STALE attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template CHANGETRACKING attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR*/DG7 alter template DATAFILE attributes (UNPROTECTED COARSE);
alter diskgroup /*ASMCMD AMBR */ DG7 add directory '+DG7/TEST';