Skip to main content

给执行计划点颜色瞧瞧 —— PostgreSQL EXPLAIN 输出颜色修改源码实验总结

·276 words·2 mins
Author
GrokDb
A little bit about me

插图

给执行计划点颜色瞧瞧 —— PostgreSQL EXPLAIN 输出颜色修改源码实验总结
#

实验目标
#

本实验旨在通过修改 PostgreSQL 的源代码,改变 EXPLAIN 命令输出的显示效果,具体目标是将 “QUERY PLAN” 标题显示为蓝色。

实验环境
#

  • 操作系统:Ubuntu 22.04.4 LTS
  • PostgreSQL 版本:16.4
  • 编程语言:C(PostgreSQL 源码修改)、Python(辅助脚本)

实现步骤
#

1. 创建测试数据
#

首先,进入 PostgreSQL 并创建测试数据:

$HOME/pgsql/bin/psql -d postgres

在 PostgreSQL 中执行以下 SQL 语句:

CREATE TABLE test (id serial PRIMARY KEY, name text);
INSERT INTO test (name) VALUES ('Alice'), ('Bob'), ('Charlie');

2. 编写 Python 辅助脚本
#

为了方便执行 EXPLAIN 命令并处理输出中的颜色信息,我们需要编写一个 Python 脚本。

创建 Python 脚本
#

使用 nano 编辑器创建 colored_explain.py 脚本:

sudo nano colored_explain.py

在编辑器中粘贴以下内容:

#!/usr/bin/env python3
import sys
import subprocess
import os

def process_output(text):
    # 将 \x1B 替换为实际的转义字符
    text = text.replace('\\x1B', '\033')
    # 移除 <EXPLAIN_COLOR> 和 </EXPLAIN_COLOR> 标记
    text = text.replace('<EXPLAIN_COLOR>', '').replace('</EXPLAIN_COLOR>', '')
    return text

if len(sys.argv) < 2:
    print("Usage: ./colored_explain.py <SQL query>")
    sys.exit(1)

query = sys.argv[1]

psql_path = os.path.expanduser('~/pgsql/bin/psql')
cmd = [psql_path, '-d', 'postgres', '-c', f"EXPLAIN {query}"]
print(f"Executing command: {' '.join(cmd)}")

result = subprocess.run(cmd, capture_output=True, text=True)

print(f"Return code: {result.returncode}")
print("Stderr:")
print(result.stderr)

# 处理和打印 stdout 输出
output = process_output(result.stdout)

print("Processed output:")
sys.stdout.buffer.write(output.encode('utf-8'))
sys.stdout.buffer.flush()

保存并退出 nano 编辑器后,赋予该脚本执行权限:

sudo chmod +x colored_explain.py

测试脚本:
#

执行以下命令查看效果:

./colored_explain.py "SELECT * FROM test WHERE id < 3"

3. PostgreSQL 源代码修改
#

接下来,修改 PostgreSQL 源代码以改变 EXPLAIN 输出中 “QUERY PLAN” 的颜色。

修改文件:src/backend/commands/explain.c
#

定位到以下代码:

TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
                   result_type, -1, 0);

将其修改为:

TupleDescInitEntry(tupdesc, (AttrNumber) 1, "\033[34mQUERY PLAN\033[0m",
                   result_type, -1, 0);

这段代码使用 ANSI 转义序列 \033[34m 将文本设置为蓝色,并使用 \033[0m 重置颜色。

4. 编译并重启 PostgreSQL
#

使用以下命令编译并安装修改后的 PostgreSQL:

./configure --prefix=$HOME/pgsql --enable-debug --enable-cassert CFLAGS="-O0 -g"
make -j$(nproc)
make install
$HOME/pgsql/bin/pg_ctl -D $HOME/pgsql/data restart

5. 执行 Python 脚本并查看结果
#

再次执行 colored_explain.py 脚本,检查修改后的 EXPLAIN 输出效果。最终结果应显示为带有蓝色 “QUERY PLAN” 的输出。

实验结果
#

实验成功,通过修改 PostgreSQL 源代码,我们成功地将 EXPLAIN 命令输出中的 “QUERY PLAN” 标题颜色更改为蓝色。以下为实验结果截图:

QUERY PLAN效果对比


实验意义
#

本实验的意义在于展示了通过源码修改,可以灵活地自定义 PostgreSQL 的输出格式。这种定制化的能力在调试和分析复杂的查询计划时尤其有用。通过为查询计划中的关键部分添加颜色,可以使分析人员更直观地识别出重点内容,提高工作效率。

此外,本实验也展示了如何从源代码级别理解和修改数据库的行为,这对于开发自定义数据库功能或优化数据库性能的工程师来说具有重要的参考价值。


参考资料
#

注意:本实验是在受控的开发环境中进行的。在对生产系统应用任何更改之前,请务必备份数据并进行彻底测试。