cannot perform an INSERT without a partition column value

Posted 境悟初

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cannot perform an INSERT without a partition column value相关的知识,希望对你有一定的参考价值。

文题是一个错误,小众错误,或许和postgresql相关,或许和citus相关。然而这个错误在网络上只会有一个地方存在。

故事背景

错误的背景就使用 benchmarksql工具测试citus的TPCC性能。因为citus是PG的一个分布式插件,能将多个单机PG节点变成分布式数据库,这种分库分表的插件的使用需要一个额外的操作:建立分片规则。

在citus中,就是建分布式表,比如对 user表基于 id分片。

SELECT create_distributed_table('user', 'id');

TPCC规范涉及9张表,分为5个场景,表之间涉及多种join和事务更新,所以这个分片规则还不是那么好建。

我从citus的tpcc测试入手,搜索到同样的issue:https://github.com/citusdata/citus/issues/4126.
这哥们给了一套建分布式表的方案,但是测出来的性能太差了。不过人家跑通了呀。

于是我基于这位仁兄的建议建了如下分布式表:关于引用表,可以参考citus文档。

SELECT create_distributed_table('bmsql_config', 'cfg_name');
SELECT create_distributed_table('bmsql_new_order', 'no_w_id');
SELECT create_distributed_table('bmsql_oorder', 'o_w_id');
SELECT create_distributed_table('bmsql_order_line', 'ol_w_id');
SELECT create_distributed_table('bmsql_history','hist_id');
SELECT create_distributed_table('bmsql_customer','c_w_id');

SELECT create_reference_table('bmsql_item');
SELECT create_reference_table('bmsql_district');
SELECT create_reference_table('bmsql_warehouse');
SELECT create_reference_table('bmsql_stock');

然后使用benchmarksql测试时就会出现下面的报错:

22:05:39,296 [Thread-1] ERROR  jTPCCTData : Unexpected SQLException in PAYMENT
22:05:39,296 [Thread-1] ERROR  jTPCCTData : ERROR: cannot perform an INSERT without a partition column value
org.postgresql.util.PSQLException: ERROR: cannot perform an INSERT without a partition column value
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:365)
	at jTPCCTData.executePayment(jTPCCTData.java:930)
	at jTPCCTData.execute(jTPCCTData.java:99)
	at jTPCCTerminal.executeTransactions(jTPCCTerminal.java:160)
	at jTPCCTerminal.run(jTPCCTerminal.java:88)
	at java.lang.Thread.run(Thread.java:748)

黎明的光辉

经过了一夜的思考,我决定冰释前嫌,重新上路。

首先,报错信息在google里搜索,结果发现只有一条完全匹配的信息:

这时我的内心是崩溃的,难的不是问题,而是孤独。

于是从这一条信息出发,发现这哥们也遇到了一样的问题,然而并没有人解答。

这真是悲哀,这条路走到了尽头,那么只有换条路了。

于是我继续从那哥们的ssue入手:https://github.com/citusdata/citus/issues/4126.

顺着开发人员的回答,我找到了官方测试benchmark的方案:https://github.com/citusdata/ch-benchmark.

这个仓库是基于 HammarDB测试框架开发的citus测试,里面的文件不多,我想肯定能找到建表语句。于是我一个个找,最终没想到是在 patch文件里: https://github.com/citusdata/ch-benchmark/blob/master/HammerDB-patch/4.0.patch

经过阅读,提取出关键信息:

SELECT create_distributed_table('bmsql_customer', 'c_w_id');
SELECT create_distributed_table('bmsql_district', 'd_w_id');
SELECT create_distributed_table('bmsql_history', 'h_w_id');
SELECT create_distributed_table('bmsql_warehouse', 'w_id');
SELECT create_distributed_table('bmsql_stock', 's_w_id');
SELECT create_distributed_table('bmsql_new_order', 'no_w_id');
SELECT create_distributed_table('bmsql_oorder', 'o_w_id');
SELECT create_distributed_table('bmsql_order_line', 'ol_w_id');
SELECT create_reference_table('bmsql_item');

这就是最终的TPCC分布式建表语句。使用这种方式建分布式表,可以正确测试出结果。

圆满结局

其实,这个问题非常小,但是我突然意识到了一些更深层次的东西。
作为一个程序员,理解东西和解决问题并不是等价的,我并不清楚citus实现分布式表的细节,只知道分布式表和引用表的概念,再加上强大的搜索引擎能力,完全可以解决别人已经遇到过的问题。
所以,我只能是一个解决已有问题的程序员,而不是一个创造事物的科学家。

突然觉得自己也挺可笑和无奈的,程序员以为自己在创造产品,创造世界,其实大部分人不过是重复地创造轮子,重复地解决别人解决过的问题。
意识到这一点,我发现这是整个人类的问题,人类有了互联网,信息互联,触手可及。但是每个人从出生开始都需要不断学习才能获取这些知识,在时间的长河中,人类的生命昙花一现,何其短暂。却也能绽放出一些娇艳。
突然想到刘慈欣大师的科幻作品《乡村教师》,要是人类的记忆可以遗传,就不用老师呕心沥血了吧。
记忆不等于知识,知识不等于能力,解决问题不等于创造未来。
我笑一笑,合上电脑。

以上是关于cannot perform an INSERT without a partition column value的主要内容,如果未能解决你的问题,请参考以下文章

[!] CDN: trunk - Cannot perform full-text search because Algolia returned an error: 0: Cannot reach

[!] CDN: trunk - Cannot perform full-text search because Algolia returned an error: 0: Cannot reach

[!] CDN: trunk - Cannot perform full-text search because Algolia returned an error: 0: Cannot reach(

[!] CDN: trunk - Cannot perform full-text search because Algolia returned an error: 0: Cannot reach

Error: Cannot perform an interactive login from a non TTY device

ORA-12838: cannot read/modify an object after modifying it in parallel