Ошибка вставки события WSO2 DAS (повторяющееся значение ключа нарушает уникальное ограничение) с PostgreSQL

Мы обнаружили ошибку в DAS (WSO2) при использовании базы данных PostgreSQL. По какой-то неизвестной нам причине заполняет журнал 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 ($1, $2, $3, $4)
< 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 ($1, $2, $3, $4)
< 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 ($1, $2, $3, $4)
< 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 ($1, $2, $3, $4)
< 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 ($1, $2, $3, $4)*

Мы не знаем, потому что это происходит, и является ли это ошибкой или сбоем совместимости между DAS и PostgreSQL. Следы ошибок, которые появляются в журнале, повторяются каждые 5 секунд, не прекращая заполнение журналов базы данных и приводя к остановке работы системы.

Как видите, есть два типа ошибок:

  • "Дублированное значение ключа нарушает уникальное ограничение XXX"
  • "отношение XXX не существует в символе 15"

Мы протестировали его с несколькими экземплярами DAS и разными PostgresSQL, и результат тот же. в чем дело?

Я настроил DAS для использования базы данных PostgreSQL как для конфигурации (master-datasources.xml), так и для событий (analytics-datasources.xml). Проведенные нами тесты с использованием PostgreSQL 9.3 и 9.6 дали одинаковый результат.


person Alfonso Blanco Criado    schedule 23.02.2017    source источник


Ответы (3)


Несмотря на тревожный характер журналов, которые вы видите, насколько я могу судить, между DAS и PostgreSQL не возникает непредвиденных ситуаций.

Ожидаются оба этих журнала, поскольку для операций доступа к данным DAS проверяет, существует ли таблица перед фиксацией. Обычно это приводит к ошибке на стороне базы данных, если таблица не существует. Это нормально.

Кроме того, операция INSERT OVERWRITE над записями будет предпринята как операция INSERT, а затем, если запись уже существует (т. е. нарушение уникального ограничения), запись будет обновлена. Это связано с отсутствием оператора MERGE в PostgreSQL до версии 9.5, а также с относительные недостатки производительности при постоянном выполнении вызовов UPDATE.

Что касается вашего решения, раскомментирование «recordMergeQuery» вполне приемлемо, но только если вы используете PostgreSQL 9.5+. В противном случае операции записи завершатся ошибкой. В этом случае мы используем новый синтаксис INSERT ... ON CONFLICT UPDATE, предлагаемый Postgres (см. [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

person Gokul    schedule 14.03.2017
comment
В Postgres нет инструкции MERGE даже в версии 9.6. - person a_horse_with_no_name; 14.03.2017
comment
@a_horse_with_no_name правильно! Следовательно, для версий Postgres 9.5 и выше мы используем INSERT ... ON CONFLICT UPDATE для RecordMergeQuery. Я изменил ответ, чтобы отразить это. Большое спасибо! - person Gokul; 15.03.2017

Проблема с "повторяющимся ключом" была решена с помощью правильного запроса "recordMergeQuery". Но другая проблема с "отношение XXX не существует в символе 15" сохраняется. Мы изменили TABLE_NAME с помощью двойных кавычек, но все равно появляется сообщение об ошибке.

Теперь с двойными кавычками в журнале отображается то же сообщение, поскольку таблицы действительно не существует. Зачем? Мы не знаем, почему это происходит. Мы удалили все временные каталоги (tmp), solr, data. База чистая, построена с нуля.

person Alfonso Blanco Criado    schedule 14.03.2017

Я обнаружил проблему и нашел решение. Проблема в том, что операция «слияния» для PostgreSQL отключена, и поэтому «вставки» терпят неудачу, когда должны выполнять «обновления».

Эта ошибка находится в файле "rdbms-config.xml". Тег «recordMergeQuery» в базе данных PostgreSQL закомментирован.

Чтобы решить эту проблему, вы должны раскомментировать тег и изменить недопустимый запрос. Правильный запрос таков:

<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>
person Alfonso Blanco Criado    schedule 24.02.2017