|
| 1 | +:sectnums: |
| 2 | +:sectnumlevels: 5 |
| 3 | + |
| 4 | += PgDog |
| 5 | + |
| 6 | +== Overview |
| 7 | +PgDog is a high-performance, open-source clustering middleware (proxy tool) designed specifically for PostgreSQL and written in Rust. It integrates automatic sharding, connection pooling, and load balancing, enabling developers to achieve horizontal scaling and high-availability management of PostgreSQL databases without modifying any application code. |
| 8 | + |
| 9 | +Note that PgDog uses PostgreSQL's native pg_query module to parse statements, so it does not support running in Oracle compatibility mode. |
| 10 | + |
| 11 | +Project URL: <https://github.com/pgdogdev/pgdog> |
| 12 | + |
| 13 | +Version: v0.1.45 |
| 14 | + |
| 15 | +Open-source license: AGPL-3.0 License |
| 16 | + |
| 17 | +== Installation |
| 18 | + |
| 19 | +[TIP] |
| 20 | +The source build was tested on Ubuntu 26.04. |
| 21 | + |
| 22 | +=== Dependencies |
| 23 | + |
| 24 | +[source,bash] |
| 25 | +---- |
| 26 | +sudo apt update && \ |
| 27 | +sudo apt install -y cmake clang curl pkg-config \ |
| 28 | + libssl-dev git build-essential mold rustup \ |
| 29 | + docker |
| 30 | +---- |
| 31 | + |
| 32 | +[TIP] |
| 33 | +The instructions in this document require two IvorySQL database instances, which can be quickly set up using the docker-compose file provided in this document. To install docker-compose, refer to: <https://docs.docker.com/compose/install/linux/> |
| 34 | + |
| 35 | +=== Building from Source |
| 36 | + |
| 37 | +[source,bash] |
| 38 | +---- |
| 39 | +wget https://github.com/pgdogdev/pgdog/archive/refs/tags/v0.1.45.tar.gz |
| 40 | +tar -zxf v0.1.45.tar.gz |
| 41 | +cd pgdog-0.1.45 |
| 42 | +
|
| 43 | +# After compilation, the executable will be generated in the `target/release` directory |
| 44 | +cargo build --release |
| 45 | +---- |
| 46 | + |
| 47 | +=== Verifying the Installation |
| 48 | + |
| 49 | +[source,bash] |
| 50 | +---- |
| 51 | +# At the time this document was written, PgDog is under rapid iterative development, so the output of the command below is incomplete |
| 52 | +./target/release/pgdog --version |
| 53 | +# Output: PgDog v |
| 54 | +---- |
| 55 | + |
| 56 | +== Configuration |
| 57 | + |
| 58 | +This document configures two shards and uses PgDog's automatic sharding feature as an example. |
| 59 | + |
| 60 | +PgDog is configured through two files: |
| 61 | + |
| 62 | +[cols="1,2"] |
| 63 | +|=== |
| 64 | +| File Name | Description |
| 65 | + |
| 66 | +| pgdog.toml |
| 67 | +| Contains basic configuration information such as PgDog's port settings and the backend PostgreSQL service configuration |
| 68 | + |
| 69 | +| users.toml |
| 70 | +| The username and password for accessing PgDog are configured here |
| 71 | +|=== |
| 72 | + |
| 73 | + |
| 74 | +Create `pgdog.toml`: |
| 75 | + |
| 76 | +[source,toml] |
| 77 | +---- |
| 78 | +# ---- ivory_shard: shard across two IvorySQL backends ---- |
| 79 | +# host, port, and database_name need to be modified according to your actual setup if you are not using the environment built with the docker-compose provided in this document |
| 80 | +[[databases]] |
| 81 | +name = "ivory_shard" |
| 82 | +host = "ivory-shard0" |
| 83 | +port = 5432 |
| 84 | +database_name = "testdb" |
| 85 | +shard = 0 |
| 86 | +
|
| 87 | +[[databases]] |
| 88 | +name = "ivory_shard" |
| 89 | +host = "ivory-shard1" |
| 90 | +port = 5432 |
| 91 | +database_name = "testdb" |
| 92 | +shard = 1 |
| 93 | +
|
| 94 | +# ---- Shard key declaration ---- |
| 95 | +# The configuration must match the actual table structure |
| 96 | +[[sharded_tables]] |
| 97 | +database = "ivory_shard" |
| 98 | +name = "orders" |
| 99 | +column = "customer_id" |
| 100 | +data_type = "bigint" |
| 101 | +---- |
| 102 | + |
| 103 | +Create `users.toml`: |
| 104 | + |
| 105 | +[source,toml] |
| 106 | +---- |
| 107 | +[admin] |
| 108 | +name = "admin" |
| 109 | +user = "admin" |
| 110 | +password = "pgdog" |
| 111 | +
|
| 112 | +[[users]] |
| 113 | +name = "ivorysql" |
| 114 | +password = "ivorysql" |
| 115 | +database = "pg_shard" |
| 116 | +pool_size = 10 |
| 117 | +
|
| 118 | +[[users]] |
| 119 | +name = "ivorysql" |
| 120 | +password = "ivorysql" |
| 121 | +database = "ivory_shard" |
| 122 | +pool_size = 10 |
| 123 | +---- |
| 124 | + |
| 125 | +Create `docker-compose.shard.yml`: |
| 126 | + |
| 127 | +[TIP] |
| 128 | +Please modify the `volumes` field according to the actual location of your configuration files. |
| 129 | + |
| 130 | +[source,dockerfile] |
| 131 | +---- |
| 132 | +# Sharding test topology (standalone compose): 2 shard backends. |
| 133 | +# ivory-shard0 IvorySQL 5.4 (pg) host:5443 |
| 134 | +# ivory-shard1 IvorySQL 5.4 (pg) host:5444 |
| 135 | +# pgdog-shard PgDog sharding proxy host:6433 |
| 136 | +# -> database ivory_shard sharded across ivory-shard0/1 |
| 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 | + pgdog-shard: |
| 162 | + image: ghcr.io/pgdogdev/pgdog:latest |
| 163 | + container_name: pgdog-shard |
| 164 | + depends_on: |
| 165 | + ivory-shard0: {condition: service_healthy} |
| 166 | + ivory-shard1: {condition: service_healthy} |
| 167 | + ports: ["6433:6432"] |
| 168 | + volumes: |
| 169 | + - ./pgdog.toml:/pgdog/pgdog.toml:ro |
| 170 | + - ./users.toml:/pgdog/users.toml:ro |
| 171 | +---- |
| 172 | + |
| 173 | +== Usage |
| 174 | + |
| 175 | +=== Starting PgDog |
| 176 | + |
| 177 | +[source,bash] |
| 178 | +---- |
| 179 | +./target/release/pgdog --config ./pgdog.toml --users ./users.toml |
| 180 | +---- |
| 181 | + |
| 182 | + |
| 183 | +=== Administration Console |
| 184 | + |
| 185 | +PgDog provides a built-in administration database. The username and password are configured via the `[[admin]]` field in `users.toml`. |
| 186 | + |
| 187 | +[source,bash] |
| 188 | +---- |
| 189 | +psql "postgres://admin:pgdog@localhost:6433/admin" |
| 190 | +---- |
| 191 | + |
| 192 | +[source,sql] |
| 193 | +---- |
| 194 | +-- View client connections and real-time statistics |
| 195 | +SHOW CLIENTS |
| 196 | +
|
| 197 | +-- View PostgreSQL connections initiated by PgDog |
| 198 | +SHOW SERVERS |
| 199 | +
|
| 200 | +-- View connection pool information |
| 201 | +SHOW POOLS |
| 202 | +
|
| 203 | +-- View the configuration currently loaded from pgdog.toml |
| 204 | +SHOW CONFIG |
| 205 | +
|
| 206 | +-- View connection pool statistics |
| 207 | +SHOW STATS |
| 208 | +
|
| 209 | +-- List of PgDog processes running on the same network. Requires service discovery to be enabled |
| 210 | +SHOW PEERS |
| 211 | +
|
| 212 | +-- Reload the configuration from disk. For which options can be changed at runtime, refer to pgdog.toml and users.toml |
| 213 | +RELOAD |
| 214 | +
|
| 215 | +-- Recreate all server connections using the existing configuration |
| 216 | +RECONNECT |
| 217 | +
|
| 218 | +-- Pause all connection pools. Clients will wait for a connection until the pools resume. Useful for performing a graceful restart of the PostgreSQL server |
| 219 | +PAUSE |
| 220 | +
|
| 221 | +-- Resume all connection pools. Clients can acquire connections again |
| 222 | +RESUME |
| 223 | +
|
| 224 | +-- List the prepared statements currently in the cache |
| 225 | +SHOW PREPARED |
| 226 | +
|
| 227 | +-- List the statements currently in the AST cache used for query routing |
| 228 | +SHOW QUERY_CACHE |
| 229 | +
|
| 230 | +-- Pause all queries in order to synchronize configuration changes across multiple PgDog instances |
| 231 | +MAINTENANCE |
| 232 | +
|
| 233 | +-- Show the PostgreSQL replication status for each database, including replica lag |
| 234 | +SHOW REPLICATION |
| 235 | +---- |
| 236 | + |
| 237 | +=== Connecting to PgDog |
| 238 | + |
| 239 | +[source,bash] |
| 240 | +---- |
| 241 | +psql "postgres://ivorysql:ivorysql@localhost:6433/ivory_shard" |
| 242 | +---- |
| 243 | + |
| 244 | +=== Performing Operations |
| 245 | + |
| 246 | +[TIP] |
| 247 | +Make sure the shard backends do not have an `orders` table; PgDog will create it automatically. |
| 248 | + |
| 249 | +[source,sql] |
| 250 | +---- |
| 251 | +-- Create the table |
| 252 | +CREATE TABLE orders ( |
| 253 | + order_id bigint, |
| 254 | + customer_id bigint, |
| 255 | + amount numeric(10,2), |
| 256 | + PRIMARY KEY (order_id, customer_id) |
| 257 | +); |
| 258 | +
|
| 259 | +-- Insert data: these rows will be inserted into the two shard backends respectively |
| 260 | +-- BUG: the `generate_series` function cannot be used here, because PgDog currently passes this function through transparently |
| 261 | +INSERT INTO orders values(1, 1, 1); |
| 262 | +INSERT INTO orders values(2, 2, 2); |
| 263 | +INSERT INTO orders values(3, 3, 3); |
| 264 | +INSERT INTO orders values(4, 4, 4); |
| 265 | +INSERT INTO orders values(5, 5, 5); |
| 266 | +INSERT INTO orders values(6, 6, 6); |
| 267 | +INSERT INTO orders values(7, 7, 7); |
| 268 | +
|
| 269 | +-- Query the data |
| 270 | +SELECT * FROM orders; |
| 271 | +---- |
| 272 | + |
| 273 | +=== Connecting to Each Shard Backend to Verify the Data |
| 274 | + |
| 275 | +[TIP] |
| 276 | +Here you will see that the entries in the two shard backends are not evenly distributed. This is because PgDog extracts the value of the `customer_id` field configured in `[[sharded_tables]]` and applies HASH-based sharding to it. |
| 277 | + |
| 278 | +[source,bash] |
| 279 | +---- |
| 280 | +# Shard 1 |
| 281 | +psql "postgres://ivorysql:ivorysql@localhost:5443/testdb", |
| 282 | +# Shard 2 |
| 283 | +psql "postgres://ivorysql:ivorysql@localhost:5444/testdb", |
| 284 | +---- |
| 285 | + |
| 286 | +Run the query on each shard backend to verify the data |
| 287 | +[source,sql] |
| 288 | +---- |
| 289 | +SELECT * FROM orders; |
| 290 | +---- |
0 commit comments