使用 AlloyDB Omni 进行逻辑复制

1. 简介

本 Codelab 介绍了如何在独立的 AlloyDB Omni 实例之间配置逻辑复制。您将在单个 Compute Engine 虚拟机上部署多个 AlloyDB Omni 实例,并使用 pglogical 扩展程序在它们之间设置复制。

在单个节点上运行多个实例对于开发、测试或模拟复制环境非常有用。在本 Codelab 结束时,您将拥有一个可正常运行的复制设置,其中一个实例充当提供方,另一个实例充当订阅方。

前提条件

  • 从 Google Cloud 控制台访问 Google Cloud 项目和 Cloud Shell。
  • 已安装并配置 Google Cloud SDK (gcloud)。如需详细了解如何安装 gcloud,请参阅 gcloud-install

学习内容

  • 了解如何使用 gcloud 为多个 AlloyDB Omni 实例创建和准备 Compute Engine 虚拟机。
  • 了解如何安装 AlloyDB Omni RPM。
  • 了解如何使用 systemd 模板配置和初始化多个 AlloyDB Omni 实例。
  • 了解如何使用 pglogical 在 AlloyDB Omni 实例之间配置逻辑复制。
  • 了解如何通过将数据从提供方复制到订阅方来验证复制。

所需条件

  • 获取 AlloyDB Omni RPM 的网址链接。这些链接会发送到您的电子邮件,其中包括指向仓库网址服务器的链接。初始化以下环境变量,以便在 Codelab 期间随时使用该网址。
    export ALLOYDB_OMNI_REPOSITORY_URL="..."
    
  • 一个可正常运行的终端,并且可以访问 Google Cloud。您可以使用 Cloud Shell 来实现这一目的。

2. 设置和要求

项目设置

创建 Google Cloud 项目

  1. 在 Google Cloud 控制台 的项目选择器页面上,选择或创建一个 Google Cloud 项目。
  2. 确保您的云项目已启用结算功能。了解如何检查项目是否已启用结算功能。

启动 Cloud Shell

虽然您可以通过笔记本电脑远程操作 Google Cloud,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

用于激活 Cloud Shell 的图标

  1. 打开 Google Cloud 控制台,然后点击右上角工具栏中的 Cloud Shell 图标。您还可以通过以下任一方式打开 Cloud Shell:
    • 如果您使用的是 Google Cloud 控制台,请按 G,然后按 S。
    • 点击此链接。

Cloud Shell 通常需要几分钟时间来预配并连接到环境。此操作完成后,您会看到类似于以下内容的输出:

Google Cloud Shell 终端显示环境已连接

3. 创建 Compute Engine 虚拟机

在本部分中,您将使用 gcloud 命令行工具创建单个 Compute Engine 虚拟机 (VM)。使用与 AlloyDB Omni RPM 完全兼容的 Rocky Linux 9 映像。

  1. 为您的项目 ID、虚拟机名称、可用区和地区定义环境变量。
    export PROJECT="your-project-id"
    export INSTANCE_NAME="alloydb-omni-multi-vm"
    export ZONE="us-central1-c"
    export REGION="us-central1"
    
  2. 使用您的 Google Cloud 账号登录,然后配置默认项目。
    gcloud auth login
    gcloud config set project $PROJECT
    
  3. 如需允许使用 Identity-Aware Proxy (IAP) 通过 SSH 连接到您的虚拟机,请创建防火墙规则。
    gcloud compute firewall-rules create allow-ssh-alloydb-omni \
        --project=$PROJECT \
        --direction=INGRESS \
        --action=allow \
        --rules=tcp:22 \
        --source-ranges="0.0.0.0/0"
    
  4. 由于虚拟机是在没有公共 IP 地址的情况下创建的,因此请配置 Cloud Router 路由器和 Cloud NAT 网关,以允许虚拟机访问外部软件包仓库并下载所需的软件。
    gcloud compute routers create alloydb-omni-router \
        --project=$PROJECT \
        --network=default \
        --region=$REGION
    
    gcloud compute routers nats create alloydb-omni-nat \
        --project=$PROJECT \
        --router=alloydb-omni-router \
        --region=$REGION \
        --nat-all-subnet-ip-ranges \
        --auto-allocate-nat-external-ips
    
  5. 验证您的虚拟私有云 (VPC) 网络是否具有有效的默认互联网网关路由。Cloud NAT 需要此路由才能将出站流量转发到互联网。
    gcloud compute routes create default-internet-route \
        --project=$PROJECT \
        --network=default \
        --destination-range=0.0.0.0/0 \
        --next-hop-gateway=default-internet-gateway
    
  6. 创建具有所需规范(16 个 vCPU、20GB 平衡永久性磁盘、Rocky Linux 9)的 Compute Engine 虚拟机实例。为了提高安全性,请使用 --no-address 标志,确保未为虚拟机分配公共 IP 地址。
    gcloud compute instances create $INSTANCE_NAME \
        --project=$PROJECT \
        --zone=$ZONE \
        --machine-type=n2-highmem-16 \
        --image-family=rocky-linux-9 \
        --image-project=rocky-linux-cloud \
        --boot-disk-size=20GB \
        --boot-disk-type=pd-balanced \
        --no-address
    
  7. 创建虚拟机后,验证虚拟机的状态。
    gcloud compute instances list --filter="name=$INSTANCE_NAME" --project=$PROJECT
    

