diff --git a/.gitbook/assets/vdb-cdc-debezium-architecture.png b/.gitbook/assets/vdb-cdc-debezium-architecture.png new file mode 100644 index 00000000..3f82f788 Binary files /dev/null and b/.gitbook/assets/vdb-cdc-debezium-architecture.png differ diff --git a/.gitbook/assets/vdb-logical-replication-architecture.png b/.gitbook/assets/vdb-logical-replication-architecture.png new file mode 100644 index 00000000..3af0a5b1 Binary files /dev/null and b/.gitbook/assets/vdb-logical-replication-architecture.png differ diff --git a/English/SUMMARY.md b/English/SUMMARY.md index a1a8ab72..eb851e2a 100644 --- a/English/SUMMARY.md +++ b/English/SUMMARY.md @@ -784,6 +784,8 @@ * [Parameters for PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/postgresql-cluster-parameters.md) * [Extensions for PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/vdb-postgresql-cluster-extensions.md) * [Migrate from PostgreSQL Single to PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/migrate-from-postgresql-single-to-cluster.md) + * [Configure Logical Replication](vdb/relational-database-service-rds/postgresql/configure-logical-replication.md) + * [Set Up CDC with Debezium](vdb/relational-database-service-rds/postgresql/set-up-cdc-with-debezium.md) * [Reference](vdb/relational-database-service-rds/reference/README.md) * [MemoryStore Database Service (MDS)](vdb/memorystore-database-service-mds/README.md) * [Redis Standalone](vdb/memorystore-database-service-mds/redis-standalone/README.md) diff --git a/English/vdb/relational-database-service-rds/postgresql/configure-logical-replication.md b/English/vdb/relational-database-service-rds/postgresql/configure-logical-replication.md new file mode 100644 index 00000000..12948414 --- /dev/null +++ b/English/vdb/relational-database-service-rds/postgresql/configure-logical-replication.md @@ -0,0 +1,238 @@ +# Configure Logical Replication for PostgreSQL Cluster + +> This guide helps you set up **PostgreSQL Logical Replication** — replicating data changes in real time from a source cluster (Publisher) to a destination cluster (Subscriber). One or both clusters can be hosted on GreenNode vDB. + +--- + +## Prerequisites + +- At least one of the two clusters (Publisher or Subscriber) must be a PostgreSQL Cluster on GreenNode vDB (**version 16 or 17**). +- Both clusters must run the **same major version** of PostgreSQL. +- The user running SQL commands must be the **owner** of the tables to replicate (to create a Publication). + +{% hint style="info" %} +GreenNode vDB supports Logical Replication for **PostgreSQL 16 and 17** only. +{% endhint %} + +--- + +## How Logical Replication Works + +![Logical Replication architecture](../../../../.gitbook/assets/vdb-logical-replication-architecture.png) + +- **Publisher**: the source cluster holding the original data. You create a `PUBLICATION` to define which tables are replicated. +- **Subscriber**: the destination cluster receiving changes. You create a `SUBSCRIPTION` to connect to the Publisher and pull data. + +**Synchronization happens in two phases:** + +1. **Initial sync**: As soon as you create a Subscription, PostgreSQL automatically copies all existing data from Publisher to Subscriber — you do not need to manually dump and restore data. This may take minutes to hours depending on data size. +2. **Streaming**: After the initial sync completes, only incremental changes (INSERT, UPDATE, DELETE) are replicated in real time. + +{% hint style="info" %} +You **do not need to dump data** — Logical Replication handles that automatically. However, you **must create the table structure (schema) on the Subscriber** before creating the Subscription, because PostgreSQL does not replicate DDL. See [Step B.3](#step-b3-create-tables-on-subscriber) for instructions. +{% endhint %} + +--- + +## Part A: vDB PostgreSQL Cluster as Publisher + +> Follow the steps in this section if your GreenNode vDB cluster is the **data source** (Publisher). + +### Step A.1: Request Activation + +Contact **GreenNode Support** to request Logical Replication activation on your cluster. GreenNode Support will configure the cluster and provide you with a **username** and **password** for the replication user — this information will be used in the connection string when the Subscriber creates its Subscription. + +To change the replication user password, run the following command on the cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +When managing Subscriptions, do not delete or modify replication slots that do not belong to you. These slots may belong to the system or other Subscriptions — accidentally dropping one will cause replication loss immediately. +{% endhint %} + +### Step A.2: Configure PostgreSQL Parameters + +Logical Replication requires three PostgreSQL parameters to be correctly configured on the **Publisher cluster**. + +| Parameter | Required value | Description | +|---|---|---| +| `wal_level` | `logical` | Required — default is `replica`, which is not sufficient for logical replication | +| `max_replication_slots` | ≥ total slots needed | Total replication slots for all replicas, subscriptions, and CDC connectors | +| `max_wal_senders` | ≥ total senders needed | Total WAL sender processes (typically equals `max_replication_slots`) | + +**How to calculate `max_replication_slots` and `max_wal_senders`:** + +| Component | Slots + senders needed | +|---|---| +| Each replica node in the cluster | 1 + 1 | +| Each Subscription (logical replication) | 1 + 1 | +| Each CDC connector (Debezium) | 1 + 1 | + +**Example:** 3-node cluster (2 replicas) + 1 subscription → `max_replication_slots = 3`, `max_wal_senders = 3`. + +{% hint style="warning" %} +Changing `wal_level`, `max_replication_slots`, and `max_wal_senders` requires a **cluster restart**. Update all three parameters at the same time to trigger only one restart. See [PostgreSQL Cluster Parameters](postgresql-cluster-parameters.md) for instructions. +{% endhint %} + +### Step A.3: Create a Publication + +1. Connect to the **Publisher cluster** using an account with **owner** rights on the tables to replicate. +2. Create a Publication for the tables to replicate: + +```sql +-- Replicate specific tables +CREATE PUBLICATION FOR TABLE orders, products; +``` + +{% hint style="info" %} +To use `FOR ALL TABLES`, contact **GreenNode Support** — this requires superuser privileges on the cluster. +{% endhint %} + +3. Verify the Publication was created: + +```sql +SELECT pubname, puballtables, pubinsert, pubupdate, pubdelete +FROM pg_publication; +``` + +--- + +## Part B: vDB PostgreSQL Cluster as Subscriber + +> Follow the steps in this section if your GreenNode vDB cluster is the **data destination** (Subscriber). + +### Step B.1: Request Logical Replication Activation + +Contact **GreenNode Support** to request Logical Replication activation on your cluster. GreenNode Support will configure the cluster and provide you with a **username** and **password** for the replication user — this information will be used in the connection string when the Subscriber creates its Subscription. + +To change the replication user password, run the following command on the cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +When managing Subscriptions, do not delete or modify replication slots that do not belong to you. These slots may belong to the system or other Subscriptions — accidentally dropping one will cause replication loss immediately. +{% endhint %} + +### Step B.2: Grant CREATE on Schema and Target Database + +Connect to the **Subscriber cluster** using the **owner** account of the target database and schema, then run the following commands: + +```sql +-- Grant CREATE on the database (required to run CREATE SUBSCRIPTION) +GRANT CREATE ON DATABASE TO ; + +-- Grant USAGE and CREATE on the schema +GRANT USAGE ON SCHEMA TO ; +GRANT CREATE ON SCHEMA TO ; +``` + +{% hint style="info" %} +`` here is the account used to run `CREATE TABLE` (Step B.3) and `CREATE SUBSCRIPTION` (Step B.4) — not the replication user in the CONNECTION string (provided by GreenNode in Step B.1). +{% endhint %} + +### Step B.3: Create Tables on Subscriber + +Logical Replication **does not create tables automatically** on the Subscriber. You must create the schema and tables on the Subscriber before creating the Subscription. + +{% hint style="info" %} +**Tip:** Instead of writing DDL by hand, use `pg_dump --schema-only` to dump the table structure from the Publisher, review the file, then apply it to the Subscriber with `psql -f`. +{% endhint %} + +```bash +# Step 1: dump schema from Publisher to a file +pg_dump \ + --schema-only \ + --table= \ + -h \ + -U \ + -d \ + -f schema.sql + +# Step 2: inspect the file before applying (optional) +# cat schema.sql + +# Step 3: apply to Subscriber +psql \ + -h \ + -U \ + -d \ + -f schema.sql +``` + +To dump multiple tables, repeat `--table` for each one. Omit `--table` to dump the entire schema. + +**Or create the table manually:** + +```sql +-- Example: create the orders table on Subscriber +CREATE TABLE orders ( + id serial PRIMARY KEY, + product text NOT NULL, + qty int NOT NULL, + ts timestamptz DEFAULT now() +); +``` + +{% hint style="warning" %} +The schema and data types of tables on the Subscriber must **exactly match** the Publisher. A mismatch will cause the Subscription to fail when applying changes. +{% endhint %} + +### Step B.4: Create a Subscription + +1. Connect to the **Subscriber cluster** using the GreenNode-provided account. +2. Create the Subscription: + +```sql +CREATE SUBSCRIPTION my_subscription + CONNECTION 'host= port=5432 dbname= user= password= sslmode=require' + PUBLICATION ; +``` + +| Parameter | Description | +|---|---| +| `host` | Publisher hostname | +| `port` | PostgreSQL connection port | +| `dbname` | Source database name on Publisher | +| `user` | Username with replication rights on Publisher | +| `password` | Password with replication rights on Publisher | +| `sslmode` | SSL encryption mode | +| `publication_name` | Publication name on Publisher | + +{% hint style="warning" %} +After creating the Subscription, PostgreSQL performs an **initial sync** — copying all existing data from the Publisher to the Subscriber. This may take minutes to hours depending on data size. +{% endhint %} + +--- + +## Verify Replication Status + +**On Publisher** — check connected Subscriptions: + +```sql +SELECT application_name, state, sent_lsn, write_lsn, flush_lsn, replay_lsn +FROM pg_stat_replication; +``` + +**On Subscriber** — check Subscription status: + +```sql +SELECT subname, pid, received_lsn, last_msg_receipt_time +FROM pg_stat_subscription; +``` + +Replication is working correctly when `state = streaming` on the Publisher and, on the Subscriber, `pid` is non-`NULL` with `received_lsn` advancing. + +--- + +## Result + +Once complete, data from the tables in your Publication on the Publisher will be continuously synchronized to the Subscriber in real time. All changes (INSERT, UPDATE, DELETE) are applied automatically. + +| I want to... | Go to | +|---|---| +| Set up CDC with Debezium | [Set Up CDC with Debezium](set-up-cdc-with-debezium.md) | +| View cluster configuration parameters | [PostgreSQL Cluster Parameters](postgresql-cluster-parameters.md) | diff --git a/English/vdb/relational-database-service-rds/postgresql/postgresql-cluster/postgresql-cluster-parameters.md b/English/vdb/relational-database-service-rds/postgresql/postgresql-cluster/postgresql-cluster-parameters.md index d2c618a3..cf0144cc 100644 --- a/English/vdb/relational-database-service-rds/postgresql/postgresql-cluster/postgresql-cluster-parameters.md +++ b/English/vdb/relational-database-service-rds/postgresql/postgresql-cluster/postgresql-cluster-parameters.md @@ -9,13 +9,28 @@ This page lists the parameters that can be customized through a **DB Configurati * All parameters in the list are modifiable. {% endhint %} +{% hint style="warning" %} +**Memory note**: Many parameters directly affect total RAM consumed by PostgreSQL. Setting values too high relative to the node's RAM can cause PostgreSQL to be **OOMKilled**. + +**Parameters that affect memory:** + +* `max_connections` — when active queries are running, memory increases due to `work_mem` allocated per sort/hash operation, multiplied by the number of concurrent connections +* `shared_buffers` — allocates shared memory at PostgreSQL start and **does not return it to the OS** for the lifetime of the process; setting it too large squeezes the OS page cache and reduces I/O efficiency +* `work_mem` — multiplied by the number of concurrent connections **and** the number of sort/hash operations per query; total actual usage can be very large when many complex queries run in parallel +* `temp_buffers` — temp table buffer per session, multiplied by `max_connections` +* `max_worker_processes` — each background worker consumes additional memory +* `max_wal_senders` — each WAL sender process requires additional memory + +Choose values appropriate for the RAM of the node flavour in use. +{% endhint %} + *** ### Connections | Parameter | Default Value | Allowed Values | Type | Unit | Description | Restart Required | | --- | --- | --- | --- | --- | --- | --- | -| `max_connections` | 100 | 14 - 65536 | integer | | Maximum number of concurrent connections to the database | **Yes** | +| `max_connections` | 100 | 25 - 2000 | integer | | Maximum number of concurrent connections to the database | **Yes** | ### Memory & Buffers @@ -80,7 +95,16 @@ This page lists the parameters that can be customized through a **DB Configurati | Parameter | Default Value | Allowed Values | Type | Unit | Description | Restart Required | | --- | --- | --- | --- | --- | --- | --- | -| `max_worker_processes` | 32 | 0 - 65536 | integer | | Maximum number of background worker processes | **Yes** | +| `max_worker_processes` | 32 | 2 - 65536 | integer | | Maximum number of background worker processes | **Yes** | + +### Replication & WAL + +| Parameter | Default Value | Allowed Values | Type | Unit | Description | Restart Required | +| --- | --- | --- | --- | --- | --- | --- | +| `wal_level` | replica | `replica` / `logical` | string | | Level of information written to WAL. Set to `logical` to use Logical Replication or CDC | **Yes** | +| `max_wal_senders` | 10 | 10 - 65536 | integer | | Maximum number of WAL sender processes, used for streaming replication and CDC | **Yes** | +| `max_wal_size` | 2048 | 32 - 2147483647 | integer | MB | Maximum WAL size before triggering a checkpoint | No | +| `checkpoint_timeout` | 300 | 30 - 86400 | integer | s | Maximum time between two automatic checkpoints | No | ### Transactions & Locking diff --git a/English/vdb/relational-database-service-rds/postgresql/set-up-cdc-with-debezium.md b/English/vdb/relational-database-service-rds/postgresql/set-up-cdc-with-debezium.md new file mode 100644 index 00000000..5ce0aecf --- /dev/null +++ b/English/vdb/relational-database-service-rds/postgresql/set-up-cdc-with-debezium.md @@ -0,0 +1,223 @@ +# Set Up CDC with Debezium + +> This guide helps you configure **Change Data Capture (CDC)** from a vDB PostgreSQL Cluster to external systems — Kafka, data pipelines, search indexes — using the **Debezium PostgreSQL Connector**. + +--- + +## Prerequisites + +- A PostgreSQL Cluster on vDB (**version 16 or 17**). +- The user creating the Publication must be the owner of the tables, or contact GreenNode Support to create a `FOR ALL TABLES` Publication. + +--- + +## What is CDC and How Does it Differ from Logical Replication? + +CDC captures all data changes (INSERT, UPDATE, DELETE) from PostgreSQL and streams them to external systems in real time. + +![CDC architecture with Debezium](../../../../.gitbook/assets/vdb-cdc-debezium-architecture.png) + +| | Logical Replication | CDC (Debezium) | +|---|---|---| +| Data destination | Another PostgreSQL Cluster | Kafka, data pipeline, etc. | +| Who creates Replication Slot? | PostgreSQL automatically | Debezium on startup | +| Slot cleanup on stop | PostgreSQL automatically | **Must clean up manually** | + +--- + +## Step 1: Request CDC Activation and Receive Credentials + +Contact **GreenNode Support** to request CDC activation on your cluster. GreenNode Support will create a dedicated user and provide you with a **username** and **password** to configure the Debezium connector. + +To change the replication user password, run the following command on the cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +When managing replication slots, do not delete or modify replication slots that do not belong to you. These slots may belong to the system or other Subscriptions — accidentally dropping one may impact the system. +{% endhint %} + +--- + +## Step 2: Check and Configure PostgreSQL Parameters + +CDC requires three PostgreSQL parameters to be correctly configured on the source cluster. If not configured, Debezium will fail to connect and adding new replicas from the portal may also fail. + +| Parameter | Required value | Description | +|---|---|---| +| `wal_level` | `logical` | Required — default is `replica`, which is not sufficient for CDC | +| `max_replication_slots` | ≥ total slots needed | Total replication slots for all replicas, subscriptions, and CDC connectors | +| `max_wal_senders` | ≥ total senders needed | Total WAL sender processes (typically equals `max_replication_slots`) | + +**How to calculate `max_replication_slots` and `max_wal_senders`:** + +| Component | Slots + senders needed | +|---|---| +| Each replica node in the cluster | 1 + 1 | +| Each Subscription (logical replication) | 1 + 1 | +| Each CDC connector (Debezium) | 1 + 1 | + +**Example:** 3-node cluster (2 replicas) + 1 CDC connector → `max_replication_slots = 3`, `max_wal_senders = 3`. + +{% hint style="warning" %} +Changing `wal_level`, `max_replication_slots`, and `max_wal_senders` requires a **cluster restart**. Update all three parameters at the same time to trigger only one restart. See [PostgreSQL Cluster Parameters](postgresql-cluster-parameters.md) for instructions. +{% endhint %} + +--- + +## Step 3: Create a Publication + +A **Publication** defines the set of tables that Debezium will monitor. You must create it before configuring the connector. + +1. Connect to the PostgreSQL Cluster using an account with owner rights on the tables to capture. +2. Create a Publication for the tables to capture: + +```sql +CREATE PUBLICATION my_cdc_pub FOR TABLE public.orders, public.products; +``` + +{% hint style="info" %} +To use `FOR ALL TABLES`, contact **GreenNode Support** — this requires superuser privileges on the cluster. +{% endhint %} + +3. Verify the Publication: + +```sql +SELECT pubname, puballtables, pubinsert, pubupdate, pubdelete +FROM pg_publication; +``` + +--- + +## Step 4: Configure the Debezium Connector + +**Kafka Connect** is the framework (bundled with Kafka) for running *connectors* — processes that move data between Kafka and external systems. Connectors are loaded into Kafka Connect as JSON configuration and managed via **REST API**. + +The **Debezium PostgreSQL Connector** runs as a *source connector* inside Kafka Connect: it maintains a connection to the source cluster, watches for data changes in the database, and pushes each change as an event to the corresponding Kafka topic. + +Use the **username and password provided by GreenNode** (replication user) to configure the Debezium PostgreSQL Connector: + +```json +{ + "name": "", + "config": { + "connector.class": "io.debezium.connector.postgresql.PostgresConnector", + "database.hostname": "", + "database.port": "5432", + "database.user": "", + "database.password": "", + "database.dbname": "", + "topic.prefix": "", + "plugin.name": "pgoutput", + "publication.name": "my_cdc_pub", + "slot.name": "", + "table.include.list": "public.orders,public.products", + "snapshot.mode": "initial" + } +} +``` + +| Parameter | Description | +|---|---| +| `database.hostname` | Hostname provided by GreenNode | +| `database.port` | PostgreSQL connection port | +| `database.user` | Username provided by GreenNode | +| `database.password` | Password provided by GreenNode | +| `database.dbname` | Source database name | +| `topic.prefix` | Prefix for Kafka topic names. Each table is published to `..` — for example: prefix `pg-cdc` → topic `pg-cdc.public.orders` | +| `plugin.name` | Logical decoding plugin (built-in since PG 10, no extension needed) | +| `publication.name` | Name of the Publication created in Step 3 | +| `slot.name` | Replication slot name — use a meaningful name for easier management | +| `table.include.list` | List of tables to capture (format: `schema.table`) | +| `snapshot.mode` | Snapshot mode when the connector starts. In the example, `initial` snapshots all existing data on first startup then switches to streaming WAL. | + +See all options at [Debezium PostgreSQL Connector — Snapshot properties](https://debezium.io/documentation/reference/stable/connectors/postgresql.html#postgresql-connector-snapshot-properties). + +{% hint style="info" %} +`plugin.name: pgoutput` is built into PostgreSQL since version 10. No additional extension installation is required. +{% endhint %} + +--- + +## Step 5: Register the Connector via Kafka Connect REST API + +Register the connector with: + +```bash +curl -X POST http://:8083/connectors \ + -H "Content-Type: application/json" \ + -d @connector-config.json +``` + +Check the connector status: + +```bash +curl -s http://:8083/connectors//status +``` + +The connector is running normally when both the connector and task `state` are `RUNNING`. + +--- + +## Step 6: Monitor the Replication Slot + +{% hint style="warning" %} +Unlike Logical Replication, **Debezium does not delete the Replication Slot when it stops**. If the connector crashes or is removed without cleaning up the slot, the slot continues holding WAL indefinitely → disk full → cluster crash. +{% endhint %} + +Periodically check the Replication Slot status by connecting to the PostgreSQL Cluster and running: + +```sql +SELECT + slot_name, + active, + pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS wal_lag +FROM pg_replication_slots; +``` + +When you no longer need the connector, **stop or delete the connector first** (so the slot becomes inactive), **then drop the slot** — a slot that is still active cannot be dropped: + +```sql +SELECT pg_drop_replication_slot(''); +``` + +--- + +## Actions to Avoid + +{% hint style="warning" %} +The following actions may cause data loss or disrupt the CDC pipeline. +{% endhint %} + +| Action | Risk | +|---|---| +| Delete the connector without dropping the Replication Slot first | Inactive slot → WAL accumulates → disk full → cluster crash | +| Run `pg_drop_replication_slot()` on a slot that is not yours | May drop a system slot → replication lost | + +--- + +## Result + +Once complete, Debezium captures all changes from tables in your Publication and pushes them to Kafka topics in the following format: + +``` +..
+``` + +Example: `my-cdc.public.orders` + +Check messages on Kafka using `kafka-console-consumer`: + +```bash +kafka-console-consumer \ + --bootstrap-server :9092 \ + --topic my-cdc.public.orders \ + --from-beginning +``` + +| I want to... | Go to | +|---|---| +| Configure Logical Replication between two Clusters | [Configure Logical Replication](configure-logical-replication.md) | +| View cluster configuration parameters | [PostgreSQL Cluster Parameters](postgresql-cluster-parameters.md) | diff --git a/Vietnamese/SUMMARY.md b/Vietnamese/SUMMARY.md index 1b1a048f..30590622 100644 --- a/Vietnamese/SUMMARY.md +++ b/Vietnamese/SUMMARY.md @@ -912,6 +912,8 @@ * [Cấu hình tham số cho PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/cau-hinh-tham-so-cho-cluster.md) * [Cài đặt Extension cho PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/cac-extension-duoc-ho-tro-cho-cluster.md) * [Migrate từ PostgreSQL Single sang PostgreSQL Cluster](vdb/relational-database-service-rds/postgresql/postgresql-cluster/migrate-tu-postgresql-single-sang-cluster.md) + * [Cấu hình Logical Replication](vdb/relational-database-service-rds/postgresql/cau-hinh-logical-replication.md) + * [Thiết lập CDC với Debezium](vdb/relational-database-service-rds/postgresql/thiet-lap-cdc-voi-debezium.md) * [Tài liệu tham khảo](vdb/relational-database-service-rds/reference/README.md) * [MemoryStore Database Service (MDS)](vdb/memorystore-database-service-mds/README.md) * [Redis Standalone](vdb/memorystore-database-service-mds/redis-standalone/README.md) diff --git a/Vietnamese/vdb/relational-database-service-rds/postgresql/cau-hinh-logical-replication.md b/Vietnamese/vdb/relational-database-service-rds/postgresql/cau-hinh-logical-replication.md new file mode 100644 index 00000000..081b1d8d --- /dev/null +++ b/Vietnamese/vdb/relational-database-service-rds/postgresql/cau-hinh-logical-replication.md @@ -0,0 +1,238 @@ +# Cấu hình Logical Replication cho PostgreSQL Cluster + +> Hướng dẫn này giúp bạn thiết lập **PostgreSQL Logical Replication** — sao chép thay đổi dữ liệu theo thời gian thực từ cluster nguồn (Publisher) sang cluster đích (Subscriber). Một hoặc cả hai cluster có thể nằm trên GreenNode vDB. + +--- + +## Điều kiện cần (Prerequisites) + +- Ít nhất một trong hai cluster (Publisher hoặc Subscriber) phải là PostgreSQL Cluster trên GreenNode vDB (**phiên bản 16 hoặc 17**). +- Cả hai cluster phải dùng **cùng phiên bản major** PostgreSQL. +- Người dùng thực hiện các lệnh SQL phải có quyền **owner** trên các bảng cần replicate (để tạo Publication). + +{% hint style="info" %} +GreenNode vDB hỗ trợ Logical Replication cho **PostgreSQL 16 và 17**. +{% endhint %} + +--- + +## Logical Replication hoạt động như thế nào? + +![Kiến trúc Logical Replication](../../../../.gitbook/assets/vdb-logical-replication-architecture.png) + +- **Publisher**: cluster nguồn, chứa dữ liệu gốc. Bạn tạo `PUBLICATION` để chỉ định bảng nào được phép replicate. +- **Subscriber**: cluster đích, nhận và áp dụng thay đổi. Bạn tạo `SUBSCRIPTION` để kết nối đến Publisher và kéo dữ liệu về. + +**Quá trình đồng bộ gồm hai giai đoạn:** + +1. **Initial sync (đồng bộ ban đầu)**: Ngay khi bạn tạo Subscription, PostgreSQL tự động sao chép toàn bộ dữ liệu hiện có từ Publisher sang Subscriber — bạn không cần dump và restore dữ liệu thủ công. Quá trình này có thể mất vài phút đến vài giờ tuỳ theo kích thước dữ liệu. +2. **Streaming (streaming thay đổi liên tục)**: Sau khi initial sync hoàn tất, chỉ các thay đổi phát sinh mới (INSERT, UPDATE, DELETE) được đồng bộ theo thời gian thực. + +{% hint style="info" %} +Bạn **không cần dump dữ liệu** — Logical Replication tự xử lý phần đó. Tuy nhiên bạn **phải tạo sẵn cấu trúc bảng (schema)** trên Subscriber trước khi tạo Subscription, vì PostgreSQL không tự replicate DDL. Xem hướng dẫn tại [Bước B.3](#bước-b3-tạo-bảng-trên-subscriber). +{% endhint %} + +--- + +## Phần A: vDB PostgreSQL Cluster là Publisher + +> Thực hiện các bước trong phần này nếu cluster GreenNode vDB của bạn là **nguồn dữ liệu** (Publisher). + +### Bước A.1: Yêu cầu kích hoạt + +Liên hệ **GreenNode Support** để yêu cầu kích hoạt tính năng Logical Replication trên cluster của bạn. GreenNode Support sẽ cấu hình và cung cấp **username** và **password** của user replication — thông tin này sẽ được dùng trong connection string khi Subscriber tạo Subscription. + +Để đổi password của replication user, chạy lệnh sau trên cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +Khi quản lý Subscription, không xóa hoặc chỉnh sửa các replication slot không thuộc sở hữu của bạn. Các slot này có thể thuộc về hệ thống — xóa nhầm có thể gây ảnh hưởng đến hệ thống. +{% endhint %} + +### Bước A.2: Cấu hình tham số PostgreSQL + +Logical Replication yêu cầu ba tham số PostgreSQL được cấu hình đúng trên **Publisher cluster**. + +| Tham số | Giá trị yêu cầu | Mô tả | +|---|---|---| +| `wal_level` | `logical` | Bắt buộc — mặc định là `replica`, không đủ để chạy logical replication | +| `max_replication_slots` | ≥ số slot cần dùng | Tổng số replication slot cho tất cả replica, subscription và CDC connector | +| `max_wal_senders` | ≥ số sender cần dùng | Tổng số WAL sender process (thường bằng `max_replication_slots`) | + +**Cách tính `max_replication_slots` và `max_wal_senders`:** + +| Thành phần | Slot + sender cần | +|---|---| +| Mỗi replica node trong cluster | 1 + 1 | +| Mỗi Subscription (logical replication) | 1 + 1 | +| Mỗi CDC connector (Debezium) | 1 + 1 | + +**Ví dụ:** cluster 3 node (2 replica) + 1 subscription → `max_replication_slots = 3`, `max_wal_senders = 3`. + +{% hint style="warning" %} +Thay đổi `wal_level`, `max_replication_slots` và `max_wal_senders` yêu cầu **khởi động lại cluster**. Nên cập nhật cả ba tham số cùng một lần để chỉ gây một lần restart. Xem hướng dẫn tại [Cấu hình tham số cho Cluster](cau-hinh-tham-so-cho-cluster.md). +{% endhint %} + +### Bước A.3: Tạo Publication + +1. Kết nối đến **Publisher cluster** bằng tài khoản có quyền **owner** trên các bảng cần replicate. +2. Tạo Publication cho các bảng cần replicate: + +```sql +-- Replicate các bảng cụ thể +CREATE PUBLICATION FOR TABLE orders, products; +``` + +{% hint style="info" %} +Nếu bạn cần tạo publication `FOR ALL TABLES`, liên hệ **GreenNode Support** để được hỗ trợ. +{% endhint %} + +3. Kiểm tra Publication đã được tạo: + +```sql +SELECT pubname, puballtables, pubinsert, pubupdate, pubdelete +FROM pg_publication; +``` + +--- + +## Phần B: vDB PostgreSQL Cluster là Subscriber + +> Thực hiện các bước trong phần này nếu cluster GreenNode vDB của bạn là **đích nhận dữ liệu** (Subscriber). + +### Bước B.1: Yêu cầu kích hoạt tính năng Logical Replication + +Liên hệ **GreenNode Support** để yêu cầu kích hoạt tính năng Logical Replication trên cluster của bạn. GreenNode Support sẽ cấu hình và cung cấp **username** và **password** của user replication — thông tin này sẽ được dùng trong connection string khi Subscriber tạo Subscription. + +Để đổi password của replication user, chạy lệnh sau trên cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +Khi quản lý Subscription, không xóa hoặc chỉnh sửa các replication slot không thuộc sở hữu của bạn. Các slot này có thể thuộc về hệ thống — xóa nhầm có thể gây ảnh hưởng đến hệ thống. +{% endhint %} + +### Bước B.2: Cấp quyền CREATE trên schema và database đích + +Kết nối đến **Subscriber cluster** bằng tài khoản **owner** của schema và database đích, sau đó chạy các lệnh sau: + +```sql +-- Cấp quyền CREATE trên database (bắt buộc để chạy CREATE SUBSCRIPTION) +GRANT CREATE ON DATABASE TO ; + +-- Cấp quyền USAGE và CREATE trên schema +GRANT USAGE ON SCHEMA TO ; +GRANT CREATE ON SCHEMA TO ; +``` + +{% hint style="info" %} +`` ở đây là tài khoản dùng để chạy `CREATE TABLE` (Bước B.3) và `CREATE SUBSCRIPTION` (Bước B.4) — không phải replication user trong CONNECTION string (được GreenNode cung cấp ở Bước B.1). +{% endhint %} + +### Bước B.3: Tạo bảng trên Subscriber + +Logical Replication **không tự tạo bảng** trên Subscriber. Trước khi tạo Subscription, bạn phải tạo schema và bảng tương ứng trên Subscriber. + +{% hint style="info" %} +**Gợi ý:** Thay vì viết lại thủ công, bạn có thể dùng `pg_dump --schema-only` để dump cấu trúc bảng từ Publisher, kiểm tra file, rồi áp dụng lên Subscriber bằng `psql -f`. +{% endhint %} + +```bash +# Bước 1: dump schema từ Publisher ra file +pg_dump \ + --schema-only \ + --table= \ + -h \ + -U \ + -d \ + -f schema.sql + +# Bước 2: kiểm tra nội dung file trước khi apply + +# Bước 3: áp dụng lên Subscriber +psql \ + -h \ + -U \ + -d \ + -f schema.sql +``` + +Nếu muốn dump nhiều bảng, thêm `--table` cho từng bảng. Bỏ flag `--table` để dump toàn bộ schema. + +**Hoặc tạo bảng thủ công:** + +```sql +-- Ví dụ: tạo bảng orders trên Subscriber +CREATE TABLE orders ( + id serial PRIMARY KEY, + product text NOT NULL, + qty int NOT NULL, + ts timestamptz DEFAULT now() +); +``` + +{% hint style="warning" %} +Schema và kiểu dữ liệu của bảng trên Subscriber phải **khớp hoàn toàn** với Publisher. Nếu không khớp, Subscription có thể sẽ báo lỗi. +{% endhint %} + +### Bước B.4: Tạo Subscription + +1. Kết nối đến **Subscriber cluster** bằng tài khoản GreenNode cung cấp. + +2. Tạo Subscription: + +```sql +CREATE SUBSCRIPTION my_subscription + CONNECTION 'host= port=5432 dbname= user= password= sslmode=require' + PUBLICATION ; +``` + +| Tham số | Mô tả | +|---|---| +| `host` | Hostname của Publisher | +| `port` | Port kết nối PostgreSQL | +| `dbname` | Tên database nguồn trên Publisher | +| `user` | Username có quyền replication trên Publisher | +| `password` | Password có quyền replication trên Publisher | +| `sslmode` | Chế độ mã hóa SSL | +| `publication_name` | Tên publication trên Publisher | + +{% hint style="warning" %} +Sau khi tạo Subscription, PostgreSQL sẽ thực hiện **initial sync** — sao chép toàn bộ dữ liệu hiện có từ Publisher sang Subscriber. Quá trình này có thể mất vài phút đến vài giờ tuỳ theo kích thước dữ liệu. +{% endhint %} + +--- + +## Kiểm tra trạng thái Replication + +**Trên Publisher** — xem Subscription đang kết nối: + +```sql +SELECT application_name, state, sent_lsn, write_lsn, flush_lsn, replay_lsn +FROM pg_stat_replication; +``` + +**Trên Subscriber** — xem trạng thái Subscription: + +```sql +SELECT subname, pid, received_lsn, last_msg_receipt_time +FROM pg_stat_subscription; +``` + +Khi `state = streaming` trên Publisher, và trên Subscriber `pid` khác `NULL` cùng `received_lsn` tăng dần, replication đang hoạt động bình thường. + +--- + +## Kết quả + +Sau khi hoàn thành, dữ liệu từ các bảng trong Publication trên Publisher sẽ được tự động đồng bộ sang Subscriber theo thời gian thực. Mọi thay đổi (INSERT, UPDATE, DELETE) đều được áp dụng. + +| Tôi muốn tiếp theo... | Đi đến | +|---|---| +| Thiết lập CDC với Debezium | [Thiết lập CDC với Debezium](thiet-lap-cdc-voi-debezium.md) | +| Xem các tham số cấu hình Cluster | [Cấu hình tham số cho Cluster](cau-hinh-tham-so-cho-cluster.md) | \ No newline at end of file diff --git a/Vietnamese/vdb/relational-database-service-rds/postgresql/postgresql-cluster/cau-hinh-tham-so-cho-cluster.md b/Vietnamese/vdb/relational-database-service-rds/postgresql/postgresql-cluster/cau-hinh-tham-so-cho-cluster.md index 6c89e728..e8e202a1 100644 --- a/Vietnamese/vdb/relational-database-service-rds/postgresql/postgresql-cluster/cau-hinh-tham-so-cho-cluster.md +++ b/Vietnamese/vdb/relational-database-service-rds/postgresql/postgresql-cluster/cau-hinh-tham-so-cho-cluster.md @@ -9,13 +9,28 @@ Trang này liệt kê các parameter có thể tùy chỉnh thông qua **DB Conf * Tất cả parameter trong danh sách đều có thể chỉnh sửa (modifiable). {% endhint %} +{% hint style="warning" %} +**Lưu ý về memory**: Nhiều parameter ảnh hưởng trực tiếp đến tổng lượng RAM mà PostgreSQL tiêu thụ. Đặt giá trị quá cao so với RAM của node có thể khiến PostgreSQL bị **OOMKilled**. + +**Các parameter ảnh hưởng đến memory:** + +* `max_connections` — khi có active query, memory tăng thêm do `work_mem` cấp phát per sort/hash operation và nhân với số connection đồng thời +* `shared_buffers` — cấp phát shared memory ngay khi PostgreSQL start và **không trả lại cho OS** trong suốt vòng đời process; đặt quá lớn sẽ chèn ép OS page cache, làm giảm hiệu quả I/O +* `work_mem` — nhân với số connection đồng thời **và** số sort/hash operation per query; tổng thực tế có thể rất lớn khi nhiều query phức tạp chạy song song +* `temp_buffers` — buffer temp table per session, nhân với `max_connections` +* `max_worker_processes` — mỗi background worker tiêu thụ thêm memory +* `max_wal_senders` — mỗi WAL sender process cần thêm memory + +Hãy chọn giá trị phù hợp với RAM của flavour node đang dùng. +{% endhint %} + *** ### Connections | Parameter | Giá trị mặc định | Giá trị cho phép | Kiểu | Unit | Công dụng | Restart Required | | --- | --- | --- | --- | --- | --- | --- | -| `max_connections` | 100 | 14 - 65536 | integer | | Số lượng tối đa các connection đồng thời truy cập đến database | **Có** | +| `max_connections` | 100 | 25 - 2000 | integer | | Số lượng tối đa các connection đồng thời truy cập đến database | **Có** | ### Memory & Buffers @@ -80,7 +95,16 @@ Trang này liệt kê các parameter có thể tùy chỉnh thông qua **DB Conf | Parameter | Giá trị mặc định | Giá trị cho phép | Kiểu | Unit | Công dụng | Restart Required | | --- | --- | --- | --- | --- | --- | --- | -| `max_worker_processes` | 32 | 0 - 65536 | integer | | Số tiến trình background tối đa | **Có** | +| `max_worker_processes` | 32 | 2 - 65536 | integer | | Số tiến trình background tối đa | **Có** | + +### Replication & WAL + +| Parameter | Giá trị mặc định | Giá trị cho phép | Kiểu | Unit | Công dụng | Restart Required | +| --- | --- | --- | --- | --- | --- | --- | +| `wal_level` | replica | `replica` / `logical` | string | | Mức độ thông tin ghi vào WAL. Đặt `logical` để dùng Logical Replication hoặc CDC | **Có** | +| `max_wal_senders` | 10 | 10 - 65536 | integer | | Số lượng WAL sender process tối đa, dùng cho streaming replication và CDC | **Có** | +| `max_wal_size` | 2048 | 32 - 2147483647 | integer | MB | Kích thước WAL tối đa trước khi trigger checkpoint | Không | +| `checkpoint_timeout` | 300 | 30 - 86400 | integer | s | Khoảng thời gian tối đa giữa hai checkpoint tự động | Không | ### Transactions & Locking diff --git a/Vietnamese/vdb/relational-database-service-rds/postgresql/thiet-lap-cdc-voi-debezium.md b/Vietnamese/vdb/relational-database-service-rds/postgresql/thiet-lap-cdc-voi-debezium.md new file mode 100644 index 00000000..8856dc0b --- /dev/null +++ b/Vietnamese/vdb/relational-database-service-rds/postgresql/thiet-lap-cdc-voi-debezium.md @@ -0,0 +1,223 @@ +# Thiết lập CDC với Debezium + +> Hướng dẫn này giúp bạn cấu hình **Change Data Capture (CDC)** từ PostgreSQL Cluster vDB sang external systems — Kafka, data pipeline, search index — sử dụng **Debezium PostgreSQL Connector**. + +--- + +## Điều kiện cần (Prerequisites) + +- Đã có PostgreSQL Cluster trên vDB (**phiên bản 16 hoặc 17**). +- Người dùng thực hiện tạo Publication phải là owner của bảng hoặc liên hệ GreenNode Support để tạo `FOR ALL TABLES`. + +--- + +## CDC là gì và khác gì Logical Replication? + +CDC capture toàn bộ thay đổi dữ liệu (INSERT, UPDATE, DELETE) từ PostgreSQL và đẩy ra external systems theo thời gian thực. + +![Kiến trúc CDC với Debezium](../../../../.gitbook/assets/vdb-cdc-debezium-architecture.png) + +| | Logical Replication | CDC (Debezium) | +|---|---|---| +| Đích nhận dữ liệu | PostgreSQL khác | Kafka, data pipeline, v.v. | +| Ai tạo Replication Slot? | PostgreSQL tự động | Debezium tạo khi khởi động | +| Cleanup Slot khi dừng | PostgreSQL tự động | **Phải xóa thủ công** | + +--- + +## Bước 1: Yêu cầu kích hoạt CDC và nhận thông tin đăng nhập + +Liên hệ **GreenNode Support** để yêu cầu kích hoạt tính năng CDC trên cluster của bạn. GreenNode Support sẽ tạo user chuyên dụng và cung cấp lại cho bạn **username** và **password** để cấu hình Debezium connector. + +Để đổi password của replication user, chạy lệnh sau trên cluster: + +```sql +ALTER USER PASSWORD ''; +``` + +{% hint style="warning" %} +Trong quá trình quản lý replication slot, không xóa hoặc chỉnh sửa các replication slot không thuộc sở hữu của bạn. Các slot này có thể thuộc về hệ thống — xóa nhầm có thể gây ảnh hưởng đến hệ thống. +{% endhint %} + +--- + +## Bước 2: Kiểm tra và cấu hình tham số PostgreSQL + +CDC yêu cầu ba tham số PostgreSQL được cấu hình đúng trên cluster nguồn. Nếu chưa được cấu hình, Debezium sẽ không thể kết nối và việc thêm replica mới trên portal cũng có thể thất bại. + +| Tham số | Giá trị yêu cầu | Mô tả | +|---|---|---| +| `wal_level` | `logical` | Bắt buộc — mặc định là `replica`, không đủ để chạy CDC | +| `max_replication_slots` | ≥ số slot cần dùng | Tổng số replication slot cho tất cả replica, subscription và CDC connector | +| `max_wal_senders` | ≥ số sender cần dùng | Tổng số WAL sender process (thường bằng `max_replication_slots`) | + +**Cách tính `max_replication_slots` và `max_wal_senders`:** + +| Thành phần | Slot + sender cần | +|---|---| +| Mỗi replica node trong cluster | 1 + 1 | +| Mỗi Subscription (logical replication) | 1 + 1 | +| Mỗi CDC connector (Debezium) | 1 + 1 | + +**Ví dụ:** cluster 3 node (2 replica) + 1 CDC connector → `max_replication_slots = 3`, `max_wal_senders = 3`. + +{% hint style="warning" %} +Thay đổi `wal_level`, `max_replication_slots` và `max_wal_senders` yêu cầu **khởi động lại cluster**. Nên cập nhật cả ba tham số cùng một lần để chỉ gây một lần restart. Xem hướng dẫn tại [Cấu hình tham số cho Cluster](cau-hinh-tham-so-cho-cluster.md). +{% endhint %} + +--- + +## Bước 3: Tạo Publication + +**Publication** định nghĩa tập hợp bảng mà Debezium sẽ theo dõi. Bạn cần tạo Publication trước khi cấu hình connector. + +1. Kết nối đến PostgreSQL Cluster bằng tài khoản có quyền owner trên các bảng cần capture. +2. Tạo Publication cho các bảng cần capture: + +```sql +CREATE PUBLICATION my_cdc_pub FOR TABLE public.orders, public.products; +``` + +{% hint style="info" %} +Nếu cần `FOR ALL TABLES`, liên hệ **GreenNode Support** để được hỗ trợ — tính năng này yêu cầu quyền superuser trên cluster. +{% endhint %} + +3. Kiểm tra Publication: + +```sql +SELECT pubname, puballtables, pubinsert, pubupdate, pubdelete +FROM pg_publication; +``` + +--- + +## Bước 4: Cấu hình Debezium Connector + +**Kafka Connect** là framework (đi kèm Kafka) dùng để chạy các *connector* — tiến trình di chuyển dữ liệu giữa Kafka và hệ thống bên ngoài. Connector được nạp vào Kafka Connect dưới dạng cấu hình JSON và quản lý qua **REST API**. + +**Debezium PostgreSQL Connector** chạy như một *source connector* bên trong Kafka Connect: nó giữ kết nối tới cluster nguồn, theo dõi dữ liệu trong database và đẩy mỗi thay đổi thành event vào Kafka topic tương ứng. + +Sử dụng **username và password do GreenNode cung cấp** (user replication) để cấu hình Debezium PostgreSQL Connector: + +```json +{ + "name": "", + "config": { + "connector.class": "io.debezium.connector.postgresql.PostgresConnector", + "database.hostname": "", + "database.port": "5432", + "database.user": "", + "database.password": "", + "database.dbname": "", + "topic.prefix": "", + "plugin.name": "pgoutput", + "publication.name": "my_cdc_pub", + "slot.name": "", + "table.include.list": "public.orders,public.products", + "snapshot.mode": "initial" + } +} +``` + +| Tham số | Mô tả | +|---|---| +| `database.hostname` | Hostname do GreenNode cung cấp | +| `database.port` | Port kết nối PostgreSQL | +| `database.user` | Username do GreenNode cung cấp | +| `database.password` | Password do GreenNode cung cấp | +| `database.dbname` | Tên database nguồn | +| `topic.prefix` | Tiền tố cho tên Kafka topic. Mỗi bảng sẽ được publish vào topic `..
` — ví dụ: prefix `pg-cdc` → topic `pg-cdc.public.orders` | +| `plugin.name` | Plugin logical decoding (built-in từ PG 10, không cần cài thêm) | +| `publication.name` | Tên Publication đã tạo ở Bước 3 | +| `slot.name` | Tên replication slot — đặt tên có ý nghĩa để dễ quản lý | +| `table.include.list` | Danh sách bảng cần capture (format: `schema.table`) | +| `snapshot.mode` | Chế độ snapshot khi connector khởi động (xem bảng bên dưới). Trong ví dụ, mode `initial` dùng để snapshot toàn bộ dữ liệu hiện có khi khởi động lần đầu, sau đó chuyển sang streaming WAL | + +Xem đầy đủ các tùy chọn tại [Debezium PostgreSQL Connector — Snapshot properties](https://debezium.io/documentation/reference/stable/connectors/postgresql.html#postgresql-connector-snapshot-properties). + +{% hint style="info" %} +`plugin.name: pgoutput` là plugin tích hợp sẵn trong PostgreSQL từ phiên bản 10. Bạn không cần cài thêm extension nào. +{% endhint %} + +--- + +## Bước 5: Đăng ký connector qua Kafka Connect REST API + +Đăng ký connector bằng lệnh: + +```bash +curl -X POST http://:8083/connectors \ + -H "Content-Type: application/json" \ + -d @connector-config.json +``` + +Kiểm tra trạng thái connector: + +```bash +curl -s http://:8083/connectors//status +``` + +Connector đang hoạt động bình thường khi `state` của connector và task đều là `RUNNING`. + +--- + +## Bước 6: Monitor Replication Slot + +{% hint style="warning" %} +Khác với Logical Replication, **Debezium không tự xóa Replication Slot khi dừng**. Nếu connector crash hoặc bị xóa mà không cleanup slot, slot sẽ tiếp tục giữ WAL → disk đầy → cluster crash. +{% endhint %} + +Định kỳ kiểm tra trạng thái Replication Slot bằng cách kết nối vào PostgreSQL Cluster và chạy: + +```sql +SELECT + slot_name, + active, + pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS wal_lag +FROM pg_replication_slots; +``` + +Khi không còn dùng connector, **dừng hoặc xóa connector trước** (để slot chuyển sang trạng thái inactive), **sau đó mới drop slot** — không thể drop một slot đang active: + +```sql +SELECT pg_drop_replication_slot(''); +``` + +--- + +## Những điều cần lưu ý + +{% hint style="warning" %} +Các hành động dưới đây có thể gây ảnh hưởng đến hệ thống hoặc làm gián đoạn CDC pipeline. +{% endhint %} + +| Hành động | Rủi ro | +|---|---| +| Xóa connector mà không xóa Replication Slot trước | Slot inactive → WAL tích lũy → disk đầy → cluster crash | +| Chạy `pg_drop_replication_slot()` trên slot không phải của bạn | Có thể xóa slot của hệ thống → có thể gây ảnh hưởng đến hệ thống| + +--- + +## Kết quả + +Sau khi hoàn thành, Debezium sẽ capture toàn bộ thay đổi từ các bảng trong Publication và đẩy ra Kafka topic theo format: + +``` +..
+``` + +Ví dụ: `my-cdc.public.orders` + +Kiểm tra message trên Kafka bằng `kafka-console-consumer`: + +```bash +kafka-console-consumer \ + --bootstrap-server :9092 \ + --topic my-cdc.public.orders \ + --from-beginning +``` + +| Tôi muốn tiếp theo... | Đi đến | +|---|---| +| Cấu hình Logical Replication giữa hai Cluster | [Cấu hình Logical Replication](cau-hinh-logical-replication.md) | +| Xem các tham số cấu hình Cluster | [Cấu hình tham số cho Cluster](cau-hinh-tham-so-cho-cluster.md) |