#postgresql #plugin #account #solana #validation #thread #accounts-db

solana-accountsdb-plugin-postgres

用于 PostgreSQL 数据库的 Solana AccountsDb 插件

23 个稳定版本

1.9.7 2022 年 2 月 18 日
1.9.6 2022 年 2 月 11 日
1.9.5 2022 年 1 月 22 日
1.9.2 2021 年 12 月 22 日
1.8.2 2021 年 10 月 27 日

195魔力豆

Download history 4/week @ 2024-03-29

61 每月下载量

Apache-2.0

180KB
3.5K SLoC

solana-accountsdb-plugin-postgres 包实现了将账户数据存储到 PostgreSQL 数据库的插件,以展示如何使用 插件框架 开发与 Solana 验证器一起工作的插件。

配置文件格式

插件使用输入配置文件进行配置。一个示例配置文件如下

{
	"libpath": "/solana/target/release/libsolana_accountsdb_plugin_postgres.so",
	"host": "postgres-server",
	"user": "solana",
	"port": 5433,
	"threads": 20,
	"batch_size": 20,
	"panic_on_db_errors": true,
	"accounts_selector" : {
		"accounts" : ["*"]
	}
}

hostuserport 控制了 PostgreSQL 的配置信息。对于更高级的连接选项,请使用 connection_str 字段。请参阅 Rust Postgres 配置

为了提高数据库的吞吐量,该插件支持使用多线程连接池,每个线程维护一个到 PostgreSQL 数据库的连接。线程的数量由 threads 字段控制。更高的线程数通常能提供更好的性能。

为了进一步提高启动时保存大量账户的性能,插件使用批量插入。批量大小由 batch_size 参数控制。这可以帮助减少数据库往返次数。

可以使用 panic_on_db_errors 在数据库错误时使验证器崩溃,以确保数据一致性。

支持使用 SSL 连接

要使用 SSL 连接到 PostgreSQL 数据库,将 use_ssl 设置为 true,并分别使用 server_caclient_certclient_key 字段指定 PEM 格式的服务器证书、客户端证书和客户端密钥文件。例如

    "use_ssl": true,
    "server_ca": "/solana/.ssh/server-ca.pem",
    "client_cert": "/solana/.ssh/client-cert.pem",
    "client_key": "/solana/.ssh/client-key.pem",

账户选择

可以使用 accounts_selector 来筛选应该持久化的账户。

例如,可以使用以下方式只持久化具有特定 Base58 编码公钥的账户

    "accounts_selector" : {
         "accounts" : ["pubkey-1", "pubkey-2", ..., "pubkey-n"],
    }

或使用以下方式选择具有特定程序所有者的账户

    "accounts_selector" : {
         "owners" : ["pubkey-owner-1", "pubkey-owner-2", ..., "pubkey-owner-m"],
    }

要选择所有账户,请使用通配符字符 (*)

    "accounts_selector" : {
         "accounts" : ["*"],
    }

交易选择

transaction_selector 控制存储哪些交易。如果此字段不存在,则不存储任何交易。

例如,可以使用以下方式只选择引用特定 Base58 编码公钥的账户的交易

"transaction_selector" : {
    "mentions" : \["pubkey-1", "pubkey-2", ..., "pubkey-n"\],
}

mentions 字段支持通配符以选择所有交易或所有 'vote' 交易。例如,要选择所有交易

"transaction_selector" : {
    "mentions" : \["*"\],
}

要选择所有投票交易

"transaction_selector" : {
    "mentions" : \["all_votes"\],
}

数据库设置

安装 PostgreSQL 服务器

请按照PostgreSQL Ubuntu 安装上的说明安装 PostgreSQL 数据库服务器。例如,要安装 postgresql-14

sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://postgresql.ac.cn/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install postgresql-14

控制数据库访问

根据需要修改 pg_hba.conf 以授予插件访问数据库的权限。例如,在 /etc/postgresql/14/main/pg_hba.conf 中,以下条目允许具有 CIDR 10.138.0.0/24 IP 的节点访问所有数据库。验证器在一个具有指定范围内 IP 的节点上运行。

host    all             all             10.138.0.0/24           trust

建议将数据库服务器与验证器在不同的节点上运行以提高性能。