4. 准备虚拟机

在本部分中,您将连接到新创建的虚拟机并准备操作系统环境。

  1. 使用 IAP 通过 SSH 连接到虚拟机。由于虚拟机没有公共 IP 地址,因此 gcloud 会自动通过 IAP 隧道传输 SSH 连接。
    gcloud compute ssh $INSTANCE_NAME --zone=$ZONE --project=$PROJECT --tunnel-through-iap
    
  2. 为基本数据目录定义环境变量。
    export BASE_PGDATA="/var/lib/alloydbomni"
    
  3. 创建基本数据目录。
    sudo mkdir -p $BASE_PGDATA
    
  4. 安装 policycoreutils-python-utils 软件包,以便配置 SELinux 政策。
    sudo dnf install -y policycoreutils-python-utils
    

5. 安装 AlloyDB Omni

准备好虚拟机后,您现在可以配置软件包仓库并安装 AlloyDB Omni RPM 软件包。

  1. 通过创建仓库配置文件,在虚拟机上配置 YUM 仓库。将 $ALLOYDB_OMNI_REPOSITORY_URL 替换为您收到的网址。
    export ALLOYDB_OMNI_REPOSITORY_URL="..."
    sudo tee /etc/yum.repos.d/alloydbomni.repo << EOF
    [alloydbomni]
    name=alloydbomni
    baseurl=$ALLOYDB_OMNI_REPOSITORY_URL
    enabled=1
    repo_gpgcheck=0
    gpgcheck=1
    gpgkey=https://dl.google.com/linux/linux_signing_key.pub
    EOF
    
  2. 更新 YUM 缓存。
    sudo yum makecache
    
  3. 安装 AlloyDB Omni RPM 软件包的第 18 版。
    sudo dnf install -y alloydbomni18
    

6. 配置多个实例

