PG数据库审计

默认审计

pgsql开启数据库审计

相关参数
在这里插入图片描述

???
在这里插入图片描述
none,表示不记录。
ddl (记录create,drop和alter) 记录所有数据定义命令,比如CREATE,ALTER,和DROP语句。(生产环境)
mod (记录ddl+insert,delete,update和truncate) 记录所有ddl语句,加上数据修改语句INSERT,UPDATE等。
all (mod+select) 记录所有执行的语句,将此配置设置为all可跟踪整个数据库执行的SQL语句,但会对数据库性能产生较大影响,生产环境不建议配置此值。

插件

验证

DDL

在这里插入图片描述

WRITE

在这里插入图片描述

ROLE

在这里插入图片描述

READ

在这里插入图片描述

pgbench -i -s 10 bpx
pgbench -r -j2 -c2  -T2 bpx
pgbench -i -s 10 bpx

在这里插入图片描述

pgaudit.log

psql
show pgaudit.log;
alter system set pgaudit.log = 'write,ddl,role';
select pg_reload_conf();
show pgaudit.log;
\q

在这里插入图片描述

关闭审计

[postgres@postgres-476a875c-0-0 /]$ psql
psql (15.7)
Type "help" for help.

postgres=# alter system set pgaudit.log = 'none';
ALTER SYSTEM
postgres=# select pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)

postgres=# show  pgaudit.log;
 pgaudit.log 
-------------
 none
(1 row)

在这里插入图片描述
在这里插入图片描述

