YMatrix SQL Query FAQ

Этот документ описывает распространённые проблемы с SQL-запросами YMatrix.


1 ERROR: EvalPlanQual can not handle subPlan with Motion node


Анализ проблемы

При установке параметра gp_enable_global_deadlock_detector в значение on режим блокировки может снижаться до RowExclusiveLock. При обновлении ключа распределения операция UPDATE разбивается на DELETE + INSERT. В этот момент при параллельном обновлении ключа распределения операция DELETE не может выполнить EvalPlanQual, а операция INSERT не блокируется, что может привести к генерации избыточных данных. Для предотвращения этого явления выбрасываются соответствующие ошибки.

Шаги воспроизведения

session 0: create table test_valplanqual (c1 int, c2 int) distributed by(c1);
CREATE
session 0: insert into test_valplanqual values(1,1);
INSERT 1
session 0: select * from test_valplanqual;
 c1 | c2
----+----
 1  | 1
(1 row)

session 1: begin;
BEGIN
session 2: begin;
BEGIN
session 1: update test_valplanqual set c1 = c1 + 1 where c1 = 1;
UPDATE 1
session 2: update test_valplanqual set c1 = c1 + 1 where c1 = 1;  <waiting ...>
session 1: end;
END
session 2<:  <... completed>
ERROR:  EvalPlanQual can not handle subPlan with Motion node  (seg1 127.0.1.1:7003 pid=34629)
session 2: end;
END
session 0: select * from test_valplanqual;
 c1 | c2
----+----
 2  | 1
(1 row)
session 0: drop table test_valplanqual;
DROP

Решение

Избегайте обновления ключей распределения.


2 ERROR: Too many unresolved insertion xids, please do a vacuum


Анализ проблемы

Текущий движок хранения mars2 ограничивает количество XID-ов INSERT, существующих на одном BLOCK, и алгоритм работает следующим образом:

#define INSERTXIDSPERBLOCK ((BLCKSZ - PAGE_RESERVED_SPACE) / sizeof(TransactionId))
#define PAGE_RESERVED_SPACE(MAXALIGN(sizeof(PageHeaderData)) + MAXALIGN(sizeof(SortHeapPageOpaqueData)))

Приблизительно (block_size - 24 + 24) / 4 подтранзакций. При значении block_size по умолчанию 8K это составляет около 2036. Ошибка возникает, когда количество подтранзакций превышает это значение.

Шаги воспроизведения

session 0: create table test_xids(id int) using mars2;
CREATE TABLE
session 0: create index ON test_xids using mars2_btree (id);
CREATE INDEX
session 0: 
 DO $$
DECLARE 
    i int; 
    _start timestamptz;
BEGIN
FOR i IN 1..3000 LOOP 
    _start = clock_timestamp();
    INSERT INTO test_xids VALUES (i);
    RAISE NOTICE 'value: % escape: % ', i, clock_timestamp() - _start; 
END LOOP;
END;
$$language plpgsql;

psql: NOTICE:  value: 1 escape: 00:00:00.019476
psql: NOTICE:  value: 2 escape: 00:00:00.002501
psql: NOTICE:  value: 3 escape: 00:00:00.00218
psql: NOTICE:  value: 4 escape: 00:00:00.002098
psql: NOTICE:  value: 5 escape: 00:00:00.002938
psql: NOTICE:  value: 6 escape: 00:00:00.001891
psql: NOTICE:  value: 7 escape: 00:00:00.001794
...
...
psql: NOTICE: value: 2069 escape: 00:00:10.001794
psql: NOTICE: value: 2070 escape: 00:00:10.001495
psql: NOTICE: value: 2071 escape: 00:00:10.001251
psql: NOTICE: ERROR:  Too many unresolved insertion xids, please do a vacuum (sortheap_external_sort.c:404)  (seg0 172.16.100.197:6000 pid=12992) (sortheap_external_sort.c:404)
CONTEXT:  SQL statement "insert into test_xids values(i)"
PL/pgSQL function inline_code_block line 7 at SQL statement

Решение

