|
| 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 | +# ---- ivory_shard:分片到两个 IvorySQL 后端 ---- |
| 80 | +# host、port以及database_name,如果不是使用本文提供的docker-compose搭建的环境,需要按照实际情况修改 |
| 81 | +[[databases]] |
| 82 | +name = "ivory_shard" |
| 83 | +host = "ivory-shard0" |
| 84 | +port = 5432 |
| 85 | +database_name = "testdb" |
| 86 | +shard = 0 |
| 87 | +
|
| 88 | +[[databases]] |
| 89 | +name = "ivory_shard" |
| 90 | +host = "ivory-shard1" |
| 91 | +port = 5432 |
| 92 | +database_name = "testdb" |
| 93 | +shard = 1 |
| 94 | +
|
| 95 | +# ---- 分片键声明 ---- |
| 96 | +# 配置必须与实际表结构统一 |
| 97 | +[[sharded_tables]] |
| 98 | +database = "ivory_shard" |
| 99 | +name = "orders" |
| 100 | +column = "customer_id" |
| 101 | +data_type = "bigint" |
| 102 | +---- |
| 103 | + |
| 104 | +创建`users.toml`: |
| 105 | + |
| 106 | +[source,toml] |
| 107 | +---- |
| 108 | +[admin] |
| 109 | +name = "admin" |
| 110 | +user = "admin" |
| 111 | +password = "pgdog" |
| 112 | +
|
| 113 | +[[users]] |
| 114 | +name = "ivorysql" |
| 115 | +password = "ivorysql" |
| 116 | +database = "pg_shard" |
| 117 | +pool_size = 10 |
| 118 | +
|
| 119 | +[[users]] |
| 120 | +name = "ivorysql" |
| 121 | +password = "ivorysql" |
| 122 | +database = "ivory_shard" |
| 123 | +pool_size = 10 |
| 124 | +---- |
| 125 | + |
| 126 | +创建`docker-compose.shard.yml`: |
| 127 | + |
| 128 | +[TIP] |
| 129 | +`volumes`字段请根据实际的配置文件位置进行修改 |
| 130 | + |
| 131 | +[source,dockerfile] |
| 132 | +---- |
| 133 | +# 分片测试拓扑(独立 compose):2 个分片后端。 |
| 134 | +# ivory-shard0 IvorySQL 5.4 (pg) host:5443 |
| 135 | +# ivory-shard1 IvorySQL 5.4 (pg) host:5444 |
| 136 | +# pgdog-shard PgDog 分片代理 host:6433 |
| 137 | +# -> 库 ivory_shard 分片到 ivory-shard0/1 |
| 138 | +
|
| 139 | +x-ivory: &ivory |
| 140 | + image: registry.highgo.com/ivorysql/ivorysql:5.4-bookworm |
| 141 | + environment: &ivoryenv |
| 142 | + MODE: pg |
| 143 | + IVORYSQL_USER: ivorysql |
| 144 | + IVORYSQL_PASSWORD: ivorysql |
| 145 | + IVORYSQL_DB: testdb |
| 146 | + healthcheck: |
| 147 | + test: ["CMD-SHELL", "pg_isready -U ivorysql -d testdb"] |
| 148 | + interval: 5s |
| 149 | + timeout: 3s |
| 150 | + retries: 30 |
| 151 | +
|
| 152 | +services: |
| 153 | + ivory-shard0: |
| 154 | + <<: *ivory |
| 155 | + container_name: ivory-shard0 |
| 156 | + ports: ["5443:5432"] |
| 157 | + ivory-shard1: |
| 158 | + <<: *ivory |
| 159 | + container_name: ivory-shard1 |
| 160 | + ports: ["5444:5432"] |
| 161 | +
|
| 162 | + pgdog-shard: |
| 163 | + image: ghcr.io/pgdogdev/pgdog:latest |
| 164 | + container_name: pgdog-shard |
| 165 | + depends_on: |
| 166 | + ivory-shard0: {condition: service_healthy} |
| 167 | + ivory-shard1: {condition: service_healthy} |
| 168 | + ports: ["6433:6432"] |
| 169 | + volumes: |
| 170 | + - ./pgdog.toml:/pgdog/pgdog.toml:ro |
| 171 | + - ./users.toml:/pgdog/users.toml:ro |
| 172 | +---- |
| 173 | + |
| 174 | +== 使用 |
| 175 | + |
| 176 | +=== 启动PgDog |
| 177 | + |
| 178 | +[source,bash] |
| 179 | +---- |
| 180 | +./target/release/pgdog --config ./pgdog.toml --users ./users.toml |
| 181 | +---- |
| 182 | + |
| 183 | + |
| 184 | +=== 管理控制台 |
| 185 | + |
| 186 | +PgDog 提供了内置的管理数据库,用户名密码通过`users.toml`中`[[admin]]`字段进行配置。 |
| 187 | + |
| 188 | +[source,bash] |
| 189 | +---- |
| 190 | +psql "postgres://admin:pgdog@localhost:6433/admin" |
| 191 | +---- |
| 192 | + |
| 193 | +[source,sql] |
| 194 | +---- |
| 195 | +-- 查看客户端连接及实时统计 |
| 196 | +SHOW CLIENTS |
| 197 | +
|
| 198 | +-- 查看从PgDog发起的PostgreSQL连接 |
| 199 | +SHOW SERVERS |
| 200 | +
|
| 201 | +-- 查看连接池信息 |
| 202 | +SHOW POOLS |
| 203 | +
|
| 204 | +-- 查看当前从pgdog.toml加载的配置 |
| 205 | +SHOW CONFIG |
| 206 | +
|
| 207 | +-- 查看连接池统计 |
| 208 | +SHOW STATS |
| 209 | +
|
| 210 | +-- 在同一网络中运行的 PgDog 进程列表。需要启用服务发现(service discovery) |
| 211 | +SHOW PEERS |
| 212 | +
|
| 213 | +-- 从磁盘重新加载配置。关于哪些选项可以在运行时修改,请参阅 pgdog.toml 和 users.toml |
| 214 | +RELOAD |
| 215 | +
|
| 216 | +-- 使用现有配置重新创建所有服务器连接 |
| 217 | +RECONNECT |
| 218 | +
|
| 219 | +-- 暂停所有连接池。客户端将一直等待连接,直到连接池恢复。可用于平滑重启 PostgreSQL 服务器 |
| 220 | +PAUSE |
| 221 | +
|
| 222 | +-- 恢复所有连接池。客户端可以重新取用连接 |
| 223 | +RESUME |
| 224 | +
|
| 225 | +-- 列出当前缓存中的prepared statements |
| 226 | +SHOW PREPARED |
| 227 | +
|
| 228 | +-- 列出当前位于 AST 缓存中、用于查询路由的语句 |
| 229 | +SHOW QUERY_CACHE |
| 230 | +
|
| 231 | +-- 暂停所有查询,以便在多个 PgDog 实例之间同步配置变更 |
| 232 | +MAINTENANCE |
| 233 | +
|
| 234 | +-- 显示每个数据库的 PostgreSQL 复制状态,包括副本延迟 |
| 235 | +SHOW REPLICATION |
| 236 | +---- |
| 237 | + |
| 238 | +=== 连接PgDog |
| 239 | + |
| 240 | +[source,bash] |
| 241 | +---- |
| 242 | +psql "postgres://ivorysql:ivorysql@localhost:6433/ivory_shard" |
| 243 | +---- |
| 244 | + |
| 245 | +=== 执行操作 |
| 246 | + |
| 247 | +[TIP] |
| 248 | +请确认分片后端没有`orders`表,PgDog会自动创建。 |
| 249 | + |
| 250 | +[source,sql] |
| 251 | +---- |
| 252 | +-- 创建表 |
| 253 | +CREATE TABLE orders ( |
| 254 | + order_id bigint, |
| 255 | + customer_id bigint, |
| 256 | + amount numeric(10,2), |
| 257 | + PRIMARY KEY (order_id, customer_id) |
| 258 | +); |
| 259 | +
|
| 260 | +-- 插入数据:这两条数据将分别插入到两个分片后端 |
| 261 | +-- BUG:这里不能使用`generate_series`函数,因为PgDog暂时对这个函数进行透传 |
| 262 | +INSERT INTO orders values(1, 1, 1); |
| 263 | +INSERT INTO orders values(2, 2, 2); |
| 264 | +INSERT INTO orders values(3, 3, 3); |
| 265 | +INSERT INTO orders values(4, 4, 4); |
| 266 | +INSERT INTO orders values(5, 5, 5); |
| 267 | +INSERT INTO orders values(6, 6, 6); |
| 268 | +INSERT INTO orders values(7, 7, 7); |
| 269 | +
|
| 270 | +-- 查询数据 |
| 271 | +SELECT * FROM orders; |
| 272 | +---- |
| 273 | + |
| 274 | +=== 分别连接两个分片后端确认数据 |
| 275 | + |
| 276 | +[TIP] |
| 277 | +这里将看到两个分片后端的条目并不是均分的,这是因为PgDog根据`[[sharded_tables]]`中配置的`customer_id`字段,提取了数值并对其进行HASH分片。 |
| 278 | + |
| 279 | +[source,bash] |
| 280 | +---- |
| 281 | +# 分片1 |
| 282 | +psql "postgres://ivorysql:ivorysql@localhost:5443/testdb", |
| 283 | +# 分片2 |
| 284 | +psql "postgres://ivorysql:ivorysql@localhost:5444/testdb", |
| 285 | +---- |
| 286 | + |
| 287 | +在分片后端分别执行查询确认数据 |
| 288 | +[source,sql] |
| 289 | +---- |
| 290 | +SELECT * FROM orders; |
| 291 | +---- |
0 commit comments