在本部分中,您将配置两个实例:inst1 和 inst2。

  1. 如需支持多个实例,请创建 systemd 模板服务文件 alloydbomni18@.service。
    sudo tee /etc/systemd/system/alloydbomni18@.service << EOF
    [Unit]
    Description=AlloyDB Omni Database server instance %I
    After=syslog.target
    After=network-online.target
    
    [Service]
    SyslogIdentifier=alloydbomni-%I
    Type=notify
    
    User=postgres
    Group=postgres
    
    # Load configuration for the instance
    EnvironmentFile=/etc/alloydbomni/%I.conf
    
    OOMScoreAdjust=-1000
    Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
    Environment=PG_OOM_ADJUST_VALUE=0
    
    ExecStartPre=/usr/lib/postgresql/18/bin/alloydbomni18-check-db-dir \${PGDATA}
    ExecStart=/usr/lib/postgresql/18/bin/postgres -D \${PGDATA}
    ExecReload=/bin/kill -HUP \$MAINPID
    
    KillMode=mixed
    KillSignal=SIGINT
    
    TimeoutSec=0
    TimeoutStartSec=0
    TimeoutStopSec=1h
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
  2. 重新加载 systemd 管理器配置,以识别新的模板服务。
    sudo systemctl daemon-reload
    
  3. 为 AlloyDB Omni 实例创建配置目录。
    sudo mkdir -p /etc/alloydbomni
    
  4. 为 inst1 配置数据目录。
    sudo tee /etc/alloydbomni/inst1.conf << EOF
    PGDATA=/var/lib/alloydbomni/inst1
    EOF
    
  5. 为 inst2 配置数据目录。
    sudo tee /etc/alloydbomni/inst2.conf << EOF
    PGDATA=/var/lib/alloydbomni/inst2
    EOF
    
  6. 为配置文件设置适当的权限。
    sudo chmod 640 /etc/alloydbomni/*.conf
    sudo chown postgres:postgres /etc/alloydbomni/*.conf
    
  7. 为这两个实例创建数据目录,并设置正确的所有权。
    sudo mkdir -p /var/lib/alloydbomni/inst1
    sudo mkdir -p /var/lib/alloydbomni/inst2
    sudo chown -R postgres:postgres /var/lib/alloydbomni
    sudo chmod 750 /var/lib/alloydbomni/inst1 /var/lib/alloydbomni/inst2
    
  8. 可选:为每个实例设置资源限制。这样可以防止一个实例占用所有虚拟机资源。为这两个实例创建 systemd 替换目录和文件。注意 :以下配置中使用的资源限制 (40%) 是示例值。请根据您的具体工作负载和虚拟机容量调整限制。对于 inst1:
    sudo mkdir -p /etc/systemd/system/alloydbomni18@inst1.service.d
    sudo tee /etc/systemd/system/alloydbomni18@inst1.service.d/override.conf << EOF
    [Service]
    CPUQuota=40%
    MemoryMax=40%
    EOF
    
    对于 inst2:
    sudo mkdir -p /etc/systemd/system/alloydbomni18@inst2.service.d
    sudo tee /etc/systemd/system/alloydbomni18@inst2.service.d/override.conf << EOF
    [Service]
    CPUQuota=40%
    MemoryMax=40%
    EOF
    

7. 初始化和准备数据库

分别初始化和准备每个数据库实例。

  1. 将 SELinux 配置为设置的宽容模式。
    sudo setenforce 0
    
    注意 :将 SELinux 设置为宽容模式会停用违规处置,因此应谨慎使用。在此 Codelab 中,此模式用于简化安装。在生产环境中,请为 AlloyDB Omni 配置适当的 SELinux 政策,以便在强制模式下运行。您可以在设置后通过运行 sudo setenforce 1 重新启用违规处置。
  2. 为 PostgreSQL postgres 管理员用户定义一个安全系数高的密码。在此 Codelab 中,此密码用于这两个实例。
    export PGPASSWORD="YourStrongPassword123!"
    
    注意 :在此 Codelab 中,为了简单起见,我们使用了在命令行中使用环境变量传递密码(例如 PGPASSWORD=$PGPASSWORD),但这样做可能会在进程列表中公开密码。在生产环境中,请使用更安全的方法,例如 .pgpass 文件或 Secret Manager。

设置 inst1

  1. 初始化 inst1 的数据库目录。
    sudo PGPASSWORD=$PGPASSWORD \
      PGDATA=/var/lib/alloydbomni/inst1 \
      /usr/lib/postgresql/18/bin/alloydbomni18-setup initdb
    
  2. 通过更新 postgresql.conf 文件,将实例配置为监听端口 5433。
    sudo sed -i \
      "s/^#*[[:space:]]*port[[:space:]]*=[[:space:]]*[0-9]*/port = 5433/" \
      /var/lib/alloydbomni/inst1/postgresql.conf
    
  3. 为 AlloyDB Omni 准备数据库实例。
    sudo PGPASSWORD=$PGPASSWORD \
      PGDATA=/var/lib/alloydbomni/inst1 \
      PGPORT=5433 \
      /usr/lib/postgresql/18/bin/alloydbomni18-setup preparedb
    

设置 inst2

  1. 初始化 inst2 的数据库目录。
    sudo PGPASSWORD=$PGPASSWORD \
      PGDATA=/var/lib/alloydbomni/inst2 \
      /usr/lib/postgresql/18/bin/alloydbomni18-setup initdb
    
  2. 将实例配置为监听端口 5434。
    sudo sed -i \
      "s/^#*[[:space:]]*port[[:space:]]*=[[:space:]]*[0-9]*/port = 5434/" \
      /var/lib/alloydbomni/inst2/postgresql.conf
    
  3. 准备数据库实例。
    sudo PGPASSWORD=$PGPASSWORD \
      PGDATA=/var/lib/alloydbomni/inst2 \
      PGPORT=5434 \
      /usr/lib/postgresql/18/bin/alloydbomni18-setup preparedb
    

8. 启动 AlloyDB Omni 服务