Чтобы избежать множественных выполнений операций INSERT INTO tablename VALUES(...) в одной транзакции, наиболее удобный подход — выполнять операции INSERT только один раз за транзакцию, вставляя данные пакетами в формате INSERT INTO tablename VALUES(...),(...),(...).
Для таблиц mars2 официально рекомендуется использовать инструмент mxgate для более эффективной записи данных.


3 ERROR: modification of distribution columns in OnConflictUpdate is not supported


Анализ проблемы

При установке параметра gp_enable_global_deadlock_detector в значение on режим блокировки может снижаться до RowExclusiveLock. При выполнении операции INSERT...ON CONFLICT DO UPDATE SET... при обновлении ключа распределения операция UPDATE разбивается на DELETE + INSERT. В этот момент происходит обновление ключа распределения, и выбрасывается данная ошибка.

Шаги воспроизведения

session 0: create table test_upsert(id int, name text, primary key(id)) distributed by(id);
CREATE TABLE
session 0: insert into test_upsert select 1, 'a';
INSERT 0 1
session 0: insert into test_upsert select 1, 'a' on conflict (id) do update set id =2;
psql: ERROR:  modification of distribution columns in OnConflictUpdate is not supported
session 0: insert into test_upsert select 1, 'a' on conflict (id) do update set name = 2;
INSERT 0 1
session 0: drop table test_upsert;
DROP

Решение

Избегайте обновления ключей распределения при выполнении операций UPSERT.


4 Графический клиент получил лог: server closed the connection unexpectedly


Графический (UI) клиент обращается к удалённой базе данных, отправляет запросы во время длительного выполнения или после длительного бездействия, и иногда клиент получает логи:

server closed the connection unexpectedly

Анализ проблемы

На клиенте настроены таймауты отмены запроса или отмены соединения при бездействии.

Решение

Измените настройки таймаута клиента и отключите таймаут.


5 Запрос UNION ALL с простыми операциями Filter медленнее, чем запрос с IN


Анализ проблемы

Для запроса IN с партиционированной таблицей после обрезки партиций остаётся только 1 партиция DEFAULT, тогда как каждая подзапрос в UNION ALL обрезается до партиции DEFAULT. После нескольких сканирований партиции DEFAULT влияние на производительность становится очевидным.

Решение

Для партиционированных таблиц: Постарайтесь избегать партиционирования по DEFAULT, не используйте UNION, вместо этого применяйте оператор IN.


6 Вставка данных типа int: запрос выполняется быстро, но в функции Plpgsql — медленно


Анализ проблемы

Запрос внутри функции Plpgsql выполняется через SPI. Результат плана SPI — соединение двух таблиц с использованием nestloop, statement rows = 1, без ANALYSE.

Решение

Выполните ANALYZE.


7 Обрезка партиций и операции обновления: два сеанса (Session) независимо обновляют — возникает взаимоблокировка


Анализ проблемы

Распределённая взаимоблокировка.

Решение

Включите обнаружение распределённых взаимоблокировок.

gpconfig -c gp_enable_global_deadlock_detector -v on


8 Использование пользовательских типов и расширение полей одной таблицы


Использование пользовательских типов

  1. Создание типа
    CREATE TYPE public.fhpm AS
    (
    avgval double precision,
    minval double precision,
    maxval double precision,
    minval_interval integer,
    maxval_interval integer
    );
  2. Создание таблицы
    CREATE TABLE datapool.test                
    (                                         
     portindex integer,                    
     begintime timestamp without time zone,
     a_1 fhpm,                             
     s_2 integer                           
    );               
  3. Пример вставки данных
    insert into datapool.test values(1,'2022-01-01','(1,1,1,1,1)',1);          
    insert into datapool.test values(2,'2022-01-01','(2,,2,,)',2);   
  4. Пример запроса атрибутов типа
    SELECT * FROM datapool.test;                             
    portindex |      begintime      |     a_1     | s_2 
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
          1 | 2022-01-01 00:00:00 | (1,1,1,1,1) |   1 
          2 | 2022-01-01 00:00:00 | (2,,2,,)    |   2 
    (2 rows)        
    SELECT (a_1).avgval FROM datapool.test;
    avgval                              
    --------
       1                                                           
       2              
    (2 rows)
    SELECT (a_1).minval FROM datapool.test;                   
    minval                                 
    --------
       1                                        
    (2 rows)

    Расширение полей одной таблицы psql: ERROR: tables can have at most 1600 columns

