Skip to content

Commit bcb93b6

Browse files
github-actions[bot]ti-chi-bot
authored andcommitted
Auto-sync: Update Chinese docs from English PR
Synced from: pingcap/docs#22572 Target PR: pingcap#21446 AI Provider: gemini Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 31eafc9 commit bcb93b6

File tree

5 files changed

+169
-5
lines changed

5 files changed

+169
-5
lines changed

TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@
650650
- 属性
651651
- [AUTO_INCREMENT](/auto-increment.md)
652652
- [AUTO_RANDOM](/auto-random.md)
653+
- [_tidb_rowid](/tidb-rowid.md)
653654
- [SHARD_ROW_ID_BITS](/shard-row-id-bits.md)
654655
- [字面值](/literal-values.md)
655656
- [Schema 对象名](/schema-object-names.md)

clustered-indexes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ summary: 本文档介绍了聚簇索引的概念、使用场景、使用方法
99

1010
目前 TiDB 中含有主键的表分为以下两类:
1111

12-
- `NONCLUSTERED`,表示该表的主键为非聚簇索引。在非聚簇索引表中,行数据的键由 TiDB 内部隐式分配的 `_tidb_rowid` 构成,而主键本质上是唯一索引,因此非聚簇索引表存储一行至少需要两个键值对,分别为
12+
- `NONCLUSTERED`,表示该表的主键为非聚簇索引。在非聚簇索引表中,行数据的键由 TiDB 内部隐式分配的 `_tidb_rowid` 值构成,而主键本质上是唯一索引,因此非聚簇索引表存储一行至少需要两个键值对,分别为
1313
- `_tidb_rowid`(键)- 行数据(值)
1414
- 主键列数据(键) - `_tidb_rowid`(值)
1515
- `CLUSTERED`,表示该表的主键为聚簇索引。在聚簇索引表中,行数据的键由用户给定的主键列数据构成,因此聚簇索引表存储一行至少只要一个键值对,即

shard-row-id-bits.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ summary: 介绍 TiDB 的 `SHARD_ROW_ID_BITS` 表属性。
55

66
# SHARD_ROW_ID_BITS
77

8-
本文介绍表属性 `SHARD_ROW_ID_BITS`,它用来设置隐式 `_tidb_rowid` 分片数量的 bit 位数。
8+
本文介绍表属性 `SHARD_ROW_ID_BITS`,它用来设置隐式 [`_tidb_rowid`](/tidb-rowid.md) 分片数量的 bit 位数。
99

1010
## 基本概念
1111

12-
对于非[聚簇索引](/clustered-indexes.md)主键或没有主键的表,TiDB 会使用一个隐式的自增 rowid。大量执行 `INSERT` 插入语句时会把数据集中写入单个 Region,造成写入热点。
12+
对于非聚簇索引主键或没有主键的表,TiDB 会使用隐藏的 [`_tidb_rowid`](/tidb-rowid.md) 作为隐式自增 rowid。大量执行 `INSERT` 插入语句时会把数据集中写入单个 Region,造成写入热点。
1313

1414
通过设置 `SHARD_ROW_ID_BITS`,可以把 rowid 打散写入多个不同的 Region,缓解写入热点问题。
1515

@@ -23,8 +23,9 @@ summary: 介绍 TiDB 的 `SHARD_ROW_ID_BITS` 表属性。
2323
|--------|--------|--------------|
2424
| 1 bit | `S` bits | `63-S` bits |
2525

26-
- 自增位的值保存在 TiKV 中,由 TiDB 按顺序分配,每次分配后值会自增 1。自增位确保了 `_tidb_rowid` 列的值全局唯一。当自增位的值耗尽后(即达到最大值时),再次自动分配时会报 `Failed to read auto-increment value from storage engine` 错误。
26+
- 自增位的值保存在 TiKV 中,由 TiDB 按顺序分配,每次分配后值会自增 1。当自增位的值耗尽后(即达到最大值时),再次自动分配时会报 `Failed to read auto-increment value from storage engine` 错误。
2727
- 关于 `_tidb_rowid` 取值范围:最终生成值包含的最大位数 = 分片位 + 自增位,最大值为 `(2^63)-1`
28+
> `_tidb_rowid` 是内部行句柄。不要假定它在所有情况下都是全局唯一的。对于未使用聚簇索引的分区表,`ALTER TABLE ... EXCHANGE PARTITION` 操作可能会导致不同分区具有相同的 `_tidb_rowid` 值。详情请参阅 [`_tidb_rowid`](/tidb-rowid.md)
2829
2930
> **注意:**
3031
>

