日志服务(SLS)兼容 PostgreSQL 协议,并支持通过标准 JDBC 驱动进行连接。您可以使用 psql 客户端、JDBC 驱动或任何兼容 PG 协议的工具接入 SLS,执行 SQL 语句以实现数据的读写与管理。
功能介绍
通过PostgreSQL协议接入SLS,您可以:
使用标准SQL语法管理LogStore(创建、修改、删除)。
使用PostgreSQL的SQL语法分析日志数据。
使用INSERT语句写入日志数据。
全面兼容 PostgreSQL 系统表,支持以原生 PG 语法无缝查询 LogStore 的 Schema 元数据。
使用限制
在使用PostgreSQL协议接入SLS时,存在以下限制:
限制项 | 说明 |
Prepared Statement | 不支持prepared statement执行(即pg协议的parse/bind/execute)。如果是采用JDBC的方式,则需要显式设置PG的查询模式为simple,比如设置下面的链接属性: 或者在JDBC url中设置preferQueryMode参数: |
事务支持 | begin/commit/rollback语句会被忽略(无任何效果) |
主键和默认值 | 不支持主键、默认值等约束 |
前提条件
已创建Project。
已获取AccessKey ID和AccessKey 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
在SLS的PostgreSQL协议中,Table对应SLS的LogStore。
创建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 | 整数 | LogStore的Shard数量 | 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_begin和query_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_begin和query_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_key和seq_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默认映射在同名Project的schema下。
查询字段结构
SELECT
column_name,
data_type
FROM
information_schema.columns
WHERE
table_name = 'access_log';