WSO2 DAS 事件插入错误(重复键值违反唯一约束)与 PostgreSQL
WSO2 DAS Event insertion error (duplicate key value violates unique constraint) with PostgreSQL
我们在使用 PostgreSQL 数据库的 DAS (WSO2) 中遇到错误。出于某种我们不知道的原因,正在用一些痕迹填充 PostgreSQL 日志:
< 2017-02-23 14:04:52.276 CET >ERROR: relation "anx__8gohuwju" does not exist at character 15
< 2017-02-23 14:04:52.276 CET >STATEMENT: SELECT 1 FROM ANX__8GOHUwJU LIMIT 1
< 2017-02-23 14:04:52.277 CET >ERROR: relation "anx__8gaxmlni" does not exist at character 15
< 2017-02-23 14:04:52.277 CET >STATEMENT: SELECT 1 FROM ANX__8GAXMlnI LIMIT 1
< 2017-02-23 14:04:52.278 CET >ERROR: relation "anx__8gicci_y" does not exist at character 15
< 2017-02-23 14:04:52.278 CET >STATEMENT: SELECT 1 FROM ANX__8GICCI_Y LIMIT 1
...
...
...
< 2017-02-23 14:04:57.335 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.337 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.337 CET >DETAIL: Key (record_id)=(770425a8-b65b-37ad-ad13-6bd45014ef9a) already exists.
< 2017-02-23 14:04:57.337 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.431 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.431 CET >DETAIL: Key (record_id)=(da6cfb07-4aff-3bb2-9c71-8f3e6d749762) already exists.
< 2017-02-23 14:04:57.431 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.433 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.433 CET >DETAIL: Key (record_id)=(da6cfb07-4aff-3bb2-9c71-8f3e6d749762) already exists.
< 2017-02-23 14:04:57.433 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.776 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.776 CET >DETAIL: Key (record_id)=(c7c32813-51c6-34dd-8a34-e76add9839b6) already exists.
< 2017-02-23 14:04:57.776 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )*
我们不知道,因为它正在发生,也不知道它是否是 DAS 和 PostgreSQL 之间的错误或兼容性故障。日志中出现的错误痕迹每5秒重复一次,不停地填充数据库的日志,导致系统停止工作。
如您所见,有两种类型的错误:
- "duplicate key value violates unique constraint XXX"
- "relation XXX does not exist at character 15"
我们已经用多个DAS 实例和不同的PostgresSQL 对其进行了测试,结果是一样的。怎么回事?
我已将 DAS 配置为使用 PostgreSQL 数据库进行配置 (master-datasources.xml) 和事件 (analytics-datasources.xml)。我们所做的测试使用的是 PostgreSQL 9.3 和 9.6,结果相同。
我已经检测到问题并找到了解决方案。问题是 PostgreSQL 的 "merge" 操作被禁用,因此 "inserts" 在应该执行 "updates".
时失败了
此错误在文件 "rdbms-config.xml" 中。 PostgreSQL数据库中的"recordMergeQuery"标签被注释掉了。
要解决这个问题,您应该取消注释标签并修改无效的查询。有效的查询是这样的:
<recordMergeQuery>INSERT INTO {{TABLE_NAME}} (partition_key, timestamp, data, record_id) VALUES (?, ?, ?, ?) ON CONFLICT (record_id) DO UPDATE SET partition_key = excluded.partition_key, timestamp = excluded.timestamp, data = excluded.data</recordMergeQuery>
“重复键”的问题已通过正确的查询解决 "recordMergeQuery"。但是“关系 XXX 在字符 15 处不存在”的另一个问题仍在继续。我们已经用双引号更改了 TABLE_NAME 但它仍然出现错误消息。
现在用双引号将日志显示为相同的消息,因为 table 实际上不存在。为什么?我们不知道为什么会这样。我们删除了所有临时目录 (tmp)、solr、数据。数据库干净,从头开始构建。
尽管您看到的日志性质令人担忧,但据我所知,DAS 和 PostgreSQL 之间没有发生意外情况。
这两个日志都是预期的,因为对于数据访问操作,DAS 会在提交之前检查 table 是否存在。如果 table 不存在,这通常会在数据库端产生错误。这是正常的。
此外,将尝试对记录执行 INSERT OVERWRITE 操作作为 INSERT,然后如果该记录已经存在(即违反唯一约束),则会更新该记录。这是由于 unavailability of a MERGE statement in PostgreSQL prior to version 9.5 以及始终执行 UPDATE 调用的相对性能缺陷。
至于您的解决方案,取消注释 "recordMergeQuery" 完全可以接受table,但前提是您使用的是 PostgreSQL 9.5+。否则,写入操作将失败。在这种情况下,we use Postgres 提供的新 INSERT ... ON CONFLICT UPDATE
语法(参见 [2])。
如果您需要任何进一步的说明,请随时询问。
链接:
[1] https://wiki.postgresql.org/wiki/SQL_MERGE
[2] https://github.com/wso2/carbon-analytics/blob/v1.3.6/features/analytics-data-connectors/org.wso2.carbon.analytics.datasource.rdbms.server.feature/src/main/resources/conf/analytics/rdbms-config.xml#L152
我们在使用 PostgreSQL 数据库的 DAS (WSO2) 中遇到错误。出于某种我们不知道的原因,正在用一些痕迹填充 PostgreSQL 日志:
< 2017-02-23 14:04:52.276 CET >ERROR: relation "anx__8gohuwju" does not exist at character 15
< 2017-02-23 14:04:52.276 CET >STATEMENT: SELECT 1 FROM ANX__8GOHUwJU LIMIT 1
< 2017-02-23 14:04:52.277 CET >ERROR: relation "anx__8gaxmlni" does not exist at character 15
< 2017-02-23 14:04:52.277 CET >STATEMENT: SELECT 1 FROM ANX__8GAXMlnI LIMIT 1
< 2017-02-23 14:04:52.278 CET >ERROR: relation "anx__8gicci_y" does not exist at character 15
< 2017-02-23 14:04:52.278 CET >STATEMENT: SELECT 1 FROM ANX__8GICCI_Y LIMIT 1
...
...
...
< 2017-02-23 14:04:57.335 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.337 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.337 CET >DETAIL: Key (record_id)=(770425a8-b65b-37ad-ad13-6bd45014ef9a) already exists.
< 2017-02-23 14:04:57.337 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.431 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.431 CET >DETAIL: Key (record_id)=(da6cfb07-4aff-3bb2-9c71-8f3e6d749762) already exists.
< 2017-02-23 14:04:57.431 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.433 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.433 CET >DETAIL: Key (record_id)=(da6cfb07-4aff-3bb2-9c71-8f3e6d749762) already exists.
< 2017-02-23 14:04:57.433 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )
< 2017-02-23 14:04:57.776 CET >ERROR: duplicate key value violates unique constraint "anx__7lvaftvw_pkey"
< 2017-02-23 14:04:57.776 CET >DETAIL: Key (record_id)=(c7c32813-51c6-34dd-8a34-e76add9839b6) already exists.
< 2017-02-23 14:04:57.776 CET >STATEMENT: INSERT INTO ANX__7LvafTvw (partition_key, timestamp, data, record_id) VALUES (, , , )*
我们不知道,因为它正在发生,也不知道它是否是 DAS 和 PostgreSQL 之间的错误或兼容性故障。日志中出现的错误痕迹每5秒重复一次,不停地填充数据库的日志,导致系统停止工作。
如您所见,有两种类型的错误:
- "duplicate key value violates unique constraint XXX"
- "relation XXX does not exist at character 15"
我们已经用多个DAS 实例和不同的PostgresSQL 对其进行了测试,结果是一样的。怎么回事?
我已将 DAS 配置为使用 PostgreSQL 数据库进行配置 (master-datasources.xml) 和事件 (analytics-datasources.xml)。我们所做的测试使用的是 PostgreSQL 9.3 和 9.6,结果相同。
我已经检测到问题并找到了解决方案。问题是 PostgreSQL 的 "merge" 操作被禁用,因此 "inserts" 在应该执行 "updates".
时失败了此错误在文件 "rdbms-config.xml" 中。 PostgreSQL数据库中的"recordMergeQuery"标签被注释掉了。
要解决这个问题,您应该取消注释标签并修改无效的查询。有效的查询是这样的:
<recordMergeQuery>INSERT INTO {{TABLE_NAME}} (partition_key, timestamp, data, record_id) VALUES (?, ?, ?, ?) ON CONFLICT (record_id) DO UPDATE SET partition_key = excluded.partition_key, timestamp = excluded.timestamp, data = excluded.data</recordMergeQuery>
“重复键”的问题已通过正确的查询解决 "recordMergeQuery"。但是“关系 XXX 在字符 15 处不存在”的另一个问题仍在继续。我们已经用双引号更改了 TABLE_NAME 但它仍然出现错误消息。
现在用双引号将日志显示为相同的消息,因为 table 实际上不存在。为什么?我们不知道为什么会这样。我们删除了所有临时目录 (tmp)、solr、数据。数据库干净,从头开始构建。
尽管您看到的日志性质令人担忧,但据我所知,DAS 和 PostgreSQL 之间没有发生意外情况。
这两个日志都是预期的,因为对于数据访问操作,DAS 会在提交之前检查 table 是否存在。如果 table 不存在,这通常会在数据库端产生错误。这是正常的。
此外,将尝试对记录执行 INSERT OVERWRITE 操作作为 INSERT,然后如果该记录已经存在(即违反唯一约束),则会更新该记录。这是由于 unavailability of a MERGE statement in PostgreSQL prior to version 9.5 以及始终执行 UPDATE 调用的相对性能缺陷。
至于您的解决方案,取消注释 "recordMergeQuery" 完全可以接受table,但前提是您使用的是 PostgreSQL 9.5+。否则,写入操作将失败。在这种情况下,we use Postgres 提供的新 INSERT ... ON CONFLICT UPDATE
语法(参见 [2])。
如果您需要任何进一步的说明,请随时询问。
链接:
[1] https://wiki.postgresql.org/wiki/SQL_MERGE
[2] https://github.com/wso2/carbon-analytics/blob/v1.3.6/features/analytics-data-connectors/org.wso2.carbon.analytics.datasource.rdbms.server.feature/src/main/resources/conf/analytics/rdbms-config.xml#L152