diff --git a/docs/administration/.pages b/docs/administration/.pages index 1d7bb99..cc0920b 100644 --- a/docs/administration/.pages +++ b/docs/administration/.pages @@ -1,7 +1,4 @@ +icon: material/shield-account nav: - - 'index.md' - - 'clients.md' - - 'config.md' - - 'pools.md' - - 'servers.md' - - '...' + - index.md + - ... | flat diff --git a/docs/administration/clients.md b/docs/administration/clients.md index 9d1b473..9328e7f 100644 --- a/docs/administration/clients.md +++ b/docs/administration/clients.md @@ -1,3 +1,7 @@ +--- +icon: material/account-multiple +--- + # Client connections PgDog provides real time statistics and information on all client connections. They can be accessed by connecting to the [admin database](index.md) and running the `SHOW CLIENTS` command: diff --git a/docs/administration/config.md b/docs/administration/config.md index 67524f2..016382d 100644 --- a/docs/administration/config.md +++ b/docs/administration/config.md @@ -1,3 +1,7 @@ +--- +icon: material/cog +--- + # Configuration PgDog provides real time access to its current configuration values. They can be accessed by connecting to the [admin database](index.md) and running the `SHOW CONFIG` command: @@ -12,8 +16,6 @@ The following configuration parameters are available and their current values: |------|---------| | `auth_type` [:material-link:](../configuration/pgdog.toml/general.md#auth_type) | `scram` | | `ban_timeout` [:material-link:](../configuration/pgdog.toml/general.md#ban_timeout) | `5m` | -| `broadcast_address` [:material-link:](../configuration/pgdog.toml/general.md#broadcast_address) | `default` | -| `broadcast_port` [:material-link:](../configuration/pgdog.toml/general.md#broadcast_port) | `6433` | | `checkout_timeout` [:material-link:](../configuration/pgdog.toml/general.md#checkout_timeout) | `1s` | | `client_idle_timeout` [:material-link:](../configuration/pgdog.toml/general.md#client_idle_timeout) | `18446744073709551615ms` | | `connect_attempt_delay` [:material-link:](../configuration/pgdog.toml/general.md#connect_attempt_delay) | `0ms` | diff --git a/docs/administration/index.md b/docs/administration/index.md index 1d3e9a0..3196cad 100644 --- a/docs/administration/index.md +++ b/docs/administration/index.md @@ -1,3 +1,7 @@ +--- +icon: material/monitor-dashboard +--- + # Administration overview PgDog keeps track of clients, servers and connection pools. It provides real time statistics on its internal operations for system diff --git a/docs/administration/maintenance_mode.md b/docs/administration/maintenance_mode.md index 823d710..35ac7f1 100644 --- a/docs/administration/maintenance_mode.md +++ b/docs/administration/maintenance_mode.md @@ -1,3 +1,7 @@ +--- +icon: material/wrench +--- + # Maintenance mode Maintenance mode pauses queries from all clients so you can synchronize configuration changes across multiple instances of PgDog. This is useful if you're changing the [sharding](../features/sharding/index.md) options. diff --git a/docs/administration/pools.md b/docs/administration/pools.md index 1ff1b92..738ce97 100644 --- a/docs/administration/pools.md +++ b/docs/administration/pools.md @@ -1,3 +1,7 @@ +--- +icon: material/pool +--- + # Connection pools PgDog provides real time statistics and information on its connection pools. You can view them by connecting to the [admin database](index.md) and running the `SHOW POOLS` command: diff --git a/docs/administration/replication.md b/docs/administration/replication.md index 3681a03..bae51ce 100644 --- a/docs/administration/replication.md +++ b/docs/administration/replication.md @@ -1,3 +1,7 @@ +--- +icon: material/content-copy +--- + # Replication PgDog provides a real time view into PostgreSQL replication for the purposes of monitoring [replication delay](../features/load-balancer/replication-failover.md#replication) and performing query traffic [failover](../features/load-balancer/replication-failover.md#failover). diff --git a/docs/administration/servers.md b/docs/administration/servers.md index eb95a98..9220c9e 100644 --- a/docs/administration/servers.md +++ b/docs/administration/servers.md @@ -1,3 +1,7 @@ +--- +icon: material/server +--- + # Server connections PgDog provides real time statistics and information on all connections to PostgreSQL databases. They can be accessed by connecting to the [admin database](index.md) and running the `SHOW SERVERS` command: diff --git a/docs/architecture/.pages b/docs/architecture/.pages new file mode 100644 index 0000000..d99a1c8 --- /dev/null +++ b/docs/architecture/.pages @@ -0,0 +1,4 @@ +icon: material/sitemap +nav: + - index.md + - ... | flat diff --git a/docs/architecture/benchmarks.md b/docs/architecture/benchmarks.md index 302ba1e..b2cafe2 100644 --- a/docs/architecture/benchmarks.md +++ b/docs/architecture/benchmarks.md @@ -1,3 +1,7 @@ +--- +icon: material/chart-bar +--- + # Benchmarks PgDog does its best to minimize its impact on database performance. Great care is taken to make sure as few operations as possible are performed diff --git a/docs/architecture/comparison.md b/docs/architecture/comparison.md index f989c8f..c8a5297 100644 --- a/docs/architecture/comparison.md +++ b/docs/architecture/comparison.md @@ -1,3 +1,7 @@ +--- +icon: material/scale-balance +--- + # Comparison to other poolers PgDog aims to be the de facto PostgreSQL proxy and pooler. Below is a feature comparison between PgDog and a few popular alternatives. diff --git a/docs/architecture/index.md b/docs/architecture/index.md index 1d42dce..56ef898 100644 --- a/docs/architecture/index.md +++ b/docs/architecture/index.md @@ -1,3 +1,7 @@ +--- +icon: material/cube-outline +--- + # Architecture overview PgDog is written in the [Rust](https://rust-lang.org) programming language. It is also asynchronous, powered by the [Tokio](https://tokio.rs) runtime. This allows PgDog to serve hundreds of thousands of connections on one machine and to take advantage of multiple CPUs. diff --git a/docs/configuration/index.md b/docs/configuration/index.md index 2be6ceb..6a6ad08 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -30,7 +30,18 @@ By default, PgDog looks for both configuration files in the current working dire ## Hot reload -Most settings can be reloaded without restarting PgDog. This allows you to tweak them at runtime without breaking client or server connections. For settings that require a restart, a note is added to the documentation. +Most settings can be reloaded without restarting PgDog. This allows to tweak PgDog at runtime without breaking client or server connections. For settings that require a restart, a note is added to the documentation. + +Hot reload can be triggered by sending `SIGHUP` to the `pgdog` process or by connecting to the [admin database](../administration/index.md) and running the `RELOAD` command. + +=== "Process signal" + ```bash + kill -HUP pgdog + ``` +=== "Admin database" + ```bash + PGPASSWORD=admin psql -h 127.0.0.1 -p 6432 -U admin admin -c 'RELOAD' + ``` ## Units diff --git a/docs/configuration/pgdog.toml/general.md b/docs/configuration/pgdog.toml/general.md index cd4ed84..7ec007d 100644 --- a/docs/configuration/pgdog.toml/general.md +++ b/docs/configuration/pgdog.toml/general.md @@ -10,7 +10,7 @@ General settings are relevant to the operations of the pooler itself, or apply t The IP address of the local network interface PgDog will bind to listen for connections. -!!! note +!!! note "Requires restart" This setting cannot be changed at runtime. Default: **`0.0.0.0`** (all interfaces) @@ -21,7 +21,7 @@ The TCP port PgDog will bind to listen for connections. Default: **`6432`** -!!! note +!!! note "Requires restart" This setting cannot be changed at runtime. ### `workers` @@ -31,7 +31,7 @@ virtual CPU. The value `0` means to spawn no threads and use the current thread Default: **`2`** -!!! note +!!! note "Requires restart" This setting cannot be changed at runtime. ### `default_pool_size` @@ -74,18 +74,12 @@ Path to the TLS certificate PgDog will use to setup TLS connections with clients Default: **none** -!!! note - This setting cannot be changed at runtime. - ### `tls_private_key` Path to the TLS private key PgDog will use to setup TLS connections with clients. If none is provided, TLS will be disabled. Default: **none** -!!! note - This setting cannot be changed at runtime. - ### `tls_client_required` Reject clients that connect without TLS. Consider setting this to `true` when using the `enabled_plain` mode of [`passthrough_auth`](#passthrough_auth). @@ -105,16 +99,10 @@ Available options are: * `verify_ca` (validate certificate only) * `verify_full` (validate certificate _and_ matching hostname) -!!! note - This setting cannot be changed at runtime. - ### `tls_server_ca_certificate` Path to a certificate bundle used to validate the server certificate on TLS connection creation. Used in conjunction with `verify_ca` or `verify_full` in [`tls_verify`](#tls_verify). -!!! note - This setting cannot be changed at runtime. - ## Healthchecks diff --git a/docs/configuration/pgdog.toml/rewrite.md b/docs/configuration/pgdog.toml/rewrite.md index ed5e93a..db3396c 100644 --- a/docs/configuration/pgdog.toml/rewrite.md +++ b/docs/configuration/pgdog.toml/rewrite.md @@ -39,5 +39,7 @@ The setting changes are applied immediately. These overrides allow canary testin ### Read more -- [Cross-shard INSERT](../../features/sharding/cross-shard-queries/insert.md#multiple-tuples) -- [Cross-shard UPDATE](../../features/sharding/cross-shard-queries/update.md#sharding-key-updates) +{{ next_steps_links([ + ("Cross-shard INSERT", "../../features/sharding/cross-shard-queries/insert.md#multiple-tuples", "Insert rows with multiple tuples across shards."), + ("Cross-shard UPDATE", "../../features/sharding/cross-shard-queries/update.md#sharding-key-updates", "Update rows that require sharding key changes."), +]) }} diff --git a/docs/features/load-balancer/healthchecks.md b/docs/features/load-balancer/healthchecks.md index d37e18b..3e1c999 100644 --- a/docs/features/load-balancer/healthchecks.md +++ b/docs/features/load-balancer/healthchecks.md @@ -9,7 +9,7 @@ All databases load balanced by PgDog are regularly checked with health checks. A If a replica database fails a health check, it's temporarily removed from the load balancer, preventing it from serving queries for a configurable period of time.
- Healthchecks + Healthchecks
## How it works diff --git a/docs/features/load-balancer/index.md b/docs/features/load-balancer/index.md index f5e43f4..20c4afb 100644 --- a/docs/features/load-balancer/index.md +++ b/docs/features/load-balancer/index.md @@ -18,7 +18,7 @@ Applications can connect to a single PgDog [endpoint](#single-endpoint), without When a query is received by PgDog, it will inspect it using the native Postgres SQL parser. If the query is a `SELECT` and the [configuration](../../configuration/pgdog.toml/databases.md) contains both primary and replica databases, PgDog will send it to one of the replicas. For all other queries, PgDog will send them to the primary.
- Load balancer + Load balancer
Applications don't have to manually route queries between databases or maintain several connection pools internally. diff --git a/docs/features/load-balancer/manual-routing.md b/docs/features/load-balancer/manual-routing.md index 02486f3..c1d1cf1 100644 --- a/docs/features/load-balancer/manual-routing.md +++ b/docs/features/load-balancer/manual-routing.md @@ -123,7 +123,7 @@ The PostgreSQL protocol supports changing connection parameters using the `SET` For example, to make sure all subsequent queries are sent to the primary, you can execute the following statement: ```postgresql -SET pgdog.role TO "primary"; +SET "pgdog"."role" TO "primary"; ``` The parameter is persisted on the connection until it's closed or the value is changed with another `SET` statement. Before routing a query, the load balancer will check the value of this parameter, so setting it early on during connection creation ensures all transactions are executed on the right database. @@ -134,7 +134,7 @@ It's possible to set routing hints for the lifetime of a single transaction, by ```postgresql BEGIN; -SET LOCAL pgdog.role TO "primary"; +SET LOCAL "pgdog"."role" TO "primary"; ``` In this example, all transaction statements (including the `BEGIN` statement) will be sent to the primary database. Whether the transaction is committed or reverted, the value of `pgdog.role` will be reset to its previous value. diff --git a/docs/features/mirroring.md b/docs/features/mirroring.md index 7955999..7ffcb18 100644 --- a/docs/features/mirroring.md +++ b/docs/features/mirroring.md @@ -11,7 +11,7 @@ Database mirroring replicates traffic, byte for byte, from one database to anoth Mirroring in PgDog is asynchronous and should have minimal impact on production databases: transactions are sent to a background task, which in turn forwards them to one or more mirror databases. If any statement fails, the error is ignored and the next one is executed.
- Mirroring + Mirroring
## Configuration diff --git a/docs/features/session-mode.md b/docs/features/session-mode.md index 1c71d54..5d14f7f 100644 --- a/docs/features/session-mode.md +++ b/docs/features/session-mode.md @@ -47,6 +47,6 @@ when a client disconnects, the PostgreSQL server connection remains intact and c #### Lazy connections Until a client issues their first query, PgDog doesn't attach it to a server connection. This allows one set of clients to connect before the previous set disconnects, -which is common when using zero-downtime deployment strategies like blue-green [^1]. +which is common when using zero-downtime deployment strategies like blue/green [^1]. [^1]: [https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html](https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/bluegreen-deployments.html) diff --git a/docs/features/sharding/2pc.md b/docs/features/sharding/2pc.md index 1e2df12..639c0ad 100644 --- a/docs/features/sharding/2pc.md +++ b/docs/features/sharding/2pc.md @@ -103,5 +103,7 @@ Two-phase commit is used for writes only. Read transactions are finished using n ## Read more -- [Omnisharded tables](omnishards.md) -- [Cross-shard queries](cross-shard-queries/index.md) +{{ next_steps_links([ + ("Omnisharded tables", "omnishards.md", "Tables replicated to every shard for fast local joins."), + ("Cross-shard queries", "cross-shard-queries/index.md", "Run queries that span multiple shards transparently."), +]) }} diff --git a/docs/features/sharding/basics.md b/docs/features/sharding/basics.md index 0f6f571..866e1ee 100644 --- a/docs/features/sharding/basics.md +++ b/docs/features/sharding/basics.md @@ -36,5 +36,7 @@ Alternatively, a sharding function can map the sharding keys directly to a shard ## Read more -- [Sharding functions](sharding-functions.md) -- [Direct-to-shard queries](query-routing.md) +{{ next_steps_links([ + ("Sharding functions", "sharding-functions.md", "Control how rows are distributed across shards."), + ("Direct-to-shard queries", "query-routing.md", "Route queries directly to the correct shard."), +]) }} diff --git a/docs/features/sharding/cross-shard-queries/copy.md b/docs/features/sharding/cross-shard-queries/copy.md index 6dbbb49..ac088a5 100644 --- a/docs/features/sharding/cross-shard-queries/copy.md +++ b/docs/features/sharding/cross-shard-queries/copy.md @@ -50,5 +50,7 @@ If the query fetches rows from more than one shard, PgDog will also ignore any ` ## Read more -- [Two-phase commit](../2pc.md) -- [Omnisharded tables](../omnishards.md) +{{ next_steps_links([ + ("Two-phase commit", "../2pc.md", "Atomic transactions spanning multiple shards."), + ("Omnisharded tables", "../omnishards.md", "Tables replicated to every shard for fast local joins."), +]) }} diff --git a/docs/features/sharding/cross-shard-queries/index.md b/docs/features/sharding/cross-shard-queries/index.md index acc3805..0011273 100644 --- a/docs/features/sharding/cross-shard-queries/index.md +++ b/docs/features/sharding/cross-shard-queries/index.md @@ -7,7 +7,7 @@ icon: material/multicast If a client can't or doesn't specify a sharding key in the query, PgDog will send that query to all shards in parallel, and combine the results automatically. To the client, this looks like the query was executed by a single database.
- Cross-shard queries + Cross-shard queries
## How it works @@ -66,9 +66,11 @@ When this setting is enabled and a query doesn't have a sharding key, instead of ## Read more -- [Sharding functions](../sharding-functions.md) -- [Cross-shard `SELECT`](select.md) -- [Cross-shard `INSERT`](insert.md) -- [Cross-shard `UPDATE` and `DELETE`](update.md) -- [DDL, e.g., `CREATE TABLE`](ddl.md) -- [`COPY` command](copy.md) +{{ next_steps_links([ + ("Sharding functions", "../sharding-functions.md", "Control how rows are distributed across shards."), + ("Cross-shard SELECT", "select.md", "Query data across all shards with automatic merging."), + ("Cross-shard INSERT", "insert.md", "Insert rows that get routed to the correct shard."), + ("Cross-shard UPDATE and DELETE", "update.md", "Modify or remove rows in tables spanning multiple shards."), + ("DDL, e.g. CREATE TABLE", "ddl.md", "Run schema changes across all shards at once."), + ("COPY command", "copy.md", "Bulk load data across shards with the COPY protocol."), +]) }} diff --git a/docs/features/sharding/cross-shard-queries/select.md b/docs/features/sharding/cross-shard-queries/select.md index fd8aa1c..7b4bfe3 100644 --- a/docs/features/sharding/cross-shard-queries/select.md +++ b/docs/features/sharding/cross-shard-queries/select.md @@ -25,6 +25,8 @@ The SQL language allows for powerful data filtration and manipulation. While we | `ORDER BY` | :material-check: | Columns must be part of the returned tuples. See [sorting](#sorting). | | `DISTINCT` / `DISTINCT BY`| :material-check: | Columns must be part of the returned tuples. | | `GROUP BY` | :material-wrench: | Columns must be part of the returned tuples. See [aggregates](#aggregates). | +| `LIMIT` | :material-check: | None. | +| `OFFSET` | :material-check: | Rows are filtered in-memory, so paginating becomes linearly more expensive with the number of pages. | | CTEs | :material-wrench: | CTE must refer to data located on the same shard. | | Window functions | :material-close: | Not currently supported. | | Subqueries | :material-wrench: | Subqueries must refer to data located on the same shard. | diff --git a/docs/features/sharding/manual-routing.md b/docs/features/sharding/manual-routing.md index f0b7dc4..d0fa5f4 100644 --- a/docs/features/sharding/manual-routing.md +++ b/docs/features/sharding/manual-routing.md @@ -69,7 +69,7 @@ The `SET` command comes from the PostgreSQL query language and is used to change ```postgresql BEGIN; - SET pgdog.shard TO 0; + SET LOCAL pgdog.shard TO 0; CREATE INDEX users_id_idx USING btree(id); COMMIT; ``` @@ -78,21 +78,14 @@ The `SET` command comes from the PostgreSQL query language and is used to change ```postgresql BEGIN; - SET pgdog.sharding_key TO 'us-east-1'; + SET LOCAL pgdog.sharding_key TO 'us-east-1'; SELECT * FROM users WHERE is_admin = true; COMMIT; ``` ### Limitations -Since `SET` changes session variables, we want to avoid leaking this state between transactions. For this reason, routing hints provided using this method are only supported inside transactions. For example: - -```postgresql -BEGIN; -SET pgdog.sharding_key TO 'us-east-1'; -SELECT * FROM users WHERE is_admin = true; -COMMIT; -``` +Sharding hints provided using `SET` follow the same semantics as regular `SET` variables. For this reason, it's always best to use them inside transactions with `SET LOCAL`. Using `SET` will persist the query routing hint until the parameter is set again. ### Latency @@ -140,5 +133,7 @@ You can read more about this in [our blog](https://pgdog.dev/blog/sharding-a-rea ## Read more -- [Cross-shard queries](cross-shard-queries/index.md) -- [Sharding functions](sharding-functions.md) +{{ next_steps_links([ + ("Cross-shard queries", "cross-shard-queries/index.md", "Run queries that span multiple shards transparently."), + ("Sharding functions", "sharding-functions.md", "Control how rows are distributed across shards."), +]) }} diff --git a/docs/features/sharding/omnishards.md b/docs/features/sharding/omnishards.md index 8679005..6af375d 100644 --- a/docs/features/sharding/omnishards.md +++ b/docs/features/sharding/omnishards.md @@ -106,7 +106,7 @@ tables = [ ] ``` -This is configurable with the `system_catalogs` setting in [`pgdog.toml`](../../configuration/pgdog.toml/general.md#system_catalogs_omnisharded): +This is configurable with the `system_catalogs` setting in [`pgdog.toml`](../../configuration/pgdog.toml/general.md#system_catalogs): ```toml [general] diff --git a/docs/features/sharding/query-routing.md b/docs/features/sharding/query-routing.md index e731d2a..692c140 100644 --- a/docs/features/sharding/query-routing.md +++ b/docs/features/sharding/query-routing.md @@ -64,13 +64,19 @@ Just like for `SELECT` queries, both [prepared statements](../prepared-statement ### Supported syntax -To correctly identify the sharding key in the `VALUES` clause, the `INSERT` statement must explicitly name the columns in the tuple. Additionally, statements must create one row at a time. Multi-tuple `INSERT`s are not currently supported. - -For example: +PgDog can automatically detect the sharding key in an `INSERT` statement, whether it specifies column names or not. It can also split multi-tuple inserts, by sending each tuple to their respective shard, for example: ```postgresql -INSERT INTO payments -- Missing column names. -VALUES ($1, $2), ($3, $4) -- More than one tuple. +-- user_id is the sharding key ($1) +INSERT INTO payments (user_id, amount) VALUES ($1, $2); + +-- user_id is automatically detected as parameter $1 +-- using schema inference +INSERT INTO payments VALUES ($1, $2); + +-- Statement is rewritten into two inserts, and each is sent +-- to different shards +INSERT INTO payments VALUES ($1, $2), ($3, $4); ``` ## UPDATE and DELETE @@ -144,5 +150,7 @@ The latter will match queries referring to the `users.id` column only. Together ## Read more -- [Cross-shard queries](cross-shard-queries/index.md) -- [Manual routing](manual-routing.md) +{{ next_steps_links([ + ("Cross-shard queries", "cross-shard-queries/index.md", "Run queries that span multiple shards transparently."), + ("Manual routing", "manual-routing.md", "Explicitly control which shard handles a query."), +]) }} diff --git a/docs/features/sharding/resharding/databases.md b/docs/features/sharding/resharding/databases.md index 8f979d8..9883063 100644 --- a/docs/features/sharding/resharding/databases.md +++ b/docs/features/sharding/resharding/databases.md @@ -24,4 +24,6 @@ If you are operating multiple Postgres databases on the same database server, th ## Next steps -- [Schema sync](schema.md) +{{ next_steps_links([ + ("Schema sync", "schema.md", "Synchronize schema across new shards before moving data."), +]) }} diff --git a/docs/features/sharding/resharding/hash.md b/docs/features/sharding/resharding/hash.md index 60b8c27..487397c 100644 --- a/docs/features/sharding/resharding/hash.md +++ b/docs/features/sharding/resharding/hash.md @@ -125,4 +125,6 @@ The replication delay between the two database clusters is measured in bytes. Wh ## Next steps -- [Traffic cutover](cutover.md) +{{ next_steps_links([ + ("Traffic cutover", "cutover.md", "Switch live traffic to the new shard configuration."), +]) }} diff --git a/docs/features/sharding/resharding/schema.md b/docs/features/sharding/resharding/schema.md index 7ecae7e..a45b78e 100644 --- a/docs/features/sharding/resharding/schema.md +++ b/docs/features/sharding/resharding/schema.md @@ -95,6 +95,8 @@ This steps is performed during the cutover stage once both schema sync and data This step will calculate the `MAX(column) + 1` values for all table sequences and set them on the respective columns. -## Read more +## Next steps -- [Move data](hash.md) +{{ next_steps_links([ + ("Move data", "hash.md", "Redistribute data across shards using hash-based resharding."), +]) }} diff --git a/docs/features/sharding/sharding-functions.md b/docs/features/sharding/sharding-functions.md index f76ff66..6fd34a0 100644 --- a/docs/features/sharding/sharding-functions.md +++ b/docs/features/sharding/sharding-functions.md @@ -182,5 +182,7 @@ This will send all queries that don't specify a schema or use a schema without a ## Read more -- [COPY command](cross-shard-queries/copy.md) -- [Two-phase commit](2pc.md) +{{ next_steps_links([ + ("COPY command", "cross-shard-queries/copy.md", "Bulk load data across shards with the COPY protocol."), + ("Two-phase commit", "2pc.md", "Atomic transactions spanning multiple shards."), +]) }} diff --git a/docs/index.md b/docs/index.md index ab81f45..394ea0c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,6 @@ +--- +icon: material/home +--- # Introduction to PgDog @@ -30,21 +33,9 @@ This documentation provides a detailed overview of all PgDog features, along wit ## Read more -
-
-