现在,您可以为这两个实例启动 systemd 服务。

  1. 如需识别新配置和替换,请重新加载 systemd 管理器配置。
    sudo systemctl daemon-reload
    
  2. 为 inst1 启用并启动服务。
    sudo systemctl enable alloydbomni18@inst1
    sudo systemctl start alloydbomni18@inst1
    
  3. 为 inst2 启用并启动服务。
    sudo systemctl enable alloydbomni18@inst2
    sudo systemctl start alloydbomni18@inst2
    
  4. 验证这两个服务是否处于活跃状态并正在运行。
    sudo systemctl status alloydbomni18@inst1
    sudo systemctl status alloydbomni18@inst2
    
    验证这两个服务的输出是否都显示 Active: active (running)。

9. 验证 AlloyDB Omni 实例

验证这两个实例是否正常运行且相互独立。

  1. 连接到 inst1(端口 5433)。系统会提示您输入在初始化和准备数据库中配置的密码。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5433 -U postgres -W
    
  2. 运行查询以验证连接。
    postgres=# SELECT version();
    
  3. 断开与实例的连接。
    postgres=# \q
    
  4. 连接到 inst2(端口 5434)。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5434 -U postgres -W
    
  5. 运行查询以验证连接。
    postgres=# SELECT version();
    
  6. 断开与实例的连接。
    postgres=# \q
    

10. 配置 pglogical 复制

使用 pglogical 扩展程序配置这两个实例之间的逻辑复制。在此场景中,inst1 充当提供方,inst2 充当订阅方。

注意 :此 Codelab 使用 postgres 超级用户进行复制连接。在生产环境中,请创建一个具有 REPLICATION 权限的专用复制用户,并仅授予其对要复制的表的访问权限。

为 pglogical 配置实例

  1. 在 shared_preload_libraries 中启用 pglogical,并在 postgresql.conf 中为 inst1 配置其他复制参数。
    # Append pglogical to shared_preload_libraries
    sudo sed -i \
      "s/\(shared_preload_libraries\s*=\s*'\)\([^']*\)'/\1\2,pglogical'/" \
      /var/lib/alloydbomni/inst1/postgresql.conf
    
    # Append replication settings
    sudo tee -a /var/lib/alloydbomni/inst1/postgresql.conf << EOF
    wal_level = logical
    max_replication_slots = 10
    max_wal_senders = 10
    max_worker_processes = 20
    track_commit_timestamp = on
    alloydb.enable_pglogical = on
    alloydb.logical_decoding = on
    EOF
    
  2. 为 inst2 配置您为 inst1 配置的设置。
    # Append pglogical to shared_preload_libraries
    sudo sed -i \
      "s/\(shared_preload_libraries\s*=\s*'\)\([^']*\)'/\1\2,pglogical'/" \
      /var/lib/alloydbomni/inst2/postgresql.conf
    
    # Append replication settings
    sudo tee -a /var/lib/alloydbomni/inst2/postgresql.conf << EOF
    wal_level = logical
    max_replication_slots = 10
    max_wal_senders = 10
    max_worker_processes = 20
    track_commit_timestamp = on
    alloydb.enable_pglogical = on
    alloydb.logical_decoding = on
    EOF
    
  3. 如需应用配置更改,请重启这两个实例。
    sudo systemctl restart alloydbomni18@inst1
    sudo systemctl restart alloydbomni18@inst2
    

设置复制角色和表

  1. 在 inst1(提供方,端口 5433)上,创建一个复制角色和要复制的表。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5433 \
      -U postgres -d postgres -c "
      DO \$\$
      BEGIN
        IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'app_owner') THEN
          CREATE ROLE app_owner WITH LOGIN PASSWORD 'Password123';
        END IF;
      END
      \$\$;
      GRANT ALL ON SCHEMA public TO app_owner;
      CREATE TABLE IF NOT EXISTS replication_test (
          id SERIAL PRIMARY KEY,
          data TEXT,
          created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      );
      ALTER TABLE replication_test OWNER TO app_owner;
    "
    
  2. 在 inst2(订阅方,端口 5434)上,创建相同的角色和表结构。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5434 \
      -U postgres -d postgres -c "
      DO \$\$
      BEGIN
        IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'app_owner') THEN
          CREATE ROLE app_owner WITH LOGIN PASSWORD 'Password123';
        END IF;
      END
      \$\$;
      GRANT ALL ON SCHEMA public TO app_owner;
      CREATE TABLE IF NOT EXISTS replication_test (
          id SERIAL PRIMARY KEY,
          data TEXT,
          created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      );
      ALTER TABLE replication_test OWNER TO app_owner;
    "
    

