PostgreSQL的学习心得和知识总结(一百五十七)|新的 COPY 选项 LOG_VERBOSITY


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

1、参考书籍:《PostgreSQL数据库内核分析》
2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》
3、PostgreSQL数据库仓库链接,点击前往
4、日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往
5、参考书籍:《PostgreSQL指南:内幕探索》,点击前往
6、参考书籍:《事务处理 概念与技术》


1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)
5、本文内容基于PostgreSQL master源码开发而成


新的 COPY 选项 LOG_VERBOSITY

  • 文章快速说明索引
  • 功能使用背景说明
  • 功能实现源码解析



文章快速说明索引

学习目标:

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


学习内容:(详见目录)

1、新的 COPY 选项 LOG_VERBOSITY


学习时间:

2024年10月27日 18:04:45


学习产出:

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


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

postgres=# select version();
                                                  version                                                   
------------------------------------------------------------------------------------------------------------
 PostgreSQL 18devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21), 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>

功能使用背景说明

Add new COPY option LOG_VERBOSITY.

This commit adds a new COPY option LOG_VERBOSITY, which controls the
amount of messages emitted during processing. Valid values are
'default' and 'verbose'.

This is currently used in COPY FROM when ON_ERROR option is set to
ignore. If 'verbose' is specified, a NOTICE message is emitted for
each discarded row, providing additional information such as line
number, column name, and the malformed value. This helps users to
identify problematic rows that failed to load.

添加新的 COPY 选项 LOG_VERBOSITY

  • 此提交添加了新的 COPY 选项 LOG_VERBOSITY,用于控制处理期间发出的消息量。有效值为“default”和“verbose”
  • 当 ON_ERROR 选项设置为忽略时,当前在 COPY FROM 中使用此选项。如果指定了“verbose”,则会为每个丢弃的行发出一条 NOTICE 消息,提供其他信息,例如行号、列名和格式错误的值。这有助于用户识别无法加载的问题行
Add log_verbosity = 'silent' support to COPY command.

Previously, when the on_error option was set to ignore, the COPY command
would always log NOTICE messages for input rows discarded due to
data type incompatibility. Users had no way to suppress these messages.

This commit introduces a new log_verbosity setting, 'silent',
which prevents the COPY command from emitting NOTICE messages
when on_error = 'ignore' is used, even if rows are discarded.
This feature is particularly useful when processing malformed files
frequently, where a flood of NOTICE messages can be undesirable.

For example, when frequently loading malformed files via the COPY command
or querying foreign tables using file_fdw (with an upcoming patch to
add on_error support for file_fdw), users may prefer to suppress
these messages to reduce log noise and improve clarity.

为 COPY 命令添加 log_verbosity = ‘silent’ 支持

  • 以前,当 on_error 选项设置为 ignore 时,COPY 命令将始终记录由于数据类型不兼容而丢弃的输入行的 NOTICE 消息。用户无法抑制这些消息
  • 此提交引入了一个新的 log_verbosity 设置 ‘silent’,当使用 on_error = ‘ignore’ 时,即使行被丢弃,它也会阻止 COPY 命令发出 NOTICE 消息。此功能在频繁处理格式错误的文件时特别有用,在这种情况下,大量的 NOTICE 消息可能是不受欢迎的
  • 例如,当通过 COPY 命令频繁加载格式错误的文件或使用 file_fdw 查询外部表时(即将发布的补丁将为 file_fdw 添加 on_error 支持),用户可能更愿意抑制这些消息以减少日志噪音并提高清晰度

案例展示1,如下:

postgres=# select version();
                                     version                                     
---------------------------------------------------------------------------------
 PostgreSQL 18devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 13.1.0, 64-bit
(1 row)