Features

-

Read more about PgDog features like load balancing, supported authentication mechanisms, TLS, health checks, and more.

-
-
-

Administration

-

Learn how to operate PgDog in production, like fetching real-time statistics from the admin database or updating configuration.

-
-
-

Installation

-

Install PgDog on your Linux server or on your Linux/Mac/Windows machine for local development.

-
-
-

Configuration

-

Reference for PgDog configuration like maximum server connections, number of shards, and more.

-
-
+{{ next_steps_links([ + ("Features", "/features/", "Read more about PgDog features like load balancing, supported authentication mechanisms, TLS, health checks, and more."), + ("Administration", "/administration/", "Learn how to operate PgDog in production, like fetching real-time statistics from the admin database or updating configuration."), + ("Installation", "/installation/", "Install PgDog on your Linux server or on your Linux/Mac/Windows machine for local development."), + ("Configuration", "/configuration/", "Reference for PgDog configuration like maximum server connections, number of shards, and more."), +]) }} diff --git a/docs/installation.md b/docs/installation.md index b45c59e..6064185 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -22,12 +22,19 @@ docker run ghcr.io/pgdogdev/pgdog:main ### SemVer -PgDog follows SemVer, and for each tagged release, a corresponding tag will be available in the Docker repository. For example, you can run v0.1.6 like so: +PgDog follows SemVer, and for each tagged release, a corresponding tag will be available in the Docker repository. For example, you can run `v0.1.29` like so: ``` -docker run ghcr.io/pgdogdev/pgdog:v0.1.6 +docker run ghcr.io/pgdogdev/pgdog:v0.1.29 ``` +### AWS ECS + +!!! note "New feature" + This is a new feature. Please report any issues you may encounter. + + We recently added a [Terraform module](https://github.com/pgdogdev/pgdog-ecs-terraform) to deploy PgDog on AWS ECS. It works with the same Docker image as our Helm chart, so the experience should be familiar. + ## From source PgDog can be easily compiled from source. For production deployments, a `Dockerfile` is provided in [GitHub](https://github.com/pgdogdev/pgdog/tree/main/Dockerfile). If you prefer to deploy on bare-metal or you're looking to run PgDog locally, you'll need to install a few dependencies. @@ -139,21 +146,9 @@ password = "hunter2" ## Next steps -
-
-

