Skip to content

Commit b805bb2

Browse files
committed
typo fix and add EN ver
1 parent f3a5b9d commit b805bb2

4 files changed

Lines changed: 207 additions & 11 deletions

File tree

‎CN/modules/ROOT/pages/master/ecosystem_components/pg_track_settings.adoc‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ make -C contrib/pg_track_settings install
6464
PG 模式与 Oracle 模式会话下命令相同:
6565
[literal, sql]
6666
----
67-
CREATE EXTENSION pg_track_settings;
68-
67+
postgres=# CREATE EXTENSION pg_track_settings;
68+
postgres=# SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_track_settings';
6969
extname | extversion
7070
-------------------+------------
7171
pg_track_settings | 2.1.2
@@ -126,7 +126,7 @@ postgres=# SELECT * FROM pg_track_settings_diff(now() - interval '10 minutes', n
126126
(1 row)
127127
----
128128

129-
from_exists / to_exists 这两列用来表达参数在两个时间点是否存在。参数被新增时 from_exists 为 false,被移除时 to_exists 为 false —— 这正是前面提到的墓碑记录发挥作用的地方。
129+
from_exists / to_exists 这两列用来表达参数在两个时间点是否存在。参数被新增时 from_exists 为 false,被移除时 to_exists 为 false。
130130

131131
查看单个参数的完整历史:
132132

@@ -179,17 +179,17 @@ postgres=# SELECT * FROM pg_reboot;
179179
180180
**关于备份:** 所有历史数据都存在普通表里,因此会被 pg_dump / pg_dumpall 完整备份。这通常是好事,但如果积累了很长的历史又不想带进备份,需要使用 pg_track_settings_reset() 清理。
181181
182-
**关于时间戳:** 历史表的 ts 列是 timestamptz 类型,存的是绝对时间点,显示时按会话时区换算。跨时区团队查历史时,注意各自会话的 TimeZone 设置可能导致看到的字符串不同,但指向的是同一时刻。
182+
* **关于时间戳:** 历史表的 ts 列是 timestamptz 类型,存的是绝对时间点,显示时按会话时区换算。跨时区团队查历史时,注意各自会话的 TimeZone 设置可能导致看到的字符串不同,但指向的是同一时刻。
183183
184-
**关于采集间隔:** 扩展记录的是「发现变更的时刻」,不是「变更实际发生的时刻」。如果两次快照之间某个参数改了又改回来,中间状态会被完全丢失。对配置审计要求严格的场景,应该配合 log_statement = 'ddl' 或专门的审计扩展一起用。
184+
* **关于采集间隔:** 扩展记录的是「发现变更的时刻」,不是「变更实际发生的时刻」。如果两次快照之间某个参数改了又改回来,中间状态会被完全丢失。对配置审计要求严格的场景,应该配合 log_statement = 'ddl' 或专门的审计扩展一起用。
185185
186-
**关于权限:** control 文件中 superuser = false,即非超级用户也可以创建该扩展(前提是拥有目标 schema 的权限)。但采集函数需要能读取 pg_settings 和 pg_db_role_setting,实际执行时仍建议用有足够权限的角色。
186+
* **关于权限:** control 文件中 superuser = false,即非超级用户也可以创建该扩展(前提是拥有目标 schema 的权限)。但采集函数需要能读取 pg_settings 和 pg_db_role_setting,实际执行时仍建议用有足够权限的角色。
187187
188-
**它不是什么:** 这个扩展只做记录,不做告警,也不会阻止任何配置修改。它是事后排查的工具,不是准入控制。
188+
* **它不是什么:** 这个扩展只做记录,不做告警,也不会阻止任何配置修改。它是事后排查的工具,不是准入控制。
189189
190190
== 适合场景
191191
192-
- 多人共同运维、配置变更缺乏统一流程的团队
193-
- 需要做性能回归分析,想确认「变慢是不是因为改了参数」的 DBA
194-
- 管理大量实例、需要集中掌握配置漂移情况的场景(配合 PoWA)
195-
- 有合规审计要求,需要证明某个时间点配置状态的环境
192+
* 多人共同运维、配置变更缺乏统一流程的团队
193+
* 需要做性能回归分析,想确认「变慢是不是因为改了参数」的 DBA
194+
* 管理大量实例、需要集中掌握配置漂移情况的场景(配合 PoWA)
195+
* 有合规审计要求,需要证明某个时间点配置状态的环境

‎EN/modules/ROOT/nav.adoc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
*** xref:master/ecosystem_components/zhparser_en.adoc[zhparser]
7777
*** xref:master/ecosystem_components/pgbackrest.adoc[pgBackRest]
7878
*** xref:master/ecosystem_components/set_user.adoc[set_user]
79+
*** xref:master/ecosystem_components/pg_track_settings.adoc[pg_track_settings]
7980
* Monitor and O&M
8081
** xref:master/getting-started/daily_monitoring.adoc[Monitoring]
8182
** xref:master/getting-started/daily_maintenance.adoc[Maintenance]

