---
url: /v6.2/rds-replace-of-postgres.md
---
# 替换衡石 metadb

在使用 HENGSHI SENSE 服务过程中，可以根据业务需要替换 HENGSHI 自带的 metadb。本文讲述使用云服务 PostgreSQL 替代衡石 metadb 的过程。

## 准备工作

在进行配置前，请在云服务 PostgreSQL 上完成如下准备工作。

建议将hengshi用户配置为高权限用户

1. \[必须] 配置衡石业务数据库
   创建用户和数据库，可参考下面示例进行操作，示例中用户名和账户名均为 hengshi。

   > \[!IMPORTANT] 重要提示
   > 创建 `hengshi` 和 `syslog` 用户时，密码均不能包含 `%`、`&` 或 `+`。后续在 `conf/hengshi-sense-env.sh` 中配置 `HS_PG_PWD` 和 `HS_SYSLOG_PWD` 时，必须使用单引号包裹密码，不能使用双引号，例如 `HS_PG_PWD='password'`。

   ```sql
   DO $body$ BEGIN IF NOT EXISTS (SELECT * FROM pg_catalog.pg_user WHERE  usename = 'hengshi') THEN CREATE ROLE hengshi CREATEDB CREATEROLE LOGIN PASSWORD 'hengshi202020'; END IF; END $body$;
   set role hengshi;
   create database hengshi;
   create database hengshi_sense_internal_storage;
   reset role;
   ```

2. \[必须] 配置衡石日志数据库
   创建衡石日志用户，建立衡石日志数据库，并将数据库权限授权给衡石日志用户。 参考下面示例进行日志用户相关准备工作。
   ```sql
   \c hengshi
   DO $body$ BEGIN IF NOT EXISTS (SELECT * FROM pg_catalog.pg_user WHERE usename = 'syslog') THEN CREATE ROLE syslog LOGIN PASSWORD 'syslog'; END IF; END $body$;
   GRANT ALL PRIVILEGES ON DATABASE hengshi to syslog;
   CREATE DATABASE syslog;
   GRANT ALL PRIVILEGES ON DATABASE syslog to syslog;
   ```

3. \[可选] 配置只读账号
   准备只读帐号（此操作在成功启动衡石服务后进行配置）。参考下面示例，设置只读账户。
   ```sql
   \c hengshi
   DO $body$ BEGIN IF NOT EXISTS (SELECT * FROM pg_catalog.pg_user WHERE  usename = 'hsro') THEN CREATE ROLE hsro LOGIN PASSWORD 'hsro202020'; END IF; END $body$;
   GRANT USAGE ON SCHEMA public TO hsro;
   ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO hsro;
   GRANT SELECT ON ALL TABLES IN SCHEMA public TO hsro;
   GRANT USAGE ON SCHEMA quartz TO hsro;
   ALTER DEFAULT PRIVILEGES IN SCHEMA quartz GRANT SELECT ON TABLES TO hsro;
   GRANT SELECT ON ALL TABLES IN SCHEMA quartz TO hsro;
   ```

4. \[必须] 配置衡石业务库权限
   使用超级管理员账号对用户进行授权操作
   Hengshi-sense 版本>=4.4，要求云服务 PostgreSQL 数据库 hengshi 用户需要具备 hengshi、hengshi_sense_internal_storage
   这两个数据库的 pg_catalog（schema）的 CREATE/USAGE 权限，或者 hengshi 用户拥有超级管理员权限
   * 查询 hengshi 用户是否具备超级管理员权限
   ```sql
   select usename from pg_catalog.pg_user where usesuper = 't' and usename = 'hengshi';
   # 查询结果不为空即表示 hengshi 用户具有超级管理员权限
   ```

> \[!TIP] 提示
> 如果 hengshi 用户具有超级管理员权限忽略下述步骤

```
* 依次连接 hengshi、hengshi_sense_internal_storage 数据库，进行授权操作
```

```sql
\c hengshi
GRANT ALL ON SCHEMA pg_catalog TO hengshi;
\c hengshi_sense_internal_storage
GRANT ALL ON SCHEMA pg_catalog TO hengshi;
```

```
* 依次连接 hengshi、hengshi_sense_internal_storage 数据库，查询授权操作是否成功
```

```sql
\c hengshi
select nspname,pri_t,rolname from (SELECT nspname, (aclexplode(COALESCE(nspacl, acldefault('n', nspowner)))).grantee        AS grantee, (aclexplode(COALESCE(nspacl, acldefault('n', nspowner)))).privilege_type AS pri_t FROM pg_namespace WHERE nspname = 'pg_catalog') a left join pg_roles b on a.grantee=b.oid where rolname = 'HS_PG_USR';
\c hengshi_sense_internal_storage
select nspname,pri_t,rolname from (SELECT nspname, (aclexplode(COALESCE(nspacl, acldefault('n', nspowner)))).grantee        AS grantee, (aclexplode(COALESCE(nspacl, acldefault('n', nspowner)))).privilege_type AS pri_t FROM pg_namespace WHERE nspname = 'pg_catalog') a left join pg_roles b on a.grantee=b.oid where rolname = 'HS_PG_USR';
```

```
* 授权成功查询结果如下，说明 hengshi 用户已拥有 USAGE、CREATE 权限
```

|nspname   | pri_t  | rolname|
|------------|--------|-------|
|pg_catalog | USAGE  | HS_PG_USR|
|pg_catalog | CREATE | HS_PG_USR|

* 使用 hengshi 用户依次连接 hengshi、hengshi_sense_internal_storage 数据库，使用下列 sql 验证用户权限，执行未出现错误信息即完成授权操作
  ```sql
  CREATE OR REPLACE FUNCTION pg_catalog.myTestCreate(text)
   RETURNS numeric
   IMMUTABLE STRICT AS
   $$
   BEGIN
   RETURN $1::numeric;
   EXCEPTION
       WHEN OTHERS THEN
           RETURN NULL;
   END
   $$ LANGUAGE plpgsql;

   select myTestCreate('123');

   DROP FUNCTION pg_catalog.myTestCreate(text);
  ```

## 修改数据库相关配置

在文件`conf/hengshi-sense-env.sh`中修改如下配置项，然后重新启动 HENGSHI SENSE。重启后，衡石 metadb 替换成功。

```shell
HS_PG_HOST=xxx         #衡石业务数据库 host
HS_PG_PORT=5432        #衡石业务数据库 port
HS_PG_DB="hengshi"     #衡石业务数据库 dbname
HS_PG_USR=hengshi      #衡石业务数据库 user
HS_PG_PWD='hengshi'    #衡石业务数据库 password

export INTERNAL_STORAGE_DB_NAME="hengshi_sense_internal_storage"  #衡石内部存储数据库

HS_SYSLOG_HOST=xxxx    #衡石日志数据库 host (一般与业务数据库一致)
HS_SYSLOG_PORT=5432    #衡石日志数据库 port (一般与业务数据库一致)
HS_SYSLOG_DB=syslog    #衡石日志数据库 dbname
HS_SYSLOG_USR=syslog   #衡石日志数据库 user
HS_SYSLOG_PWD='syslog' #衡石日志数据库 password

export HS_PG_IF_EXTERNAL=true  # 声明使用外部PG数据库替代衡石业务数据库
```
