Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CN/antora.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: ivorysql-doc
title: IvorySQL
version: v4.5
start_page: v4.5/welcome.adoc
version: master
start_page: master/welcome.adoc
asciidoc:
attributes:
source-language: asciidoc@
Expand Down
63 changes: 32 additions & 31 deletions CN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
* xref:v4.5/welcome.adoc[欢迎]
* xref:v4.5/1.adoc[发行说明]
* xref:v4.5/2.adoc[关于IvorySQL]
* xref:master/welcome.adoc[欢迎]
* xref:master/1.adoc[发行说明]
* xref:master/2.adoc[关于IvorySQL]
* IvorySQL入门
** xref:v4.5/3.adoc[快速开始]
** xref:v4.5/4.adoc[日常监控]
** xref:v4.5/5.adoc[日常维护]
** xref:master/3.1.adoc[快速开始]
** xref:master/3.2.adoc[日常监控]
** xref:master/3.3.adoc[日常维护]
* IvorySQL高级
** xref:v4.5/6.adoc[安装指南]
** xref:v4.5/7.adoc[集群搭建]
** xref:v4.5/8.adoc[开发者指南]
** xref:v4.5/9.adoc[运维管理指南]
** xref:v4.5/10.adoc[迁移指南]
** xref:master/4.1.adoc[安装指南]
** xref:master/4.2.adoc[集群搭建]
** xref:master/4.3.adoc[开发者指南]
** xref:master/4.4.adoc[运维管理指南]
** xref:master/4.5.adoc[迁移指南]
* IvorySQL生态
** xref:v4.5/11.adoc[PostGIS]
** xref:v4.5/12.adoc[pgvector]
** xref:master/5.1.adoc[PostGIS]
** xref:master/5.2.adoc[pgvector]
* IvorySQL架构设计
** 查询处理
*** xref:v4.5/31.adoc[双parser]
*** xref:master/6.1.1.adoc[双parser]
** 兼容框架
*** xref:v4.5/30.adoc[initdb过程]
*** xref:master/6.2.1.adoc[initdb过程]
* Oracle兼容功能列表
** xref:v4.5/14.adoc[1、框架设计]
** xref:v4.5/15.adoc[2、GUC框架]
** xref:v4.5/16.adoc[3、大小写转换]
** xref:v4.5/17.adoc[4、双模式设计]
** xref:v4.5/18.adoc[5、兼容Oracle like]
** xref:v4.5/19.adoc[6、兼容Oracle匿名块]
** xref:v4.5/20.adoc[7、兼容Oracle函数与存储过程]
** xref:v4.5/21.adoc[8、内置数据类型与内置函数]
** xref:v4.5/22.adoc[9、新增Oracle兼容模式的端口与IP]
** xref:v4.5/26.adoc[10、XML函数]
** xref:v4.5/27.adoc[11、兼容Oracle sequence]
** xref:v4.5/28.adoc[12、包]
** xref:v4.5/29.adoc[13、不可见列]
* xref:v4.5/32.adoc[社区贡献指南]
* xref:v4.5/24.adoc[工具参考]
* xref:v4.5/25.adoc[FAQ]
** xref:master/7.1.adoc[1、框架设计]
** xref:master/7.2.adoc[2、GUC框架]
** xref:master/7.3.adoc[3、大小写转换]
** xref:master/7.4.adoc[4、双模式设计]
** xref:master/7.5.adoc[5、兼容Oracle like]
** xref:master/7.6.adoc[6、兼容Oracle匿名块]
** xref:master/7.7.adoc[7、兼容Oracle函数与存储过程]
** xref:master/7.8.adoc[8、内置数据类型与内置函数]
** xref:master/7.9.adoc[9、新增Oracle兼容模式的端口与IP]
** xref:master/7.10.adoc[10、XML函数]
** xref:master/7.11.adoc[11、兼容Oracle sequence]
** xref:master/7.12.adoc[12、包]
** xref:master/7.13.adoc[13、不可见列]
** xref:master/7.14.adoc[14、RowID]
* xref:master/8.adoc[社区贡献指南]
* xref:master/9.adoc[工具参考]
* xref:master/10.adoc[FAQ]
File renamed without changes.
File renamed without changes.
148 changes: 148 additions & 0 deletions CN/modules/ROOT/pages/master/7.14.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
:sectnums:
:sectnumlevels: 5

:imagesdir: ./_images

= RowID

== 目的

IvorySQL提供了兼容Oracle RowID的功能。RowID是一种伪列,在创建表时由数据库自动生成,对于数据库中的每一行,RowID 伪列返回该行的地址。

RowID 应当具备以下特性:

|====
| 1. 逻辑的标识每一行,且值唯一
| 2. 可以通过ROWID快速查询和修改表的其他列,自身不能被插入和修改
| 3. 用户可以控制是否开启此功能
|====

== 实现说明
在IvorySQL中系统列 ctid 字段代表了数据行在表中的物理位置,也就是行标识(tuple identifier),由一对数值组成(块编号和行索引),可以通过ctid快速的查找表中的数据行,这样和Oracle的RowID行为很相似,但是ctid值有可能会改变(例如update/ vacuum full等),因此ctid不适合作为一个长期的行标识。