Используйте пользовательский тип для обхода ограничения в 1600 полей на одну таблицу. Если вас это интересует, вы можете попробовать самостоятельно. Ниже приведены примеры реализации.

CREATE TYPE public.fhpm1 AS
(
a0001 double precision,
a0002 double precision,
...
a1600 double precision);

CREATE TABLE datapool.test1                
(
portindex integer,
begintime timestamp without time zone,
a_1 fhpm1,
s_2 integer,
a_3 fhpm2
);

Генерация скрипта типа с 1600 столбцами

echo 'CREATE TYPE public.fhpm1 AS(' > test.sql
for i in {1..1599};do
echo 'a'$i' double precision,' >> test.sql
done
echo 'a1600 double precision);' >> test.sql


9 ERROR,XX000,Right sibling's left-link doesn't match : block 817 links to 45366 instead of expected 70930 in index ""tab_idx""


Анализ проблемы

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

Решение

Перестройте индекс.

drop index tab_idx;
create index tab_idx on table &tablename (column1,column2..);


10 Ошибка при обновлении и удалении cannot delete from table "&tablename" because it does not have a replica identity and publishes deletes


Анализ проблемы

Таблица включает логическую репликацию. Если для логически реплицируемой таблицы не заданы параметры, можно выполнять только операции INSERT. Операции UPDATE и DELETE вызывают вышеуказанную ошибку. Эта логическая репликация присутствовала в ранних версиях PostgreSQL, но сохранялась и в последующих. Рекомендуется не включать эту функцию в YMatrix.

Проблема повторяется

test6=# create table test as select * from pg_tables distributed randomly;
SELECT 94
test6=# create publication rep_source for table test;
CREATE PUBLICATION
test6=# insert into test select * from test;
INSERT 0 94
test6=# update test set tablename='pg_class_old' where tablename='pg_class';
psql: ERROR:  cannot update table "test" because it does not have a replica identity and publishes updates
HINT:  To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.
test6=# delete from test where tablename='pg_class';
psql: ERROR:  cannot delete from table "test" because it does not have a replica identity and publishes deletes
HINT:  To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.

Решение

Установите предыдущее изображение (previous image), содержащее все столбцы, при обновлении и удалении.

alter table &schema.tablename REPLICA IDENTITY FULL;

Или удалите соответствующую задачу репликации и публикации.

select a.*,b.prrelid::regclass tablename from pg_publication a,pg_publication_rel b where a.oid=b.prpubid;
drop publication &任务名;


11 ERROR: could not read block 0 in file "base/1588803/269422"


Анализ проблемы

Блок файла повреждён, что делает соответствующий файл недоступным для чтения.

Проблема повторяется

test6=# create table test as select * from pg_tables distributed randomly;
SELECT 94
test6=# create index idx_tabname on test1(tablename);
CREATE INDEX
test6=# select relname,relfilenode from pg_class where relname in('test1','idx_tabname');
   relname   | relfilenode 
----------------------------------------------------------------------------------------------------------------------------------
 idx_tabname |      269422
 test1       |      269421
(2 rows)

Найдите соответствующий файл по relfilenode и удалите один из них (здесь удаляется файл индекса).

test6=# select * from test1 where tablename='a';
psql: ERROR:  could not read block 0 in file "base/1588803/269422": read only 8123 of 8192 bytes

Решение

Согласно ошибке relfilenode, определите, повреждён ли файл таблицы или файл индекса:

Ситуация 1: Файл индекса повреждён. Просто перестройте его с помощью команды reindex.

Ситуация 2: Если есть Mirror, повреждён файл таблицы данных. Скопируйте файл Mirror с тем же содержимым и замените им файл Primary.

Ситуация 3: Если Mirror отсутствует, повреждён файл таблицы данных. Скопируйте данные с рабочего экземпляра отдельно, пересоздайте таблицу — данные с повреждённого экземпляра будут потеряны.


12 Примеры преобразования строк в столбцы


При использовании YMatrix вы столкнётесь с необходимостью преобразования строк в столбцы. Ниже приведён демонстрационный пример. Конкретные шаги:

Пример преобразования строк в столбцы

  1. Создайте тестовую таблицу
    create table test (name varchar(20),zbfm varchar(20),value integer);
  2. Вставьте тестовые данные
    iINSERT INTO test VALUES ('Zhang San', 'Age', 60);
    INSERT INTO test VALUES ('Zhang San', 'Height', 95);
    INSERT INTO test VALUES ('Zhang San', 'Weight', 31);
    INSERT INTO test VALUES ('Zhang San', 'Shoe Size', 42);
    INSERT INTO test VALUES ('Li Si', 'Age', 50);
    INSERT INTO test VALUES ('Li Si', 'Height', 83);
    INSERT INTO test VALUES ('Li Si', 'Weight', 84);
    INSERT INTO test VALUES ('Li Si', 'Shoe Size', 43);
    INSERT INTO test VALUES ('Wang Wu', 'Age', 97);
    INSERT INTO test VALUES ('Wang Wu', 'Height', 75);
    INSERT INTO test VALUES ('Wang Wu', 'Weight', 66);
    INSERT INTO test VALUES ('Wang Wu', 'Shoe Size', 44);
  3. Запросите тестовые данные
    select * from test;
    name    | zbfm     | value 
    -----------+----------+--------
    Zhang San | Age      |    60  
    Zhang San | Height   |    95  
    Zhang San | Weight   |    31  
    Zhang San | Shoe Size|    42  
    Wang Wu   | Age      |    97  
    Wang Wu   | Height   |    75  
    Wang Wu   | Weight   |    66  
    Wang Wu   | Shoe Size|    44  
    Li Si     | Age      |    50  
    Li Si     | Height   |    83  
    Li Si     | Weight   |    84  
    Li Si     | Shoe Size|    43
    (12 rows)
  4. Отобразите данные в виде строк и столбцов
    select name,
    max(case when zbfm='Age' then value else 0 end) as Age,
    max(case when zbfm='Height' then value else 0 end) as Height,
    max(case when zbfm='Weight' then value else 0 end) as Weight,
    max(case when zbfm='Shoe Size' then value else 0 end) as Shoe Size
    from test 
    group by name
    order by Age desc;
    name    | Age | Height | Weight | Shoe Size  
    ---------+-----+--------+--------+-----------  
    Wang Wu  |  97 |     75 |     66 |        44  
    Zhang San|  60 |     95 |     31 |        42
    (3 rows)


    13 Примеры преобразования столбцов в строки


При использовании YMatrix вы столкнётесь с необходимостью преобразования столбцов в строки. Ниже приведён демонстрационный пример. Конкретные шаги:

Пример преобразования столбцов в строки

  1. Создайте тестовую таблицу
    drop table if exists t_unpivot;
    create table t_unpivot(
     currenttimestamp bigint  ,
     deviceid text  ,
     devicetemplatecode varchar  ,
     statisticstype text ,
     co2 float ,
     currentpowersum float ,
     currenttemperature float ,
     curtemp float ,
     duration float ,
     dust_level float 
    );
  2. Вставьте тестовые данные
    insert into t_unpivot values(1646376466611,'1.2.156.156.11.20.227161606742980522','138700003','statistics_avg',12.4,23.4,null,null,null,55.5);
    insert into t_unpivot values(1646376466612,'1.2.156.156.11.20.607141619709364801','122400004','statistics_avg',null,34.3,56.3,null,null,null);
    insert into t_unpivot values(1646376466613,'1.2.156.156.11.20.929741642180181067','178800001','statistics_avg',null,null,null,43.2,null,null);
    insert into t_unpivot values(1646376466614,'1.2.156.156.11.20.327231588865913990','123200004','statistics_avg',null,null,null,null,23.2,null);
    insert into t_unpivot values(1646376466615,'1.2.156.156.11.20.155831629756361011','154900008','statistics_avg',null,null,21.2,null,null,null);
  3. Просмотрите тестовые данные
    select * from t_unpivot;
    currenttimestamp |               deviceid               | devicetemplatecode | statisticstype | co2  | currentpowersum | currenttemperature | curtemp | duration | dust_level 
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     1646376466612 | 1.2.156.156.11.20.607141619709364801 | 122400004          | statistics_avg |      |            34.3 |               56.3 |         |          |           
     1646376466611 | 1.2.156.156.11.20.227161606742980522 | 138700003          | statistics_avg | 12.4 |            23.4 |                    |         |          |       55.5
     1646376466613 | 1.2.156.156.11.20.929741642180181067 | 178800001          | statistics_avg |      |                 |                    |    43.2 |          |           
     1646376466615 | 1.2.156.156.11.20.155831629756361011 | 154900008          | statistics_avg |      |                 |               21.2 |         |          |           
     1646376466614 | 1.2.156.156.11.20.327231588865913990 | 123200004          | statistics_avg |      |                 |                    |         |     23.2 |           
    (5 rows)
  4. Отобразите данные в виде столбцов и строк
    select currenttimestamp, 
        deviceid, 
        devicetemplatecode,
        statisticstype,
        (b.rec).key as key, 
        (b.rec).value as value 
    from
    (select currenttimestamp, 
         deviceid, 
         devicetemplatecode,
         statisticstype,
         jsonb_each_text(row_to_json(t.*)::jsonb-'currenttimestamp'-'deviceid'-'devicetemplatecode'-'statisticstype') as rec  
    from t_unpivot t
    ) b
    where (b.rec).value is not null;
    currenttimestamp |               deviceid               | devicetemplatecode | statisticstype |        key         | value 
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     1646376466612 | 1.2.156.156.11.20.607141619709364801 | 122400004          | statistics_avg | currentpowersum    | 34.3
     1646376466612 | 1.2.156.156.11.20.607141619709364801 | 122400004          | statistics_avg | currenttemperature | 56.3
     1646376466611 | 1.2.156.156.11.20.227161606742980522 | 138700003          | statistics_avg | co2                | 12.4
     1646376466611 | 1.2.156.156.11.20.227161606742980522 | 138700003          | statistics_avg | dust_level         | 55.5
     1646376466611 | 1.2.156.156.11.20.227161606742980522 | 138700003          | statistics_avg | currentpowersum    | 23.4
     1646376466613 | 1.2.156.156.11.20.929741642180181067 | 178800001          | statistics_avg | curtemp            | 43.2
     1646376466615 | 1.2.156.156.11.20.155831629756361011 | 154900008          | statistics_avg | currenttemperature | 21.2
     1646376466614 | 1.2.156.156.11.20.327231588865913990 | 123200004          | statistics_avg | duration           | 23.2
    (8 rows)


    14 pg_hba.conf Исключение разрешения удалённого доступа из-за порядка конфигурации файла


Анализ проблемы

pg_hba.conf — это конфигурационный файл, ограничивающий права удалённого доступа к базе данных. Порядок прав доступа читается сверху вниз. Неправильный порядок конфигурации приводит к сбою контроля доступа.

Проблема повторяется

Создайте тестового пользователя.

test6=# create role test with login password 'test';
psql: NOTICE:  resource queue required -- using default resource queue "pg_default"
CREATE ROLE

Попробуйте войти.

[mxadmin@mxd2 mxseg-1]$ psql test6 -U test -h 192.168.8.12 -p 5432
Password for user test: 
psql (12)
Type "help" for help.
test6=>

Ограничьте удалённый вход тестового пользователя, изменив pg_hba.conf. Разместите ограничение в конце файла.

[mxadmin@mxd2 mxseg-1]$ vi pg_hba.conf
#user access rules
host            all             all             0.0.0.0/0       md5
host all test 0.0.0.0/0  reject     //添加权限限制
[mxadmin@mxd2 mxseg-1]$ mxstop -u
//Test login, login is normal, and the remote is not restricted successfully
[mxadmin@mxd2 mxseg-1]$ psql test6 -U test -h 192.168.8.12 -p 5432
Password for user test: 
psql (12)
Type "help" for help.
test6=> 

Решение

Проверьте текущие ограничения пользователя в pg_hba.conf и добавьте строку ограничения прав в соответствующее место.

