论文:Anarchy in the Database: A Survey and Evaluation of Database Management System Extensibility
github:https://github.com/cmu-db/ext-analyzer
pgconf:The trouble with extensions (PGConf.dev 2025)
why this paper
这是一篇数据库插件综述(主要是Postgres),主要讲不同数据库插件的实现方式、存在的问题和最重要的兼容性。其中最重磅的结论是:对 400 多个 PostgreSQL 扩展的评估显示,其中 16.8% 的扩展与至少一个其他扩展存在兼容性问题,且可能导致系统故障。
分析工具和结果见github;Marco Slot的ppt演讲见PGconf。
插件类别
插件分类
插件分类章节特别冗长,其实一个图就能看明白了。
6种数据库的插件:

- PostgreSQL(1986):C 语言编写,从设计之初就定位为可扩展架构。因此,PostgreSQL 拥有最为丰富多样的可扩展生态网络。
- MySQL(1994): C++ 语言编写,其最知名的特性是存储引擎插件架构。
- MariaDB(2009):作为 MySQL 的分支版本,它同样基于 C++ 开发,支持的扩展数量比原版 MySQL 更多。
- SQLite(2000):嵌入式数据库,C 语言编写,可适配各类硬件设备与操作系统环境。
- Redis(2009):内存型键值库,C++ 语言编写,其可扩展性独具特色 ------ 仅支持在 DBMS key-value存储层之上运行。
- DuckDB(2018):嵌入式分析型数据库,C++ 编写,拥有快速兴起的可扩展生态系统。
灵活性和安全性
插件的安全性和灵活性只能二选一,pg的插件是最灵活也是最不安全的,redis是最安全也最不灵活的:

postgres的插件一般怎么实现的
pg总体有两种方式实现扩展:
- 通过handler function实现,如UDF,UDTs, external tables, storage engines, and index access methods.
- 通过hooks钩子实现扩展。将钩子声明为全局变量中的函数指针,如果设置了钩子,它将调用这些指针而不是自己的代码
实现方式可能是都包含的,并不排他。其他5个库的实现总体类似,但是他们都没有hooks这种形式的实现。

插件可能使用不同的方式来实现,比如funcion+types+index am,这就是可扩展性类型数量(number of extensibility types)。从figure 1可以看到有1-3中类型的扩展是最多的,而使用最多的实现方式就是function。
从table3可以看出,有92.5%的插件都在使用UDF,毕竟是面向用户的特性,开发最为方便、门槛低。最少的是客户端认证,因为这种场景本身也不多。
插件代码的copy率
文章还进行了一个有趣的调查研究,插件代码从build-in代码中的copy情况:

441个插件中有16.6%--73个插件含有至少1行从PG源码中copy的代码。详细分布如上图左。
为什么有这么多插件是copy的代码呢?因为
- pg源码中有些是静态声明的函数,只能在本文件中调用,所以只能copy
- 因为插件本身的需求,函数可能需要做出一点调整,所以只能copy出来调整
而插件一般copy函数调整了多少呢?如上图右。
可以看出,原封不动copy的其实是很少的。
总之,插件代码从pg源码中copy,是因为某些原因而不得已的,整体copy率也不高。
重磅!------PG插件的兼容性
这是这篇文章最有趣的部分,总计对96个extension进行1对1的兼容性测试,测试发现有16.8%的两个插件是不兼容的!

