[Greenplum] PL/R Error ERROR: Error on receive from seg0 slice1: server closed the connection unexpectedly 확인사항과 대처 방안
Greenplum and PostgreSQL Database 2020. 4. 1. 23:56이번 포스팅에서는 Greenplum DB에서 PL/R을 실행했을 때 "Error on receive from seg0 slice1: server closed the connection unexpectedly" 에러가 발생했을 경우 확인해보고 수정하는 예를 소개하겠습니다.
먼저, PL/R의 input으로 사용할 array 가 들어있는 간단한 예제 테이블을 만들어보겠습니다.
create schema test; drop table if exists test.sample_tbl_agg; create table test.sample_tbl_agg ( grp varchar(50) not null , prod varchar(50) , x_agg integer[] , y_agg numeric[] ) distributed by (grp, prod); insert into test.sample_tbl_agg values ('AA', 'GGG', array[1, 2, 3, 4, 5], array[0.112, 0.243, 0.318, 0.416, 0.534]); insert into test.sample_tbl_agg values ('BB', 'SSS', array[1, 2, 3, 4, 5], array[0.103, 0.212, 0.302, 0.453, 0.593]); select * from test.sample_tbl_agg; |
(1) Greenplum DB에서 PL/R return 받는 데이터 유형을 잘못 설정할 경우 server closed the connection unexpectedly 에러 발생 |
예제로 사용한 PL/R 함수는 국소 회귀모형(Local Regression)을 R의 LOESS() 함수를 적합해서 평활(smoothing)한 결과값을 array형태로 반환하는 것입니다. 그런데 returns numeric[] 으로 하는 바람에 서버가 비정상적으로 끊기고 리커버리 되는 상황이 발생하였습니다.
------------------------------------------ -- PL/R on Greenplum : Error --Query execution failed -- --Reason: --SQL Error [58M01]: ERROR: Error on receive from seg0 slice1 172.17.0.2:40000 pid=895: server closed the connection unexpectedly -- Detail: -- This probably means the server terminated abnormally -- before or while processing the request. ------------------------------------------ drop function if exists test.exec_loess(integer[], numeric[]); create or replace function test.exec_loess(x integer[], y numeric[]) returns numeric[] -- **** it causes an error **** as $$ y_loess <- loess(y~ x)$fitted return (y_loess) $$ language plr; -- Execute PL/R LOESS, but Error (server closed -_-;;;) select grp , prod , x_agg , test.exec_loess(x_agg, y_agg) as y_loess -- error from test.sample_tbl_agg; |
(2) PL/R return 데이터 유형을 맞게 설정해줄 경우 정상 수행됨 |
이번에는 위의 (1)번에서 정의했던 PL/R 함수를 삭제(drop)하고 y 에 해당하는 인자의 데이터 유형을 기존numeric[] 에서 float8[] 으로 새로 변경하고, return 받는 데이터 유형도 기존의 returns numeric[] 에서 returns float8[] 로 변경하여 정의한 후에 PL/R 함수를 실행해보겠습니다. PL/R이 Greenplum에서 정상적으로 잘 수행되네요.
PL/R 수행 후의 결과를 return 받을 데이터 유형 (data type)을 잘 확인하고 맞게 설정을 해주어야 합니다.
-- drop old PL/R UDF which used 'returns numeric[]' drop function if exists test.exec_loess(integer[], numeric[]); -- create new PL/R UDF which uses 'returns float[]' drop function if exists test.exec_loess(integer[], float8[]); create or replace function test.exec_loess(x integer[], y float8[]) returns float8[] -- ** not numeric[], but float8[] ** as $$ y_loess <- loess(y~ x)$fitted return (y_loess) $$ language plr; -- Execute PL/R LOESS select grp , prod , x_agg , test.exec_loess(x_agg, y_agg) as y_loess_agg from test.sample_tbl_agg; |
본 포스팅의 주제는 아닙니다만, 위의 PL/R에서 반환받는 값이 array 형태이다보니 조회해서 보기에, 또 이를 가지고 연산을 하거나 다른 테이블과 조인을 하기에 불편한감이 있습니다. 이에 unnest() 함수를 사용해서 array를 풀어서 long format으로 조회하는 예제도 추가로 아래에 예를 들어보았습니다.
-- unnest to see in a long format select a.grp , a.prod , unnest(a.x_agg) as x , unnest(a.y_loess_agg) as y_loess from ( select grp , prod , x_agg , test.exec_loess(x_agg, y_agg) as y_loess_agg from test.sample_tbl_agg) a; |
(3) returns setof 을 사용해서 행(row) 단위로 PL/R 결과를 반환하기 (returns rows instead of array using 'returns setof' in PL/R on Greenplum) |
위의 (2)번에서 unnest() 를 소개한 김에 옆으로 조금만 더 세어보자면요,
위의 (2)번에서는 returns float8[] --> PL/R 수행 시 array 를 반환했던 반면에,
이번 (3)번에서는 returns setof float8 --> PL/R 수행 시 rows 를 반환하도록 하는 경우입니다.
'returns setof' 처럼 'setof'가 추가된게 다르구요, 'float8[]' array가 아니라 'float8' 형태인게 다릅니다.
이렇게 개별 float8 값을 row로 반환하므로 위의 (2)번처럼 unnest() 함수를 써서 array를 long format으로 풀어줄 필요가 없이도 (2)번의 unnest() 를 쓴 것과 동일한 결과를 얻었습니다.
--------------------------------------- -- returns setof: rows in a long format --------------------------------------- drop function if exists test.exec_loess(integer[], float8[]); create or replace function test.exec_loess(x integer[], y float8[]) returns setof float8 -- not array, but rows as $$ y_loess <- loess(y~ x)$fitted return (y_loess) $$ language plr; -- Execute PL/R LOESS select grp , prod , unnest(x_agg) as x , test.exec_loess(x_agg, y_agg) as y_loess -- not array, but rows from test.sample_tbl_agg;
|
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요.