sql-statements/sql-statement-show-table-next-rowid.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ summary: TiDB 数据库中 SHOW TABLE NEXT_ROW_ID 的使用概况。
77

88
`SHOW TABLE NEXT_ROW_ID` 语句用于显示用户表中某些特殊列的详情,主要包含以下几种类型:
99

10-
* TiDB 创建的 [`AUTO_INCREMENT`](/auto-increment.md) 类型列,即 `_tidb_rowid`
10+
* TiDB 自动管理的隐藏行句柄列 `_tidb_rowid``_tidb_rowid`
1111
* 用户创建的 `AUTO_INCREMENT` 类型列
1212
* 用户创建的 [`AUTO_RANDOM`](/auto-random.md) 类型列
1313
* 用户创建的 [`SEQUENCE`](/sql-statements/sql-statement-create-sequence.md) 对象信息
@@ -69,3 +69,5 @@ SHOW TABLE t NEXT_ROW_ID;
6969
* [CREATE TABLE](/sql-statements/sql-statement-create-table.md)
7070
* [AUTO_RANDOM](/auto-random.md)
7171
* [CREATE_SEQUENCE](/sql-statements/sql-statement-create-sequence.md)
72+
* [_tidb_rowid](/tidb-rowid.md)
73+

tidb-rowid.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: _tidb_rowid
3+
summary: 了解 `_tidb_rowid` 是什么,何时可用,以及如何安全地使用它。
4+
---
5+
6+
# _tidb_rowid
7+
8+
`_tidb_rowid` 是一个 TiDB 使用的隐藏系统列,作为不使用聚集索引的表的行句柄。你不会在表模式中声明此列,但当表使用 `_tidb_rowid` 作为其句柄时,你可以在 SQL 中引用它。
9+
10+
在当前实现中,`_tidb_rowid` 是一个由 TiDB 管理的额外的 `BIGINT NOT NULL` 句柄列。
11+
12+
> **警告:**
13+
>
14+
> - 在所有情况下,都不要假定 `_tidb_rowid` 是全局唯一的。对于不使用聚集索引的分区表,`ALTER TABLE ... EXCHANGE PARTITION` 可能会导致不同分区具有相同的 `_tidb_rowid` 值。
15+
> - 如果你需要一个稳定的唯一标识符,请定义并使用显式主键,而不是依赖 `_tidb_rowid`
16+
17+
## `_tidb_rowid` 何时可用
18+
19+
`_tidb_rowid` 可用于其行句柄不是聚集主键的表。实际上,这意味着以下表类型会使用 `_tidb_rowid`
20+
21+
- 没有主键的表
22+
- 主键明确定义为 `NONCLUSTERED` 的表
23+
24+
`_tidb_rowid` 不适用于使用聚集索引的表,包括以下情况:
25+
26+
- 主键为整数且作为聚集行句柄的表
27+
- 在复合主键上具有聚集索引的表
28+
29+
以下示例显示了区别:
30+
31+
```sql
32+
CREATE TABLE t1 (a INT, b VARCHAR(20));
33+
CREATE TABLE t2 (id BIGINT PRIMARY KEY NONCLUSTERED, a INT);
34+
CREATE TABLE t3 (id BIGINT PRIMARY KEY CLUSTERED, a INT);
35+
```
36+
37+
对于 `t1``t2`,你可以查询 `_tidb_rowid`
38+
39+
```sql
40+
SELECT _tidb_rowid, a, b FROM t1;
41+
SELECT _tidb_rowid, id, a FROM t2;
42+
```
43+
44+
对于 `t3``_tidb_rowid` 不可用,因为聚集主键已经是行句柄:
45+
46+
```sql
47+
SELECT _tidb_rowid, id, a FROM t3;
48+
```
49+
50+
```sql
51+
ERROR 1054 (42S22): Unknown column '_tidb_rowid' in 'field list'
52+
```
53+
54+
## 读取 `_tidb_rowid`
55+
56+
对于支持的表,你可以在 `SELECT` 语句中使用 `_tidb_rowid`。这对于分页、故障排除和批量处理等任务非常有用。
57+
58+
示例:
59+
60+
```sql
61+
CREATE TABLE t (a INT, b VARCHAR(20));
62+
INSERT INTO t VALUES (1, 'x'), (2, 'y');
63+
64+
SELECT _tidb_rowid, a, b FROM t ORDER BY _tidb_rowid;
65+
```
66+
67+
```sql
68+
+-------------+---+---+
69+
| _tidb_rowid | a | b |
70+
+-------------+---+---+
71+
| 1 | 1 | x |
72+
| 2 | 2 | y |
73+
+-------------+---+---+
74+
```
75+
76+
要检查 TiDB 将要分配的下一个行 ID 值,请使用 `SHOW TABLE ... NEXT_ROW_ID`
77+
78+
```sql
79+
SHOW TABLE t NEXT_ROW_ID;
80+
```
81+
82+
```sql
83+
+-----------------------+------------+-------------+--------------------+-------------+
84+
| DB_NAME | TABLE_NAME | COLUMN_NAME | NEXT_GLOBAL_ROW_ID | ID_TYPE |
85+
+-----------------------+------------+-------------+--------------------+-------------+
86+
| update_doc_rowid_test | t | _tidb_rowid | 30001 | _TIDB_ROWID |
87+
+-----------------------+------------+-------------+--------------------+-------------+
88+
```
89+
90+
## 写入 `_tidb_rowid`
91+
92+
默认情况下,TiDB 不允许 `INSERT``REPLACE``UPDATE` 语句直接写入 `_tidb_rowid`
93+
94+
```sql
95+
INSERT INTO t(_tidb_rowid, a, b) VALUES (101, 4, 'w');
96+
```
97+
98+
```sql
99+
ERROR 1105 (HY000): insert, update and replace statements for _tidb_rowid are not supported
100+
```
101+
102+
如果你需要在数据导入或迁移期间保留行 ID,请先启用系统变量 [`tidb_opt_write_row_id`](/system-variables.md#tidb_opt_write_row_id)
103+
104+
```sql
105+
SET @@tidb_opt_write_row_id = ON;
106+
INSERT INTO t(_tidb_rowid, a, b) VALUES (100, 3, 'z');
107+
SET @@tidb_opt_write_row_id = OFF;
108+
109+
SELECT _tidb_rowid, a, b FROM t WHERE _tidb_rowid = 100;
110+
```
111+
112+
```sql
113+
+-------------+---+---+
114+
| _tidb_rowid | a | b |
115+
+-------------+---+---+
116+
| 100 | 3 | z |
117+
+-------------+---+---+
118+
```
119+
120+
> **警告:**
121+
>
122+
> `tidb_opt_write_row_id` 仅用于导入和迁移场景。不推荐用于常规应用程序写入。
123+
124+
## 限制
125+
126+
- 你不能创建名为 `_tidb_rowid` 的用户列。
127+
- 你不能将现有用户列重命名为 `_tidb_rowid`
128+
- `_tidb_rowid` 是一个内部行句柄。不要将其视为长期业务键。
129+
- 在分区的非聚集表上,`_tidb_rowid` 的值不保证在分区之间是唯一的。执行 `EXCHANGE PARTITION` 后,不同分区可能包含具有相同 `_tidb_rowid` 值的行。
130+
- `_tidb_rowid` 是否存在取决于表布局。如果表使用聚集索引,请改用主键。
131+
132+
## 热点考虑
133+
134+
对于使用 `_tidb_rowid` 的表,TiDB 默认按递增顺序分配行 ID。在写密集型工作负载下,这可能会导致写热点。
135+
136+
要缓解此问题(针对依赖隐式行 ID 的表),请考虑使用 [`SHARD_ROW_ID_BITS`](/shard-row-id-bits.md),并在需要时使用 [`PRE_SPLIT_REGIONS`](/sql-statements/sql-statement-split-region.md#pre_split_regions)
137+
138+
示例:
139+
140+
```sql
141+
CREATE TABLE t (
142+
id BIGINT PRIMARY KEY NONCLUSTERED,
143+
c INT
144+
) SHARD_ROW_ID_BITS = 4;
145+
```
146+
147+
`SHARD_ROW_ID_BITS` 仅适用于使用隐式行 ID 路径的表。它不适用于聚集索引表。
148+
149+
## 相关语句和变量
150+
151+
- [`SHOW TABLE NEXT_ROW_ID`](/sql-statements/sql-statement-show-table-next-rowid.md):显示 TiDB 将要分配的下一个行 ID
152+
- [`SHARD_ROW_ID_BITS`](/shard-row-id-bits.md):分片隐式行 ID 以减少热点
153+
- [`Clustered Indexes`](/clustered-indexes.md):解释了何时表使用主键而不是 `_tidb_rowid`
154+
- [`tidb_opt_write_row_id`](/system-variables.md#tidb_opt_write_row_id):控制是否允许写入 `_tidb_rowid`
155+
156+
## 另请参阅
157+
158+
- [CREATE TABLE](/sql-statements/sql-statement-create-table.md)
159+
- [AUTO_INCREMENT](/auto-increment.md)
160+
- [Non-transactional DML](/non-transactional-dml.md)

0 commit comments

Comments
 (0)