postgres=# \set SHOW_CONTEXT always
postgres=# 
postgres=# CREATE TABLE check_ign_err (n int, m int[], k int);
CREATE TABLE
postgres=# COPY check_ign_err FROM STDIN WITH (on_error ignore, log_verbosity verbose);
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 1    {1}     1
>> a    {2}     2
>> 3    {3}     3333333333
>> 4    {a, 4}  4
>> 
>> 5    {5}     5
>> 6    a
>> 7    {7}     a
>> 8    {8}     8
>> \.
NOTICE:  skipping row due to data type incompatibility at line 2 for column "n": "a"
CONTEXT:  COPY check_ign_err
NOTICE:  skipping row due to data type incompatibility at line 3 for column "k": "3333333333"
CONTEXT:  COPY check_ign_err
NOTICE:  skipping row due to data type incompatibility at line 4 for column "m": "{a, 4}"
CONTEXT:  COPY check_ign_err
NOTICE:  skipping row due to data type incompatibility at line 5 for column "n": ""
CONTEXT:  COPY check_ign_err
NOTICE:  skipping row due to data type incompatibility at line 7 for column "m": "a"
CONTEXT:  COPY check_ign_err
NOTICE:  skipping row due to data type incompatibility at line 8 for column "k": "a"
CONTEXT:  COPY check_ign_err
NOTICE:  6 rows were skipped due to data type incompatibility
COPY 3
postgres=# table check_ign_err;
 n |  m  | k 
---+-----+---
 1 | {1} | 1
 5 | {5} | 5
 8 | {8} | 8
(3 rows)

postgres=#

案例展示2,如下:

postgres=# CREATE DOMAIN dcheck_ign_err2 varchar(15) NOT NULL;
CREATE DOMAIN
postgres=# CREATE TABLE check_ign_err2 (n int, m int[], k int, l dcheck_ign_err2);
CREATE TABLE
postgres=# COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity verbose);
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 1    {1}     1       'foo'
>> 2    {2}     2       \N
>> \.
NOTICE:  skipping row due to data type incompatibility at line 2 for column "l": null input
CONTEXT:  COPY check_ign_err2
NOTICE:  1 row was skipped due to data type incompatibility
COPY 1
postgres=# table check_ign_err2;
 n |  m  | k |   l   
---+-----+---+-------
 1 | {1} | 1 | 'foo'
(1 row)

postgres=#

案例展示3,如下:

postgres=# COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity silent);
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 3    {3}     3       'bar'
>> 4    {4}     4       \N
>> \.
COPY 1
postgres=# table check_ign_err2;
 n |  m  | k |   l   
---+-----+---+-------
 1 | {1} | 1 | 'foo'
 3 | {3} | 3 | 'bar'
(2 rows)

postgres=# COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity default);
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 5    {5}     5       'bar'
>> 6    {6}     6       \N
>> \.
NOTICE:  1 row was skipped due to data type incompatibility
COPY 1
postgres=#

OK,接下来做一个小结 如下(当 ON_ERROR 选项设置为ignore时):

  1. 如果至少有一行被丢弃,则在 COPY FROM 结束时会发出一条 NOTICE 消息,其中包含被忽略的行数。
  2. 当 LOG_VERBOSITY 选项设置为 verbose 时,对于每个被丢弃的行,都会发出一条 NOTICE 消息,其中包含输入文件的行和输入转换失败的列名。
  3. 当设置为 silent 时,不会发出有关被忽略的行的消息。

功能实现源码解析

相关数据结构如下:

// src/include/commands/copy.h

/*
 * Represents verbosity of logged messages by COPY command.
 */
typedef enum CopyLogVerbosityChoice
{
	COPY_LOG_VERBOSITY_SILENT = -1, /* logs none */
	COPY_LOG_VERBOSITY_DEFAULT = 0, /* logs no additional messages. As this is
									 * the default, assign 0 */
									// 不记录其他消息。由于这是默认设置,因此分配 0
	COPY_LOG_VERBOSITY_VERBOSE, /* logs additional messages */
} CopyLogVerbosityChoice;
// src/backend/commands/copy.c

