This is an automated email from the ASF dual-hosted git repository.
lihaopeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new 65435c858c4 make row-store hit condition more clear (#2631)
65435c858c4 is described below
commit 65435c858c49f9d59e51d9f00a6a48a231f7379d
Author: lihangyu <[email protected]>
AuthorDate: Wed Jul 16 18:44:33 2025 +0800
make row-store hit condition more clear (#2631)
## Versions
- [x] dev
- [x] 3.0
- [x] 2.1
- [ ] 2.0
## Languages
- [x] Chinese
- [x] English
## Docs Checklist
- [x] Checked by AI
- [ ] Test Cases Built
---
docs/table-design/row-store.md | 75 ++++++++++++++++------
.../current/table-design/row-store.md | 48 +++++++++++---
.../version-2.1/table-design/row-store.md | 11 +---
.../version-3.0/table-design/row-store.md | 45 +++++++++++--
.../version-3.0/table-design/row-store.md | 74 +++++++++++++++------
5 files changed, 190 insertions(+), 63 deletions(-)
diff --git a/docs/table-design/row-store.md b/docs/table-design/row-store.md
index 7efaa688d4a..d6670489a1f 100644
--- a/docs/table-design/row-store.md
+++ b/docs/table-design/row-store.md
@@ -35,39 +35,74 @@ When creating a table, specify whether to enable row
storage, which columns to e
A page is the smallest unit for storage read and write operations, and
`page_size` refers to the size of a row-store page. This means that reading a
single row requires generating a page IO. The larger this value is, the better
the compression effect and the lower the storage space usage. However, the IO
overhead during point queries increases, resulting in lower performance
(because each IO operation reads at least one page). Conversely, the smaller
the value, the higher the storage spa [...]
-## Example
+## Row Store Hit Conditions
-The example below creates an 8-column table, where "key,v1,v3,v5,v7" are the 5
columns enabled for row storage. To optimize for high-concurrency point query
performance, the page_size is configured to 4KB.
+Row store hit conditions are divided into two scenarios: one is
high-concurrency primary key point queries that depend on table attributes and
satisfy point query conditions, and the other is single-table `SELECT *`
queries. These two query types are explained below.
-```
+- For high-concurrency primary key point queries, the table attributes need to
have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and
`"store_row_column" = "true"` (all columns are stored separately in the row
store, which incurs relatively high storage costs) or `"row_store_columns" =
"key,v1,v3,v5,v7"` (only specified columns are stored in the row store). When
querying, ensure the `WHERE` clause includes all primary keys with equality
conditions connected by `AND`, e.g., `S [...]
+
+- For general non-primary key point queries, to utilize the row store, the
table model must be `DUPLICATE` or have `"enable_unique_key_merge_on_write" =
"true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored
separately in the row store, which incurs relatively high storage costs).
Queries satisfying this pattern can hit the row store with `SELECT * FROM tbl
[WHERE XXXXX] ORDER BY XXX LIMIT N`, where the content in square brackets is an
optional query condition. Not [...]
+
+
+## Usage Examples
+
+The following example creates a table with 8 columns, where the 5 columns
`key, v1, v3, v5, v7` are enabled for row store, and the `page_size` is set to
4KB for high-concurrency point query performance.
+
+```
CREATE TABLE `tbl_point_query` (
- `key` int(11) NULL,
- `v1` decimal(27, 9) NULL,
- `v2` varchar(30) NULL,
- `v3` varchar(30) NULL,
- `v4` date NULL,
- `v5` datetime NULL,
- `v6` float NULL,
- `v7` datev2 NULL
+ `k` int(11) NULL,
+ `v1` decimal(27, 9) NULL,
+ `v2` varchar(30) NULL,
+ `v3` varchar(30) NULL,
+ `v4` date NULL,
+ `v5` datetime NULL,
+ `v6` float NULL,
+ `v7` datev2 NULL
) ENGINE=OLAP
-UNIQUE KEY(`key`)
+UNIQUE KEY(`k`)
COMMENT 'OLAP'
-DISTRIBUTED BY HASH(`key`) BUCKETS 1
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
- "enable_unique_key_merge_on_write" = "true",
- "light_schema_change" = "true",
- "row_store_columns" = "key,v1,v3,v5,v7",
- "row_store_page_size" = "4096"
+ "enable_unique_key_merge_on_write" = "true",
+ "light_schema_change" = "true",
+ "row_store_columns" = "k,v1,v3,v5,v7",
+ "row_store_page_size" = "4096"
);
```
-Query
+Query 1
+
+```
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
+```
+The `EXPLAIN` output for the above statement should include the
`SHORT-CIRCUIT` marker. For more details on point query usage, refer to
[High-Concurrency Point
Query](../query-acceleration/high-concurrent-point-query).
+
+The following example demonstrates how a `DUPLICATE` table can meet row store
query conditions.
+
```
-SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
+CREATE TABLE `tbl_duplicate` (
+ `k` int(11) NULL,
+ `v1` string NULw
+) ENGINE=OLAP
+DUPLICATE KEY(`k`)
+COMMENT 'OLAP'
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
+PROPERTIES (
+ "light_schema_change" = "true",
+ "store_row_column" = "true",
+ "row_store_page_size" = "4096"
+);
```
-For more information on point query usage, please refer to [High-Concurrent
Point Query](../query-acceleration/high-concurrent-point-query).
+`"store_row_column" = "true"` is required.
+
+Query 2 (Note: It must hit TOPN query optimization and must be `SELECT *`)
+
+```
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```
+The `EXPLAIN` output for the above statement should include the `FETCH ROW
STORE` marker and the `OPT TWO PHASE` marker.
## Notice
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
index 16b160e636a..d7d59c0f831 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/table-design/row-store.md
@@ -22,7 +22,7 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
"store_row_column" = "true"
```
-2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置
row_store_columns 参数 (3.0之后的版本),格式为逗号分割的列名
+2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置
row_store_columns 参数(3.0 之后的版本),格式为逗号分割的列名
```
"row_store_columns" = "column1,column2,column3"
```
@@ -34,6 +34,13 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的
IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个
page),反过来值越小存储空间极高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB
甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+## 行存命中条件
+行存命中条件分成两种情况,一种是高并发主键点查需要依赖表的属性以及查询满足点查条件,另一种是单表 SELECT * 查询,下面针对这两种查询进行说明。
+
+- 对于主键高并发点查,建表属性需要开启 `"enable_unique_key_merge_on_write" = "true"`(MOW 表)以及
`"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)或者 `"row_store_columns"
= "key,v1,v3,v5,v7"`(只会存储询部分列到行存中)。查询的时候注意 where 条件中需要有所有的主键等值并且是 AND,例如`SELECT
* FROM tbl WHERE k1 = 1 AND k2 = 2` 或者查询部分列 `SELECT v1, v2 FROM tbl WHERE k1 =
1 AND k2 = 2`,如果行存只包含了部分列(v1),但是查询的列不在行存中(例如 v2),那么将会从列存中查询剩余的列,该例子中 v1
将会从行存查询,而 v2 会从列存中查询(列存的 page size 更大,会有更多的读放大),通过 EXPLAIN
可以确认是否命中主键高并发点查优化,更多点查的使用请参考 [高并发点查](../query- [...]
+
+
+- 对于一般的非主键点查,如果想要走行存那么表模型 DUPLICATE 或者开启`"enable_unique_key_merge_on_write" =
"true"`(MOW 表),以及及 `"store_row_column" =
"true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)。查询满足这种模式将可以命中行存`SELECT * FROM tble [WHERE
XXXXX] ORDER BY XXX LIMIT N` 方括号中的是可选查询条件,注意目前只能是`SELECT *`,且需要命中 TOPN
的延迟物化优化,具体参考[TOPN
查询优化](../query-acceleration/optimization-technology-principle/topn-optimization),即命中`OPT
TWO PHASE`。最后通过 EXPLAIN 查看是否有有`FETCH ROW STORE`相应的标记即可确认命中行存
## 使用示例
@@ -41,7 +48,7 @@ page 是存储读写的最小单元,page_size 是行存 page 的大小,也
```
CREATE TABLE `tbl_point_query` (
- `key` int(11) NULL,
+ `k` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL,
`v3` varchar(30) NULL,
@@ -50,23 +57,48 @@ CREATE TABLE `tbl_point_query` (
`v6` float NULL,
`v7` datev2 NULL
) ENGINE=OLAP
-UNIQUE KEY(`key`)
+UNIQUE KEY(`k`)
COMMENT 'OLAP'
-DISTRIBUTED BY HASH(`key`) BUCKETS 1
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
- "row_store_columns" = "key,v1,v3,v5,v7",
+ "row_store_columns" = "k,v1,v3,v5,v7",
"row_store_page_size" = "4096"
);
```
-查询
+查询 1
+
```
-SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
```
+explain 上述语句应该包含 `SHORT-CIRCUIT` 相应的标记。更多点查的使用请参考
[高并发点查](../query-acceleration/high-concurrent-point-query) 。
+
+下面这个例子展示了 DUPLICATE 表怎么命中行存查询条件
-更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
+```
+CREATE TABLE `tbl_duplicate` (
+ `k` int(11) NULL,
+ `v1` string NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`k`)
+COMMENT 'OLAP'
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
+PROPERTIES (
+ "light_schema_change" = "true",
+ "store_row_column" = "true",
+ "row_store_page_size" = "4096"
+);
+```
+` "store_row_column" = "true",` 是必须的
+
+查询 2(注意命中 TOPN 查询优化以及需要是`SELECT *`)
+
+```
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```
+explain 上述语句应该包含`FETCH ROW STORE` 相应的标记,以及`OPT TWO PHASE`标记
## 注意事项
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
index faf7d3d1d56..7ac2d93862d 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-2.1/table-design/row-store.md
@@ -22,12 +22,7 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
"store_row_column" = "true"
```
-2. 哪些列开启行存:如果 `"store_row_column" = "true"`,默认所有列开启行存,若需要指定部分列开启行存,设置
row_store_columns 参数(3.0 之后的版本),格式为逗号分割的列名
-```
-"row_store_columns" = "column1,column2,column3"
-```
-
-3. 行存 page_size:默认为 16KB。
+2. 行存 page_size:默认为 16KB。
```
"row_store_page_size" = "16384"
```
@@ -37,7 +32,7 @@ page 是存储读写的最小单元,page_size 是行存 page 的大小,也
## 使用示例
-下面的例子创建一个 8 列的表,其中 "key,v1,v3,v5,v7" 这 5 列开启行存,为了高并发点查性能配置 page_size 为 4KB。
+下面的例子创建一个 8 列的表,为了高并发点查性能配置 page_size 为 4KB。
```
CREATE TABLE `tbl_point_query` (
@@ -56,7 +51,7 @@ DISTRIBUTED BY HASH(`key`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
- "row_store_columns" = "key,v1,v3,v5,v7",
+ "store_row_column" = "true",
"row_store_page_size" = "4096"
);
```
diff --git
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/table-design/row-store.md
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/table-design/row-store.md
index faf7d3d1d56..6bd0257cf97 100644
---
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/table-design/row-store.md
+++
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-3.0/table-design/row-store.md
@@ -34,6 +34,13 @@ Doris 默认采用列式存储,每个列连续存储,在分析场景(如
page 是存储读写的最小单元,page_size 是行存 page 的大小,也就是说读一行也需要产生一个 page 的
IO。这个值越大压缩效果越好存储空间占用越低,但是点查时 IO 开销越大性能越低(因为一次 IO 至少读一个
page),反过来值越小存储空间极高,点查性能越好。默认值 16KB 是大多数情况下比较均衡的选择,如果更偏向查询性能可以配置较小的值比如 4KB
甚至更低,如果更偏向存储空间可以配置较大的值比如 64KB 甚至更高。
+## 行存命中条件
+行存命中条件分成两种情况,一种是高并发主键点查需要依赖表的属性以及查询满足点查条件,另一种是单表 SELECT * 查询,下面针对这两种查询进行说明。
+
+- 对于主键高并发点查,建表属性需要开启 `"enable_unique_key_merge_on_write" = "true"`(MOW 表)以及
`"store_row_column" = "true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)或者 `"row_store_columns"
= "key,v1,v3,v5,v7"`(只会存储询部分列到行存中)。查询的时候注意 where 条件中需要有所有的主键等值并且是 AND,例如`SELECT
* FROM tbl WHERE k1 = 1 AND k2 = 2` 或者查询部分列 `SELECT v1, v2 FROM tbl WHERE k1 =
1 AND k2 = 2`,如果行存只包含了部分列(v1),但是查询的列不在行存中(例如 v2),那么将会从列存中查询剩余的列,该例子中 v1
将会从行存查询,而 v2 会从列存中查询(列存的 page size 更大,会有更多的读放大),通过 EXPLAIN
可以确认是否命中主键高并发点查优化,更多点查的使用请参考 [高并发点查](../query- [...]
+
+
+- 对于一般的非主键点查,如果想要走行存那么表模型 DUPLICATE 或者开启`"enable_unique_key_merge_on_write" =
"true"`(MOW 表),以及及 `"store_row_column" =
"true"`(所有列都会在行存中单独额外存一份,存储代价相对较高)。查询满足这种模式将可以命中行存`SELECT * FROM tble [WHERE
XXXXX] ORDER BY XXX LIMIT N` 方括号中的是可选查询条件,注意目前只能是`SELECT *`,且需要命中 TOPN
的延迟物化优化,具体参考[TOPN
查询优化](../query-acceleration/optimization-technology-principle/topn-optimization),即命中`OPT
TWO PHASE`。最后通过 EXPLAIN 查看是否有有`FETCH ROW STORE`相应的标记即可确认命中行存
## 使用示例
@@ -41,7 +48,7 @@ page 是存储读写的最小单元,page_size 是行存 page 的大小,也
```
CREATE TABLE `tbl_point_query` (
- `key` int(11) NULL,
+ `k` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL,
`v3` varchar(30) NULL,
@@ -50,24 +57,48 @@ CREATE TABLE `tbl_point_query` (
`v6` float NULL,
`v7` datev2 NULL
) ENGINE=OLAP
-UNIQUE KEY(`key`)
+UNIQUE KEY(`k`)
COMMENT 'OLAP'
-DISTRIBUTED BY HASH(`key`) BUCKETS 1
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
- "row_store_columns" = "key,v1,v3,v5,v7",
+ "row_store_columns" = "k,v1,v3,v5,v7",
"row_store_page_size" = "4096"
);
```
-查询
+查询 1
+
+```
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
+```
+explain 上述语句应该包含 `SHORT-CIRCUIT` 相应的标记。更多点查的使用请参考
[高并发点查](../query-acceleration/high-concurrent-point-query) 。
+
+下面这个例子展示了 DUPLICATE 表怎么命中行存查询条件
+
```
-SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
+CREATE TABLE `tbl_duplicate` (
+ `k` int(11) NULL,
+ `v1` string NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`k`)
+COMMENT 'OLAP'
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
+PROPERTIES (
+ "light_schema_change" = "true",
+ "store_row_column" = "true",
+ "row_store_page_size" = "4096"
+);
```
+` "store_row_column" = "true",` 是必须的
-更多点查的使用请参考 [高并发点查](../query-acceleration/high-concurrent-point-query) 。
+查询 2(注意命中 TOPN 查询优化以及需要是`SELECT *`)
+```
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```
+explain 上述语句应该包含`FETCH ROW STORE` 相应的标记,以及`OPT TWO PHASE`标记
## 注意事项
diff --git a/versioned_docs/version-3.0/table-design/row-store.md
b/versioned_docs/version-3.0/table-design/row-store.md
index 7efaa688d4a..e4611f6f405 100644
--- a/versioned_docs/version-3.0/table-design/row-store.md
+++ b/versioned_docs/version-3.0/table-design/row-store.md
@@ -34,40 +34,74 @@ When creating a table, specify whether to enable row
storage, which columns to e
A page is the smallest unit for storage read and write operations, and
`page_size` refers to the size of a row-store page. This means that reading a
single row requires generating a page IO. The larger this value is, the better
the compression effect and the lower the storage space usage. However, the IO
overhead during point queries increases, resulting in lower performance
(because each IO operation reads at least one page). Conversely, the smaller
the value, the higher the storage spa [...]
+## Row Store Hit Conditions
-## Example
+Row store hit conditions are divided into two scenarios: one is
high-concurrency primary key point queries that depend on table attributes and
satisfy point query conditions, and the other is single-table `SELECT *`
queries. These two query types are explained below.
-The example below creates an 8-column table, where "key,v1,v3,v5,v7" are the 5
columns enabled for row storage. To optimize for high-concurrency point query
performance, the page_size is configured to 4KB.
+- For high-concurrency primary key point queries, the table attributes need to
have `"enable_unique_key_merge_on_write" = "true"` (MOW table) and
`"store_row_column" = "true"` (all columns are stored separately in the row
store, which incurs relatively high storage costs) or `"row_store_columns" =
"key,v1,v3,v5,v7"` (only specified columns are stored in the row store). When
querying, ensure the `WHERE` clause includes all primary keys with equality
conditions connected by `AND`, e.g., `S [...]
-```
+- For general non-primary key point queries, to utilize the row store, the
table model must be `DUPLICATE` or have `"enable_unique_key_merge_on_write" =
"true"` (MOW table) and `"store_row_column" = "true"` (all columns are stored
separately in the row store, which incurs relatively high storage costs).
Queries satisfying this pattern can hit the row store with `SELECT * FROM tbl
[WHERE XXXXX] ORDER BY XXX LIMIT N`, where the content in square brackets is an
optional query condition. Not [...]
+
+
+## Usage Examples
+
+The following example creates a table with 8 columns, where the 5 columns
`key, v1, v3, v5, v7` are enabled for row store, and the `page_size` is set to
4KB for high-concurrency point query performance.
+
+```
CREATE TABLE `tbl_point_query` (
- `key` int(11) NULL,
- `v1` decimal(27, 9) NULL,
- `v2` varchar(30) NULL,
- `v3` varchar(30) NULL,
- `v4` date NULL,
- `v5` datetime NULL,
- `v6` float NULL,
- `v7` datev2 NULL
+ `k` int(11) NULL,
+ `v1` decimal(27, 9) NULL,
+ `v2` varchar(30) NULL,
+ `v3` varchar(30) NULL,
+ `v4` date NULL,
+ `v5` datetime NULL,
+ `v6` float NULL,
+ `v7` datev2 NULL
) ENGINE=OLAP
-UNIQUE KEY(`key`)
+UNIQUE KEY(`k`)
COMMENT 'OLAP'
-DISTRIBUTED BY HASH(`key`) BUCKETS 1
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
- "enable_unique_key_merge_on_write" = "true",
- "light_schema_change" = "true",
- "row_store_columns" = "key,v1,v3,v5,v7",
- "row_store_page_size" = "4096"
+ "enable_unique_key_merge_on_write" = "true",
+ "light_schema_change" = "true",
+ "row_store_columns" = "k,v1,v3,v5,v7",
+ "row_store_page_size" = "4096"
);
```
-Query
+Query 1
+
```
-SELECT key, v1, v3, v5, v7 FROM tbl_point_query WHERE key = 100;
+SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100
```
+The `EXPLAIN` output for the above statement should include the
`SHORT-CIRCUIT` marker. For more details on point query usage, refer to
[High-Concurrency Point
Query](../query-acceleration/high-concurrent-point-query).
+
+The following example demonstrates how a `DUPLICATE` table can meet row store
query conditions.
-For more information on point query usage, please refer to [High-Concurrent
Point Query](../query-acceleration/high-concurrent-point-query).
+```
+CREATE TABLE `tbl_duplicate` (
+ `k` int(11) NULL,
+ `v1` string NULw
+) ENGINE=OLAP
+DUPLICATE KEY(`k`)
+COMMENT 'OLAP'
+DISTRIBUTED BY HASH(`k`) BUCKETS 1
+PROPERTIES (
+ "light_schema_change" = "true",
+ "store_row_column" = "true",
+ "row_store_page_size" = "4096"
+);
+```
+
+`"store_row_column" = "true"` is required.
+
+Query 2 (Note: It must hit TOPN query optimization and must be `SELECT *`)
+
+```
+SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10
+```
+The `EXPLAIN` output for the above statement should include the `FETCH ROW
STORE` marker and the `OPT TWO PHASE` marker.
## Notice
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]