Trino 作为多数据源统一查询层的实现方案 ¶
近期,我司在项目推进中遇到一项跨库(两个 gauss 库)查询需求。客户方现有 Trino 环境,本可通过连接该环境直接实现跨库查询,但由于历史原因(其采购的私有化 Trino 服务对应的维护团队已解散,无人接手运维,客户出于风险顾虑明确表示 “不敢动” 现有环境),该方案无法推进。
因此,为解决这一跨库查询需求,我方独立部署一套私有化 Trino 环境,以此作为替代方案实现数据跨库查询功能。
一、部署两个测试数据源 ¶
mkdir /demo-trino/{opengauss,trino} -p
1. 编写 opengauss 编排文件 ¶
cat /demo-trino/opengauss/compose.yaml
services:
opengauss-1:
image: opengauss/opengauss:7.0.0-RC2.B003
container_name: opengauss-1
ports:
- 1234:5432
privileged: true
volumes:
- ./db1_data:/var/lib/opengauss/data
environment:
TZ: Asia/Shanghai
GS_PASSWORD: "!zdW4Krw8CfBLPFJ9twF0tO2NYtS1IDF" # 设置数据库初始化密码(必须满足复杂度要求)
GS_USERNAME: 'test1'
GS_DB: 'postgres'
networks:
- trino-demo-network
opengauss-2:
image: opengauss/opengauss:7.0.0-RC2.B003
container_name: opengauss-2
ports:
- 1235:5432
privileged: true
volumes:
- ./db2_data:/var/lib/opengauss/data
environment:
TZ: Asia/Shanghai
GS_PASSWORD: "!dW4Krw8CfBLPFJ9twF0tO2NYtS1IDF" # 设置数据库初始化密码(必须满足复杂度要求)
GS_USERNAME: 'test2'
GS_DB: 'postgres'
networks:
- trino-demo-network
networks:
trino-demo-network:
driver: bridge
2. 启动服务 ¶
docker compose up -d
3. 插入测试数据 ¶
1. 在 DB1 数据库中创建 ¶
-- 创建订单主表(记录订单基本信息)
CREATE TABLE sales_orders (
order_id INT PRIMARY KEY, -- 订单ID(关联键)
customer_id INT NOT NULL, -- 客户ID
order_date VARCHAR(10) NOT NULL, -- 下单日期(字符串类型,格式:YYYY-MM-DD)
total_amount DECIMAL(10, 2) NOT NULL, -- 订单总金额
payment_status VARCHAR(20) NOT NULL, -- 支付状态:未支付/已支付/退款
sales_region VARCHAR(50) NOT NULL -- 销售区域
);
COMMENT ON TABLE sales_orders IS '销售订单主表,存储订单的基本信息';
COMMENT ON COLUMN sales_orders.order_id IS '订单唯一标识,作为关联其他表的主键';
COMMENT ON COLUMN sales_orders.customer_id IS '客户唯一标识,关联客户信息表';
COMMENT ON COLUMN sales_orders.order_date IS '下单日期,字符串格式存储(YYYY-MM-DD)';
COMMENT ON COLUMN sales_orders.total_amount IS '订单总金额,保留两位小数';
COMMENT ON COLUMN sales_orders.payment_status IS '支付状态,可选值:未支付/已支付/退款';
COMMENT ON COLUMN sales_orders.sales_region IS '销售区域,如华东、华北等';
-- 插入测试数据(2025年6月的订单)
INSERT INTO sales_orders (order_id, customer_id, order_date, total_amount, payment_status, sales_region)
VALUES
(1001, 101, '2025-06-05', 2999.99, '已支付', '华东'), -- 6月5日订单
(1002, 102, '2025-06-12', 1599.00, '已支付', '华北'), -- 6月12日订单
(1003, 103, '2025-06-18', 4599.50, '未支付', '华南'), -- 6月18日订单
(1004, 104, '2025-06-25', 899.99, '已退款', '西北'); -- 6月25日订单
-- 验证数据
SELECT * FROM datarc.sales_orders;
2. 在 DB2 数据库中创建 ¶
-- 创建订单明细表(记录订单包含的商品明细)
CREATE TABLE sales_order_items (
item_id INT PRIMARY KEY, -- 明细ID
order_id INT NOT NULL, -- 订单ID(与订单主表sales_orders关联)
product_id INT NOT NULL, -- 商品ID
product_name VARCHAR(100) NOT NULL, -- 商品名称
quantity INT NOT NULL, -- 购买数量
unit_price DECIMAL(10, 2) NOT NULL, -- 单价
subtotal DECIMAL(10, 2) NOT NULL -- 小计金额(quantity * unit_price)
);
COMMENT ON TABLE sales_order_items IS '销售订单明细表,存储订单中包含的商品明细信息';
COMMENT ON COLUMN sales_order_items.item_id IS '明细记录唯一标识';
COMMENT ON COLUMN sales_order_items.order_id IS '关联订单主表的订单ID';
COMMENT ON COLUMN sales_order_items.product_id IS '商品唯一标识';
COMMENT ON COLUMN sales_order_items.product_name IS '商品名称';
COMMENT ON COLUMN sales_order_items.quantity IS '商品购买数量';
COMMENT ON COLUMN sales_order_items.unit_price IS '商品单价,保留两位小数';
COMMENT ON COLUMN sales_order_items.subtotal IS '商品小计金额(数量×单价)';
-- 插入测试数据(与订单主表的order_id对应)
INSERT INTO sales_order_items (item_id, order_id, product_id, product_name, quantity, unit_price, subtotal)
VALUES
(1, 1001, 1, '笔记本电脑', 1, 2999.99, 2999.99),
(2, 1002, 2, '无线耳机', 2, 799.50, 1599.00),
(3, 1002, 3, '手机壳', 1, 29.90, 29.90), -- 订单1002总金额为1628.90(与主表保持一致)
(4, 1003, 4, '智能手表', 1, 4599.50, 4599.50),
(5, 1004, 5, '蓝牙音箱', 1, 899.99, 899.99);
-- 验证数据
SELECT * FROM sales_order_items;
3. 验证数据 ¶
验证数据 |
---|
![]() |
二、部署 trino 数据源 ¶
文件结构
root@jenkins:/demo-trino/trino# tree
.
├── compose.yaml
├── data
└── etc
├── catalog
│ ├── opengauss-1.properties
│ └── opengauss-2.properties
├── config.properties
├── jvm.config
└── node.properties
1. 编写 compose.yaml 文档 ¶
mkdir /demo-trino/trino/{etc,data}
mkdir /demo-trino/trino/etc/catalog
services:
# Trino 服务
trino:
image: trinodb/trino:latest
container_name: trino
ports:
- "8080:8080" # Trino Web UI 和 JDBC 连接端口
volumes:
- ./etc:/etc/trino # 挂载 Trino 配置文件
- ./data:/data/trino # 挂载数据目录
- ./trino/etc/password-authenticator.properties:/etc/password-authenticator.properties
environment:
- TZ=Asia/Shanghai
restart: unless-stopped
networks:
- opengauss_trino-demo-network
networks:
opengauss_trino-demo-network:
external: true # 关键:声明该网络已存在,无需重新创建
2. 编写 catalog 配置 ¶
1. opengauss-1 配置 ¶
cat /demo-trino/trino/etc/catalog/opengauss-1.properties
connector.name=postgresql
connection-url=jdbc:postgresql://opengauss-1:1234/postgres
connection-user=test1
connection-password=!zdW4Krw8CfBLPFJ9twF0tO2NYtS1IDF
case-insensitive-name-matching=true
2. opengauss-2 配置 ¶
cat /demo-trino/trino/etc/catalog/opengauss-2.properties
connector.name=postgresql
connection-url=jdbc:postgresql://opengauss-2:1235/postgres
connection-user=test2
connection-password=!dW4Krw8CfBLPFJ9twF0tO2NYtS1IDF
case-insensitive-name-matching=true
3. 编写 config.properties ¶
cat /demo-trino/trino/etc/config.properties
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
discovery.uri=http://example.net:8080
# 新增认证配置
#http-server.authentication.type=PASSWORD
cat /demo-trino/trino/etc/password-authenticator.properties
password-authenticator.name=file
file.password-file=/etc/trino/password.db
5. 创建密码 ¶
创建密码文件:
touch /demo-trino/trino/etc/password.db
添加或更新用户密码test
:
htpasswd -B -C 10 password.db test
4. 编写 jvm 配置 ¶
cat /demo-trino/trino/etc/jvm.config
-server
-Xmx8G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
5. 编写 node.properties ¶
node.environment=production
node.id=trino-coordinator-1
node.data-dir=/data/trino
二、使用 trino 查询 ¶
1. 进入 trino ¶
docker compose exec -it trino trino
2. 命令查看所有已配置的数据源(CATALOGS) ¶
SHOW CATALOGS;
trino> SHOW CATALOGS;
Catalog
-------------
1-opengauss
2-opengauss
system
(3 rows)
3. 查看 db1 下的 schemas (对应为pg中的数据库 postgres ) ¶
SHOW SCHEMAS FROM "1-opengauss" ;
4. 查看数据库中的所有表 ¶
show tables from "1-opengauss".test1;
5. 查询表数据 ¶
select * from "1-opengauss".test1.sales_orders limit 10;
6. 聚合两个库查询(跨库查询) ¶
SELECT
o.order_id,
o.customer_id,
o.order_date,
i.product_name,
i.quantity,
i.subtotal
FROM
"1-opengauss".test1.sales_orders o
INNER JOIN
"2-opengauss".test2.sales_order_items i
ON o.order_id = i.order_id;
经测试没问题、然后连接我方产品进行后续工作。