Features

-

Read more about PgDog features like load balancing, supported authentication mechanisms, TLS, health checks, and more.

-
-
-

Administration

-

Learn how to operate PgDog in production, like fetching real-time statistics from the admin database or updating configuration.

-
-
-

Architecture

-

Read about PgDog internals and how it works under the hood.

-
-
-

Configuration

-

Reference for PgDog configuration like maximum server connections, number of shards, and more.

-
-
+{{ next_steps_links([ + ("Features", "/features/", "Read more about PgDog features like load balancing, supported authentication mechanisms, TLS, health checks, and more."), + ("Administration", "/administration/", "Learn how to operate PgDog in production, like fetching real-time statistics from the admin database or updating configuration."), + ("Architecture", "/architecture/", "Read about PgDog internals and how it works under the hood."), + ("Configuration", "/configuration/", "Reference for PgDog configuration like maximum server connections, number of shards, and more."), +]) }} diff --git a/docs/migrating-to-pgdog/from-pgbouncer.md b/docs/migrating-to-pgdog/from-pgbouncer.md index 94ae641..c980da6 100644 --- a/docs/migrating-to-pgdog/from-pgbouncer.md +++ b/docs/migrating-to-pgdog/from-pgbouncer.md @@ -314,5 +314,7 @@ pooler_mode = "session" ## Read more -- [`pgdog.toml`](../configuration/pgdog.toml/general.md) -- [`users.toml`](../configuration/users.toml/users.md) +{{ next_steps_links([ + ("pgdog.toml", "../configuration/pgdog.toml/general.md", "Main configuration file for PgDog settings, databases, and sharding."), + ("users.toml", "../configuration/users.toml/users.md", "Configure user authentication and per-user pool settings."), +]) }} diff --git a/docs/style.css b/docs/style.css index b739812..2ef6918 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1,12 +1,214 @@ -table { - table-layout: fixed !important; - display: table !important; +/* ===== Custom Properties ===== */ +:root { + --card-border-radius: 8px; + --card-padding: 1.2rem; + --transition-speed: 0.2s; } +/* ===== Header ===== */ .md-header { - --md-primary-fg-color: rgb(7, 81, 207); + --md-primary-fg-color: rgb(7, 81, 207); + backdrop-filter: blur(8px); +} + +[data-md-color-scheme="slate"] .md-header { + --md-primary-fg-color: rgb(30, 58, 138); + background-color: hsla(230, 15%, 14%, 0.85); +} + +/* ===== Tables ===== */ +table { + table-layout: fixed !important; + display: table !important; +} + +.md-typeset table:not([class]) { + border-radius: var(--card-border-radius); + overflow: hidden; + border: 1px solid var(--md-default-fg-color--lightest); + font-size: 0.75rem; } +.md-typeset table:not([class]) th { + background-color: var(--md-default-fg-color--lightest); + font-weight: 600; + text-transform: uppercase; + font-size: 0.65rem; + letter-spacing: 0.05em; +} + +/* ===== Screenshots ===== */ .screenshot { - border-radius: 8px; + border-radius: var(--card-border-radius); + border: 1px solid var(--md-default-fg-color--lightest); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); +} + +/* ===== Card Grid ===== */ +.grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 1rem; + margin: 1.5rem 0; +} + +.grid > div { + padding: var(--card-padding); + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: var(--card-border-radius); + transition: all var(--transition-speed) ease; + background: var(--md-default-bg-color); +} + +.grid > div:hover { + border-color: var(--md-primary-fg-color); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); + transform: translateY(-2px); +} + +.grid > div h4 { + margin: 0 0 0.5rem 0; + font-size: 0.9rem; +} + +.grid > div h4 a { + color: var(--md-primary-fg-color); + text-decoration: none; + font-weight: 600; +} + +.grid > div p { + margin: 0; + font-size: 0.82rem; + color: var(--md-default-fg-color--light); + line-height: 1.5; +} + +/* ===== Code Blocks ===== */ +.md-typeset pre > code { + border-radius: var(--card-border-radius); +} + +.md-typeset code { + border-radius: 4px; + font-size: 0.82em; +} + +.md-typeset .highlight { + border-radius: var(--card-border-radius); + overflow: hidden; +} + +/* ===== Inline Code ===== */ +.md-typeset :not(pre) > code { + padding: 0.1em 0.4em; + background-color: var(--md-code-bg-color); + border: 1px solid var(--md-default-fg-color--lightest); +} + +/* ===== Admonitions ===== */ +.md-typeset .admonition, +.md-typeset details { + border-radius: var(--card-border-radius); + border-width: 0 0 0 4px; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05); +} + +/* ===== Navigation ===== */ +.md-nav__item .md-nav__link--active { + font-weight: 600; +} + +/* ===== Content Width ===== */ +.md-grid { + max-width: 1400px; +} + +/* ===== Footer ===== */ +.md-footer { + margin-top: 2rem; +} + +/* ===== Hero Section (homepage) ===== */ +.hero { + text-align: center; + padding: 2rem 0 1rem; +} + +.hero h1 { + font-size: 2.2rem; + font-weight: 700; + margin-bottom: 0.5rem; +} + +.hero p { + font-size: 1.1rem; + color: var(--md-default-fg-color--light); + max-width: 640px; + margin: 0 auto 1.5rem; + line-height: 1.6; +} + +.hero .hero-buttons { + display: flex; + gap: 0.75rem; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 1rem; +} + +.hero .hero-buttons a { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.6rem 1.4rem; + border-radius: 6px; + font-weight: 600; + font-size: 0.88rem; + text-decoration: none; + transition: all var(--transition-speed) ease; +} + +.hero .hero-buttons .btn-primary { + background-color: var(--md-primary-fg-color); + color: var(--md-primary-bg-color); +} + +.hero .hero-buttons .btn-primary:hover { + opacity: 0.9; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +.hero .hero-buttons .btn-secondary { + border: 1px solid var(--md-default-fg-color--lighter); + color: var(--md-default-fg-color); +} + +.hero .hero-buttons .btn-secondary:hover { + border-color: var(--md-primary-fg-color); + color: var(--md-primary-fg-color); +} + +/* ===== Feature Cards (icons) ===== */ +.grid > div .card-icon { + font-size: 1.6rem; + margin-bottom: 0.5rem; + display: block; +} + +/* ===== Tabs ===== */ +.md-typeset .tabbed-labels > label { + font-size: 0.75rem; + font-weight: 600; +} + +/* ===== Responsive ===== */ +@media screen and (max-width: 76.25em) { + .hero h1 { + font-size: 1.6rem; + } + + .hero p { + font-size: 0.95rem; + } } diff --git a/main.py b/main.py index 8cd7b7c..cfcf75f 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,89 @@ +import logging +import os +import posixpath +from urllib.parse import urlparse + from mkdocs.structure.files import Files +log = logging.getLogger("mkdocs.plugins.macros") + + def define_env(env): + def _validate_link(href, page): + """Check that a .md link target exists on disk.""" + parsed = urlparse(href) + path = parsed.path + + if not path.endswith('.md') or path.startswith('http'): + return + + page_dir = posixpath.dirname(page.file.src_path) + resolved = posixpath.normpath(posixpath.join(page_dir, path)) + abs_path = os.path.join(env.conf['docs_dir'], resolved) + + if not os.path.isfile(abs_path): + log.warning( + f"Card link in '{page.file.src_path}' points to " + f"'{href}' but '{resolved}' does not exist." + ) + + def _resolve_link(href, page): + """Resolve a relative .md link to the correct site URL.""" + _validate_link(href, page) + + parsed = urlparse(href) + path = parsed.path + + if not path.endswith('.md') or path.startswith('http'): + return href + + # Get the directory of the current page source + page_dir = posixpath.dirname(page.file.src_path) + # Resolve the relative path + resolved = posixpath.normpath(posixpath.join(page_dir, path)) + # Convert .md to trailing slash + resolved = resolved.replace('.md', '/') + # Handle index files + if resolved.endswith('/index/'): + resolved = resolved[:-len('index/')] + + url = '/' + resolved + if parsed.fragment: + url += '#' + parsed.fragment + return url + @env.macro def next_steps_links(links): + page = env.page rendered = [] for link in links: + title, href, desc = link + resolved = _resolve_link(href, page) + rendered.append(f""" +
+

