6. 关于PG源代码中的ereport类似的函数的一些理解
当我们阅读PG源代码时,会很容易注意到在源代码各处都有类似的函数调用:
ereport(PANIC,
(errmsg("could not locate a valid checkpoint record at %X/%X",
LSN_FORMAT_ARGS(CheckPointLoc))));
这种函数类似C语言中的printf()函数,会在日志中写入信息。我们看看这个函数的定义:
#define ereport(elevel, ...) \
ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__)
再继续挖掘下去:
#define ereport_domain(elevel, domain, ...) \
do { \
const int elevel_ = (elevel); \
pg_prevent_errno_in_scope(); \
if (errstart(elevel_, domain)) \
__VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \
if (elevel_ >= ERROR) \
pg_unreachable(); \
} while(0)
我们在上述代码中看到这样的语句:
if (elevel_ >= ERROR) \
pg_unreachable(); \
pg_unreachable()函数的定义如下:
#define pg_unreachable() abort()
关于abort()函数的用法,可以参考这个网页:
https://man7.org/linux/man-pages/man3/abort.3.html
由这个网页可知:abort()实际上就是终止本进程。
ERROR的定义如下:
#define PGWARNING 19 /* Must equal WARNING; see NOTE below. */
#define WARNING_CLIENT_ONLY 20 /* Warnings to be sent to client as usual, but
* never to the server log. */
#define ERROR 21 /* user error - abort transaction; return to
* known state */
#define PGERROR 21 /* Must equal ERROR; see NOTE below. */
#define FATAL 22 /* fatal error - abort process */
#define PANIC 23 /* take down the other backends with me */
根据以上的分析,我们可以得出一个结论:
当我们使用ereport()时,如果第一个参数是ERROR或者更高等级的错误(包括PGERROR, FATAL和PANIC)时,则本进程在ereport()函数执行结束时会终止。