//Откорректированный файл `pg_hab.conf`
[mxadmin@mxd2 mxseg-1]$ vi pg_hba.conf
# Правила доступа пользователя
host all test 0.0.0.0/0  reject     // Добавить ограничение прав
host            all             all             0.0.0.0/0       md5
[mxadmin@mxd2 mxseg-1]$ mxstop -u
// Проверка входа — вход не удался, удалённые ограничения успешно применены
[mxadmin@mxd2 mxseg-1]$ psql test6 -U test -h 192.168.8.12 -p 5432
psql: error: could not connect to server: FATAL:  pg_hba.conf rejects connection for host "192.168.8.12", user "test", database "test6", SSL off


15 idle in transaction timeout сообщает об ошибке


Анализ проблемы

Таймаут соединения idle in transaction, который управляется параметрами и должен настраиваться осторожно.

Проблема повторяется

Проверьте текущие настройки параметра.

test=# show idle_in_transaction_session_timeout ;
 idle_in_transaction_session_timeout 
----------------------------------------------------------------------------------------------------------------------------------
 100s
(1 row)

Для удобства демонстрации установите этот параметр на уровне сессии в 10 секунд.

test=# set idle_in_transaction_session_timeout ='10s';
SET
test=# show idle_in_transaction_session_timeout ;
 idle_in_transaction_session_timeout 
----------------------------------------------------------------------------------------------------------------------------------
 10s
(1 row)

Включите транзакцию и проверьте влияние этого параметра.

test=# begin ;
BEGIN
test=# select count(*) from pg_tables;
 count 
-------
   104
(1 row)

Подождите более 10 секунд перед повторным выполнением.

test=# select count(*) from pg_tables;
psql: FATAL:  terminating connection due to idle-in-transaction timeout
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.

Проверьте лог базы данных.

2023-02-22 10:47:07.577478 PST,"mxadmin","test",p43086,th-484071296,"[local]",,2023-02-22 10:44:30 PST,0,con25838,cmd8,seg-1,,dx25863,,sx1,"FATAL","25P03","terminating connection due to idle-in-transaction timeout",,,,,,,0,,"postgres.c",4018,

Решение

  1. Настройте этот параметр осторожно — он может привести к откату долгих транзакций.
  2. При возникновении этой проблемы можно изменить системные параметры или установить параметры на уровне сессии.

Изменение системного параметра.

$ gpconfig -c idle_in_transaction_session_timeout -v 10s
$ gpstop -u 

Установка параметра на уровне сессии.

$ set idle_in_transaction_session_timeout='10s';


16 insufficient memory reserved for statement


Анализ проблемы

Сеанс использует память, превышающую установленное значение statement_mem. Объём клиентских данных невелик, но существует очень много партиций. Слишком большое количество партиций приводит к значительному потреблению памяти при count(*).

Проблема повторяется

Создайте партиционированную таблицу с максимальным количеством партиций.