/*
 * Process the statement option list for COPY.
 * 处理 COPY 的语句选项列表。
 *
 * Scan the options list (a list of DefElem) and transpose the information
 * into *opts_out, applying appropriate error checking.
 * 扫描选项列表(DefElem 列表)并将信息转置到 *opts_out,应用适当的错误检查。
 *
 * If 'opts_out' is not NULL, it is assumed to be filled with zeroes initially.
 * 如果“opts_out”不为 NULL,则假定它最初用零填充。
 *
 * This is exported so that external users of the COPY API can sanity-check
 * a list of options.  In that usage, 'opts_out' can be passed as NULL and
 * the collected data is just leaked until CurrentMemoryContext is reset.
 * 导出此信息,以便 COPY API 的外部用户可以对选项列表进行健全性检查。
 * 在这种用法中,“opts_out”可以作为 NULL 传递,并且收集的数据只会泄露,直到 CurrentMemoryContext 重置。
 *
 * Note that additional checking, such as whether column names listed in FORCE
 * QUOTE actually exist, has to be applied later.  This just checks for
 * self-consistency of the options list.
 * 请注意,稍后必须应用其他检查,例如 FORCE QUOTE 中列出的列名是否实际存在。
 * 这只是检查选项列表的自洽性。
 */
void
ProcessCopyOptions(ParseState *pstate,
				   CopyFormatOptions *opts_out,
				   bool is_from,
				   List *options)
{
	...
	/* Support external use for option sanity checking */
	if (opts_out == NULL)
		opts_out = (CopyFormatOptions *) palloc0(sizeof(CopyFormatOptions));
	...
	/* Extract options from the statement node tree */
	foreach(option, options)
	{
		DefElem    *defel = lfirst_node(DefElem, option);
		...
		else if (strcmp(defel->defname, "log_verbosity") == 0)
		{
			if (log_verbosity_specified)
				errorConflictingDefElem(defel, pstate);
			log_verbosity_specified = true;
			opts_out->log_verbosity = defGetCopyLogVerbosityChoice(defel, pstate);
		}
		...
	}
	...
}

在这里插入图片描述

如上,即使没有指定该选项 也会被设置成默认值COPY_LOG_VERBOSITY_DEFAULT。接下来看一下解析函数:

/*
 * Extract a CopyLogVerbosityChoice value from a DefElem.
 */
static CopyLogVerbosityChoice
defGetCopyLogVerbosityChoice(DefElem *def, ParseState *pstate)
{
	char	   *sval;

	/*
	 * Allow "silent", "default", or "verbose" values.
	 */
	sval = defGetString(def);
	if (pg_strcasecmp(sval, "silent") == 0)
		return COPY_LOG_VERBOSITY_SILENT;
	if (pg_strcasecmp(sval, "default") == 0)
		return COPY_LOG_VERBOSITY_DEFAULT;
	if (pg_strcasecmp(sval, "verbose") == 0)
		return COPY_LOG_VERBOSITY_VERBOSE;

	ereport(ERROR,
			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
	/*- translator: first %s is the name of a COPY option, e.g. ON_ERROR */
			 errmsg("COPY %s \"%s\" not recognized", "LOG_VERBOSITY", sval),
			 parser_errposition(pstate, def->location)));
	return COPY_LOG_VERBOSITY_DEFAULT;	/* keep compiler quiet */
}

接下来看一下详细调试过程,如下:

在这里插入图片描述

在这里插入图片描述

此时的函数堆栈,如下:

NextCopyFrom(CopyFromState cstate, ExprContext * econtext, Datum * values, _Bool * nulls)
CopyFrom(CopyFromState cstate) 
DoCopy(ParseState * pstate, const CopyStmt * stmt, int stmt_location, int stmt_len, uint64 * processed)
standard_ProcessUtility(PlannedStmt * pstmt, const char * queryString, _Bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment * queryEnv, DestReceiver * dest, QueryCompletion * qc)
ProcessUtility(PlannedStmt * pstmt, const char * queryString, _Bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment * queryEnv, DestReceiver * dest, QueryCompletion * qc) 
PortalRunUtility(Portal portal, PlannedStmt * pstmt, _Bool isTopLevel, _Bool setHoldSnapshot, DestReceiver * dest, QueryCompletion * qc) 
PortalRunMulti(Portal portal, _Bool isTopLevel, _Bool setHoldSnapshot, DestReceiver * dest, DestReceiver * altdest, QueryCompletion * qc)
PortalRun(Portal portal, long count, _Bool isTopLevel, _Bool run_once, DestReceiver * dest, DestReceiver * altdest, QueryCompletion * qc)
exec_simple_query(const char * query_string)
...

