PostgreSQL SPI 中的错误处理

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介:

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
6天前
|
存储 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将在一次后端崩溃后自动重新初始化。
1130 0
|
6天前
|
SQL 关系型数据库 数据库
关系型数据库选择合适的数据库管理系统
【5月更文挑战第5天】关系型数据库选择合适的数据库管理系统
259 2
关系型数据库选择合适的数据库管理系统
|
6天前
|
关系型数据库 MySQL BI
关系型数据库选择合适的数据库管理系统
【5月更文挑战第4天】关系型数据库选择合适的数据库管理系统
182 4
关系型数据库选择合适的数据库管理系统
|
4天前
|
Cloud Native 关系型数据库 分布式数据库
祝贺!阿里云PolarDB斩获数据库国际顶会ICDE 2024工业赛道最佳论文
阿里云斩获国际顶会ICDE 2024最佳论文,0.5秒实现数据库跨机实例迁移。
祝贺!阿里云PolarDB斩获数据库国际顶会ICDE 2024工业赛道最佳论文
|
4天前
|
关系型数据库 数据库 数据安全/隐私保护
使用PostgreSQL进行高级数据库管理
【5月更文挑战第17天】本文介绍了使用PostgreSQL进行高级数据库管理,涵盖性能调优、安全性加强和备份恢复。性能调优包括索引优化、查询优化、分区和硬件配置调整;安全性涉及权限管理、加密及审计监控;备份恢复则讨论了物理备份、逻辑备份和持续归档。通过这些实践,可提升PostgreSQL的性能和安全性,确保数据资源的有效管理。
|
6天前
|
存储 Cloud Native 关系型数据库
PolarDB-X 是面向超高并发、海量存储和复杂查询场景设计的云原生分布式数据库系统
【5月更文挑战第14天】PolarDB-X 是面向超高并发、海量存储和复杂查询场景设计的云原生分布式数据库系统
44 2
|
6天前
|
Cloud Native 关系型数据库 分布式数据库
PolarDB是阿里云自主研发的关系型云原生数据库
【5月更文挑战第14天】PolarDB是阿里云自主研发的关系型云原生数据库
46 3
|
6天前
|
存储 关系型数据库 MySQL
Percona XtraBackup是否支持PostgreSQL数据库备份?
【5月更文挑战第13天】Percona XtraBackup是否支持PostgreSQL数据库备份?
52 1
|
6天前
|
负载均衡 关系型数据库 MySQL
关系型数据库的安装和配置数据库节点
【5月更文挑战第5天】关系型数据库的安装和配置数据库节点
131 3
关系型数据库的安装和配置数据库节点