PostgreSQL的学习心得和知识总结(一百六十五)|深入理解PostgreSQL数据库之以更高的分辨率记录时间戳

目录结构

注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:

1、参考书籍:++《PostgreSQL数据库内核分析》++

2、参考书籍:++《数据库事务处理的艺术:事务管理与并发控制》++

3、++PostgreSQL数据库仓库链接,点击前往++

4、++日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往++

5、参考书籍:++《PostgreSQL中文手册》++

6、++参考书籍:《PostgreSQL指南:内幕探索》,点击前往++


1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)

2、本文目的:开源共享 抛砖引玉 一起学习

3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关

4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)

5、本文内容基于PostgreSQL 17.0源码开发而成


深入理解PostgreSQL数据库之以更高的分辨率记录时间戳



文章快速说明索引

学习目标:

做数据库内核开发久了就会有一种 少年得志,年少轻狂 的错觉,然鹅细细一品觉得自己其实不算特别优秀 远远没有达到自己想要的。也许光鲜的表面掩盖了空洞的内在,每每想到于此,皆有夜半临渊如履薄冰之感。为了睡上几个踏实觉,即日起 暂缓其他基于PostgreSQL数据库的兼容功能开发,近段时间 将着重于学习分享Postgres的基础知识和实践内幕。


学习内容:(详见目录)

1、以更高的分辨率记录时间戳


学习时间:

2024年12月14日 22:28:35


学习产出:

1、PostgreSQL数据库基础知识回顾 1个
2、CSDN 技术博客 1篇
3、PostgreSQL数据库内核深入学习


注:下面我们所有的学习环境是Centos8+PostgreSQL master+Oracle19C+MySQL8.0

sql 复制代码
postgres=# select version();
                                   version                                    
------------------------------------------------------------------------------
 PostgreSQL 17.0 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 13.1.0, 64-bit
(1 row)

postgres=#

#-----------------------------------------------------------------------------#

SQL> select * from v$version;          

BANNER        Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
BANNER_FULL	  Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.17.0.0.0	
BANNER_LEGACY Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
CON_ID 0


#-----------------------------------------------------------------------------#

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.06 sec)

mysql>

功能使用背景说明

如下,这是集群启动和建立连接的过程 这里面的时间戳精度(保留三位)到达了毫秒级别:

powershell 复制代码
[postgres@localhost:~/test/bin]$ ./pg_ctl start -D test/
waiting for server to start....2024-12-15 00:21:29.593 PST [2940] LOG:  starting PostgreSQL 18devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-15), 64-bit
2024-12-15 00:21:29.594 PST [2940] LOG:  listening on IPv6 address "::1", port 5432
2024-12-15 00:21:29.594 PST [2940] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2024-12-15 00:21:29.601 PST [2940] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2024-12-15 00:21:29.606 PST [2943] LOG:  database system was shut down at 2024-12-15 00:21:21 PST
2024-12-15 00:21:29.610 PST [2940] LOG:  database system is ready to accept connections
 done
server started
[postgres@localhost:~/test/bin]$ ./psql 
psql (18devel)
Type "help" for help.

postgres=# set log_duration = on;
2024-12-15 00:21:48.027 PST [2954] LOG:  duration: 0.340 ms
SET
postgres=# select count(*) from pg_proc;
2024-12-15 00:22:03.993 PST [2954] LOG:  duration: 7.544 ms
 count 
-------
  3374
(1 row)

postgres=# \q
[postgres@localhost:~/test/bin]$ 

但是有人可能会希望得到更高精度的时间戳值,这个问题在之前的邮件列表里面已经讨论过了 但是因为未能达成共识 该patch属于废弃状态:

3位精度的设置,实际上是有意为之,如下:


功能使用补丁解析

我们这里使用上面邮件列表里面的patch,效果如下:

powershell 复制代码
[postgres@localhost:~/test/bin]$ ./pg_ctl start -D data
waiting for server to start....[2024-12-15 00:51:13.709806 PST 1734252673.709806] [15698] LOG:  starting PostgreSQL 18devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 13.1.0, 64-bit
[2024-12-15 00:51:13.710184 PST 1734252673.710184] [15698] LOG:  listening on IPv6 address "::1", port 5432
[2024-12-15 00:51:13.710221 PST 1734252673.710221] [15698] LOG:  listening on IPv4 address "127.0.0.1", port 5432
[2024-12-15 00:51:13.711134 PST 1734252673.711134] [15698] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
[2024-12-15 00:51:13.713547 PST 1734252673.713547] [15701] LOG:  database system was shut down at 2024-12-15 00:41:14 PST
[2024-12-15 00:51:13.715426 PST 1734252673.715426] [15698] LOG:  database system is ready to accept connections
 done
server started
[postgres@localhost:~/test/bin]$ ./psql 
psql (18devel)
Type "help" for help.

postgres=# show log_line_prefix ;
 log_line_prefix 
