> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 扩展与 ABI 的行为方式

> 本页介绍 VillageSQL 扩展 ABI：服务器拥有什么、扩展拥有什么，以及这种划分如何在崩溃恢复、复制、还原和模式操作中发挥作用。

VillageSQL 扩展框架 (VEF) 会在 MySQL 服务器代码中预定的位置调用扩展代码。发生在扩展输出上的一切——崩溃恢复、复制、模式操作、备份——都由服务器以与处理任何内置列类型相同的方式来处理。本文档描述了这个边界：VEF 做什么、扩展做什么，以及由此产生的系统在运行时如何表现。

本页中的示例使用 [vsql-uuid](https://github.com/villagesql/vsql-uuid) 扩展来说明数据如何流动。

## ABI 边界

VillageSQL 扩展通过一个二进制接口 (ABI) 与服务器交互，该接口在扩展与服务器之间有着清晰的所有权分离。

**服务器拥有：**

* 存储：InnoDB 读写字节；它不解释这些字节
* 模式：列类型元数据以及每个类型由哪个扩展注册都存储在 VillageSQL 系统表中，并在重启后持久保留
* 恢复、复制和备份：这些操作作用于原始字节，与任何内置列类型相同
* 扩展注册：名称、版本以及函数/类型注册在启动时从 VillageSQL 系统表重新加载

**扩展拥有：**

* 二进制格式：`from_string` 编码函数定义了写入磁盘的内容；`to_string` 在输出时将其读回
* 业务规则：验证、比较、哈希和错误处理
* 状态：扩展不会在服务器为其存储的字节之外持久保留任何内容

有关完整的二进制接口——结构体、函数指针 typedef 以及协议版本控制——请参阅服务器仓库中的 [`villagesql/sdk/include/villagesql/abi/types.h`](https://github.com/villagesql/villagesql-server/blob/main/villagesql/sdk/include/villagesql/abi/types.h)。

## 自定义类型如何存储

当您将某列声明为 `UUID`（以 vsql-uuid 为例）时，服务器会为每行存储一个固定长度的原始字节块。人类可读的形式——例如 `d7d665f3-bb13-4c2f-b10f-d2126eb40cba`——仅存在于边界处：`from_string` 在写入时将其编码为二进制，`to_string` 在读取时将其解码回来。中间的一切——存储、重做日志、崩溃恢复、二进制日志——都作用于这些字节而不解释它们。

## 崩溃恢复

扩展会在服务器重启时自动重新加载——无需手动干预。您可以通过 `INFORMATION_SCHEMA.EXTENSION_REGISTRATION` 来验证这一点，它在重启后显示的注册条目与重启前相同。

行数据通过 InnoDB 的正常崩溃恢复得以存续。扩展的二进制格式从不被特殊处理——InnoDB 处理 UUID 列的方式与处理 `VARBINARY` 列没有任何不同。

## 二进制日志格式

在行格式复制（默认方式）中，自定义类型的值以原始二进制形式在二进制日志中传输。没有重新编码步骤：写入 binlog 时不会调用扩展的 `from_string`，而 `to_string` 仅在客户端读回该值时才被调用。

一个 UUID 列的行级二进制日志条目如下所示：

```
### INSERT INTO `abi_test`.`t1`
### SET
###   @1='\xd7\xd6\x65\xf3\xbb\x13\x4c\x2f\xb1\x0f\xd2\x12\x6e\xb4\x0c\xba'
###   @2='alpha'
```

那 16 个原始字节原封不动地流经二进制日志。安装了该扩展的消费者可以通过 `to_string` 将它们解码为可读值；而未安装该扩展的消费者——例如外部 CDC 管道或 binlog 读取器——只能看到原始字节。

## 还原

还原 VillageSQL 服务器的工作方式与崩溃恢复相同：服务器启动，读取其扩展注册信息，并自动加载每个扩展。对于扩展类型的列不需要特殊处理——原始字节就在备份中，扩展会按需对其进行解码。

扩展不存储在数据库内部——它们作为 `.veb` 文件存在于磁盘上的 `veb_dir` 中。如果服务器在已还原的实例上启动时缺少 VEB 文件，启动会以 `VEB file not found` 中止。`.veb_expansion_cache` 不能替代 `.veb` 本身。在分发您的扩展时，请确保您的用户知道要将 `veb_dir` 与数据目录一起包含在任何备份或服务器迁移中。

## 模式操作

对含有扩展类型列的表执行 `ALTER TABLE` 的行为与对内置类型完全相同。服务器在其模式元数据中跟踪该列的扩展绑定，并且该绑定在表重建后得以存续。在含有 vsql-uuid `id` 列的表上添加或修改其他列，会使 UUID 数据保持完好。
