使用PostgreSQL协议接入SLS

更新时间:
复制为 MD 格式

日志服务(SLS)兼容 PostgreSQL 协议,并支持通过标准 JDBC 驱动进行连接。您可以使用 psql 客户端、JDBC 驱动或任何兼容 PG 协议的工具接入 SLS,执行 SQL 语句以实现数据的读写与管理。

功能介绍

通过PostgreSQL协议接入SLS,您可以:

  • 使用标准SQL语法管理LogStore(创建、修改、删除)。

  • 使用PostgreSQLSQL语法分析日志数据。

  • 使用INSERT语句写入日志数据。

  • 全面兼容 PostgreSQL 系统表,支持以原生 PG 语法无缝查询 LogStore 的 Schema 元数据。

使用限制

在使用PostgreSQL协议接入SLS时,存在以下限制:

限制项

说明

Prepared Statement

不支持prepared statement执行(即pg协议的parse/bind/execute)。如果是采用JDBC的方式,则需要显式设置PG的查询模式为simple,比如设置下面的链接属性:

props.setProperty(PGProperty.PREFER_QUERY_MODE.getName(), "simple");

或者在JDBC url中设置preferQueryMode参数:

jdbc:postgresql://{endpoint}:5432/{project}?preferQueryMode=simple

事务支持

begin/commit/rollback语句会被忽略(无任何效果)

主键和默认值

不支持主键、默认值等约束

前提条件

  • 已创建Project

  • 已获取AccessKey IDAccessKey Secret。具体操作,请参见创建AccessKey

  • 已安装PostgreSQL客户端工具(如psql)或其他支持PostgreSQL协议的工具。

连接SLS

pg客户端,使用以下URL格式连接SLS:

postgresql://{AccessKey_ID}:{AccessKey_Secret}@{Endpoint}:5432/{Project_Name}
# 连接默认会开启TLS连接(认证采用MD5),若要显式关闭TLS(比如客户端不支持),可以指定sslmode参数为disable
postgresql://{AccessKey_ID}:{AccessKey_Secret}@{Endpoint}:5432/{Project_Name}?sslmode=disable

通过JDBC的方式采用postgres协议连接SLS时,则可以采用如下配置:

private static final String URL = "jdbc:postgresql://{Endpoint}:5432/{Project_Name}?preferQueryMode=simple";
private static final String AccessKey_ID = "xyz";
private static final String AccessKey_Secret = "123456";

public static void main(String[] args) throws Exception
{
    Properties props = new Properties();
    props.setProperty(PGProperty.USER.getName(), AccessKey_ID);
    props.setProperty(PGProperty.PASSWORD.getName(), AccessKey_Secret);

    try (Connection conn = DriverManager.getConnection(URL, props)) {
        System.out.println("连接成功!");
    }
}

参数说明:

参数

说明

示例

AccessKey_ID

阿里云账号或RAM用户的AccessKey ID

LTAI5t***

AccessKey_Secret

阿里云账号或RAM用户的AccessKey Secret

***

Endpoint

SLS服务入口地址,更多信息,请参见服务入口。注意,Endpoint中必须加上project名称(即示例说明)。

{projectName}.cn-hangzhou.log.aliyuncs.com

Project_Name

日志项目名称

my-project

管理Table

SLSPostgreSQL协议中,Table对应SLSLogStore。

创建Table

使用CREATE TABLE语句创建LogStore:

CREATE TABLE users (
    id           BIGINT,
    name         TEXT,
    create_time  TIMESTAMP
)
WITH (
    shard_count = 4,
    ttl = 14,
    default_query_range = '1d',
    full_text_search_enabled = true,

    index_tokens = '&[ ]",''\',

    log_time_field = 'create_time',
    insert_any_allowed = false
);

支持的列类型:

PostgreSQL类型

SLS类型

说明

int8/bigint/int4/integer/int2/smallint/oid

long

整数类型

text/varchar/char/bpchar/uuid

text

字符串类型

float4/real/float8/double precision/numeric

double

浮点数类型

json

json

JSON类型

Table属性(WITH子句):

属性名

类型

说明

默认值

示例

shard_count

整数

LogStoreShard数量

4

4

ttl

整数

数据保存时间(天)

365

14

default_query_range

字符串

默认查询时间范围,格式:{n}{d/m/s}(天/分钟/秒)

'1d'

'3d'

full_text_search_enabled

布尔

是否开启全文检索

false

true

index_tokens

字符串

分词使用的tokens

默认分词符

'&[]",'''

log_time_field

字符串