-----------------
 [%m %n] [%p] 
(1 row)

postgres=# set log_duration = on;
[2024-12-15 00:51:31.914028 PST 1734252691.914028] [15730] LOG:  duration: 0.083 ms
SET
postgres=# select count(*) from pg_proc ;
[2024-12-15 00:51:36.048291 PST 1734252696.048291] [15730] LOG:  duration: 9.896 ms
 count 
-------
  3377
(1 row)

postgres=# \q
[postgres@localhost:~/test/bin]$

patch的内容,如下:

powershell 复制代码
[postgres@localhost:~/postgres → master]$ cat 1.patch 
diff --git a/src/backend/utils/error/csvlog.c b/src/backend/utils/error/csvlog.c
index acdffb6d06..1c87a2eb74 100644
--- a/src/backend/utils/error/csvlog.c
+++ b/src/backend/utils/error/csvlog.c
@@ -86,7 +86,7 @@ write_csvlog(ErrorData *edata)
 
        initStringInfo(&buf);
 
-       /* timestamp with milliseconds */
+       /* timestamp with microseconds */
        appendStringInfoString(&buf, get_formatted_log_time());
        appendStringInfoChar(&buf, ',');
 
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 289059435a..281e34db53 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -2657,7 +2657,7 @@ char *
 get_formatted_log_time(void)
 {
        pg_time_t       stamp_time;
-       char            msbuf[13];
+       char            msbuf[16];
 
        /* leave if already computed */
        if (formatted_log_time[0] != '\0')
@@ -2677,13 +2677,13 @@ get_formatted_log_time(void)
         * nonempty or CSV/JSON mode can be selected.
         */
        pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
-       /* leave room for milliseconds... */
-                               "%Y-%m-%d %H:%M:%S     %Z",
+       /* leave room for microseconds... */
+                               "%Y-%m-%d %H:%M:%S        %Z",
                                pg_localtime(&stamp_time, log_timezone));
 
-       /* 'paste' milliseconds into place... */
-       sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000));
-       memcpy(formatted_log_time + 19, msbuf, 4);
+       /* 'paste' microseconds into place... */
+       sprintf(msbuf, ".%06d", (int) saved_timeval.tv_usec);
+       memcpy(formatted_log_time + 19, msbuf, 7);
 
        return formatted_log_time;
 }
@@ -3023,9 +3023,9 @@ log_status_format(StringInfo buf, const char *format, ErrorData *edata)
                                                saved_timeval_set = true;
                                        }
 
-                                       snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",
+                                       snprintf(strfbuf, sizeof(strfbuf), "%ld.%06d",
                                                         (long) saved_timeval.tv_sec,
-                                                        (int) (saved_timeval.tv_usec / 1000));
+                                                        (int) (saved_timeval.tv_usec));
 
                                        if (padding != 0)
                                                appendStringInfo(buf, "%*s", padding, strfbuf);
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index a2ac7575ca..f347c8ce23 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -593,9 +593,9 @@
                                        #   %b = backend type
                                        #   %p = process ID
                                        #   %P = process ID of parallel group leader
-                                       #   %t = timestamp without milliseconds
-                                       #   %m = timestamp with milliseconds
-                                       #   %n = timestamp with milliseconds (as a Unix epoch)
+                                       #   %t = timestamp without microseconds
+                                       #   %m = timestamp with microseconds
+                                       #   %n = timestamp with microseconds (as a Unix epoch)
                                        #   %Q = query ID (0 if none or not computed)
                                        #   %i = command tag
                                        #   %e = SQL state
[postgres@localhost:~/postgres → master]$

当然这里也可以做一个GUC进行控制,我们这里就不再赘述了!

相关推荐
开心工作室_kaic1 分钟前
springboot437校园悬赏任务平台(论文+源码)_kaic
运维·开发语言·数据库·php·apache
代码欢乐豆6 分钟前
NoSQL大数据存储技术测试(7)键值对数据库Redis和其他NoSQL数据库
大数据·数据库·nosql
Crossoads20 分钟前
【汇编语言】内中断(二) —— 安装自己的中断处理程序:你也能控制0号中断
android·开发语言·数据库·人工智能·深度学习·机器学习·汇编语言
中东大鹅24 分钟前
【Java】链接数据库简介
java·开发语言·数据库
百香果果ccc27 分钟前
SQL中数据库相关的操作
数据库·sql·oracle
溟洵1 小时前
【C++第三方库】快速上手---轻量级数据库SQLite和单元测试工具Gtest
数据库·c++·后端·单元测试·sqlite
2401_884810741 小时前
MySQL运算符知识点
数据库·mysql
码到成龚2 小时前
SQL server学习05-查询数据表中的数据(上)
数据库·sql·学习
向上的车轮6 小时前
Redis是什么?Redis和MongoDB的区别在那里?
数据库·redis·mongodb