‎EN/modules/ROOT/pages/master/ecosystem_components/ecosystem_overview.adoc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ IvorySQL, as an advanced open-source database compatible with Oracle and based o
4242
|*28*| xref:master/ecosystem_components/zhparser_en.adoc[zhparser] | master branch | PostgreSQL extension for full-text search of Chinese language (Mandarin Chinese). It implements a Chinese language parser base on the | Search engine、keyword extraction
4343
|*29*| xref:master/ecosystem_components/pgbackrest.adoc[pgBackRest] | 2.58.0 | pgBackRest is a reliable backup and restore solution for PostgreSQL that seamlessly scales up to the largest databases and workloads | Disaster recovery backup, large database backup, off-site/multi-tier disaster recovery
4444
| *30* | xref:master/ecosystem_components/set_user.adoc[set_user] | REL4_2_0 | PostgreSQL security auditing extension with controlled role switching, supporting allowlists, enforced auditing, and blocking of high-risk operations | Controlled role switching, privilege management, audit logging
45+
| *31* | xref:master/ecosystem_components/pg_track_settings.adoc[pg_track_settings] | 2.1.2 | PostgreSQL configuration tracking extension that records configuration change history | Configuration auditing, change tracking
4546
|====
4647

4748
These plugins have all been tested and adapted by the IvorySQL team to ensure stable operation in the IvorySQL environment. Users can select appropriate plugins based on business needs to further enhance the capabilities and flexibility of the database system.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
:sectnums:
2+
:sectnumlevels: 5
3+
4+
= pg_track_settings
5+
6+
== Overview
7+
pg_track_settings is a PostgreSQL extension written in only about 500 lines of PL/pgSQL that tracks changes to the PostgreSQL configuration.
8+
9+
It provides a function (pg_track_settings_snapshot()) that must be called periodically. On each call, it stores the settings that have changed since the previous call. If PostgreSQL's start time differs from the one recorded previously, it also records the new start time. pg_track_settings is normally used together with a tool such as Cron or PoWA so that sampling happens regularly in production.
10+
11+
Both IvorySQL's PG mode and its Oracle compatibility mode support pg_track_settings.
12+
13+
Project page: <https://github.com/rjuju/pg_track_settings>
14+
15+
License: PostgreSQL License
16+
17+
== Function overview
18+
19+
=== Global parameters
20+
21+
[options="header"]
22+
|===
23+
| Function | Purpose
24+
| pg_track_settings_snapshot() | Collect the current configuration and record the differences
25+
| pg_track_settings(timestamptz) | Return the full configuration as of the given point in time; if the argument is omitted, the current time is used
26+
| pg_track_settings_diff(timestamptz, timestamptz) | Return every parameter that changed between the two points in time
27+
| pg_track_settings_log(text) | Return the complete change history of a single given parameter
28+
|===
29+
30+
=== Database-level / role-level override parameters
31+
32+
[options="header"]
33+
|===
34+
| Function | Purpose
35+
| pg_track_db_role_settings(timestamptz) | All override settings as of the given point in time
36+
| pg_track_db_role_settings_diff(timestamptz, timestamptz) | Override settings that changed between the two points in time
37+
| pg_track_db_role_settings_log(text) | Change history of a single override parameter
38+
|===
39+
40+
=== Maintenance
41+
42+
[options="header"]
43+
|===
44+
| Function | Purpose
45+
| pg_track_settings_reset() | Clear all history records
46+
|===
47+
48+
== Installation and enablement
49+
50+
=== Building from source
51+
52+
Build and install from source:
53+
[literal, bash]
54+
----
55+
# Build and install pg_track_settings
56+
cd ivorysql
57+
git clone https://github.com/rjuju/pg_track_settings.git contrib/pg_track_settings
58+
make -C contrib/pg_track_settings install
59+
----
60+
61+
=== Installing the extension
62+
63+
The commands are the same in PG mode and Oracle mode sessions:
64+
[literal, sql]
65+
----
66+
postgres=# CREATE EXTENSION pg_track_settings;
67+
postgres=# SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_track_settings';
68+
extname | extversion
69+
-------------------+------------
70+
pg_track_settings | 2.1.2
71+
----
72+
73+
== Usage walkthrough
74+
75+
[TIP]
76+
====
77+
The output below is illustrative; it is meant to show the form in which each function returns its results.
78+
====
79+
80+
First take a snapshot to establish a baseline:
81+
82+
[literal, sql]
83+
----
84+
postgres=# SELECT pg_track_settings_snapshot();
85+
pg_track_settings_snapshot
86+
----------------------------
87+
t
88+
(1 row)
89+
----
90+
91+
At this point the history table already holds a first batch of records:
92+
93+
[literal, sql]
94+
----
95+
postgres=# SELECT DISTINCT ts FROM pg_track_settings_history;
96+
ts
97+
-------------------------------
98+
2026-09-08 10:00:37.449846+08
99+
(1 row)
100+
----
101+
102+
Now suppose someone changes a setting and reloads:
103+
104+
[literal, sql]
105+
----
106+
postgres=# ALTER SYSTEM SET work_mem = '32MB';
107+
postgres=# SELECT pg_reload_conf();
108+
----
109+
110+
Take another snapshot, then look at the changes over that period:
111+
112+
[TIP]
113+
====
114+
In Oracle compatibility mode you must use make_interval(mins => 10) instead of interval '10 minutes', otherwise an error is raised.
115+
====
116+
117+
[literal, sql]
118+
----
119+
postgres=# SELECT pg_track_settings_snapshot();
120+
121+
postgres=# SELECT * FROM pg_track_settings_diff(now() - interval '10 minutes', now());
122+
name | from_setting | from_exists | to_setting | to_exists
123+
----------+--------------+-------------+------------+-----------
124+
work_mem | 4096 | t | 32768 | t
125+
(1 row)
126+
----
127+
128+
The from_exists / to_exists columns express whether the parameter existed at each of the two points in time. When a parameter is added, from_exists is false; when it is removed, to_exists is false.
129+
130+
View the complete history of a single parameter:
131+
132+
[literal, sql]
133+
----
134+
postgres=# SELECT * FROM pg_track_settings_log('work_mem');
135+
ts | name | setting_exists | setting
136+
-------------------------------+----------+----------------+---------
137+
2026-09-08 10:06:42.581682+08 | work_mem | t | 32768
138+
2026-09-08 10:00:37.449846+08 | work_mem | t | 4096
139+
(2 rows)
140+
----
141+
142+
Reconstruct the full configuration as of any point in time:
143+
144+
[literal, sql]
145+
----
146+
postgres=# SELECT * FROM pg_track_settings('2026-09-08 10:03:00');
147+
name | setting
148+
------------------------------+---------
149+
[...]
150+
checkpoint_completion_target | 0.9
151+
checkpoint_timeout | 300
152+
work_mem | 4096
153+
[...]
154+
----
155+
156+
View the history of override parameters:
157+
158+
[literal, sql]
159+
----
160+
postgres=# SELECT * FROM pg_track_db_role_settings_log('statement_timeout');
161+
ts | dbname | rolname | name | setting_exists | setting
162+
-------------------------------+----------+----------+-------------------+----------------+---------
163+
2026-09-08 11:15:03.112094+08 | appdb | | statement_timeout | t | 30s
164+
----
165+
166+
View the instance restart history:
167+
168+
[literal, sql]
169+
----
170+
postgres=# SELECT * FROM pg_reboot;
171+
ts
172+
-------------------------------
173+
2026-09-08 09:39:43.609195+08
174+
(1 row)
175+
----
176+
177+
== Things to be aware of
178+
179+
**About backups:** All historical data is stored in ordinary tables, so it is backed up in full by pg_dump / pg_dumpall. This is usually a good thing, but if a long history has accumulated and you do not want it included in the backup, use pg_track_settings_reset() to clean it up.
180+
181+
* **About timestamps:** The ts column of the history tables is of type timestamptz, so it stores an absolute point in time and is converted to the session time zone for display. When a team spanning multiple time zones queries the history, note that different session TimeZone settings may produce different displayed strings, even though they refer to the same instant.
182+
183+
* **About the sampling interval:** The extension records the moment a change was *discovered*, not the moment the change actually *occurred*. If a parameter is changed and then changed back between two snapshots, the intermediate state is lost entirely. In scenarios with strict configuration-audit requirements, it should be used together with log_statement = 'ddl' or a dedicated audit extension.
184+
185+
* **About privileges:** The control file sets superuser = false, meaning non-superusers can also create the extension (provided they have privileges on the target schema). However, the collection function needs to be able to read pg_settings and pg_db_role_setting, so in practice it is still advisable to run it as a role with sufficient privileges.
186+
187+
* **What it is not:** This extension only records; it does not alert, and it does not prevent any configuration change. It is a tool for after-the-fact investigation, not admission control.
188+
189+
== Suitable scenarios
190+
191+
* Teams where several people share operational duties and configuration changes lack a unified process
192+
* DBAs performing performance regression analysis who want to confirm whether "it got slower" was caused by a parameter change
193+
* Environments managing a large number of instances where configuration drift needs to be tracked centrally (together with PoWA)
194+
* Environments with compliance audit requirements that need to prove the configuration state at a given point in time

0 commit comments

Comments
 (0)