通过错误来理解PostgreSQL

首先

这篇文章是在迪普股份有限公司2023年的圣诞节日历的第一天发布的!

关于这篇文章

你知道错误吗?你对PostgreSQL不太了解吧?

這篇文章的目的是為了讓人能夠理解那些難以理解的事情。它將幫助你瞭解錯誤的相關知識,同時也能增進對於PostgreSQL的理解。

通过阅读文章可以获得什么信息

通过了解以下内容,您将更深入地了解PostgreSQL。

    • PostgreSQLに関わるエラー

 

    PostgreSQL内の処理について

通过错误来理解PostgreSQL。

我们立即进入正题吧。

有关PostgreSQL的处理

首先要加深对PostgreSQL处理的理解。
在发送给PostgreSQL服务器的请求之后,如果在收到返回之前(查询)期间没有理解,那么很难确定错误的原因。具体而言,可能会在处理SQL语法错误的同时还进行网络调查等。如果不仔细阅读错误并理解,可能会采取错误的行动,因此需要深入了解处理过程,以便了解在PostgreSQL的哪个部分出现了什么错误。

我用一张图总结了非常简洁的流程。

問い合わせ処理の流れ.drawio.png

图内容如下:
1. 从客户端请求连接。
2. 如果没有问题,建立连接。
3. 从客户端发出SQL查询。
4. 完成内部处理并将结果返回给客户端。

现在我们对处理流程有了基本的了解,接下来让我们加深对PostgreSQL的理解,包括错误处理。

错误和PostgreSQL的处理

从这里开始,我们将共享有关错误的信息。
我们还将总结错误发生在PostgreSQL处理的哪个地方以及如何发生的信息。

严重错误:剩余的连接槽被保留用于非复制超级用户连接。

当请求使用第①个连接时,错误将如下所示。

错误消息如下所示。

-bash-4.2$ psql -U test
ユーザ test のパスワード:
psql: FATAL: remaining connection slots are reserved for non-replication superuser connections

可以启动一个针对连接的独立进程,但是可以通过max_connections参数指定该进程的最大数量。
由于superuser_reserved_connections参数为超级用户连接预留了空位,所以当非超级用户无法连接时会出现错误。

fatal_connections.drawio.png

错误:在“serect”处附近出现语法错误。

如果执行错误的SQL语句,将会发生错误。例如以下错误。

postgres=# serect * from table;
ERROR:  syntax error at or near "serect"
LINE 1: serect * from table;
      ^

在语法分析过程中出现错误。
具体来说,在初始解析(解析)阶段检查语法是否正确时发生错误。

error_syntax.drawio.png

错误:关系“xxx”不存在。

当指定的表格不存在时会出现错误。

postgres=# select * from aaa;
ERROR:  relation "aaa" does not exist
LINE 1: select * from aaa;
                      ^

这个错误在计划/优化步骤中出现的错误。
计划/优化程序从生成用于在查询中扫描每个关系(表)的计划开始。因此,在此过程中会进行表等的存在确认,如果不存在则会出错。

error_relation.drawio.png

运行时错误

当试图对目标对象进行操作,但没有相应权限时,会出现错误。

postgres=# select * from aaa;
ERROR:  permission denied for table aaa
                      ^

在计划者/优化器阶段会出现这个错误。
在执行计划创建完成后,在查询执行之前会进行权限检查。
如果没有所需的权限,则会产生错误。

error_relation.drawio.png

总结

这次总结的内容还有一些不完整的部分。比如在解析器和重写过程之间似乎有一个名为分析器的阶段,但由于找不到可靠的文章,所以我希望今后能加深对查询处理的理解。尽管如此,我认为通过简单地理解处理过程,能够扩大应对的范围,所以请务必借此文章来进一步加深理解。

请参考。

学习PostgreSQL从内部结构―设计和运维计划的准则
PostgreSQL内部概述
面向Oracle技术人员的PostgreSQL自学书
PostgreSQL入门∼查询处理篇∼
PostgreSQL: 查询处理

关于连接的细节被省略了。
广告
将在 10 秒后关闭
bannerAds