PostgreSQL打印实时查询语句的三种方法
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">方法 1:通过 PostgreSQL 日志实时查看</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1. 修改 PostgreSQL 配置文件</a></li><li><a href="#_lab2_0_1">2. 重启 PostgreSQL 容器</a></li><li><a href="#_lab2_0_2">3. 实时查看日志</a></li><li><a href="#_lab2_0_3">日志示例</a></li></ul><li><a href="#_label1">方法 2:通过 pg_stat_activity 实时监控</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_4">1. 查询实时执行的 SQL</a></li><li><a href="#_lab2_1_5">2. 使用 watch 实时刷新</a></li></ul><li><a href="#_label2">方法 3:使用 pg_stat_statements 扩展</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_6">1. 启用 pg_stat_statements</a></li><li><a href="#_lab2_2_7">2. 查询实时 SQL 统计</a></li></ul><li><a href="#_label3">注意事项</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">总结</a></li><ul class="second_class_ul"></ul></ul></div><p>最后通过后端flask sqlalchemy开启<code>SQLALCHEMY_ECHO</code>每次数据库访问打印实现了:</p><p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202509/2025090909084131.jpg" /></p>
<p class="maodian"><a name="_label0"></a></p><h2>方法 1:通过 PostgreSQL 日志实时查看</h2>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>1. 修改 PostgreSQL 配置文件</h3>
<p>在 <code>docker-compose.yml</code> 中挂载的 <code>postgresql.conf</code> 文件中,添加以下日志配置:</p>
<div class="jb51code"><pre class="brush:yaml;"># 开启日志记录所有 SQL 语句
log_statement = 'all'
# 设置日志输出格式(推荐包含时间、进程 ID 等)
log_line_prefix = '%t [%p]: '
# 开启日志收集器
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
</pre></div>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>2. 重启 PostgreSQL 容器</h3>
<div class="jb51code"><pre class="brush:bash;">docker compose down
docker compose up -d
</pre></div>
<p class="maodian"><a name="_lab2_0_2"></a></p><h3>3. 实时查看日志</h3>
<p>通过 <code>docker logs</code> 或直接访问挂载的日志目录实时查看:</p>
<div class="jb51code"><pre class="brush:bash;"># 方法 1:通过 docker logs 实时查看
docker compose logs -f postgres
# 方法 2:直接访问宿主机日志目录(假设日志挂载到 ./logs)
tail -f ./logs/postgresql-*.log
</pre></div>
<p class="maodian"><a name="_lab2_0_3"></a></p><h3>日志示例</h3>
<div class="jb51code"><pre class="brush:sql;">2025-09-07 16:24:38.123 UTC : LOG:statement: SELECT * FROM my_table;
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>方法 2:通过 pg_stat_activity 实时监控</h2>
<p class="maodian"><a name="_lab2_1_4"></a></p><h3>1. 查询实时执行的 SQL</h3>
<p>定期执行以下 SQL 语句(可通过脚本或 <code>watch</code> 命令):</p>
<div class="jb51code"><pre class="brush:sql;">SELECT
pid,
usename,
query,
query_start,
now() - query_start AS duration
FROM
pg_stat_activity
WHERE
state = 'active'
AND query != '<IDLE>'
ORDER BY
query_start DESC;
</pre></div>
<p class="maodian"><a name="_lab2_1_5"></a></p><h3>2. 使用 watch 实时刷新</h3>
<div class="jb51code"><pre class="brush:bash;">watch -n 1 "psql -U postgres -d postgres -c 'SELECT * FROM pg_stat_activity;'"
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>方法 3:使用 pg_stat_statements 扩展</h2>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>1. 启用 pg_stat_statements</h3>
<p>在 <code>postgresql.conf</code> 中添加:</p>
<div class="jb51code"><pre class="brush:plain;">shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
</pre></div>
<p>重启容器后执行:</p>
<div class="jb51code"><pre class="brush:sql;">CREATE EXTENSION pg_stat_statements;
</pre></div>
<p class="maodian"><a name="_lab2_2_7"></a></p><h3>2. 查询实时 SQL 统计</h3>
<div class="jb51code"><pre class="brush:sql;">SELECT
query,
calls,
total_exec_time,
mean_exec_time
FROM
pg_stat_statements
ORDER BY
total_exec_time DESC
LIMIT 10;
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>注意事项</h2>
<ol><li><strong>日志性能开销</strong>:<code>log_statement = 'all'</code> 会记录所有 SQL,可能影响性能,建议仅用于调试。</li><li><strong>日志轮转</strong>:通过 <code>log_rotation_age</code> 和 <code>log_rotation_size</code> 控制日志文件大小。</li><li><strong>权限问题</strong>:确保挂载的日志目录(如 <code>./logs</code>)有写入权限。</li><li><strong>生产环境</strong>:建议仅记录慢查询(<code>log_min_duration_statement</code>)而非所有语句。</li></ol>
<p class="maodian"><a name="_label4"></a></p><h2>总结</h2>
<ul><li><strong>实时打印每条查询</strong>:使用 <strong>方法 1(日志记录)</strong>。</li><li><strong>实时监控活跃查询</strong>:使用 <strong>方法 2(<code>pg_stat_activity</code>)</strong>。</li><li><strong>分析历史查询性能</strong>:使用 <strong>方法 3(<code>pg_stat_statements</code>)</strong>。</li></ul>
頁:
[1]