# 使用pg_tde插件
#### 简介
pg_tde是面向PostgreSQL的透明数据加密（Transparent Data Encryption, TDE）扩展，数据写入磁盘时自动加密、读取时自动解密；整个过程对上层应用和SQL完全透明，无需修改业务代码。相比磁盘级和文件系统级加密，pg_tde实现了数据库粒度的加密控制，即使存储介质或备份文件泄露，无密钥也无法解析数据内容。
如需使用pg_tde插件，请[提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)申请。
#### 支持的版本
仅PostgreSQL 16.14、17.10及以上的最新小版本支持该插件。可通过以下SQL语句查询当前实例是否支持该插件：
```
SELECT * FROM pg_available_extension_versions WHERE name = 'pg_tde';
```
#### 约束与限制
- 加密表不支持逻辑解码和逻辑复制，需要手动迁移。
- 当前版本不支持索引加密、系统表加密以及WAL日志加密。
- 由于密钥文件的特殊性，如当前数据库存在加密表，该实例不支持大版本和小版本升级。
- 存在容灾关系的实例，若要使用pg_tde插件，必须在创建密钥文件前，确保所有实例（容灾主、备）都已预加载pg_tde插件，否则将导致容灾备实例异常。
 
#### 插件安装和卸载
1. 在实例列表，单击实例名称，进入"概览"页面。
2. 选择"插件管理"，搜索pg_tde插件，单击"加载"。
   图1插件管理   
   ![](https://support.huaweicloud.com/usermanual-rds-pg/zh-cn_image_0000002772824389.png "点击放大") 
3. 重启实例，使shared_preload_libraries参数值生效。
4. 安装pg_tde插件。
   - 通过界面安装pg_tde。 在"插件管理"页面，选择对应的数据库，搜索pg_tde，单击"安装"。
     图2安装pg_tde   
     ![](https://support.huaweicloud.com/usermanual-rds-pg/zh-cn_image_0000002743145242.png "点击放大") 
   
   - 通过SQL安装pg_tde。 登录到对应的数据库，执行如下SQL创建插件：
     ```
     CREATE EXTENSION IF NOT EXISTS pg_tde;
     ```
     
    
5. 卸载pg_tde插件。
   - 通过界面卸载pg_tde。 在"插件管理"页面，选择对应的数据库，搜索pg_tde，单击"卸载"。
     图3卸载pg_tde   
     ![](https://support.huaweicloud.com/usermanual-rds-pg/zh-cn_image_0000002772664499.png "点击放大") 
   
   - 通过SQL卸载pg_tde。 登录到对应的数据库，执行如下SQL删除插件：
     ```
     DROP EXTENSION IF EXISTS pg_tde;
     ```
     
   
   
   ![](https://support.huaweicloud.com/usermanual-rds-pg/public_sys-resources/note_3.0-zh-cn.png)
   当前数据库若使用了加密表功能，卸载插件将会失败，若要完全卸载，请备份好加密表的数据后，使用**DROP EXTENSION IF EXISTS pg_tde CASCADE**语句卸载，或删除加密表后通过界面卸载。
   
 
#### 基本使用
- 设置主密钥
  ```
  -- 密钥文件目录需确保 Ruby 用户有读写权限，建议直接放在 /var/lib/pgsql/data/pg_tde 下
  SELECT pg_tde_add_key_provider_file('my_file_keyring1','/var/lib/pgsql/data/pg_tde/my_keyring1'); 
  SELECT pg_tde_set_principal_key('my_principal_key_v1','my_file_keyring1');
  ```
  
- 创建加密表
  ```
  -- 使用 tde_heap_basic 访问方法
  CREATE TABLE test_encrypted_users (id INT PRIMARY KEY,   name TEXT,   age INT,   created_at TIMESTAMP ) USING tde_heap_basic; 
  -- 验证表是否为加密表
  SELECT pg_tde_set_principal_key('my_principal_key_v1','my_file_keyring1');
  ```
  

- 轮换密钥
  ```
  SELECT pg_tde_add_key_provider_file('my_file_keyring2','/var/lib/pgsql/data/pg_tde/my_keyring2'); 
  SELECT pg_tde_rotate_principal_key('my_principal_key_v2','my_file_keyring2');
  ```
  
![](https://support.huaweicloud.com/usermanual-rds-pg/public_sys-resources/note_3.0-zh-cn.png)
对加密表的操作，除创建表外，其余SQL语句与普通表相同。