我们选择了表的oid加一个序列值组成的复合类型来做为RowID值,其中的序列是系统列。如果RowID功能被开启,则在建表的同时创建一个名为table-id_rowid_seq 的序列。同时在heap_form_tuple构造函数中,为HeapTupleHeaderData 的长度增加8个字节,并标识td->t_infomask = HEAP_HASROWID 位来表示rowid的存在。

在开启了支持ROWID的GUC参数或建表时带上 WITH ROWID 选项,以及对普通表执行 ALTER TABLE … SET WITH ROWID 时会通过增加序列创建命令来创建一个序列。
```
/*
* Build a CREATE SEQUENCE command to create the sequence object,
* and add it to the list of things to be done before this CREATE/ALTER TABLE
*/
seqstmt = makeNode(CreateSeqStmt);
seqstmt->with_rowid = true;
seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
seqstmt->options = lcons(makeDefElem("as",
(Node *) makeTypeNameFromOid(INT8OID, -1),
-1),
seqstmt->options);
seqstmt->options = lcons(makeDefElem("nocache",
NULL,
-1),
seqstmt->options);
```

同时为了快速通过RowID伪列查询到一行数据,默认会在表的RowID列上创建一个UNIQUE索引,以提供快速查询功能。

RowID列做为系统属性列其实现是通过在 heap.c 中新增一个系统列来实现的。
```
/*
* Compatible Oracle ROWID pseudo column.
*/
static const FormData_pg_attribute a7 = {
.attname = {"rowid"},
.atttypid = ROWIDOID,
.attlen = -1,
.attnum = RowIdAttributeNumber,
.attcacheoff = -1,
.atttypmod = -1,
.attbyval = false,
.attalign = TYPALIGN_SHORT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true,
.attislocal = true,
};
```

在pg_class系统表中增加一个 bool 类型的字段 relhasrowid,用于标识建表时的 WITH ROWID选项,如果建表时带了WITH ROWID选项,则 relhasrowid为 t,否则为f。
用户在执行 ALTER table … SET WITH ROWID/ WITHOUT ROWID 命令时,也会修改这个值。

```
/* T if we generate ROWIDs for rows of rel */
bool relhasrowid BKI_DEFAULT(f);
```

在RowID的存储方面,如果启用了RowID 伪列功能,则在插入表之前 heap_form_tuple函数会根据参数TupleDesc 中tdhasrowid 是否为true 在 HeapTupleHeaderData 中增加8个字节来存储序列值。
在heap_prepare_insert 函数中获取序列的nextval值,存在HeapTupleHeader 相应的位置。

```
if (relation->rd_rel->relhasrowid)
{
// Get the sequence next value
seqnum = nextval_internal(relation->rd_rowdSeqid, true);
// Set the HeapTupleHeader
HeapTupleSetRowId(tup, seqnum);
}
```

== 功能开启

IvorySQL提供了多种方式来开启RowID功能。

=== 通过GUC参数开启

在IvorySQL 的兼容Oracle 模式下,可以通过 set ivorysql.default_with_rowids to on 来开启RowID,这个参数默认值为off。打开后创建的表,默认就带有了RowID列,可以通过 \d+ 表名 来查看。

在当前sesssion 中,如果这个GUC参数为 on,所有创建的表都将带上RowID列。
```
ivorysql=# show ivorysql.default_with_rowids;
ivorysql.default_with_rowids
------------------------------
off
(1 row)
```
```
ivorysql=# create table t(a int);
CREATE TABLE
ivorysql=# \d+ t
Table "public.t"
Column | Type | Collation | Nullable | Default | Invisible | Storage | Compression | Stats target | Description
--------+-----------------+-----------+----------+---------+-----------+---------+-------------+--------------+-------------
a | pg_catalog.int4 | | | | | plain | | |
Access method: heap
```
=== 通过建表语句中增加 WITH ROWID 选项开启

在建表语句中增加 WITH ROWID 选项。用户可以选择在需要的表上带有这个选项,没有WITH ROWID选项,将会创建一个普通的表。

```
ivorysql=# create table t2(a int) with rowid;
CREATE TABLE
ivorysql=# \d+ t2
Table "public.t2"
Column | Type | Collation | Nullable | Default | Invisible | Storage | Compression | Stats target | Description
--------+-----------------+-----------+----------+---------+-----------+---------+-------------+--------------+-------------
a | pg_catalog.int4 | | | | | plain | | |
Indexes:
"t2_16432_rowid_idx" btree (rowid)
Access method: heap
Has ROWID: yes
```

=== 通过对现有表ALTER TABLE … SET WITH ROWID开启

这种方式允许当一个普通表需要使用 ROWID 时,通过ATLER 命令去添加ROWID 列。
也可以通过ALTER TABLE … SET WITHOUT ROWID命令去除RowID。