<think>我们正在处理一个PostgreSQL存储过程执行效率问题,具体现象是:在数据库内部调用存储过程耗时显著增加(与之前相比或与外部调用相比)。根据用户提供的信息和引用,我们可以从多个角度进行排查。 关键引用回顾: [^1]: 优化PostgreSQL存储过程需要综合考虑查询优化、存储过程结构、服务器配置和定期维护。 [^2]: 合理配置日志有助于故障排除和性能分析,特别是审计日志和安全监控。 [^3]: 使用pg_stat_statements扩展可以统计历史查询的执行次数、总耗时、平均耗时,识别高频慢查询。 [^4]: 提到了压测和参数调优,以及如何分析性能瓶颈。 根据这些引用,我们可以制定排查步骤: 1. **分析存储过程内部查询**:使用EXPLAIN ANALYZE分析存储过程中的每个查询语句,查看执行计划是否低效。 2. **使用pg_stat_statements**:识别存储过程中哪些查询最耗时。 3. **检查参数嗅探(Parameter Sniffing)**:PostgreSQL中也可能存在类似问题,即由于参数值不同导致执行计划不佳。 4. **检查锁等待**:存储过程执行期间是否被其他事务阻塞。 5. **检查日志**:特别是审计日志和错误日志,看是否有异常或警告。 6. **资源使用情况**:检查CPU、内存、I/O在存储过程执行期间的使用情况。 7. **事务和并发设置**:检查存储过程是否在事务中运行,以及事务隔离级别等。 下面我们详细展开: ### 一、执行计划分析 使用`EXPLAIN ANALYZE`执行存储过程中的关键查询,或者将整个存储过程包装在一个事务中执行并分析。 例如,对于存储过程中的一个查询: ```sql EXPLAIN ANALYZE SELECT ... -- 存储过程中的查询语句 ``` 如果存储过程包含多个语句,可以逐个分析。关注是否有全表扫描、嵌套循环连接、不合适的索引等。 ### 二、使用pg_stat_statements 安装并启用pg_stat_statements扩展(如果尚未启用): ```sql CREATE EXTENSION IF NOT EXISTS pg_stat_statements; ``` 然后查询最耗时的SQL语句: ```sql SELECT query, calls, total_exec_time, mean_exec_time, rows FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10; ``` 注意:可能需要重置pg_stat_statements(使用`SELECT pg_stat_statements_reset()`)来获取最新的数据。 ### 三、参数嗅探问题 在PostgreSQL中,执行计划会缓存,但有时会因为参数值的变化导致计划不佳。我们可以通过以下方式解决: 1. 使用`PLAN`选项强制重新规划: ```sql EXECUTE your_procedure(param1, param2) WITH (PLAN); ``` 2. 在存储过程内部使用动态SQL,并添加`EXECUTE ... USING`,这样可以为每次执行生成新的计划(但需谨慎,可能增加规划开销)。 3. 使用`CREATE STATISTICS`创建扩展统计信息,帮助优化器做出更好的选择。 ### 四、锁等待 在存储过程执行期间,检查是否有锁等待: ```sql SELECT * FROM pg_locks WHERE NOT granted; ``` 或者使用`pg_blocking_pids`函数查找阻塞当前会话的进程: ```sql SELECT pg_blocking_pids(pid) FROM pg_stat_activity WHERE pid = <your_pid>; ``` ### 五、日志分析 配置PostgreSQL日志,记录慢查询(例如超过1秒的查询): 在postgresql.conf中设置: ``` log_min_duration_statement = 1000 # 单位毫秒 log_statement = 'all' # 可选,记录所有语句,但生产环境慎用 ``` 然后重启或重新加载配置,查看日志中记录的慢查询。 ### 六、资源监控 使用系统工具(如top, iotop, iostat, vmstat)监控数据库服务器资源使用情况。同时,PostgreSQL自带的`pg_stat_activity`视图可以查看当前活动会话: ```sql SELECT * FROM pg_stat_activity WHERE state = 'active'; ``` 关注状态为“active”的会话,特别是执行时间长的。 ### 七、事务设置 检查存储过程是否在事务中运行,以及事务的隔离级别。长时间的事务可能导致锁持有时间过长,或者由于快照过旧导致性能下降(在REPEATABLE READ或SERIALIZABLE隔离级别下)。 另外,检查存储过程中是否有大量的中间提交(COMMIT),这可能导致额外的开销。 ### 优化建议 1. **索引优化**:根据执行计划添加缺失的索引。 2. **重写存储过程**:避免复杂的逻辑,将一些操作拆分成多个存储过程,或者将部分逻辑移到应用层。 3. **调整配置参数**:如`work_mem`、`shared_buffers`等,根据[^4]提到的压测方法进行调优。 4. **定期维护**:执行`VACUUM ANALYZE`更新统计信息,重建索引等。 如果问题仍然存在,考虑使用性能分析工具(如pg_profile、pgBadger)对数据库进行更深入的分析。 §§ 相关问题 §§ 1. 如何解释PostgreSQL的执行计划? 2. pg_stat_statements扩展的详细使用方法是什么? 3. 如何配置PostgreSQL的慢查询日志? 4. PostgreSQL中有哪些常见的锁类型?如何解决锁等待问题? 5. 如何调整PostgreSQL的内存参数以优化性能?[^4]</think>### PostgreSQL 存储过程执行效率排查指南 当存储过程在数据库内部调用耗时显著增加时,需从执行计划、资源争用和参数优化三个维度排查。以下是系统化的诊断流程: --- #### 一、核心原因分析 1. **执行计划劣化(参数嗅探问题)** PostgreSQL 会根据首次调用参数生成执行计划缓存,当后续参数分布差异大时(如`WHERE status=@status`中`@status`从高频值变为低频值),会导致全表扫描等低效操作[^1][^3]。 **验证方法**: ```sql EXPLAIN (ANALYZE, BUFFERS) CALL your_procedure(param1, param2); -- 获取实际执行计划 ``` 2. **资源争用与锁阻塞** - **锁等待**:存储过程涉及`SELECT ... FOR UPDATE`或数据修改时,可能被其他事务阻塞 - **内存不足**:`work_mem`设置过小导致磁盘临时文件写入(检查`EXPLAIN`中的`Disk Usage`) **诊断工具**: ```sql -- 查看锁等待 SELECT * FROM pg_locks WHERE NOT granted; -- 检查临时文件写入 SELECT datname, temp_files FROM pg_stat_database; ``` 3. **统计信息过时** 数据分布变化后未及时更新统计信息,导致优化器误判: ```sql SELECT last_analyzed FROM pg_stat_all_tables WHERE relname = 'your_table'; -- 检查统计信息更新时间 ``` --- #### 二、优化解决方案 1. **执行计划优化** - **禁用参数嗅探**(PostgreSQL 12+): ```sql CREATE OR REPLACE PROCEDURE your_proc(param INT) AS $$ DECLARE local_param INT = param; -- 屏蔽参数嗅探 BEGIN SELECT ... WHERE col = local_param; END; $$ LANGUAGE plpgsql; ``` - **强制重新编译**: ```sql ALTER PROCEDURE your_proc SET plan_cache_mode = force_custom_plan; ``` 2. **资源争用处理** - **提升`work_mem`**(针对排序/哈希操作): ```sql SET LOCAL work_mem = '64MB'; -- 在存储过程内动态设置 ``` - **缩短锁持有时间**: ```sql BEGIN; CALL your_proc(...); COMMIT; -- 显式控制事务范围 ``` 3. **统计信息维护** ```sql ANALYZE your_table; -- 手动更新统计信息 VACUUM ANALYZE your_table; -- 清理死元组并更新统计信息 ``` --- #### 三、深度诊断工具 | 工具 | 命令/方法 | 关键指标 | |---------------------|--------------------------------------------------------------------------|----------------------------| | `pg_stat_statements`| `SELECT * FROM pg_stat_statements WHERE query ~ 'your_proc'` | `mean_time`, `rows` [^3] | | 执行计划分析 | `EXPLAIN (ANALYZE, BUFFERS) CALL your_proc()` | `Planning Time`, `Execution Time` | | 日志分析 | 设置`log_min_duration_statement = 1000` 记录慢查询 | 定位具体慢速语句 [^2] | | 系统视图 | `SELECT * FROM pg_stat_activity WHERE query ~ 'your_proc'` | `wait_event_type`(锁等待) | > **关键建议**:优先检查`EXPLAIN ANALYZE`输出中的`Planning Time`。若计划时间占比高(如>30%),说明存在参数嗅探或统计信息问题;若执行时间高,需优化查询或调整资源参数[^1][^4]。 --- #### 四、高级调优策略 1. **批量处理优化** 避免逐行操作,使用`RETURN QUERY`或`FORALL`: ```sql CREATE PROCEDURE batch_update() AS $$ BEGIN UPDATE table SET col = new_val WHERE condition; END; $$ LANGUAGE plpgsql; ``` 2. **连接池控制** 使用`pgbouncer`限制并发连接,避免连接风暴导致资源争用。 3. **参数化压测** 参考[^4]方法调整压测参数: ```bash pgbench -c 20 -j 4 -T 60 -f proc_test.sql ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值