指定作为sls LogStore日志时间的字段 (数据插入时使用),类型必须为timestamp或者long (可以为epoch 秒/毫秒/微妙/纳秒,系统会自动识别)。该配置,用于数据写入时, 自动识别作为LogStore的日志时间字段

-

'create_time'

insert_any_allowed

布尔

是否允许写入任意数据(不进行schema校验),如果对写入的数据进行schema校验,可以将这个值设置为false

true

false

hot_ttl

整数

LogStore的数据保存为热存储的天数,超过这些天数后,数据会自动转为低频存储(参考管理智能存储分层)。如果不设置这个,数据生命周期内总是保存为热存储。

-

7

chn_columns

字符串

定义包含中文的列(这些列的索引会开启中文分词),多个列名采用英文逗号隔开,其中__line__表示全文索引。注意,开启中文分词后,会影响分词性能,请谨慎使用。

-

'__line__,message,error'

修改Column

支持以下Column修改操作:

新增Column:

ALTER TABLE users ADD COLUMN change_time TEXT;

重命名Column:

ALTER TABLE users RENAME COLUMN change_time TO update_time;

修改Column类型:

ALTER TABLE users ALTER COLUMN update_time TYPE TIMESTAMP;

删除Column:

ALTER TABLE users DROP COLUMN update_time;

清除数据

使用TRUNCATE语句清除Table中的所有数据:

TRUNCATE TABLE users;
说明:数据删除后,SQL可见性需要约30秒才能生效。

删除Table

使用DROP TABLE语句删除Table(对应删除LogStore):

DROP TABLE users;

查询数据

基本查询

使用标准SQL SELECT语句查询数据:

SELECT id, name FROM users LIMIT 10;
说明:如果SQL中没有指定查询时间范围,将使用default_query_range指定的默认时间范围。如果创建Table时未设置default_query_range,默认查询最近15分钟的数据。

指定查询时间范围

您可以通过以下两种方式指定查询时间范围:

方式一:使用__time__字段

-- 指定查询时间下限
SELECT id, name FROM users 
WHERE __time__ > 1766646000
LIMIT 10;

-- 指定查询时间范围
SELECT id, name FROM users 
WHERE __time__ > 1766646000 AND __time__ < 1766646987
LIMIT 10;
说明__time__的值为Unix时间戳(秒)。必须设置查询时间下限才能生效;如果不设置上限,则结束时间默认为当前时间。

方式二:使用query_beginquery_end变量

-- 设置查询时间下限
SET query_begin = 1766646000; 
SELECT id, name FROM users LIMIT 10;

-- 设置查询时间范围
SET query_begin = 1766646000; 
SET query_end = 1766646987; 
SELECT id, name FROM users LIMIT 10;

-- 在单条语句中设置(推荐)
SET query_begin = 1766646000; SET query_end = 1766646987; SELECT id, name FROM users LIMIT 10;
说明:变量query_beginquery_end一旦设置,则整个连接周期内都是有效的。另外,可以通过show query_begin/query_end来查看当前变量设置的值(如果为0,则表示没有设置过)。

写入数据

基本写入

使用INSERT INTO语句写入数据:

INSERT INTO users (id, name, create_time) 
VALUES
    (1, 'Name#1', '2025-12-25T06:54:19'),
    (2, 'Name#2', '2025-12-25T06:54:20'),
    (3, 'Name#3', '2025-12-25T06:54:21');

EXACTLY ONCE写入

SLS PostgreSQL协议不支持唯一性约束(如主键),但支持EXACTLY ONCE的写入方式,确保数据只写入一次。

使用hash_keyseq_id变量实现EXACTLY ONCE写入:

SET hash_key = 'file#1'; 
SET seq_id = 1; 
INSERT INTO users (id, name, create_time) 
VALUES
    (1, 'Name#1', '2025-12-25T06:54:19'),
    (2, 'Name#2', '2025-12-25T06:54:20'),
    (3, 'Name#3', '2025-12-25T06:54:21');

参数说明:

参数

说明

hash_key

用于标识数据来源的唯一键

seq_id

序列号,必须从1开始,且对于相同hash_key必须单调递增

重复数据错误处理:

当写入重复数据时,服务端会返回如下格式的错误信息:

error: sequence id is lower than expected, hash_key=xyz,current sequence_id=100,requested sequence_id=90

您可以使用以下正则表达式提取服务端当前的seq_id:

current\s+sequence_id=(\d+)

查询元数据

查询所有LogStore

SELECT 
    table_schema, 
    table_name
FROM 
    information_schema.tables;
说明:LogStore默认映射在同名Projectschema下。

查询字段结构

SELECT 
    column_name, 
    data_type
FROM 
    information_schema.columns 
WHERE 
    table_name = 'access_log';

相关文档