> ## 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.

# 安装扩展

> 如何使用扩展为 VillageSQL 添加新功能。

安装 VillageSQL 扩展，以向数据库添加自定义类型、函数和功能。

## 命令语法

```sql theme={null}
INSTALL EXTENSION extension_name [VERSION 'version'];
```

提供 `VERSION` 时，服务器会打开 `{name}-{version}.veb`，
将该版本与清单进行比较，如果两者不一致则中止安装：

```text theme={null}
ERROR 3219 (HY000): Version mismatch in '<file>': filename says 'X' but manifest says 'Y'
```

省略该子句则安装 `{name}.veb`；或者，如果只存在带版本号的 VEB，
则安装唯一的 `{name}-{version}.veb`。请参阅 [选择版本](#selecting-a-version)。

<Info>
  扩展以 `.veb`（VillageSQL 扩展包）文件的形式分发，其中包含编译后的库和元数据。
</Info>

<h3 id="selecting-a-version">
  选择版本
</h3>

`veb_dir` 中的 VEB 文件可以命名为 `{name}.veb`（不带版本号）或 `{name}-{version}.veb`（带版本号）。要安装特定的带版本号 VEB，请添加 `VERSION` 子句：

```sql theme={null}
INSTALL EXTENSION vsql_uuid VERSION '0.2.0';
```

使用 `VERSION` 时，服务器会打开 `vsql_uuid-0.2.0.veb`，并验证其 `manifest.json` 中的版本是否与 `0.2.0` 匹配。

不使用 `VERSION` 时，服务器按如下方式解析文件：

* 如果 `{name}.veb` 存在，则安装它；版本从其 `manifest.json` 中读取。
* 否则，如果恰好存在一个 `{name}-{version}.veb`，则安装它；文件名中的版本会与其 `manifest.json` 中的版本进行核对。
* 否则，安装失败，您必须指定一个版本。

<Warning>
  如果存在多个带版本号的 VEB 且不存在不带版本号的 VEB，则 `INSTALL EXTENSION` 会失败并报错 `Multiple versions of extension '<name>' found in '<dir>'; specify a version with INSTALL EXTENSION <name> VERSION 'x.y.z'`。请使用显式的 `VERSION` 子句重新运行。
</Warning>

<h3 id="extension-naming-conventions">
  扩展命名约定
</h3>

VillageSQL 在不同的上下文中采用不同的命名约定：

* **SQL 命令：** 使用下划线：`INSTALL EXTENSION vsql_uuid`
* **仓库名称：** 使用连字符：`github.com/villagesql/vsql-uuid`
* **文件名：** 使用下划线：`vsql_uuid.veb`
* **manifest.json：** 使用下划线以匹配 SQL：`"name": "vsql_uuid"`

**示例：**

```bash theme={null}
# Clone from GitHub repo (hyphens in URL)
git clone https://github.com/villagesql/vsql-uuid

# But .veb file uses underscores
ls vsql_uuid.veb

# Install with underscores (no quotes)
INSTALL EXTENSION vsql_uuid;
```

<h2 id="required-privilege">
  所需权限
</h2>

`INSTALL EXTENSION`、`UNINSTALL EXTENSION` 和 `ALTER EXTENSION` 受
`EXTENSION_ADMIN` 动态权限保护。这些语句会将本机扩展代码加载到正在运行的服务器中，
因此它们需要管理权限，非特权账户无法使用。

`EXTENSION_ADMIN` 是在全局范围（`ON *.*`）授予的动态权限：

```sql theme={null}
GRANT EXTENSION_ADMIN ON *.* TO user@host;
```

为了向后兼容，`SUPER` 也被接受作为后备权限，因此已持有 `SUPER` 的账户
无需单独授权即可运行这些语句。

由 `--initialize` 或 `--initialize-insecure` 创建的数据目录会直接将
`EXTENSION_ADMIN` 授予 `root@localhost`，因此新服务器无需手动授权。
就地升级现有数据目录时，每个持有 `SUPER` 的用户账户都会被授予 `EXTENSION_ADMIN` —
但仅当没有任何账户已持有该权限时才会如此，因此已升级过一次的服务器
在以后的升级中不会再次回填。保留的 `mysql.*` 系统账户被排除在外。

两种权限都不具备的账户会在任何扩展工作开始之前被拒绝：

```text theme={null}
ERROR 1227 (42000): Access denied; you need (at least one of) the EXTENSION_ADMIN or SUPER privilege(s) for this operation
```

以同样的方式撤销该权限：

```sql theme={null}
REVOKE EXTENSION_ADMIN ON *.* FROM user@host;
```

撤销会立即生效，而不是在下次连接时生效。服务器会在每条扩展 DDL 语句上
对照账户的当前授权检查 `EXTENSION_ADMIN`/`SUPER`，因此现有会话在撤销后
不会保留该权限 — 它的下一条语句就会失败，并报出上面显示的相同
`ERROR 1227 (42000)`。

## 先决条件

* 正在运行的 VillageSQL Server 实例
* 管理员权限（root 或同等权限）

## 安装内置扩展

与 VillageSQL 一起提供的内置扩展已位于 `veb_dir` 中。只需启用它们：

```sql theme={null}
-- Connect to VillageSQL
mysql -u root -p

-- Install the extension
INSTALL EXTENSION vsql_complex;
```

### 验证安装

```sql theme={null}
-- List installed extensions
SELECT * FROM INFORMATION_SCHEMA.EXTENSIONS;
```

**输出：**

```
+----------------+-------------------+-----------------+----------------------+--------------------+-----------------------+
| EXTENSION_NAME | EXTENSION_VERSION | PENDING_VERSION | PENDING_REQUESTED_AT | PENDING_LAST_ERROR | PENDING_LAST_ERROR_AT |
+----------------+-------------------+-----------------+----------------------+--------------------+-----------------------+
| vsql_complex   | 0.0.1             | NULL            | NULL                 | NULL               | NULL                  |
+----------------+-------------------+-----------------+----------------------+--------------------+-----------------------+
```

### 测试功能

```sql theme={null}
-- Create a database first
CREATE DATABASE test_db;
USE test_db;

-- Test extension functions
CREATE TABLE test (id INT, value COMPLEX);
INSERT INTO test VALUES (1, '(3,4)');
SELECT complex_abs(value) FROM test;  -- Returns 5.0

-- Clean up
DROP TABLE test;
DROP DATABASE test_db;
```

## 安装外部扩展

对于单独下载或构建的扩展：

<Info>
  在安装外部扩展之前，您的服务器必须配置 `veb_dir`。请参阅 [配置 veb\_dir](/docs/zh/mysql-9.7/stable/managing#configuring-veb_dir)。
</Info>

### 1. 复制 .veb 文件

找到服务器的扩展目录，然后将 `.veb` 文件复制到其中：

```sql theme={null}
-- Find the extension directory
SHOW VARIABLES LIKE 'veb_dir';
```

```bash theme={null}
cp /path/to/my_extension.veb /path/to/veb_dir/
```

### 2. 安装扩展

```sql theme={null}
INSTALL EXTENSION my_extension;
```

要固定预期的版本（在 CI 或脚本化的部署中很有用），请包含
`VERSION` 子句：

```sql theme={null}
INSTALL EXTENSION my_extension VERSION '1.2.0';
```

如果清单报告的版本不同，则安装失败，并且不会注册任何内容：

```
ERROR 3219 (HY000): Cannot install extension 'my_extension': manifest version
is '0.0.1' but VERSION '1.2.0' was specified
```

这是后备文件路径（不存在 `{name}-{version}.veb`）— 它与前面显示的
`Version mismatch in '<file>'` 错误属于不同的代码路径，后者在
带版本号的文件本身存在时触发。

### 3. 验证安装

```sql theme={null}
SELECT * FROM INFORMATION_SCHEMA.EXTENSIONS WHERE EXTENSION_NAME = 'my_extension';
```

## 故障排除

| 问题                                                                                                                      | 解决方案                                                                           |
| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `Extension not found`                                                                                                   | 验证 `.veb` 文件是否位于 `veb_dir` 中：`SHOW VARIABLES LIKE 'veb_dir'`                   |
| `Permission denied`                                                                                                     | 检查文件权限：`chmod 644 extension.veb`                                               |
| `extension name mismatch`                                                                                               | 扩展的内部名称与 `.veb` 文件名不匹配。重新构建扩展。                                                 |
| `vef_register not found: ...`                                                                                           | `.veb` 文件未导出有效的 VEF 入口点。使用正确的 SDK 重新构建。                                        |
| `vef_register returned an error: ...`                                                                                   | 扩展注册失败。阅读附加的消息以获取详细信息。                                                         |
| `Cannot install extension 'name': manifest version is 'X' but VERSION 'Y' was specified`                                | `VERSION` 子句选择了 `{name}-{version}.veb`，但其内部清单报告了不同的版本。请使用清单中的版本重新运行，或修正文件名。    |
| `Multiple versions of extension 'name' found in '<dir>'; specify a version with INSTALL EXTENSION name VERSION 'x.y.z'` | 存在多个 `{name}-{version}.veb` 文件，但没有不带版本号的 `{name}.veb`。请使用显式的 `VERSION` 子句重新运行。 |

有关更多故障排除信息，请参阅 [管理扩展](/docs/zh/mysql-9.7/stable/managing)。

## 后续步骤

<CardGroup cols={2}>
  <Card title="管理扩展" icon="sliders" href="/docs/zh/mysql-9.7/stable/managing">
    监控和排除已安装扩展的故障
  </Card>

  <Card title="可用扩展" icon="list" href="/docs/zh/mysql-9.7/stable/extensions">
    浏览您可以安装的扩展
  </Card>

  <Card title="创建扩展" icon="code" href="/docs/zh/mysql-9.7/stable/create">
    构建您自己的扩展
  </Card>
</CardGroup>