```
ivorysql=# create table t3(a int);
CREATE TABLE
ivorysql=# alter table t3 set with rowid;
ALTER TABLE
ivorysql=# \d+ t3;
Table "public.t3"
Column | Type | Collation | Nullable | Default | Invisible | Storage | Compression | Stats target | Description
--------+-----------------+-----------+----------+---------+-----------+---------+-------------+--------------+-------------
a | pg_catalog.int4 | | | | | plain | | |
Access method: heap
Has ROWID: yes
```
File renamed without changes.
File renamed without changes.
20 changes: 10 additions & 10 deletions EN/antora.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: ivorysql-doc
title: IvorySQL
version: v4.5
start_page: v4.5/welcome.adoc
asciidoc:
attributes:
source-language: asciidoc@
table-caption: false
nav:
- modules/ROOT/nav.adoc
name: ivorysql-doc
title: IvorySQL
version: master
start_page: master/welcome.adoc
asciidoc:
attributes:
source-language: asciidoc@
table-caption: false
nav:
- modules/ROOT/nav.adoc
63 changes: 32 additions & 31 deletions EN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
* xref:v4.5/welcome.adoc[Welcome]
* xref:v4.5/1.adoc[Release]
* xref:v4.5/2.adoc[About]
* xref:master/welcome.adoc[Welcome]
* xref:master/1.adoc[Release]
* xref:master/2.adoc[About]
* Getting Started with IvorySQL
** xref:v4.5/3.adoc[Quick Start]
** xref:v4.5/4.adoc[Monitoring]
** xref:v4.5/5.adoc[Maintenance]
** xref:master/3.1.adoc[Quick Start]
** xref:master/3.2.adoc[Monitoring]
** xref:master/3.3.adoc[Maintenance]
* IvorySQL Advanced Feature
** xref:v4.5/6.adoc[Installation]
** xref:v4.5/7.adoc[Building Cluster]
** xref:v4.5/8.adoc[Developer]
** xref:v4.5/9.adoc[Operation Management]
** xref:v4.5/10.adoc[Migration]
** xref:master/4.1.adoc[Installation]
** xref:master/4.2.adoc[Building Cluster]
** xref:master/4.3.adoc[Developer]
** xref:master/4.4.adoc[Operation Management]
** xref:master/4.5.adoc[Migration]
* IvorySQL Ecosystem
** xref:v4.5/11.adoc[PostGIS]
** xref:v4.5/12.adoc[pgvector]
** xref:master/5.1.adoc[PostGIS]
** xref:master/5.2.adoc[pgvector]
* IvorySQL Architecture Design
** Query Processing
*** xref:v4.5/31.adoc[Dual Parser]
*** xref:master/6.1.1.adoc[Dual Parser]
** Compatibility Framework
*** xref:v4.5/30.adoc[initdb Process]
*** xref:master/6.2.1.adoc[initdb Process]
* List of Oracle compatible features
** xref:v4.5/14.adoc[1、Ivorysql frame design]
** xref:v4.5/15.adoc[2、GUC Framework]
** xref:v4.5/16.adoc[3、Case conversion]
** xref:v4.5/17.adoc[4、Dual-mode design]
** xref:v4.5/18.adoc[5、Compatible with Oracle like]
** xref:v4.5/19.adoc[6、Compatible with Oracle anonymous block]
** xref:v4.5/20.adoc[7、Compatible with Oracle functions and stored procedures]
** xref:v4.5/21.adoc[8、Built-in data types and built-in functions]
** xref:v4.5/22.adoc[9、Added Oracle compatibility mode ports and IP]
** xref:v4.5/26.adoc[10、XML Function]
** xref:v4.5/27.adoc[11、Compatible with Oracle sequence]
** xref:v4.5/28.adoc[12、Package]
** xref:v4.5/29.adoc[13、Invisible Columns]
* xref:v4.5/23.adoc[Community contribution]
* xref:v4.5/24.adoc[Tool Reference]
* xref:v4.5/25.adoc[FAQ]
** xref:master/7.1.adoc[1、Ivorysql frame design]
** xref:master/7.2.adoc[2、GUC Framework]
** xref:master/7.3.adoc[3、Case conversion]
** xref:master/7.4.adoc[4、Dual-mode design]
** xref:master/7.5.adoc[5、Compatible with Oracle like]
** xref:master/7.6.adoc[6、Compatible with Oracle anonymous block]
** xref:master/7.7.adoc[7、Compatible with Oracle functions and stored procedures]
** xref:master/7.8.adoc[8、Built-in data types and built-in functions]
** xref:master/7.9.adoc[9、Added Oracle compatibility mode ports and IP]
** xref:master/7.10.adoc[10、XML Function]
** xref:master/7.11.adoc[11、Compatible with Oracle sequence]
** xref:master/7.12.adoc[12、Package]
** xref:master/7.13.adoc[13、Invisible Columns]
** xref:master/7.14.adoc[14、RowID Column]
* xref:master/8.adoc[Community contribution]
* xref:master/9.adoc[Tool Reference]
* xref:master/10.adoc[FAQ]
File renamed without changes.
File renamed without changes.
Loading