【重新发现PostgreSQL之美】- 39 谁动了我的奶酪

背景


场景:

  • 关键数据被误操作或篡改怎么办?

挑战:

  • 怎么发现和定位?
  • 怎么快速通知?
  • 能不能记下前后变化差异?
  • 能不能回退?
  • 采取什么行动?
  • 能不能限制?
  • 能不能藏起来, 基于行或者列?

PG 解决方案:

  • 发现并记下来
  • 可回退
  • 告状
  • 拒绝执行
  • 藏起来
  • 细粒度权限控制

例子


1、发现并记下来:

谁干的:

  • 客户端: ip, port
  • 数据库端: username, dbname, ip, port, timestamp, application_name等会话特征

dml:

  • update old.value, new.value
  • delete old.value
  • insert new.value

《PostgreSQL 触发器用法详解1》
《PostgreSQL 触发器用法详解2》
《PostgreSQL 闪回- flash back query emulate by trigger》
《PostgreSQL 跟踪记录是谁写入的,谁更新的, 什么时间点, 来源IP等》
《PostgreSQL 跟踪记录被更新了多少次, 每次更新的前后值, 》
《PostgreSQL 跟踪记录(row,tuple)的插入、更新时间- spi,moddatetime trigger》
《PostgreSQL 14 preview - System Versioned Temporal Table - flashback闪回、跟踪、审计record/row/tuple历史版本》

DDL:

  • drop, truncate 回收站

《PostgreSQL Oracle 兼容性之- 事件触发器实现类似Oracle的回收站功能》
《PostgreSQL 回收站功能- 基于HOOK的recycle bin pgtrashcan》

或者使用审计:
《PostgreSQL 审计- pg_audit module》
log_statement = all

2、可回退

《PostgreSQL 最佳实践- 在线增量备份与任意时间点恢复》
《PostgreSQL 闪回- flash back query emulate by trigger》

3、可实时告状

notify

SENDMAIL

4、拒绝、忽略执行

拒绝执行: trigger 报错: raise exception
忽略执行: before trigger return null

5、藏起来

《EnterpriseDB & PostgreSQL RLS & Oracle VPD》

[ AS { PERMISSIVE | RESTRICTIVE } ]
[ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
[ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
[ USING ( using_expression ) ]
[ WITH CHECK ( check_expression ) ]

6、细粒度权限控制

权限: 查询、插入、更新、删除、截断、外键、触发器

粒度: 表、列、行

[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...]
| ALL TABLES IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
CREATE POLICY name ON table_name
[ AS { PERMISSIVE | RESTRICTIVE } ]
[ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
[ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
[ USING ( using_expression ) ]
[ WITH CHECK ( check_expression ) ]

 

上一篇:WinSock - 建立无连接的通信


下一篇:Flink Forward Asia 2019 | 总结和展望(附PPT)