配置 pglogical 节点和订阅

  1. 在 inst1 上初始化 pglogical 提供方节点。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5433 \
      -U postgres -d postgres -c "
      CREATE EXTENSION IF NOT EXISTS pglogical;
      SELECT pglogical.create_node(
          node_name := 'provider',
          dsn := 'host=127.0.0.1 port=5433 dbname=postgres user=postgres password=YourStrongPassword123!'
      );
      SELECT pglogical.replication_set_add_table('default', 'replication_test');
    "
    
  2. 在 inst2 上初始化 pglogical 订阅方节点并创建订阅。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5434 \
      -U postgres -d postgres -c "
      CREATE EXTENSION IF NOT EXISTS pglogical;
      SELECT pglogical.create_node(
          node_name := 'subscriber',
          dsn := 'host=127.0.0.1 port=5434 dbname=postgres user=postgres password=YourStrongPassword123!'
      );
      SELECT pglogical.create_subscription(
          subscription_name := 'test_subscription',
          provider_dsn := 'host=127.0.0.1 port=5433 dbname=postgres user=postgres password=YourStrongPassword123!'
      );
    "
    
    注意 :创建订阅后,初始同步可能需要一些时间才能完成。

11. 验证 pglogical 复制

通过在提供方上插入数据并在订阅方上查询数据,验证复制是否按预期运行。

  1. 验证订阅是否处于活跃状态。可能需要几秒钟才能转换为 replicating。
    /usr/lib/postgresql/18/bin/psql -t -A -h localhost -p 5434 \
      -U postgres -d postgres -c "
      SELECT status FROM pglogical.show_subscription_status() WHERE subscription_name = 'test_subscription';
      "
    
  2. 在继续之前,请确认输出显示 replicating。
  3. 在提供方 (inst1) 上插入测试行。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5433 \
      -U postgres -d postgres -c "
      INSERT INTO replication_test (data) VALUES ('Hello from replication provider!');
    "
    
  4. 如需验证数据是否已复制,请在 inst2 上查询表。
    /usr/lib/postgresql/18/bin/psql -h localhost -p 5434 \
      -U postgres -d postgres -c "SELECT * FROM replication_test;"
    
    确认您可以看到在 inst1 上插入的行。

12. 清理

清理资源。首先,销毁虚拟机上的 AlloyDB Omni 实例,然后删除 Google Cloud 资源。

销毁 AlloyDB Omni 实例

在删除虚拟机之前,您可以停止并停用服务,并移除其配置和数据,从而清理 AlloyDB Omni 实例。

  1. 停止并停用 inst1 的服务,并移除其数据和配置。
    sudo systemctl stop alloydbomni18@inst1
    sudo systemctl disable alloydbomni18@inst1
    sudo rm -rf /var/lib/alloydbomni/inst1
    sudo rm -f /etc/alloydbomni/inst1.conf
    
  2. 停止并停用 inst2 的服务,并移除其数据和配置。
    sudo systemctl stop alloydbomni18@inst2
    sudo systemctl disable alloydbomni18@inst2
    sudo rm -rf /var/lib/alloydbomni/inst2
    sudo rm -f /etc/alloydbomni/inst2.conf
    
  3. 重新加载 systemd 管理器配置并重置失败的单元。
    sudo systemctl daemon-reload
    sudo systemctl reset-failed
    

清理 Google Cloud 资源

清理实例后,删除 Compute Engine 虚拟机和其他资源。

  1. 断开与 SSH 会话的连接。
    exit
    
  2. 删除 Compute Engine 虚拟机实例。
    gcloud compute instances delete $INSTANCE_NAME --zone=$ZONE --project=$PROJECT --quiet
    
  3. 删除防火墙规则。
    gcloud compute firewall-rules delete allow-ssh-alloydb-omni --project=$PROJECT --quiet
    
  4. 删除 Cloud NAT 和 Cloud Router。
    gcloud compute routers nats delete alloydb-omni-nat --router=alloydb-omni-router --region=$REGION --project=$PROJECT --quiet
    gcloud compute routers delete alloydb-omni-router --region=$REGION --project=$PROJECT --quiet
    
  5. 删除默认的互联网路由。
    gcloud compute routes delete default-internet-route --project=$PROJECT --quiet
    

13. 恭喜

您已成功在单个 Compute Engine 虚拟机上部署和配置多个 AlloyDB Omni 实例。

所学内容

  • 了解如何预配和准备 Compute Engine 虚拟机。
  • 了解如何安装 AlloyDB Omni RPM。
  • 了解如何为多个实例配置 systemd 模板。
  • 了解如何在不同端口上初始化、配置和启动多个独立服务。
  • 了解如何验证每个实例的独立性。

了解详情