上面多行的循环处理,结束之后 如下:

在这里插入图片描述

postgres=# COPY check_ign_err2 FROM STDIN WITH (on_error ignore, log_verbosity verbose);
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 7    {7}     7       'bar'
>> 8    {8}     8       \N
>> 9    {9}     9       \N
>> \.
NOTICE:  skipping row due to data type incompatibility at line 2 for column "l": null input
NOTICE:  skipping row due to data type incompatibility at line 3 for column "l": null input
NOTICE:  2 rows were skipped due to data type incompatibility
COPY 1
postgres=#

如果这里设置的是silent,那么上面这一行也不会打印了!

这个功能比较简单,这里不再赘述!对错误信息的提示量根据自己需要酌情设置即可,如果指定了verbose,则会为每个丢弃的行发出一条 NOTICE 消息,提供其他信息(如上):

  • 例如行号、列名和格式错误的值
  • 这有助于用户识别无法加载的问题行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905439.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【力扣打卡系列】二叉树的最近公共祖先

坚持按题型打卡&刷&梳理力扣算法题系列,语言为go,Day18 二叉树的最近公共祖先 题目描述 解题思路 最近公共祖先分类讨论 当前节点是空节点(返回当前节点)当前节点是p(返回当前节点)当前节点是q&am…

Redis常见面试题总结(上)

