查看: 431|回复: 7

转贴:做好一个通用数据库产品不易

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2023-9-7 05:17 来自手机 | 显示全部楼层 |阅读模式
本帖最后由 newkid 于 2023-9-7 05:25 编辑

https://mp.weixin.qq.com/s?__biz=MzA5MzQxNjk1NQ==&mid=2647850620&idx=1&sn=396be3a9d15c35790b85be84644879cc&chksm=887862e8bf0febfe03ce70d45c8fa4cc2a58895ba5ab3f1284088d432a03615505a08c2f25c5&xtrack=1&scene=90&subscene=93&sessionid=1694034857&flutter_pos=8&clicktime=1694034870&enterid=1694034870&ascene=56&fasttmpl_type=0&fasttmpl_fullversion=6844695-en_US-zip&fasttmpl_flag=0&realreporttime=1694034870051#rd
做好一个通用数据库产品不易[color=rgba(0, 0, 0, 0.9)][color=rgba(0, 0, 0, 0.3)]Original [color=var(--weui-FG-2)]白鳝 [color=var(--weui-LINK)][url=]白鳝的洞穴[/url] [color=var(--weui-FG-2)]2023-09-05 20:14 [color=var(--weui-FG-2)]Posted on 江苏
[color=rgba(0, 0, 0, 0.9)][color=rgba(0, 0, 0, 0.5)]收录于合集
#数据库原理[color=rgba(0, 0, 0, 0.3)]215个

#国产数据库[color=rgba(0, 0, 0, 0.3)]145个

#信创生态[color=rgba(0, 0, 0, 0.3)]156个
#Oracle[color=rgba(0, 0, 0, 0.3)]16个
#Postgresql[color=rgba(0, 0, 0, 0.3)]68个


[color=rgba(0, 0, 0, 0.9)]我以前虽然也做过十多年软件开发,不过做一个真正的产品是最近这五六年的事情了,把D-SMART从一个项目变成一个产品,我们花了5年时间,目前还只是做了个开头。想做一个让不同应用习惯,不同应用场景的用户都略微满意的产品确实太难了。想做好一个数据库产品更是不易,**不是找上几个好点子,拉上三五个业内高手,找一些开源组件,赶上三五年就能大成的。因为通用数据库产品将要面对成千上万千奇百怪的用户和场景。经常看到某个DBA说,这数据库厂商太垃圾了了,这么简单的功能都做不好。实际上使用者把数据库研发想得过于简单了,如此复杂的产品,哪怕一个小功能的实现,都不那么容易做好。         
昨天一个朋友给我发来一个十分有趣的USE CASE,他们的应用在从Oracle向PG兼容的数据库上迁移的时候遇到了一个令人十分啼笑皆非的问题。我们先来看Oracle上是什么样的。         上述的一个事务大家可能都很常见,也会觉得很正常吧。启动一个事务后,在其中一条SQL语句中出现了一个语法错误,因为t2表不存在。在Oracle中不会影响事务,整个事务可以继续完成。如果换到PG数据库中,会怎么样呢?什么情况?居然整个事务出现了问题,无法继续执行了。于是我测试了一些发源于PG的数据库产品,报考人大金仓、openGauss等,无一例外,都存在类似的问题。
刚开始的时候我对这个场景也不太理解,问朋友为什么会出现事务中房屋不存在表的问题,他说他们的应用很复杂,有些组件可能没有安装,就会出现某张表不存在的情况,这些问题以前使用Oracle时都不是问题。于是我咨询了几个数据库厂商的架构师,出乎意外的是,他们似乎都知道这个问题,以前也有用户提出过类似的需求。
         经过分析我发现,实际上这个问题在PG数据库中也是历史悠久了,PG给出的解决方案是在JDBC引擎中提供一个autosave的参数,如果打开该参数连接数据库,则在每条SQL执行的时候自动生成一个savepoint,当某条SQL出现类似错误的时候,可以作为一个子事务单独回滚,从而不影响父事务。这种在JDBC中启动子事务的做法对性能是有极大影响的,如果某个应用的一个事务中执行的SQL数量很多,那么影响就会更大。在psql客户端、ODBC引擎中也有类似的方法可以实现上述功能。为了解决客户端对每条SQL都启动一个SAVEPOINT成本太高。于是有人就想到了能否在服务器端直接对每条执行的SQL自动产生一个savepoint,一旦出现类似问题,回滚掉这条SQL就行了。pg_statement_rollback就是一个这样的解决方案。因为PGER发现PG的这个问题在Oracle、DB2等商用数据库中并不存在。因此他们猜测Oracle和DB2是在服务端实现了自动回滚事务。于是模仿Oracle做了一个PG的 插件。我们先来看看这个插件的效果。         
pg_statement_rollback支持PG 9.5以上,所以基于低于这个版本的PG内核开发的国产数据库,比如openGauss和早期的人大金仓是无法安装的。启用了插件之后,似乎还是如此,并没有解决这个问题。这是怎么回事呢?仔细阅读了插件的说明后终于明白了其中的原委。既然插件的原理是在服务端自动启动了一个savepoint,那么要纠正这个错误就必须手工rollback到这个savepoint。这是pg_statement_rollback假定的那个场景,当一条SQL执行出错,但是这条SQL并不对整个事务的其他部分产生影响的时候,可以通过这个插件来解决。这个技术实现还是把那条语法错误的SQL当成了事务的一部分。不过似乎Oracle的实现并非如此,因为那条SQL执行过程中出现了语法错误,那么这条出错的SQL并未对整个事务产生任何影响。如果把这条SQL不认为是事务的一部分,直接忽略掉这个执行出错,可能更符合应用逻辑。
        
