|
| 1 | + |
| 2 | +:sectnums: |
| 3 | +:sectnumlevels: 5 |
| 4 | + |
| 5 | += PgDog |
| 6 | + |
| 7 | +== 概述 |
| 8 | +PgDog 是一个专为 PostgreSQL 设计的高性能、开源集群中间件(代理工具),采用 Rust 语言编写。它集成了自动分片、连接池和负载均衡功能,能让开发者在无需修改任何应用程序代码的前提下,实现 PostgreSQL 数据库的水平扩展与高可用管理。 |
| 9 | + |
| 10 | +注意,PgDog 使用 PostgreSQL 原生的 pg_query 模块实现语句解析,所以暂时不支持在 Oracle 兼容模式下运行。 |
| 11 | + |
| 12 | +项目地址:<https://github.com/pgdogdev/pgdog> |
| 13 | + |
| 14 | +版本:v0.1.45 |
| 15 | + |
| 16 | +开源协议:AGPL-3.0 License |
| 17 | + |
| 18 | +== 安装 |
| 19 | + |
| 20 | +[TIP] |
| 21 | +源码测试安装环境为 Ubuntu 26.04。 |
| 22 | + |
| 23 | +=== 依赖 |
| 24 | + |
| 25 | +[source,bash] |
| 26 | +---- |
| 27 | +sudo apt update && \ |
| 28 | +sudo apt install -y cmake clang curl pkg-config \ |
| 29 | + libssl-dev git build-essential mold rustup \ |
| 30 | + docker |
| 31 | +---- |
| 32 | + |
| 33 | +[TIP] |
| 34 | +本文使用说明需要两个IvorySQL数据库实例,可通过本文提供的docker-compose文件快速搭建。安装docker-compose请参考:<https://docs.docker.com/compose/install/linux/> |
| 35 | + |
| 36 | +=== 源码安装 |
| 37 | + |
| 38 | +[source,bash] |
| 39 | +---- |
| 40 | +wget https://github.com/pgdogdev/pgdog/archive/refs/tags/v0.1.45.tar.gz |
| 41 | +tar -zxf v0.1.45.tar.gz |
| 42 | +cd pgdog-0.1.45 |
| 43 | +
|
| 44 | +# 编译完后,会在`target/release`目录下生成可执行文件 |
| 45 | +cargo build --release |
| 46 | +---- |
| 47 | + |
| 48 | +=== 验证安装 |
| 49 | + |
| 50 | +[source,bash] |
| 51 | +---- |
| 52 | +# PgDog在本文档编写时处于快速迭代开发阶段,所以下面命令的输出不完整 |
| 53 | +./target/release/pgdog --version |
| 54 | +# 输出:PgDog v |
| 55 | +---- |
| 56 | + |
| 57 | +== 配置 |
| 58 | + |
| 59 | +本文将配置两个分片,对PgDog的自动分片功能为例进行使用说明。 |
| 60 | + |
| 61 | +PgDog通过两个文件进行配置: |
| 62 | + |
| 63 | +[cols="1,2"] |
| 64 | +|=== |
| 65 | +| 文件名 | 说明 |
| 66 | + |
| 67 | +| pgdog.toml |
| 68 | +| 包含PgDog的端口配置、后端PostgreSQL服务的配置等基础配置信息 |
| 69 | + |
| 70 | +| users.toml |
| 71 | +| 访问PgDog的用户名和密码在这里配置 |
| 72 | +|=== |
| 73 | + |
| 74 | + |
| 75 | +创建`pgdog.toml`: |
| 76 | + |
| 77 | +[source,toml] |
| 78 | +---- |
| 79 | +[general] |
| 80 | +host = "0.0.0.0" |
| 81 | +port = 6432 |
| 82 | +default_pool_size = 10 |
| 83 | +
|
| 84 | +# ---- ivory_shard:分片到两个 IvorySQL 后端 ---- |
| 85 | +# host、port以及database_name,如果不是使用本文提供的docker-compose搭建的环境,需要按照实际情况修改 |
| 86 | +[[databases]] |
| 87 | +name = "ivory_shard" |
| 88 | +host = "ivory-shard0" |
| 89 | +port = 5432 |
| 90 | +database_name = "testdb" |
| 91 | +user = "ivorysql" # 如果不提供,默认使用`users.toml`中对应的`name` |
| 92 | +password = "ivorysql" # 如果不提供,默认使用`users.toml`中对应的`password` |
| 93 | +shard = 0 |
| 94 | +
|
| 95 | +[[databases]] |
| 96 | +name = "ivory_shard" |
| 97 | +host = "ivory-shard1" |
| 98 | +port = 5432 |
| 99 | +database_name = "testdb" |
| 100 | +shard = 1 |
| 101 | +
|
| 102 | +# ---- 分片键声明 ---- |
| 103 | +# 配置必须与实际表结构统一 |
| 104 | +[[sharded_tables]] |
| 105 | +database = "ivory_shard" |
| 106 | +name = "orders" |
| 107 | +column = "customer_id" |
| 108 | +data_type = "bigint" |
| 109 | +---- |
| 110 | + |
| 111 | +创建`users.toml`: |
| 112 | + |
| 113 | +[source,toml] |
| 114 | +---- |
| 115 | +[admin] |
| 116 | +name = "admin" |
| 117 | +user = "admin" |
| 118 | +password = "pgdog" |
| 119 | +
|
| 120 | +[[users]] |
| 121 | +name = "ivorysql" |
| 122 | +password = "ivorysql" |
| 123 | +database = "ivory_shard" |
| 124 | +pool_size = 10 |
| 125 | +---- |
| 126 | + |
| 127 | +创建`docker-compose.shard.yml`: |
| 128 | + |
| 129 | +[TIP] |
| 130 | +`volumes`字段请根据实际的配置文件位置进行修改 |
| 131 | + |
| 132 | +[source,dockerfile] |
| 133 | +---- |
| 134 | +# 分片测试拓扑(独立 compose):2 个分片后端。 |
| 135 | +# ivory-shard0 IvorySQL 5.4 (pg) host:5443 |
| 136 | +# ivory-shard1 IvorySQL 5.4 (pg) host:5444 |
| 137 | +
|
| 138 | +x-ivory: &ivory |
| 139 | + image: registry.highgo.com/ivorysql/ivorysql:5.4-bookworm |
| 140 | + environment: &ivoryenv |
| 141 | + MODE: pg |
| 142 | + IVORYSQL_USER: ivorysql |
| 143 | + IVORYSQL_PASSWORD: ivorysql |
| 144 | + IVORYSQL_DB: testdb |
| 145 | + healthcheck: |
| 146 | + test: ["CMD-SHELL", "pg_isready -U ivorysql -d testdb"] |
| 147 | + interval: 5s |
| 148 | + timeout: 3s |
| 149 | + retries: 30 |
| 150 | +
|
| 151 | +services: |
| 152 | + ivory-shard0: |
| 153 | + <<: *ivory |
| 154 | + container_name: ivory-shard0 |
| 155 | + ports: ["5443:5432"] |
| 156 | + ivory-shard1: |
| 157 | + <<: *ivory |
| 158 | + container_name: ivory-shard1 |
| 159 | + ports: ["5444:5432"] |
| 160 | +---- |
| 161 | + |
| 162 | +== 使用 |
| 163 | + |
| 164 | +=== 启动PgDog |
| 165 | + |
| 166 | +[source,bash] |
| 167 | +---- |
| 168 | +./target/release/pgdog --config ./pgdog.toml --users ./users.toml |
| 169 | +---- |
| 170 | + |
| 171 | + |
| 172 | +=== 管理控制台 |
| 173 | + |
| 174 | +PgDog 提供了内置的管理数据库,用户名密码通过`users.toml`中`[[admin]]`字段进行配置。 |
| 175 | + |
| 176 | +[source,bash] |
| 177 | +---- |
| 178 | +psql "postgres://admin:pgdog@localhost:6433/admin" |
| 179 | +---- |
| 180 | + |
| 181 | +[source,sql] |
| 182 | +---- |
| 183 | +-- 查看客户端连接及实时统计 |
| 184 | +SHOW CLIENTS |
| 185 | +
|
| 186 | +-- 查看从PgDog发起的PostgreSQL连接 |
| 187 | +SHOW SERVERS |
| 188 | +
|
| 189 | +-- 查看连接池信息 |
| 190 | +SHOW POOLS |
| 191 | +
|
| 192 | +-- 查看当前从pgdog.toml加载的配置 |
| 193 | +SHOW CONFIG |
| 194 | +
|
| 195 | +-- 查看连接池统计 |
| 196 | +SHOW STATS |
| 197 | +
|
| 198 | +-- 在同一网络中运行的 PgDog 进程列表。需要启用服务发现(service discovery) |
| 199 | +SHOW PEERS |
| 200 | +
|
| 201 | +-- 从磁盘重新加载配置。关于哪些选项可以在运行时修改,请参阅 pgdog.toml 和 users.toml |
| 202 | +RELOAD |
| 203 | +
|
| 204 | +-- 使用现有配置重新创建所有服务器连接 |
| 205 | +RECONNECT |
| 206 | +
|
| 207 | +-- 暂停所有连接池。客户端将一直等待连接,直到连接池恢复。可用于平滑重启 PostgreSQL 服务器 |
| 208 | +PAUSE |
| 209 | +
|
| 210 | +-- 恢复所有连接池。客户端可以重新取用连接 |
| 211 | +RESUME |
| 212 | +
|
| 213 | +-- 列出当前缓存中的prepared statements |
| 214 | +SHOW PREPARED |
| 215 | +
|
| 216 | +-- 列出当前位于 AST 缓存中、用于查询路由的语句 |
| 217 | +SHOW QUERY_CACHE |
| 218 | +
|
| 219 | +-- 暂停所有查询,以便在多个 PgDog 实例之间同步配置变更 |
| 220 | +MAINTENANCE |
| 221 | +
|
| 222 | +-- 显示每个数据库的 PostgreSQL 复制状态,包括副本延迟 |
| 223 | +SHOW REPLICATION |
| 224 | +---- |
| 225 | + |
| 226 | +=== 连接PgDog |
| 227 | + |
| 228 | +[source,bash] |
| 229 | +---- |
| 230 | +psql "postgres://ivorysql:ivorysql@localhost:6433/ivory_shard" |
| 231 | +---- |
| 232 | + |
| 233 | +=== 执行操作 |
| 234 | + |
| 235 | +[TIP] |
| 236 | +请确认分片后端没有`orders`表,PgDog会自动创建。 |
| 237 | + |
| 238 | +[source,sql] |
| 239 | +---- |
| 240 | +-- 创建表 |
| 241 | +CREATE TABLE orders ( |
| 242 | + order_id bigint, |
| 243 | + customer_id bigint, |
| 244 | + amount numeric(10,2), |
| 245 | + PRIMARY KEY (order_id, customer_id) |
| 246 | +); |
| 247 | +
|
| 248 | +-- 插入数据:这两条数据将分别插入到两个分片后端 |
| 249 | +-- BUG:这里不能使用`generate_series`函数,因为PgDog暂时对这个函数进行透传 |
| 250 | +INSERT INTO orders values(1, 1, 1); |
| 251 | +INSERT INTO orders values(2, 2, 2); |
| 252 | +INSERT INTO orders values(3, 3, 3); |
| 253 | +INSERT INTO orders values(4, 4, 4); |
| 254 | +INSERT INTO orders values(5, 5, 5); |
| 255 | +INSERT INTO orders values(6, 6, 6); |
| 256 | +INSERT INTO orders values(7, 7, 7); |
| 257 | +
|
| 258 | +-- 查询数据 |
| 259 | +SELECT * FROM orders; |
| 260 | +---- |
| 261 | + |
| 262 | +=== 分别连接两个分片后端确认数据 |
| 263 | + |
| 264 | +[TIP] |
| 265 | +这里将看到两个分片后端的条目并不是均分的,这是因为PgDog根据`[[sharded_tables]]`中配置的`customer_id`字段,提取了数值并对其进行HASH分片。 |
| 266 | + |
| 267 | +[source,bash] |
| 268 | +---- |
| 269 | +# 分片1 |
| 270 | +psql "postgres://ivorysql:ivorysql@localhost:5443/testdb", |
| 271 | +# 分片2 |
| 272 | +psql "postgres://ivorysql:ivorysql@localhost:5444/testdb", |
| 273 | +---- |
| 274 | + |
| 275 | +在分片后端分别执行查询确认数据 |
| 276 | +[source,sql] |
| 277 | +---- |
| 278 | +SELECT * FROM orders; |
| 279 | +---- |
0 commit comments