{title}

+

{desc}

+
+ """) + rendered = "\n".join(rendered) + return f'''
{rendered}
''' + + @env.macro + def card_grid(cards): + """Render a grid of cards with icon, title, link, and description. + Each card: (icon, title, link, description) + """ + page = env.page + rendered = [] + for card in cards: + icon, title, href, desc = card + resolved = _resolve_link(href, page) rendered.append(f"""
-

{link[0]}

-

{link[2]}

+ {icon} +

{title}

+

{desc}

""") rendered = "\n".join(rendered) diff --git a/mkdocs.yml b/mkdocs.yml index 19c0852..5154fa1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,43 +1,53 @@ site_name: PgDog repo_url: "https://github.com/pgdogdev/pgdog" +repo_name: pgdogdev/pgdog site_url: "https://docs.pgdog.dev" +site_description: "PgDog - PostgreSQL query router, pooler, load balancer, and sharding proxy." + extra_css: - style.css -site_description: "PgDog - PostgreSQL query router, pooler, load balancer, and sharding proxy." + theme: + name: material logo: /images/logo-64x64.png favicon: /images/logo-64x64.png - name: material + + icon: + repo: fontawesome/brands/github + admonition: + note: octicons/tag-16 + tip: octicons/squirrel-16 + warning: octicons/alert-16 + danger: octicons/zap-16 + example: octicons/beaker-16 + features: - content.code.copy + - content.code.annotate + - content.tabs.link + - navigation.instant + - navigation.instant.progress + - navigation.tracking + - navigation.sections + - navigation.indexes + - navigation.top + - navigation.footer - search.suggest + - search.highlight - search.share + - toc.follow + font: text: Inter - code: Source Code Pro - palette: - # Palette toggle for automatic mode - - media: "(prefers-color-scheme)" - toggle: - icon: material/brightness-auto - name: Switch to light mode + code: JetBrains Mono - # Palette toggle for light mode - - media: "(prefers-color-scheme: light)" - scheme: default - primary: blue - toggle: - icon: material/brightness-7 - name: Switch to dark mode + palette: + scheme: slate + primary: indigo + accent: indigo - # Palette toggle for dark mode - - media: "(prefers-color-scheme: dark)" - scheme: slate - primary: blue - toggle: - icon: material/brightness-4 - name: Switch to system preference docs_dir: docs + markdown_extensions: - pymdownx.highlight: anchor_linenums: true @@ -46,17 +56,26 @@ markdown_extensions: - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences + - pymdownx.mark + - pymdownx.keys - footnotes - admonition - pymdownx.details - - pymdownx.superfences - pymdownx.tabbed: alternate_style: true - md_in_html - attr_list + - def_list + - tables + - toc: + permalink: true + toc_depth: 3 - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.tasklist: + custom_checkbox: true + plugins: - search - awesome-pages @@ -67,3 +86,9 @@ plugins: 'features/sharding/migrations.md': 'features/sharding/schema_management/migrations.md' 'features/sharding/primary-keys.md': 'features/sharding/schema_management/primary_keys.md' 'features/sharding/cross-shard/index.md': 'features/sharding/cross-shard-queries/index.md' + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/pgdogdev/pgdog + generator: false