昨天下午我和一个国产数据库厂商的架构师针对这个问题做了探讨,刚开始的时候他表示这个需求以前有一个用户提出过,因为比较复杂,所以还没有确定是否要开展这方面的研发。他认为在一个事务中不通过子事务来回滚一条SQL语句这个需求**不是数据库来实现,而是应用自己来实现,回滚掉整个事务是**的解决方案。         
实际上对这个问题,PG社区的产品经理以及一些国产数据库的产品经理都产生了错误的理解。他们把这个问题抽象为“在不使用子事务的前提下在事务中回滚掉某条SQL”。而实际上这个问题并非如此。一个事务中会发生很多种SQL出错,比如部分主键/外键冲突、触发器故障、自增字段故障、某张表无法扩展等,这类出错,回滚掉整个事务是**的处理方法。         
而这个CASE与之不同,应该是一种特殊的情况,这条SQL因为语法语义上的错误,实际上并不能执行,不会对整个事务产生任何影响。此时无需回滚任何子事务,而只需要忽略这个错误就可以了。这实际上是一个新的需求,不能和回滚某条SQL的需求混为一谈。         
理解了这个场景需求后,和我交流的数据库架构师认为这个需求很合理,而且他们的研发人员在实现该功能上也没有太大的难度。以前这个问题没有得到解决是因为解题的思路出现了问题,今天理顺了这个场景解决这个问题就十分简单了。如果能够把一些像语法、对象、约束的检查和事务状态分离来,可能可以实现一个轻量级的语句级回滚功能。他们会很快把该功能排期到研发中。         
这个案例实际上并不复杂,实现起来技术难度也不高。不过PG实现这个功能的时候,对这个场景需求的理解产生了错误,因此在解决该问题的时候走上了一条邪路。从这个简单的场景也可以看出,要做好一个数据库,仅仅依靠**的研发人员和数据库产品经理、架构师是完全不够的,在大量的用户场景中不断磨练,才能够让数据库产品变得更加强大。只有长时间在大量的用户中磨练的产品才能真正走向成熟。希望我今天的这个案例能让那些觉得自己数据库产品技术上远远领先于Oracle这些过时年代产品的数据库从业人员能够清醒一些,通用数据库产品能适应用户的各种场景才是王道,做好这一点,不是靠高水平的天才设计出来的,是需要时间来沉淀的。         
         



论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
 楼主| 发表于 2023-9-7 05:27 | 显示全部楼层
OO 的电脑里面有上百种数据库了吧?快测试一下其他库表现如何。

转帖一点东西真是难于上青天,图片被微信限制,ITPUB又有无数敏感词。坚决拥护****的领导!

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
 楼主| 发表于 2023-9-7 05:32 | 显示全部楼层
引用:“ 一个事务中会发生很多种SQL出错,比如部分主键/外键冲突、触发器故障、自增字段故障、某张表无法扩展等,这类出错,回滚掉整个事务是最 佳的处理方法。”

对于上述错误,ORACLE也只是做了语句级的回滚,并不会回滚整个事务。如果执行的是PLSQL块则整个块所做的修改被回滚。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2023-9-7 06:34 来自手机 | 显示全部楼层
duckdb没有这个问题
~ $ duckdb
v0.7.1 b00b93f
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D create table t1 as select 1 a;
D begin;
D update t1 set a=2;
D select a from t2;
Error: Catalog Error: Table with name t2 does not exist!
Did you mean "t1"?
LINE 1: select a from t2;
                      ^
D select a from t1;
┌───────┐
│   a   │
│ int32 │
├───────┤
│     2 │
└───────┘
D end;
D begin;
D update t1 set a=20;
D select a from t1;
┌───────┐
│   a   │
│ int32 │
├───────┤
│    20 │
└───────┘
D select a from t2;
Error: Catalog Error: Table with name t2 does not exist!
Did you mean "t1"?
LINE 1: select a from t2;
                      ^
D rollback;
D select a from t1;
┌───────┐
│   a   │
│ int32 │
├───────┤
│     2 │
└───────┘
D end;
Error: TransactionContext Error: cannot commit - no transaction is active

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2023-9-7 08:03 | 显示全部楼层
sqlite也是好的
sqlite>  create table t1 as select 1 a;
sqlite> begin;
sqlite> update t1 set a=2;
sqlite> select a from t2;
Parse error: no such table: t2
sqlite> select a from t1;
2
sqlite> rollback;
sqlite> end;
Runtime error: cannot commit - no transaction is active
sqlite>

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2023-9-7 09:29 来自手机 | 显示全部楼层
https://mp.weixin.qq.com/s/B0XAjKk00OonFrQ8Xt16iw 后续

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
 楼主| 发表于 2023-9-7 22:10 | 显示全部楼层
很多产品都解决了,可见不算什么难题。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2023-9-8 08:02 | 显示全部楼层
newkid 发表于 2023-9-7 22:10
很多产品都解决了,可见不算什么难题。

就是惯例,像oracle的空字符串就是NULL

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表