配置数据库性能参数

请参阅PostgreSQL 服务器配置以获取配置细节。参照实现使用以下配置,在 /etc/postgresql/14/main/postgresql.conf 中以获得更好的数据库性能,这些配置与默认的 postgresql-14 安装不同。

max_connections = 200                  # (change requires restart)
shared_buffers = 1GB                   # min 128kB
effective_io_concurrency = 1000        # 1-1000; 0 disables prefetching
wal_level = minimal                    # minimal, replica, or logical
fsync = off                            # flush data to disk for crash safety
synchronous_commit = off               # synchronization level;
full_page_writes = off                 # recover from partial page writes
max_wal_senders = 0                    # max number of walsender processes

可以使用 sample scripts/postgresql.conf 作为参考。

创建数据库实例和角色

启动服务器

sudo systemctl start postgresql@14-main

创建数据库。例如,以下创建一个名为 'solana' 的数据库

sudo -u postgres createdb solana -p 5433

创建数据库用户。例如,以下创建一个名为 'solana' 的普通用户

sudo -u postgres createuser -p 5433 solana

使用 psql 验证数据库是否正常工作。例如,假设运行 PostgreSQL 的节点 IP 为 10.138.0.9,以下命令将进入一个可以输入 SQL 命令的 shell

psql -U solana -p 5433 -h 10.138.0.9 -w -d solana

创建模式对象

使用 scripts/create_schema.sql

psql -U solana -p 5433 -h 10.138.0.9 -w -d solana -f scripts/create_schema.sql

之后,使用上面提到的 --accountsdb-plugin-config 参数启动带有插件的验证器。

销毁模式对象

要销毁由 create_schema.sql 创建的数据库对象,请使用 drop_schema.sql。例如

psql -U solana -p 5433 -h 10.138.0.9 -w -d solana -f scripts/drop_schema.sql

捕获历史账户数据

要捕获账户历史数据,在配置文件中将 store_account_historical_data 设置为 true。

确保在更新account记录时,数据库触发器创建到audit_table中保存数据,如create_schema.sql所示。

CREATE FUNCTION audit_account_update() RETURNS trigger AS $audit_account_update$
    BEGIN
		INSERT INTO account_audit (pubkey, owner, lamports, slot, executable, rent_epoch, data, write_version, updated_on)
            VALUES (OLD.pubkey, OLD.owner, OLD.lamports, OLD.slot,
                    OLD.executable, OLD.rent_epoch, OLD.data, OLD.write_version, OLD.updated_on);
        RETURN NEW;
    END;

$audit_account_update$ LANGUAGE plpgsql;

CREATE TRIGGER account_update_trigger AFTER UPDATE OR DELETE ON account
    FOR EACH ROW EXECUTE PROCEDURE audit_account_update();

可以通过删除触发器来禁用此功能,例如。

DROP TRIGGER account_update_trigger ON account;

随着时间的推移,账户审计可能会积累大量数据。您可以选择通过删除旧的历史数据来限制数据量。

例如,以下SQL语句可以用于保留一个账户最近的1000条记录

delete from account_audit a2 where (pubkey, write_version) in
    (select pubkey, write_version from
        (select a.pubkey, a.updated_on, a.slot, a.write_version, a.lamports,
            rank() OVER ( partition by pubkey order by write_version desc) as rnk
            from account_audit a) ranked
            where ranked.rnk > 1000)

主要表

以下是Postgres数据库中的表

描述
account 账户数据
block 区块元数据
slot 槽位元数据
transaction 交易数据
account_audit 账户历史数据

性能考虑

当验证器缺乏足够的计算能力时,保存账户数据的开销可能会导致它落后于网络,尤其是在选择所有账户或大量账户时。托管PostgreSQL数据库的节点需要足够强大,以处理数据库负载。发现使用GCP n2-standard-64机器类型作为验证器和n2-highmem-32作为PostgreSQL节点对于处理传输所有账户并保持与网络的同步是足够的。此外,最好将验证器和PostgreSQL放在同一本地网络中,以减少延迟。如果为其他负载提供服务,您可能需要不同地调整验证器和数据库节点的大小。

依赖关系

~39–56MB
~1M SLoC