TTC协议(TTS即ORACLE DATA)协议分析
TTC 是构建在 TNS 协议之上的应用层协议,它负责解决客户端和服务器之间可能存在的差异(如字符集、数据类型表示),并管理所有高级别的数据交换,包括 SQL 语句的发送、结果集的返回、游标管理和过程调用。
1. 引言
Two-Task Common (TTC) 协议是 Oracle 客户端(如 OCI, ODPI-C, JDBC-OCI) 和数据库服务器之间进行数据交换的核心应用层协议。它运行在 TNS 协议之上,TNS 的 `DATA` 包(类型 `0x0E`)的有效载荷就是 TTC 消息。
TTC 的主要职责是:
数据类型转换:在客户端和服务器不同的内部数据表示格式之间进行转换(如字节序、浮点数格式)。
字符集转换:在客户端和服务器不同的字符集(如 US7ASCII, AL32UTF8)之间进行转换。
SQL 执行控制:传输 SQL 语句、PL/SQL 块、调用存储过程。
结果集描述与获取:传输查询结果的元数据(描述)和实际行数据。
会话状态管理:管理游标、事务状态和会话参数。
2. TTC 消息结构
TTC 消息被封装在 TNS `DATA` 包的数据区内。一个 TNS `DATA` 包可以包含一个或多个 TTC 消息。每个 TTC 消息由一个操作码(Opcode)和紧随其后的特定于该操作的数据组成。
2.1. 通用头结构
TTC 消息通常以一个或多个字节的操作码开始。最重要的操作码是 `0x02` 和 `0x03`,它们标志着 TTC 数据交换的开始,并且它们自身拥有一个复杂的头结构。
TTC 数据头(对于 Opcode 0x02/0x03)
当一个 TNS `DATA` 包的 Flags 字段指示其为 SQL 操作(通常是)时,其 TTC 载荷通常以一个 `TTC Data Header` 开始。
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| TTC Header Version | Opcode (0x02/0x03) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Redo Length / Cursor ID | Flags / MX |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Error/Failure Offset | Array Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Iteration Count / UID | OACFXID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OACFNUM / MXER | Bookmark Flag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Bookmark Length | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Statement Type | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key Value / Reserved | Parser Mode |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Optimizer Goal | NLS Ratio |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NLS Language Length | NLS Language (Var) /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ NLS Territory Length | NLS Territory (Var) /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Client Character Set Length | Client Charset (Var) /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ ... ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TTC Header Version (8位): TTC 头版本号。
Opcode (8位): TTC 操作码。
`0x02`: OCI 函数调用 (通常用于 SQL 操作,如 `PARSE`, `EXECUTE`, `FETCH`)。
`0x03`: 数据行 (用于发送数据或返回查询结果)。
其他常见操作码: `0x04` (描述信息), `0x05` (错误信息), `0x07` (状态信息), `0x0A` (认证), `0x0E` (提交/回滚), `0x4B` (LOB 操作) 等。
Cursor ID (16位, 大端序): 与此操作关联的游标标识符。
Flags / MX (8位): 功能标志位,含义取决于操作。
Array Size / Iteration Count (16位, 大端序): 对于批量操作,表示数组大小或迭代次数。Statement Type (8位): 指示 SQL 语句的类型。
`0x00`: `SELECT`
`0x01`: `UPDATE`
`0x02`: `DELETE`
`0x03`: `INSERT`
`0x04`: `CREATE`
`0x05`: `DROP`
`0x06`: `ALTER`
`0x07`: `BEGIN` (匿名块)
`0x09`: `CALL`
Parser Mode (8位)**: 解析模式标志(如是否进行语法检查、是否创建执行计划)。
在这个通用头之后,是特定于 `Opcode` 的数据。对于 `0x02` (OCI 调用),后面会跟着一个或多个参数,每个参数描述一个绑定变量或返回值。
3. 关键操作流程
3.1. SQL 查询执行 (SELECT)
1. 客户端 -> 服务器: `PARSE` (Opcode 0x02)
包含 `Statement Type=0x00` (SELECT) 和 SQL 文本。
如果 SQL 中有绑定变量(如 `:id`),会包含绑定变量描述参数。
2. 客户端 -> 服务器: `EXECUTE` (Opcode 0x02)
为所有绑定变量提供实际数据值。
服务器执行语句,准备结果集。
3. 客户端 -> 服务器: `FETCH` (Opcode 0x02)
请求下一批数据行。`Array Size` 字段指示请求的行数。
4. 服务器 -> 客户端: `DATA` (Opcode 0x03)
返回请求的行数据。每一行包含多个列数据。
5. 服务器 -> 客户端: `STATUS` (Opcode 0x07)
指示 `FETCH` 操作的状态(如成功、无更多数据)。
3.2. 数据表示 (Data Representation)
TTC 的核心功能之一是对数据类型进行编码和解码。数据在网络上以一种标准化的格式传输。
每个数据值在传输时通常由一个**长度指示符**和**数据本身**组成。
长度指示符:
对于可变长度类型(如 `VARCHAR2`, `RAW`, `NULL`),首先是一个长度字节/字。
如果长度为 `0xFF` (1字节) 或 `0xFFFF` (2字节),表示 `NULL` 值。
如果长度是 `0xFE`,表示值是 `零长度` (空字符串)。
数据本身:
NUMBER: 使用 Oracle 专有的可变长度格式编码。每个字节表示两个十进制数字(最高4位和最低4位),符号和指数信息也包含在其中。`0x80` 表示数字 `0`。
DATE/TIMESTAMP: 固定长度字段(通常 7-11 字节),包含年、月、日、时、分、秒、小数秒。
CHAR/VARCHAR2: 原始字符数据,已转换为数据库字符集。
NCHAR/NVARCHAR2: 原始字符数据,已转换为国家字符集。
RAW/BLOB/CLOB: 以字节流形式传输。对于大对象,会分片传输。
ROWID: 以特定格式编码的二进制或字符表示。
3.3. 绑定与定义 (Binding & Defining)
绑定 (输入): 在 `PARSE/EXECUTE` 中,客户端使用 `0x21` (BIND) 参数描述每个绑定变量(名称、数据类型、最大长度等),并在 `EXECUTE` 中提供数据。
定义 (输出): 在 `DESCRIBE` (可选) 或第一次 `FETCH` 之后,服务器使用 `0x22` (DEFINE) 参数描述每个返回列(名称、数据类型、最大长度等)。后续的 `DATA` 包就根据这个定义来解析数据。
4. 版本差异
9.2.0.2: 基础 TTC 功能已成熟。支持主要数据类型和基本操作。
11.2.0.4: 增强了高级数据类型(如 `TIMESTAMP WITH TIME ZONE`)的支持。改进了 LOB 的传输效率(如 `LOB Prefetch`)。
12.2.0.1: 引入了对多租户架构(CDB/PDB)的更好支持。可能扩展了 TTC 头以携带容器上下文信息。进一步优化大数据量传输。
19.3.0.0: 持续的性能优化和安全性增强。与 12.2 协议大体相同,但可能在内部操作码或错误处理上有细微差别。