我有一个本地数据库,它是生产数据库,所有操作都在该数据库上实时进行。我通过触发器将每个操作的日志存储在另一个数据库的审核日志表中。它基本上检查行的任何列中是否有任何更改,它将删除该行并再次添加(我认为这不是一个好方法,因为它应该简单地更新它,但是由于某些原因,我需要删除并添加它再次)。
有些表可以快速进行操作,例如在数据库中添加了100s
行。这减慢了将数据保存到审核日志表中的过程。现在,如果触发器不得不喜欢删除100
rows
并再次添加100
,它将明显影响性能;如果行数增加,它将进一步降低性能。
解决该问题的最佳实践应该是什么,我一直在研究Read Replica
和Foreign Data Wrapper
,但对于只读副本,它对于PostgreSQL来说只是可读且不可写的,我并没有真正去了解它。知道Foreign Data Wrapper会如何帮助我,这是我一位同事的建议。
希望有人可以指引我正确的方向。
答案 0 :(得分:1)
日志根据定义是仅追加。记录器永远不要修改或删除现有条目。
审核日志没有不同。审核触发器应INSERT
记录每个更改(但是您要定义“更改”)。他们绝对不能UPDATE
或DELETE
任何东西*。
更改和相应的日志条目应写入同一事务中的同一数据库,以确保原子性/一致性;直接登录到远程数据库将始终为您提供提交日志但未进行更改的窗口(反之亦然)。
如果您需要汇总这些日志条目并将其推送到其他数据库,则应该从外部进程而不是触发器本身进行操作。如果您需要实时进行此操作,则可以通过notification channel告知新更改的过程。
*实际上,您应该从插入日志的用户那里获得对审核表的revoke UPDATE
/ DELETE
特权。此外,理想情况下,触发器应该是日志表上具有SECURITY DEFINER
权限的特权用户拥有的INSERT
函数。连接数据库的用户不应被授予直接写入日志表的权限。
这可以确保如果您的客户端应用程序受到威胁(无论是由于故障还是恶意用户(例如利用SQL注入漏洞)),那么您的审核日志将保留其更改的所有内容的完整而准确的记录。