测试方式:
- 安装。是的,安装就可能有问题了,并且作者进行了A->B,B->A两种顺序的安装和测试,所以可以看到图是不对称的
- 运行扩展提供的单元测试
- pgbench。冒烟测试。pgbench当然很简单,不过结果很不错的话也可以说明一定问题了。
在兼容性最差的插件top20里面,也能看到很多常见的插件:
- 常用的插件:pg_hint_plan,vector,pg_show_plans,pgsentinel,pg_cron,pg_stat_kcache
- 很重的插件:citus,timescaledb
这些极其常见的插件和明星插件的兼容性可以这么差,这个结果足以惊掉下巴。
细思极恐的是,这还只是简单的捉对测试,3-10个插件的运行才应该是生产常态,而且生产环境也比论文中的三种测试方式更加复杂多变。
最后论文还提出插件兼容性较差的原因:插件使用越多的组件、扩展type、hooks,就越有可能跟其他扩展不兼容。
挑刺
- 其实还是研究的postgres
文章标题是写DBMS的,但主要还是写pg的兼容性,mysql、redis等等的兼容性只是综述带过,完全没有实验数据。(虽然综述也很有意思,可以了解到mysql和redis的插件是怎么实现的)。
另一个方面,这个文章有一种另类"总-分-总"的感觉," DBMS-postgres-DBMS"😅
- 兼容性测试不足
PG有400+插件,只测试了其中96个兼容性测试,也只有1-1的兼容性测试,不包含3个插件及以上的测试。兼容性测试不算特别全面。
结论
PG的插件确实很多很灵活,数量也很多,你都很难找到哪些是PG插件不支持的功能。但是插件本身几乎是"无政府状态",插件的开发和使用都有些问题。
从兼容性结果来看,插件的兼容性是比较差的,甚至插件的安装顺序影响兼容性,多插件本身也依赖hook的执行顺序,比如2个插件都要求自己最后执行就比较尴尬了。"什么都有"不代表"什么都装"。
插件的安全问题
PG的插件在安全层面管理几乎是没有的,无论是插件本身不安全还是用户使用插件提权。
-
如果扩展包含有不安全的语言,能限制其行为的只有OS而不是DBMS
-
如果扩展可以访问用户空间,OS层就做不了管理了
-
通过查询(如UDF)实现的extension基本不会绕过ACL策略。虽然UDF更安全,但是也不是绝对安全,因为可以有含管理员权限的UDF。
-
单hook可能不会受到ACL的限制,因为在postgres中ACL只在planning和execution层执行。PG提供了
SECURITY LABEL来限制对象(包括插件)的访问控制
软件管理的哲学思考
"如果扩展包含有不安全的语言,能限制其行为的只有OS而不是DBMS"
这句话本身没有毛病,但是含有"你的目录会被删除"的暗示。为了反驳一下这句话,可以这样思考。
如果你使用这款软件,那么就是信任这款软件,如同pg本身一样(但即使使用pg这款软件,也需要建立postgres这个os user,而不是直接使用root)。至于插件,可以把它当成pg软件的一部分。pg之所以被信任,能直接在生产环境安装,是因为业界有口皆碑。同样插件也是一样的,选择有口皆碑的插件,而不是胡乱使用。这本质上是postgres社区把关和插件提供方把关的区别。对于云服务商,很多插件都是不支持的,云服务商承担了插件把关的职能和背锅的责任。
版本收敛
pg的插件版本有这些特性:
-
同一个插件,不同的数据库版本会有不同的插件包
-
插件有不同的版本
这就导致对插件版本没有管理的话,会出现多到难以管理的软件version。针对这个问题,限制不同PG版本安装指定的某一个插件版本,是一个不错的选择。至于处于某些需求的原因需要插件升级,通过pg版本升级来实现。这样的策略相当于牺牲了一定的灵活性,来保证稳定性。我个人认为是值得的,因为升级插件这个需求本身不多,但可以减少很多软件管理问题和未知的兼容性问题。
使用插件时要考虑兼容性问题
既然插件兼容性不怎么样,那么管理插件变得尤为重要,我们不希望数据库返回奇怪的结果甚至跑着跑着就挂了
- 插件管理策略:1.安装必要插件 2.再按需创建需要的插件 3.不要装没什么人用的插件
- 搜索兼容性矩阵。虽然PG兼容性测试并不完美,但还是有价值的。因为论文不好直接搜兼容性矩阵,但可以"ctrl+f"搜索ext-analyzer的兼容性表格,初步判断你需要使用的插件的兼容性是否优秀。
趣闻
在1976年的INGRES论文中,已通过扩展实现了UDF;即使是POSTGRES,也在1986年的初始版本中转移了这个功能实现。而ORACLE 的UDF实现是ORACLE 7,release时间是1992年,比PG晚不少。


而SQL标准是1996年才包含了UDF,离INGRES的UDF过去了整20年。stone braker确实是不太注重标准的推动。