共计 6547 个字符,预计需要花费 17 分钟才能阅读完成。
有时候我们想要知道一个特定的 database block 位于 ASM 的哪个磁盘,磁盘的哪个 AU 以及 AU 的哪一个块。本篇文章将向大家展示如何解决这个问题。
首先在数据库里创建测试表空间:
SQL> create tablespace t_cs datafile ‘+testdg’ size 50M autoextend off;
Tablespace created.
SQL> set long 200
SQL> set linesize 200
SQL> select f.file#, f.name “file”, t.name “tablespace”
2 from v$datafile f, v$tablespace t
3 where t.name=’T_CS’ and f.ts# = t.ts#;
FILE# file tablespace
———- ————————————————– ——————————
11 +TESTDG/jyrac/datafile/t_cs.256.932913341 T_CS
注意到 ASM file number 是 256, 现在创建一张测试表并插入数据:
SQL> create table t(n number,name varchar2(20)) tablespace t_cs;
Table created.
SQL> insert into t values(1,’JY’);
1 row created.
SQL> commit;
Commit complete.
查询表 T 所占用的数据块号:
SQL> select rowid,name from t;
ROWID NAME
—————— ————————————————–
AAAV/pAALAAAACHAAA JY
SQL> select dbms_rowid.rowid_block_number(‘AAAV/pAALAAAACHAAA’) “block number” from dual;
block number
————
135
查询数据文件的块大小:
SQL> select block_size from v$datafile where file#=11;
BLOCK_SIZE
———-
8192
可以看到插入的数据位于 135 号块,数据文件块大小为 8K。
连接 ASM 实例,查询 256 号文件的区分布:
SQL> select group_number from v$asm_diskgroup where name=’TESTDG’;
GROUP_NUMBER
————
5
SQL> select
2 xnum_kffxp, — virtual extent number
3 pxn_kffxp, — physical extent number
4 disk_kffxp, — disk number
5 au_kffxp — allocation unit number
6 from x$kffxp
7 where number_kffxp=256 — asm file 256
8 and group_kffxp=5 — group number 1
9 order by 1,2,3;
XNUM_KFFXP PXN_KFFXP DISK_KFFXP AU_KFFXP
———- ———- ———- ———-
0 0 2 41
0 1 3 38
1 2 3 39
1 3 2 42
2 4 1 41
2 5 0 36
3 6 0 37
3 7 2 43
4 8 2 45
4 9 1 42
5 10 3 40
5 11 1 43
6 12 1 44
6 13 2 47
7 14 0 38
7 15 1 45
8 16 2 48
8 17 0 39
9 18 3 43
9 19 0 40
10 20 1 46
10 21 3 44
11 22 0 41
11 23 3 45
12 24 2 49
12 25 3 46
13 26 3 47
13 27 2 46
14 28 1 47
14 29 0 42
15 30 0 43
15 31 2 52
16 32 2 53
16 33 1 48
17 34 3 48
17 35 1 49
18 36 1 50
18 37 2 54
19 38 0 44
19 39 1 51
20 40 2 55
20 41 0 45
21 42 3 50
21 43 0 46
22 44 1 52
22 45 3 51
23 46 0 47
23 47 3 52
24 48 2 56
24 49 3 53
25 50 3 54
25 51 2 59
26 52 1 53
26 53 0 48
27 54 0 49
27 55 2 60
28 56 2 61
28 57 1 54
29 58 3 55
29 59 1 56
30 60 1 58
30 61 2 65
31 62 0 51
31 63 1 59
32 64 2 66
32 65 0 52
33 66 3 57
33 67 0 53
34 68 1 60
34 69 3 58
35 70 0 54
35 71 3 59
36 72 2 67
36 73 3 60
37 74 3 61
37 75 2 68
38 76 1 61
38 77 0 55
39 78 0 56
39 79 2 71
40 80 2 72
40 81 1 63
41 82 3 63
41 83 1 64
42 84 1 65
42 85 2 73
43 86 0 57
43 87 1 66
44 88 2 74
44 89 0 58
45 90 3 64
45 91 0 59
46 92 1 67
46 93 3 65
47 94 0 60
47 95 3 66
48 96 2 77
48 97 3 67
49 98 3 69
49 99 2 78
50 100 1 69
50 101 0 61
2147483648 0 1 57
2147483648 1 0 50
2147483648 2 2 62
105 rows selected.
可以看到文件的区分布在所有磁盘,由于数据文件为 Normal 冗余,每个区都是两副本。注意我说的是数据文件为 Normal 冗余。默认情况下,文件会继承磁盘组的冗余策略。控制文件是个例外:即使在 Normal 冗余的磁盘组,如果磁盘组包含至少 3 个 failgroup,控制文件也会被创建为 high 冗余。
查询磁盘组的 AU 大小:
SQL> select block_size,allocation_unit_size from v$asm_diskgroup where group_number=5;
BLOCK_SIZE ALLOCATION_UNIT_SIZE
———- ——————–
4096 1048576
AU 大小为 1MB。注意每个磁盘组可以有不同的 AU 大小。
现在已知测试数据在 256 号 ASM file 的 135 号块。数据块为 8K 的情况下,每个 AU 可以包含 128 个块。这就意味着 135 号块位于第二个 virtual extent 的第 7 个块。第二个 virtual extent 包含 3 号磁盘的 39 号 au 和 2 号磁盘的 42 号 au.
查询磁盘 2 和 3 的名字:
SQL> set long 200
SQL> set linesize 200
SQL> select disk_number, name,path from v$asm_disk where group_number=5 and disk_number in (2,3);
DISK_NUMBER NAME PATH
———– ———————————————————— ————————————————–
2 TESTDG_0002 /dev/raw/raw13
3 TESTDG_0003 /dev/raw/raw14
测试数据位于 2 号磁盘的 42 号 AU 的第 7 个块。我们首先将这个 AU 的数据 dd 出来:
[grid@jyrac1 ~]$ dd if=/dev/raw/raw13 bs=1024k count=1 skip=42 of=AU42.dd
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.021209 seconds, 49.4 MB/s
注意几个参数的含义:
bs=1024k — AU 的大小
skip=42 — 它是指跳过文件的前 42 个数据块,从第 43 个数据块开始,因为 AU 的序号是从 0 开始
count=1 — 只需要导出一个 AU
然后将 7 号块的数据从 AU 中导出:
[grid@jyrac1 ~]$ dd if=AU42.dd bs=8k count=1 skip=7 of=block135.dd
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 9.3e-05 seconds, 88.1 MB/s
注意 bs 指定为 8k(数据块大小),skip 指它是指跳过文件的前 7 个数据块,从第 8 个数据块开始,因为 AU 中的块号也是从 0 开始(要导出的块号)。
查看数据块内容:
[grid@jyrac1 ~]$ od -c block135.dd
0000000 006 242 \0 \0 207 \0 300 002 020 W 314 \0 \0 \0 001 006
0000020 305 276 \0 \0 001 \0 020 \0 351 _ 001 \0 016 W 314 \0
0000040 \0 \0 350 037 002 037 2 \0 200 \0 300 002 005 \0 \r \0
….
0017760 001 200 001 , 001 002 002 301 002 002 J Y 001 006 020 W
0020000
在内容的最后可以看到插入的数据 — JY. 注意 Oracle 数据块从下向上填充。
查看 3 号磁盘 /dev/raw/raw14 的 39 号 AU,结果是一样的
[grid@jyrac1 ~]$ dd if=/dev/raw/raw14 bs=1024k count=1 skip=39 of=AU39.dd
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.017309 seconds, 60.6 MB/s
[grid@jyrac1 ~]$ dd if=AU39.dd bs=8k count=1 skip=7 of=block135_copy.dd
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 0.000207 seconds, 39.6 MB/s
0000000 006 242 \0 \0 207 \0 300 002 020 W 314 \0 \0 \0 001 006
0000020 305 276 \0 \0 001 \0 020 \0 351 _ 001 \0 016 W 314 \0
0000040 \0 \0 350 037 002 037 2 \0 200 \0 300 002 005 \0 \r \0
….
0017760 001 200 001 , 001 002 002 301 002 002 J Y 001 006 020 W
0020000
小结:
要定位 ASM 中数据块的位置,需要知道数据块位于哪个数据文件。然后通过 X$KFFXP 视图查看数据文件的区分布。还需要数据块大小和 ASM AU 大小去定位数据块位于哪个 AU。以上操作和 ASM 或者 RDBMS 的版本无关。(V$ASM_ATTRIBUTE 视图除外,因为在 10g 中没有该视图)在 Normal 和 high 冗余模式下,将会有多副本数据。但是定位数据块的方法是相同的。
更多 Oracle 相关信息见 Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-01/139605.htm