Redis 基础 什么是 Redis? Redis (REmote DIctionary Server)是一个基于 C 语言开发的开源 NoSQL 数据库(BSD 许可)。与传统数据库不同的是,Redis 的数据是保存在内存中的(内存数据库,支持持久…

Training-free layout control with cross-attention guidance

https://zhuanlan.zhihu.com/p/666445024https://zhuanlan.zhihu.com/p/666445024 支持两种模式,1.sd文生图;2.绑定了dreambooth和text inversion的图像编辑。 # ------------------ example input ------------------examples &

‌Spring MVC的主要组件有哪些?

前言 SpringMVC的核心组件包括DispatcherServlet、Controller、HandlerMapping、HandlerAdapter、ViewResolver、ModelAndView等,它们协同工作以支持基于MVC架构的Web应用程序开发。这些组件使得开发人员能够以一种声明式和模块化的方式构建Web应用程序&#xff0c…

Python突破浏览器TLS/JA3 指纹

初识指纹遇到一个网站,忽然发现无论如何如何更换UA和代理请求都是403,curl_cffi 可模拟真实浏览器的 TLS | JA3 指纹。 查看 tls 指纹的网站: https://tls.browserleaks.com/json不同网站的生成的指纹可能有差异,但是多次访问同一个网站生成…

Redis新数据类型

新数据类型 Bitmaps 命令 setbit 实例 getbit 实例 bitcount 实例 bitop 实例 Bitmaps与set 对比 HyperLogLog 命令 pfadd 实例 pfcount 实例 pfmerge 实例 Geospatial 命令 geoadd 实例 geopos 实例 geodist 实例 georadius 实例 Bitmaps Ⅰ.B…

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …

Java Executor ScheduledExecutorService 源码

前言 相关系列 《Java & Executor & 目录》《Java & Executor & ScheduledExecutorService & 源码》《Java & Executor & ScheduledExecutorService & 总结》《Java & Executor & ScheduledExecutorService & 问题》 涉及内容 …

C++:继承~派生类以及衍生的多继承与菱形继承问题

C中的继承其实是一个C中的坑,主要体现在其多继承(菱形继承)方面,我们先来了解下继承的概念 一,继承的概念与定义 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许我们在保持原有类特性的基础上进行扩展&#xff0c;增…

Python 从入门到实战43(Pandas数据结构)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;可以熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们学习了NumPy数组操作的相关基础知识。今天学习一下pa…

工程项目智能化管理平台,SpringBoot框架智慧工地源码,实现工程建设施工可视化、智能化的全过程闭环管理。

智慧工地管理系统的建设以“1个可扩展性平台2个应用端3方数据融合N个智能设备”为原则。以“智、保、安、全”为导向&#xff0c;与工程建设管理信息系统、综合安防平台深度集成&#xff0c;构建统一的标准化工地平台&#xff0c;实现现场人员、车辆、项目、安全、进度等方面的…

使用React构建现代Web应用

&#x1f496; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4bb; Gitee主页&#xff1a;瑕疵的gitee主页 &#x1f680; 文章专栏&#xff1a;《热点资讯》 使用React构建现代Web应用 1 引言 2 React简介 3 安装React 4 创建React项目 5 设计应用结构 6 创建组件 7 使用组件…

哈希——哈希表处理哈希冲突的方法

处理哈希冲突 实践中哈希表⼀般还是选择除法散列法作为哈希函数。 当然哈希表无论选择什么哈希函数也避免不了冲突&#xff08;主要作用就是减少冲突&#xff09;&#xff0c;那么插入数据时&#xff0c;如何解决冲突呢&#xff1f;主要有两种两种方法&#xff0c;开放定址法和…

海外云手机是什么?对外贸电商有什么帮助?

在外贸电商领域&#xff0c;流量引流已成为卖家们关注的核心问题。越来越多的卖家开始利用海外云手机&#xff0c;通过TikTok等社交平台吸引流量&#xff0c;以推动商品在海外市场的销售。那么&#xff0c;海外云手机到底是什么&#xff1f;它又能为外贸电商卖家提供哪些支持呢…

Hadoop-001-本地虚拟机环境搭建

一、安装VMware 官方下载VMware&#xff1a; https://vmware.mdsoft.top/?bd_vid5754305114651491003 二、下载镜像文件 阿里云镜像仓库&#xff1a; https://mirrors.aliyun.com/centos/ 本文档使用 CentOS-7-x86_64-DVD-1810-7.6.iso 搭建虚拟机 三、搭建虚拟机 1、编辑…

Oracle视频基础1.1.2练习

1.1.2 需求&#xff1a; 查询oracle组件和粒度大小&#xff0c; select component,granule_size from v$sga_dynamic_components;Oracle SGA 中组件和粒度大小查询详解 在 Oracle 数据库的内存结构中&#xff0c;SGA&#xff08;System Global Area&#xff0c;系统全局区&am…

动态上下文信念(DCB)

DCB&#xff08;动态上下文信念&#xff09;是一个用于累积通过注视获得信息的状态表示组件。它由三个部分组成&#xff1a; Fovea&#xff08;中央凹&#xff09;&#xff1a;接收来自注视位置周围区域的高分辨率视觉输入。Contextual beliefs&#xff08;上下文信念&#xf…

双月生日会:温暖相聚,共庆美好时刻

亲爱的华清远见西安中心的家人们&#xff1a; &#x1f389;&#x1f382; 在这金风送爽的秋日里&#xff0c;我们迎来了9、10月的生日会。在这个特别的日子里&#xff0c;我们聚集一堂&#xff0c;共同庆祝那些在这两个月份里出生的小伙伴们的生日。&#x1f382; 活动现场布…

Junit + Mockito保姆级集成测试实践

一、做好单测&#xff0c;慢即是快 对于单元测试的看法&#xff0c;业界同仁理解多有不同&#xff0c;尤其是在业务变化快速的互联网行业&#xff0c;通常的问题主要有&#xff0c;必须要做吗&#xff1f;做到多少合适&#xff1f;现在没做不也挺好的吗&#xff1f;甚至一些大…

【经典论文阅读11】ESMM模型——基于贝叶斯公式的CVR预估

传统的CVR模型&#xff08;也就是直接对conversion rate建模的模型&#xff09;在实际应用中面临两个问题&#xff08;样本选择偏差与数据稀疏性问题&#xff09;。为了解决这两个问题&#xff0c;本文提出ESMM模型。该模型巧妙地利用用户行为序列去建模这个问题&#xff0c;从…