数据库内核月报 - 2015 / 09-PgSQL · 答疑解惑 · 诡异的函数返回值

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介:

背景

修改PG源码时,在elog.c文件中准备调用timestamp.c中的TimestampTz GetCurrentTimestamp(void),以获取当前时间,TimestampTz是个int64类型,但是返回值类型不是期望的(是个int32值),但是在另外一个文件postgres.c调用返回的是正常的,如下:

elog.c: GetCurrentTimestamp() = 3891376011
postgres.c: GetCurrentTimestamp() = 495621643471576

也就是说,同一个函数在不同文件返回值的长度完全不同!

原因调查

首先查看具体函数定义GetCurrentTimestamp(),怀疑是elog.c没有宏定义HAVE_INT64_TIMESTAMP,随后gdb调试查看,最终计算的结果result确实是int64的值,当这个函数返回之后得到的值却变成了int32的值。

TimestampTz
GetCurrentTimestamp(void)
{
	TimestampTz result;
	struct timeval tp;

	gettimeofday(&tp, NULL);

	result = (TimestampTz) tp.tv_sec -
		((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);

#ifdef HAVE_INT64_TIMESTAMP
	result = (result * USECS_PER_SEC) + tp.tv_usec;
#else
	result = result + (tp.tv_usec / 1000000.0);
#endif

	return result;
}

难道elog.c调用的不是timestamp.c中这个函数?继续在源码中查找这个GetCurrentTimestamp函数定义,看是否有多个定义。但是查找的结果是除了这个文件有定义,其他文件都没有这个函数定义,并且在timestamp.c这个函数中添加debug信息也都打印出来了,现在可以确定是函数返回的时候将int64转成int32了。百思不得其解之际,最后在编译日志中发现一个warning:

elog.c:2245: warning: implicit declaration of function ‘GetCurrentTimestamp’

在网上搜了一下,这种警告是由于函数未声明引起的,但是GetCurrentTimestamp()在timestamp.h中声明了,通过对比postgres.c和elog.c include的头文件发现区别:postgres.c包含#include "utils/timestamp.h",也就是在postgres.c 中含有GetCurrentTimestamp的函数声明,而在elog.c中却没有。在通过测试发现,C程序如果在函数调用前,没有对函数作声明,则编译系统会把第一次遇到的该函数形式(函数定义或函数调用)作为函数的声明,并将函数类型默认为int 型!

解决方法

在elog.c中添加#include "utils/timestamp.h"头文件,并查看编译日志看是否有其他这样的warning。重新配置编译选项,加上-Werror-implicit-function-declaration,将这种warning改成error,提前报错。

总结

对于这个warning需要重视,通过修改编译选项将其变成error,便于我们发现问题,错误发现的越早越好,避免在编译时忽略或者掩盖错误。如果不是这个函数返回值错误特别明显,它将有可能成为一个隐形的bug。

目录
相关文章
|
6月前
|
SQL 数据挖掘 测试技术
南大通用GBase8s数据库:LISTAGG函数的解析
南大通用GBase8s数据库:LISTAGG函数的解析
|
6月前
|
SQL 测试技术 数据库
|
7月前
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
9月前
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
9月前
|
SQL 数据处理 数据库
|
9月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
955 0
|
11月前
|
SQL 存储 运维
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构
随着网易游戏品类及产品的快速发展,游戏数据分析场景面临着越来越多的挑战,为了保证系统性能和 SLA,要求引入新的组件来解决特定业务场景问题。为此,网易游戏引入 Apache Doris 构建了全新的湖仓一体架构。经过不断地扩张,目前已发展至十余集群、为内部上百个项目提供了稳定可靠的数据服务、日均查询量数百万次,整体查询性能得到 10-20 倍提升。
网易游戏如何基于阿里云瑶池数据库 SelectDB 内核 Apache Doris 构建全新湖仓一体架构
|
10月前
|
存储 大数据 关系型数据库
从 ClickHouse 到阿里云数据库 SelectDB 内核 Apache Doris:快成物流的数智化货运应用实践
目前已经部署在 2 套生产集群,存储数据总量达百亿规模,覆盖实时数仓、BI 多维分析、用户画像、货运轨迹信息系统等业务场景。
|
11月前
|
SQL Java Apache
阿里云数据库 SelectDB 版内核 Apache Doris 2.1.4 版本正式发布
亲爱的社区小伙伴们,Apache Doris 2.1.4 版本已于 2024 年 6 月 26 日正式发布。在 2.1.4 版本中,我们对数据湖分析场景进行了多项功能体验优化,重点修复了旧版本中异常内存占用的问题,同时提交了若干改进项以及问题修复,进一步提升了系统的性能、稳定性及易用性,欢迎大家下载使用。
|
16天前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!