Postgresql 之 基于表的dml审计

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介:

应用场景中有些业务表比较关键,需要对关键业务表的变更进行记录,以下通过在表上创建触发器调用函数的方法对关键业务表dml的操作进行跟踪记录到表table_change_rec中,以便后续审计查询。

跟踪的测试表

CREATE TABLE test (id int primary key, info text, crt_time timestamp(0));

创建hstore extension;

CREATE EXTENSION hstore;

创建通用的存储跟踪记录的记录表

CREATE TABLE table_change_rec (
id serial8 primary key,
relid oid,
table_schema text,
table_name text,
when_tg text,
level text,
op text,
old_rec hstore,
new_rec hstore,
crt_time timestamp without time zone DEFAULT now(),
username text,
client_addr inet,
client_port int);

创建通用的触发器函数

CREATE OR REPLACE FUNCTION dml_trace()
RETURNS trigger
LANGUAGE plpgsql
AS $BODY$
DECLARE
v_new_rec hstore;
v_old_rec hstore;
v_username text := session_user;
v_client_addr inet := inet_client_addr();
v_client_port int := inet_client_port();
BEGIN
case TG_OP
when 'DELETE' then
v_old_rec := hstore(OLD.*);
insert into table_change_rec (relid, table_schema, table_name, when_tg, level, op, old_rec, username, client_addr, client_port)
values (tg_relid, tg_table_schema, tg_table_name, tg_when, tg_level, tg_op, v_old_rec, v_username, v_client_addr, v_client_port);
when 'INSERT' then
v_new_rec := hstore(NEW.*);
insert into table_change_rec (relid, table_schema, table_name, when_tg, level, op, new_rec, username, client_addr, client_port)
values (tg_relid, tg_table_schema, tg_table_name, tg_when, tg_level, tg_op, v_new_rec, v_username, v_client_addr, v_client_port);
when 'UPDATE' then
v_old_rec := hstore(OLD.*);
v_new_rec := hstore(NEW.*);
insert into table_change_rec (relid, table_schema, table_name, when_tg, level, op, old_rec, new_rec, username, client_addr, client_port)
values (tg_relid, tg_table_schema, tg_table_name, tg_when, tg_level, tg_op, v_old_rec, v_new_rec, v_username, v_client_addr, v_client_port);
else
return null;
end case;
RETURN null;
END;
$BODY$ strict;

在测试表上创建触发器.

CREATE TRIGGER tg AFTER DELETE or INSERT or UPDATE ON test FOR EACH ROW EXECUTE PROCEDURE dml_trace();

测试插入, 删除, 更新操作是否被跟踪.

测试插入, 删除, 更新操作是否被跟踪.

postgres=# insert into test values (1, 'highgo', now());
INSERT 0 1
postgres=# update test set info='HighgoDB' where id=1;
UPDATE 1
postgres=# delete from test where id=1;
DELETE 1
postgres=# select * from table_change_rec;
id | relid | table_schema | table_name | when_tg | level | op | old_r
ec | new_rec |

   crt_time          | username | client_addr | client_port 
1 106952 public test AFTER ROW INSERT
"id"=>"1", "info"=>"highgo", "crt_time"=>"2018-04-23 10:37:42" 20
18-04-23 10:37:42.387136 postgres
2 106952 public test AFTER ROW UPDATE "id"=>"1", "info"=>"highgo", "crt
_time"=>"2018-04-23 10:37:42" "id"=>"1", "info"=>"HighgoDB", "crt_time"=>"2018-04-23 10:37:42" 20
18-04-23 10:37:51.626954 postgres
3 106952 public test AFTER ROW DELETE "id"=>"1", "info"=>"HighgoDB", "c
rt_time"=>"2018-04-23 10:37:42" 20
18-04-23 10:38:00.382681 postgres

(3 rows)

postgres=# select id,(each(old_rec)).* from table_change_rec;

id key value
2 id 1
2 info highgo
2 crt_time 2018-04-23 10:37:42
3 id 1
3 info HighgoDB
3 crt_time 2018-04-23 10:37:42

(6 rows)

postgres=select id,(each(new_rec)).* from table_change_rec;

id key value
1 id 1
1 info highgo
1 crt_time 2018-04-23 10:37:42
2 id 1
2 info HighgoDB
2 crt_time 2018-04-23 10:37:42

(6 rows)

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
SQL 关系型数据库 PostgreSQL
把PostgreSQL的表导入SQLite
把PostgreSQL的表导入SQLite
70 0
|
2月前
|
SQL 监控 关系型数据库
实时计算 Flink版操作报错合集之在设置监控PostgreSQL数据库时,将wal_level设置为logical,出现一些表更新和删除操作报错,怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
3月前
|
关系型数据库 PostgreSQL
postgresql如何将没有关联关系的两张表的字段合并
【6月更文挑战第2天】postgresql如何将没有关联关系的两张表的字段合并
57 3
|
3月前
|
SQL 关系型数据库 数据库连接
ClickHouse(20)ClickHouse集成PostgreSQL表引擎详细解析
ClickHouse的PostgreSQL引擎允许直接查询和插入远程PostgreSQL服务器的数据。`CREATE TABLE`语句示例展示了如何定义这样的表,包括服务器信息和权限。查询在只读事务中执行,简单筛选在PostgreSQL端处理,复杂操作在ClickHouse端完成。`INSERT`通过`COPY`命令在PostgreSQL事务中进行。注意,数组类型的处理和Nullable列的行为。示例展示了如何从PostgreSQL到ClickHouse同步数据。一系列的文章详细解释了ClickHouse的各种特性和表引擎。
88 0
|
3月前
|
SQL 关系型数据库 PostgreSQL
【sql】PostgreSQL物化视图表使用案例
【sql】PostgreSQL物化视图表使用案例
32 0
|
4月前
|
关系型数据库 PostgreSQL
postgresql将没有关联关系的两张表合并成一张
【5月更文挑战第4天】postgresql将没有关联关系的两张表合并成一张
102 5
|
3月前
|
关系型数据库 PostgreSQL
postgresql如何将没有关联关系的两张表合并成一张
【6月更文挑战第2天】postgresql如何将没有关联关系的两张表合并成一张
26 0
|
10月前
|
SQL 关系型数据库 数据库
postgresql中连接两张表更新第三张表(updata)
如何结合两张表的数据来更新第三张表
227 0
|
4月前
|
关系型数据库 数据库 PostgreSQL
postgresql | 数据库| 生成2000W条的简单测试表
postgresql | 数据库| 生成2000W条的简单测试表
194 0
|
关系型数据库 PostgreSQL
PostgreSQL表用户列最大个数
PostgreSQL表用户列最大个数
163 0
下一篇
DDNS