PostgreSQL SPI 中的错误处理

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介:

PostgreSQL SPI 用于在 C 或是其他编程语言编写的扩展函数(存储过程)中调用数据库本身的解析器、规划器和执行器的功能,以及对 SQL 语句进行执行。

在最重要的一个函数 SPI_execute 的文档中,说明了发生错误时,将会返回下列负值之一:

SPI_ERROR_ARGUMENT
如果command为NULL或者count小于 0

SPI_ERROR_COPY
如果尝试COPY TO stdout或者COPY FROM stdin

SPI_ERROR_TRANSACTION
如果尝试了一个事务操纵命令( BEGIN、 COMMIT、 ROLLBACK、 SAVEPOINT、 PREPARE TRANSACTION、 COMMIT PREPARED、 ROLLBACK PREPARED或者其他变体)

SPI_ERROR_OPUNKNOWN
如果命令类型位置(不应该会发生)

SPI_ERROR_UNCONNECTED
如果调用过程未连接

你一定会奇怪,为什么只有这么几个呢?还有其他的很多情况呢?比如传进去的 SQL 有语法错误,或是实际执行时报错,这些情况下会返回什么呢?

然后文档中又说:注意如果一个通过 SPI 调用的命令失败,那么控制将不会返回到你的过程中。当然啦,你的过程所在的事务或者子事务将被回滚(这可能看起来令人惊讶,因为据文档所说 SPI 函数大多数都有错误返回约定。但是那些约定只适用于在 SPI 函数本身内部检测到的错误)。通过在可能失败的 SPI 调用周围建立自己的子事务可以在错误之后恢复控制。当前文档中并未记载这些,因为所需的机制仍然在变化中。

原来检查 SPI_execute 的源代码可知,只有发生了上面几种情况的错误时,SPI 会返回给你错误代码;而其他更内部的地方发生的所有错误,程序都是直接调用的 ereport 方法,如果错误级别达到 ERROR 及以上时,会中断程序的执行,将事务回滚,并将错误信息:1、记到日志中;2、返回给客户端。

因此,其他情况的错误,你根本就不必处理,PG 也不给你机会处理。你只有在客户端才能看到具体的报错信息。

如果你是在一个很大的逻辑里,不想整个事务被回滚掉,想出错后控制还返回给程序,可以用 PG_TRYPG_CATCHPG_END_TRY 几个宏来通知 ereport 将控制返回给程序,同时用一个子事务把对 SPI 的调用包起来,参考 PL/Python 源代码 plpy_spi.c 中,PLy_spi_subtransaction_<begin/commit/abort> 等方法的处理。

这也是因为 PostgreSQL 是用 C 语言开发的,一个不够强的地方。假如将来用 Rust 重写,一定会比现在的处理方式好得多。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
4月前
|
存储 SQL Oracle
02-PostgreSQL 存储过程的进阶介绍(含游标、错误处理、自定义函数、事务)
02-PostgreSQL 存储过程的进阶介绍(含游标、错误处理、自定义函数、事务)
|
关系型数据库 数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 19 章 服务器配置_19.14. 错误处理
19.14. 错误处理 exit_on_error (boolean) 如果为真,任何错误将中止当前会话。默认情况下,这个值被设置为假,这样只有 FATAL 错误(致命)将中止会话。 restart_after_crash (boolean) 当被设置为真(默认值)时,PostgreSQL将在一次后端崩溃后自动重新初始化。
1148 0
|
关系型数据库 分布式数据库 PolarDB
|
关系型数据库 分布式数据库 定位技术
PolarDB for PostgreSQL 开源必读手册-VACUUM处理(中)
PolarDB for PostgreSQL 开源必读手册-VACUUM处理
138 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
339 0
|
存储 缓存 关系型数据库
|
存储 SQL 并行计算
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍(中)
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍
392 0
|
存储 算法 安全
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍(下)
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍
359 0
|
关系型数据库 分布式数据库 开发工具
|
存储 关系型数据库 Linux
PolarDB for PostgreSQL 开源必读手册-PolarDB安装与配置(下)
PolarDB for PostgreSQL 开源必读手册-PolarDB安装与配置
618 0