/* --------
* pgstat_report_query_id() -
*
* 该函数用于更新顶层查询标识符(query identifier)
* --------
*/
void
pgstat_report_query_id(uint64 query_id, bool force)
{
volatile PgBackendStatus *beentry = MyBEEntry;
/*
* 如果未启用跟踪活动(track_activities),则查询标识符(st_query_id)应已被重置。
*/
// 在 PostgreSQL 中,通过配置参数 track_activities 可以启用或禁用跟踪后端进程的活动信息。
// 如果禁用了跟踪活动,意味着不需要记录和跟踪后端进程的执行活动,包括查询标识符。
if (!beentry || !pgstat_track_activities)
return;
/*
我们只报告顶层查询的标识符。
存储的query_id 在后端进程调用 pgstat_report_activity(STATE_RUNNING) 或通过使用 force 标志显式调用此函数时会被重置。
如果存储的查询标识符不为零,意味着当前查询不是顶层命令,因此除非显式调用来重置标识符,否则会忽略提供的标识符
*/
//当存储的查询标识符不为零时,意味着当前执行的查询不是顶层查询,而是嵌套在其他查询内部。
//在这种情况下,除非显式调用 pgstat_report_query_id 函数并使用 force 标志重置标识符,否则将忽略提供的查询标识符。
if (beentry->st_query_id != 0 && !force)
return;
/*
更新我的状态条目,遵循在之前和之后增加 st_changecount 的协议。
我们在这里使用了一个 volatile 指针,以确保编译器不会进行过度优化。
*/
// PGSTAT_BEGIN_WRITE_ACTIVITY 和 PGSTAT_END_WRITE_ACTIVITY 是宏定义,用于在更新后端状态条目时执行必要的同步操作。
/*
在这段代码中,首先调用 PGSTAT_BEGIN_WRITE_ACTIVITY 宏,它可能会进行一些同步操作,例如获取互斥锁或执行其他必要的准备工作。
然后,将查询标识符 query_id 赋值给后端状态条目的 st_query_id 字段,即更新了查询标识符。
最后,调用 PGSTAT_END_WRITE_ACTIVITY 宏,它可能会执行一些同步操作,例如释放互斥锁或进行其他清理工作。
*/
// 这两个宏的作用是确保对后端状态条目的更新是线程安全的,并且在并发环境下正确地同步访问。
PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
beentry->st_query_id = query_id;
PGSTAT_END_WRITE_ACTIVITY(beentry);
}
函数的作用和行为可以总结如下:
- 如果跟踪活动被禁用或当前后端进程的活动状态不可跟踪,则函数不执行任何操作,直接返回。
- 如果已存在非零的查询标识符且未使用 force 参数调用该函数,则函数不执行任何操作,忽略提供的查询标识符。
- 否则,函数将后端进程的顶层查询标识符更新为提供的查询标识符。
- 函数确保更新操作是线程安全的,并使用同步机制来保证并发访问的正确性。