test=# create table test (id int,read numeric,write numeric,dttime timestamp)
test-# Distributed by (id)
test-# Partition by range(dttime)
test-# (start ('2022-11-01'::date)
test(# end ('2022-12-01'::date)
test(# every ('1 hours'::interval));
CREATE TABLE

Вставьте небольшое количество данных в таблицу.

test=# insert into test 
test-# select j as id,random()*10 as read,random()*10 as write,i as dttime from generate_series('2022-11-01', '2022-11-30',interval '1 hours') as i,generate_series(1,100) j;
INSERT 0 69800

При поиске в таблице возникла ошибка.

test=# select count(*) from test;
psql: ERROR:  insufficient memory reserved for statement

Решение

  1. Временное решение:
    • Измените параметр statement_mem на уровне сессии set statement_mem ='1000MB'
  2. Постоянное решение:
    • Настройте системное значение statement_mem gpconfig -c statement_mem -v 10000MB. When adjusting, you need to pay attention to the size ofmax_statement_mem`.
    • Если вы не хотите менять системные параметры, необходимо перепланировать партиционирование — текущее соотношение партиций и объёма данных таблицы неоптимально.


17 evalplanqual can not hanlde subplan with motion node


Анализ проблемы

Разные транзакции обновляют одни и те же данные ключа распределения. После фиксации первой транзакции другие транзакции выдают ошибку.

Проблема повторяется

Создайте таблицу.

test=# create table test1 as 
test-# select i id,md5(random()::text) tag_id1
test-# from generate_series(1,10) i;
psql: NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'id' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
SELECT 10

Сессия A начинает транзакцию с обновлением записи id=1.

test=# begin;
BEGIN
test=# update test1 set id=11 where id=1;
UPDATE 1

Сессия B начинает транзакцию с обновлением записи id=1.

test=# begin;
BEGIN
test=# update test1 set id=11 where id=1;

Зафиксируйте транзакцию сессии A.

test=# begin;
BEGIN
test=# update test1 set id=11 where id=1;
UPDATE 1
test=# 
test=# commit;
COMMIT

Сессия B выдала ошибку.

test=# begin;
BEGIN
test=# update test1 set id=11 where id=1;
psql: ERROR:  EvalPlanQual can not handle subPlan with Motion node  (seg1 192.168.8.12:6001 pid=49302)

Решение

  1. Избегайте одновременного автоматического обновления одного и того же ключа распределения несколькими транзакциями.
  2. При обновлении данных используйте автоматические транзакции базы данных, а не запускайте их вручную.
  3. Избегайте использования длинных транзакций в приложении.


18 Создание таблицы на клиенте невозможно запросить на Linux, но можно на клиенте


Сообщение об ошибке

SELECT * FROM ttemp;
psql: ERROR:  relation "ttemp" does not exist
LINE 1: SELECT * FROM ttemp;
                      ^

Анализ проблемы

Просмотрите ошибку.

psql: ERROR:  relation "ttemp" does not exist
LINE 1: SELECT * FROM ttemp;
                      ^
  1. Выполните \dn, чтобы просмотреть список схем, show search_path; — чтобы узнать текущую схему по умолчанию. Убедитесь, в какой схеме создана таблица, и выполните запрос с указанием schema.table.
    
    postgres=# \dn
    List of schemas
     Name    |  Owner  
    -------------+----------
    gp_toolkit | mxadmin
    public     | mxadmin
    (2 rows)

postgres=# SHOW search_path ; search_path

"$user", public (1 row)

Обнаружено, что схема по умолчанию — `public`.

2. Выполните `\l`, чтобы просмотреть список баз данных.
```Bash
postgres=# \l
                               List of databases
   Name    |  Owner  | Encoding |  Collate   |   Ctype    |  Access privileges  
------------+------------+--------------------------------------------------------------------------------------------------------
 matrixmgr | mxadmin | UTF8     | en_US.utf8 | en_US.utf8 | 
 postgres  | mxadmin | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | mxadmin | UTF8     | en_US.utf8 | en_US.utf8 | =c/mxadmin         +
           |         |          |            |            | mxadmin=CTc/mxadmin
 template1 | mxadmin | UTF8     | en_US.utf8 | en_US.utf8 | =c/mxadmin         +
           |         |          |            |            | mxadmin=CTc/mxadmin
(4 rows)
  1. Проверьте корректность информации подключения клиента и программы.

Обнаружено, что программа подключена к кластеру базы данных на порту 5432, а Linux — на порту 5433.

postgres=# SHOW port;
 port 
------
 5433
(1 row)

Решение

Остановите кластер на порту 5433.

[mxadmin@mdw ~]$ gpstop -a

Измените порт и информацию MASTER_DATA_DIRECTORY в переменных окружения.

$ vim ~mxadmin/.matrixdb.env

export PGPORT=5432
export MASTER_DATA_DIRECTORY=/mxdata_20220909145815/master/mxseg-1

Загрузите новые переменные окружения.

$ source ~mxadmin/.matrixdb.env


19 Потеря данных и дублирование при вставке данных с ключами распределения UUID


Описание проблемы

При выполнении операции INSERT INTO table_uuid SELECT ... FROM количество вставленных записей колеблется. При этом результат SELECT стабилен и не меняется.

Пример: При многократном выполнении операции INSERT результат колеблется, а результат SELECT всегда стабильно равен 1.

INSERT 0 0
Time: 25.774 ms
INSERT 0 1
Time: 40.934 ms
INSERT 0 2
Time: 34.338 ms
INSERT 0 3
Time: 32.562 ms

Анализ проблемы

Проблема возникает из-за сочетания трёх условий:

  1. SET OPTIMIZER TO ON.
  2. Использование случайных функций, таких как random(), для генерации UUID.
  3. Ключ распределения вставляемой в целевую таблицу записи — UUID.

Решение

Измените одно из трёх вышеуказанных условий, чтобы избежать данной проблемы.


20 Версия операционной системы базы данных была обновлена с CentOS7 на CentOS8, и производительность запросов ухудшилась


Анализ проблемы

Red Hat 8 добавил службу ssd, которая аутентифицирует все соединения, что снижает эффективность создания и аутентификации соединений, особенно в сценариях с большим количеством сегментов — производительность запросов значительно снижается.

Проблема повторяется

  1. Создайте кластер на операционной системе CentOS7
  2. Создайте кластер на операционной системе CentOS8
  3. Создайте несколько связанных таблиц
  4. Выполните запрос с соединением нескольких таблиц
  5. Сравните эффективность запросов в двух системах

Решение

  1. Преобразуйте маленькие таблицы в копируемые таблицы, чтобы уменьшить количество сегментов.
  2. Отключите соответствующую службу операционной системы
    systemctl stop sssd
    systemctl stop sssd-kcm.socket


    21 При выполнении SQL-запросов отображается ошибка insufficial memory reserved for statement


Анализ проблемы

Память, используемая при оценке запланированного запроса при выполнении SQL, превышает лимит параметра statement_mem.

Решение

  1. Увеличьте значение параметра statement_mem, чтобы избежать превышения лимита памяти при оценке запроса.

  2. Проверьте, является ли запрашиваемая таблица партиционированной. Если да — объедините партиции.

22 Ошибка при создании расширения matrixts


Проблема повторяется

Создайте исходную базу данных db1, целевую базу данных db2, а также расширение matrixts и несколько таблиц на db1.

CREATE DATABASE db1;
CREATE DATABASE db2;
\c db1
CREATE EXTENSION matrixts;
CREATE TABLE t1(c INT);
CREATE TABLE t2(c INT);

Используйте инструмент «Синхронизация структуры» в клиентском ПО Navicat Premium для синхронизации соответствующих таблиц, представлений, функций и т. д. базы данных db1 с базой данных db2.

В этот момент выполните CREATE EXTENSION matrixts в базе данных db2, и возникнет аналогичная ошибка:

ERROR:  type "<type name>" already exists
ERROR:  function "<function name>" already exists with same argument types

Например:

db2=# CREATE EXTENSION matrixts;
psql: NOTICE:  Releasing segworker groups to finish aborting the transaction.
psql: ERROR:  type "mxkv_text" already exists
ERROR:  could not open gp_segment_configutation dump file:gpsegconfig_dump:No such file or directory (cdbutil.c:151)
db2=# CREATE EXTENSION matrixts;
psql: ERROR:  function "set_policy" already exists with same argument types
ERROR:  could not open gp_segment_configutation dump file:gpsegconfig_dump:No such file or directory (cdbutil.c:151)

Анализ проблемы

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

Когда пользователь создаёт плагин matrixts через CREATE EXTENSION matrixts, плагин matrixts не может быть инициализирован из-за существования функций, типов и других объектов с одинаковыми именами.

Решение

  1. Если вы получили ошибку из-за некорректных действий, удалите конфликтующие функции и типы с одинаковыми именами.
    DROP TYPE mxkv_float4 cascade;
    DROP TYPE mxkv_float8 cascade;
    DROP TYPE mxkv_int4 cascade;
    DROP TYPE mxkv_text cascade;
    DROP FUNCTION set_policy;
    DROP FUNCTION drop_policy(rel regclass);
    DROP FUNCTION drop_policy(rel regclass, policy_name text);
    DROP FUNCTION set_policy_action(rel regclass, action_name text, args text);
    DROP FUNCTION set_policy_action(rel regclass, action_name text, in_disabled boolean);
    DROP FUNCTION disable_policy_action(rel regclass, action_name text);
    DROP FUNCTION enable_policy_action(rel regclass, action_name text);
  2. Если вы не выполняли операции синхронизации через клиент, создайте новую базу данных. После создания плагина matrixts в этой базе данных выполните синхронизацию определений таблиц, представлений и т. д.