展示页内容(不分片的表和索引)
在数据库的世界里,页是存储数据的基本单元。GBase 8s数据库其页结构对于优化数据存取、提高查询效率至关重要。本文将带您深入了解GBase 8s页结构的展示,探索不分片的表和索引的内部世界。
1、展示页的方法
1.1 展示页通常用 oncheck命令
- 根据 chunk号+页偏移展示:
- oncheck -pP chunk_number page_offset
- 根据 分区号+逻辑页号展示(这两个概念随后章节介绍):
- oncheck -pp partition_number logical_page_number
注意:chunk_number从1开始,page_offset 和 logical_page_number都是从0开始。
1.2 如何获取partition_number?
- 如果没有分片的话,从systables(或者 sysmaster:systabnames 中)。
- 如果是分片的话, 查询sysfragments。
- 使用oncheck -pt 找到所有分片的partition_number。
注意:
- oncheck 可以识别10进制和16进制的数。
- oncheck可以显示大部分的页。但是对于逻辑日志的页,请使用onlog。
1.3 定位partition numbers
- partition number(partnum)唯一标识特定的tblspace。
- 一个未分片的表只有一个数据tblspace,因此只有一个分区号。
- 对于每个dbspace片段,分片表有一个tblspace(和一个partnum)。
- 关于partition numbers的详细介绍,在随后的文章介绍。
对于没有分片的表,使用systables就可以
select partnum, hex(partnum) from systables where tabname = 'table_name';
也可以用:
database sysmaster;
select partnum, hex(partnum) from systabnames where tabname = 'table_name';
对于分片的表,需要使用sysfragments,
select partn, hex(partn) from systables t, sysfragments f
where t.tabid = f.tabid and tabname = "table_name";
最容易的获取partnums的方法:
oncheck -pt database_name:table_name
1.4 展示特定行所在页
- 先找到关心行的rowid
- select *,rowid from your_table where __条件自选__;
- 然后展示页
- oncheck -pp database:table_name rowid
2、展示页 - 不分片的表和索引
2.1准备元数据
drop database if exists test1;
create database test1 with log;
create table t1(c1 int, c2 char(100), c3 varchar(100)) in datadbs1;
create index i1 on t1(c1) in datadbs1;
2.2 准备数据
生成数据的脚本
[root@centos7_2 ix9111]# cat generate_data.py
#!/usr/bin/python
def main():
fp = open("data.unl", "w")
for i in range(0,1000):
fp.write("%d|%08dxxxxxxxxxxxxxxxxxxx|%08dxxxxxxxxxxxxxxxxxxxxxxxxxx\n" % (i, i, i))
fp.close()
if __name__ == '__main__':
main()
生成数据,并加载数据
./ generate_data.py
dbaccess test1 -
load from 'data.unl' insert into t1;
2.3 基于物理地址寻找页
获取物理地址:
oncheck -pt test1:t1
数据部分
Extents
Logical Page Physical Page Size Physical Pages
0 4:57 32 32
32 4:93 96 96
索引部分
Extents
Logical Page Physical Page Size Physical Pages
0 4:53 4 4
4 4:89 4 4
8 4:189 8 8
展示数据部分
oncheck -pP 4 58 (57是bitmap页,需要跳过)
[root@gbasehdr202 test]# oncheck -pP 4 58
addr stamp chksum nslots flag type frptr frcnt next prev
4:58 287029 610f 13 1 DATA 1844 148 0 0
0
slot ptr len flag
1 24 140 0
2 164 140 0
3 304 140 0
4 444 140 0
5 584 140 0
6 724 140 0
7 864 140 0
8 1004 140 0
9 1144 140 0
10 1284 140 0
11 1424 140 0
12 1564 140 0
13 1704 140 0
slot 1:
0: 0 0 0 0 30 30 30 30 30 30 30 30 78 78 78 78 ....00000000xxxx
16: 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 20 xxxxxxxxxxxxxxx
32: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
64: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
96: 20 20 20 20 20 20 20 20 0 22 30 30 30 30 30 30 ."000000
112: 30 30 78 78 78 78 78 78 78 78 78 78 78 78 78 78 00xxxxxxxxxxxxxx
128: 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxx....
略
展示索引部分
oncheck -pP 4 54
[root@gbasehdr202 test]# oncheck -pP 4 54
addr stamp chksum nslots flag type frptr frcnt next prev
4:54 289313 6a17 7 70 BTREE 76 1940 0 0
slot ptr len flag
1 24 8 0
2 36 8 0
3 44 8 0
4 52 8 0
5 60 8 0
6 68 8 0
7 32 4 0
slot 1:
0: 80 0 0 99 0 0 0 3 ................
slot 2:
0: 80 0 1 33 0 0 0 2 ...3............
slot 3:
0: 80 0 1 cd 0 0 0 4 ...M............
slot 4:
0: 80 0 2 67 0 0 0 5 ...g............
slot 5:
0: 80 0 3 1 0 0 0 6 ................
slot 6:
0: 80 0 3 9b 0 0 0 7 ................
slot 7:
0: 0 0 0 8 ................
2.4 基于逻辑地址1
获取 partnum
[root@centos7_2 test]# oncheck -pt test1:t1
数据部分
Partition partnum 4194306
索引部分
Partition partnum 4194307
展示数据部分
[root@gbasehdr202 test]# oncheck -pp 4194306 1
addr stamp chksum nslots flag type frptr frcnt next prev
4:58 287029 610f 13 1 DATA 1844 148 0 0
slot ptr len flag
1 24 140 0
2 164 140 0
3 304 140 0
4 444 140 0
5 584 140 0
6 724 140 0
7 864 140 0
8 1004 140 0
9 1144 140 0
10 1284 140 0
11 1424 140 0
12 1564 140 0
13 1704 140 0
slot 1:
0: 0 0 0 0 30 30 30 30 30 30 30 30 78 78 78 78 ....00000000xxxx
16: 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 20 xxxxxxxxxxxxxxx
32: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
64: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
96: 20 20 20 20 20 20 20 20 0 22 30 30 30 30 30 30 ."000000
112: 30 30 78 78 78 78 78 78 78 78 78 78 78 78 78 78 00xxxxxxxxxxxxxx
128: 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxx....
展示索引部分
[root@gbasehdr202 test]# oncheck -pp 4194307 1
addr stamp chksum nslots flag type frptr frcnt next prev
4:54 289313 6a17 7 70 BTREE 76 1940 0 0
slot ptr len flag
1 24 8 0
2 36 8 0
3 44 8 0
4 52 8 0
5 60 8 0
6 68 8 0
7 32 4 0
slot 1:
0: 80 0 0 99 0 0 0 3 ................
slot 2:
0: 80 0 1 33 0 0 0 2 ...3............
slot 3:
0: 80 0 1 cd 0 0 0 4 ...M............
slot 4:
0: 80 0 2 67 0 0 0 5 ...g............
slot 5:
0: 80 0 3 1 0 0 0 6 ................
slot 6:
0: 80 0 3 9b 0 0 0 7 ................
slot 7:
0: 0 0 0 8 ................
2.5 基于逻辑地址2
获取数据部分的partnum
[root@centos7_2 test]# dbaccess test1 -
Database selected.
> select partnum from systables where tabname = 't1';
partnum
4194389
1 row(s) retrieved.
获取索引部分的partnum
> select f.partn from sysfragments f, systables t where f.tabid = t.tabid and t.tabname='t1';
partn
4194390
1 row(s) retrieved.
获取了partnum后,展示页的方式同上一节。
2.6 基于rowid
获取rowid
[root@centos7_2 test]# dbaccess test1 -
Database selected.
> select c1, rowid from t1 where c1 = 0;
c1 rowid
0 257
1 row(s) retrieved.
展示:
oncheck -pp test1:t1 257
[root@gbasehdr202 test]# oncheck -pp test1:t1 257
addr stamp chksum nslots flag type frptr frcnt next prev
4:58 287029 610f 13 1 DATA 1844 148 0 0
slot ptr len flag
1 24 140 0
2 164 140 0
3 304 140 0
4 444 140 0
5 584 140 0
6 724 140 0
7 864 140 0
8 1004 140 0
9 1144 140 0
10 1284 140 0
11 1424 140 0
12 1564 140 0
13 1704 140 0
slot 1:
0: 0 0 0 0 30 30 30 30 30 30 30 30 78 78 78 78 ....00000000xxxx
16: 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 20 xxxxxxxxxxxxxxx
32: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
64: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
96: 20 20 20 20 20 20 20 20 0 22 30 30 30 30 30 30 ."000000
112: 30 30 78 78 78 78 78 78 78 78 78 78 78 78 78 78 00xxxxxxxxxxxxxx
128: 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxx....
略
2.7 直接读chunk
目标:从chunk文件中,找到数据页的内容,以物理地址( 4 2337 )为例,进行查找。
需要强制一次检查点,确保数据落地。
onmode -c
确定chunk 4对应的文件。
[root@gbasehdr202 test]# onstat -d
On-Line -- Up 00:22:55 -- 17346180 Kbytes
Dbspaces
address number flags fchunk nchunks pgsize flags owner name
4545c028 1 0x70001 1 1 2048 N BA gbasedbt rootdbs
47ddc7f0 2 0x1070001 2 1 2048 N PBA gbasedbt plog
47eb8dd0 3 0x60001 3 1 2048 N BA gbasedbt llog
47966dd0 4 0x60001 4 1 2048 N BA gbasedbt datadbs1
47d90560 5 0x60001 5 1 2048 N BA gbasedbt datadbs2
47d29dd0 6 0x60001 6 1 2048 N BA gbasedbt datadbs3
47d255b0 7 0x60001 7 1 8192 N BA gbasedbt data8dbs1
47b22da0 8 0x60001 8 1 8192 N BA gbasedbt data8dbs2
47d94520 9 0x60001 9 1 8192 N BA gbasedbt data8dbs3
4847fd78 10 0x42001 10 1 8192 N TBA gbasedbt tmpdbspace
486f5560 11 0x68001 11 1 2048 N SBA gbasedbt sbspace1
479fe5b0 12 0x4a001 12 1 2048 N UBA gbasedbt tmpsbspace
12 active, 2047 maximum
Chunks
address chunk/dbs offset size free bpages flags pathname
4545c258 1 1 0 78848 65818 PO-B-- /gbase8s/3.3.0_2X4_1/ids/storage/rootdbs
47d9a028 2 2 0 32768 0 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_plog_p_1
47bb8028 3 3 0 32768 15 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_llog_p_1
47bc2028 4 4 0 32768 32571 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_datadbs1_p_1
47d92028 5 5 0 32768 32715 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_datadbs2_p_1
47c99028 6 6 0 32768 32715 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_datadbs3_p_1
48722028 7 7 0 8192 8139 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_data8dbs1_p_1
47ad5028 8 8 0 8192 8139 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_data8dbs2_p_1
47e4f028 9 9 0 8192 8139 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_data8dbs3_p_1
486f4028 10 10 0 8192 8139 PO-BE- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_tmpdbspace_p_1
47eee028 11 11 0 32768 23802 23802 POSB-- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_sbspace1_p_1
Metadata 1745 8466 1745
47bd3028 12 12 0 32768 23802 23802 POSB-- /gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_tmpsbspace_p_1
Metadata 1745 8466 1745
12 active, 32766 maximum
NOTE: The values in the "size" and "free" columns for DBspace chunks are
displayed in terms of "pgsize" of the DBspace to which they belong.
从物理文件中读取2048字节
dd if=/gbase8s/3.3.0_2X4_1/ids/storage/ol_gbasedbt1210_20240718181816_datadbs1_p_1 of=/tmp/1.txt bs=2048 count=1 skip=58
查看读取的内容
vi /tmp/1.txt
%!xxd
如下:标黄的部分,是前三行的开始,也就是整数0,1,2.
0000000: 3a00 0000 0400 0f61 0d00 0108 3407 9400 :......a....4... 0000010: 0000 0000 0000 0000 0000 0000 3030 3030 ............0000 0000020: 3030 3030 7878 7878 7878 7878 7878 7878 0000xxxxxxxxxxxx 0000030: 7878 7878 7878 7820 2020 2020 2020 2020 xxxxxxx 0000040: 2020 2020 2020 2020 2020 2020 2020 2020 0000050: 2020 2020 2020 2020 2020 2020 2020 2020 0000060: 2020 2020 2020 2020 2020 2020 2020 2020 0000070: 2020 2020 2020 2020 2020 2020 2020 2020 0000080: 0022 3030 3030 3030 3030 7878 7878 7878 ."00000000xxxxxx 0000090: 7878 7878 7878 7878 7878 7878 7878 7878 xxxxxxxxxxxxxxxx 00000a0: 7878 7878 0000 0001 3030 3030 3030 3031 xxxx....00000001 00000b0: 7878 7878 7878 7878 7878 7878 7878 7878 xxxxxxxxxxxxxxxx 00000c0: 7878 7820 2020 2020 2020 2020 2020 2020 xxx 00000d0: 2020 2020 2020 2020 2020 2020 2020 2020 00000e0: 2020 2020 2020 2020 2020 2020 2020 2020 00000f0: 2020 2020 2020 2020 2020 2020 2020 2020 0000100: 2020 2020 2020 2020 2020 2020 0022 3030 ."00 0000110: 3030 3030 3031 7878 7878 7878 7878 7878 000001xxxxxxxxxx 0000120: 7878 7878 7878 7878 7878 7878 7878 7878 xxxxxxxxxxxxxxxx 0000130: 0000 0002 3030 3030 3030 3032 7878 7878 ....00000002xxxx 0000140: 7878 7878 7878 7878 7878 7878 7878 7820 xxxxxxxxxxxxxxx 0000150: 2020 2020 2020 2020 2020 2020 2020 2020 0000160: 2020 2020 2020 2020 2020 2020 2020 2020 0000170: 2020 2020 2020 2020 2020 2020 2020 2020 0000180: 2020 2020 2020 2020 2020 2020 2020 2020 0000190: 2020 2020 2020 2020 0022 3030 3030 3030 ."000000 00001a0: 3032 7878 7878 7878 7878 7878 7878 7878 02xxxxxxxxxxxxxx 00001b0: 7878 7878 7878 7878 7878 7878 0000 0003 xxxxxxxxxxxx.... 00001c0: 3030 3030 3030 3033 7878 7878 7878 7878 00000003xxxxxxxx 00001d0: 7878 7878 7878 7878 7878 7820 2020 2020 xxxxxxxxxxx |
3、附录:
页头数据格式
页头的数据,有些是16进制的,有些是10进制的,这里给出定义,可以避免歧义。
addr stamp chksum nslots flag type frptr frcnt next prev
DEC:DEC DEC HEX DEC HEX CHAR DEC DEC HEX HEX
比如:
[root@centos7_2 test]# oncheck -pP 4 2337
addr stamp chksum nslots flag type frptr frcnt next prev
4:2337 6362036 1af0 13 801 DATA 1844 148 0 0
其中,type列是由pg_flags翻译过来的,范围参见备注。
slot数据格式
slot 开始的时候是这个页全部slot的列表
- slot ptr len flag
- 1 24 140 0
- 2 164 140 0
slot 是 slot的编号
ptr 是slot指向数据开始地址在页内的偏移
len 是slot指向数据的长度
flag 如果slot指向的数据有前向指针(就是这个页放不下了,需要续行。),则f lg是2,否则是0
记住,插槽不是一行,而是一个容器。槽可以包含数据行、数据行的一部分(在跨页拆分的行的情况下)或其他结构。插槽表条目由长度和页面上的位置组成。
通过本文的探索,我们对GBase 8s的页结构有了更深入的理解。从物理地址到逻辑地址,从数据页到索引页,每一部分都承载着数据库运行的关键信息。希望本文能够帮助您更好地掌握GBase 8s的内部机制,提升数据库管理的效率和效果。