修复BRI触发器 + copy的内存持续增长问题
在原有的函数CopyFrom实现中,如果迭代中的元组无需插入(skip_tuple=true, BRI触发器会引起此情况),此种情况出现时 会导致per-tuple memory context不会reset,如果所有的元组均被触发器转移,会导致该内存上下文不断增长。 本次提交修复了此问题。 发生skip_tuple的情况,必然是BRI存在,可以在每次迭代都安全reset per-tuple memory context。 另:foreign table也需要每次reset(不会存在bulk insert的情况),本提交一并修复。
This commit is contained in:
@ -4282,7 +4282,7 @@ uint64 CopyFrom(CopyState cstate)
|
||||
*/
|
||||
if ((resultRelInfo->ri_TrigDesc != NULL &&
|
||||
(resultRelInfo->ri_TrigDesc->trig_insert_before_row || resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) ||
|
||||
cstate->volatile_defexprs) {
|
||||
cstate->volatile_defexprs || isForeignTbl) {
|
||||
useHeapMultiInsert = false;
|
||||
} else {
|
||||
useHeapMultiInsert = true;
|
||||
@ -4819,6 +4819,8 @@ uint64 CopyFrom(CopyState cstate)
|
||||
|
||||
if (!skip_tuple && isForeignTbl) {
|
||||
resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate, resultRelInfo, slot, NULL);
|
||||
Assert(!useHeapMultiInsert);
|
||||
resetPerTupCxt = true;
|
||||
processed++;
|
||||
} else if (!skip_tuple) {
|
||||
/*
|
||||
@ -5004,6 +5006,14 @@ uint64 CopyFrom(CopyState cstate)
|
||||
* tuples inserted by an INSERT command.
|
||||
*/
|
||||
processed++;
|
||||
} else {/*skip_tupe == true*/
|
||||
/*
|
||||
* only the before row insert trigget would make skip_tupe==true
|
||||
* which useHeapMultiInsert must be false
|
||||
* so we can safely reset the per-tuple memory context in next iteration
|
||||
*/
|
||||
Assert(useHeapMultiInsert == false);
|
||||
resetPerTupCxt = true;
|
||||
}
|
||||
#ifdef PGXC
|
||||
}
|
||||
|
||||
@ -321,3 +321,45 @@ DROP TABLE x;
|
||||
DROP TABLE y;
|
||||
DROP FUNCTION fn_x_before();
|
||||
DROP FUNCTION fn_x_after();
|
||||
CREATE TABLE measurement (
|
||||
city_id int not null,
|
||||
logdate int not null,
|
||||
peaktemp int,
|
||||
unitsales int
|
||||
);
|
||||
CREATE TABLE measurement_movement (
|
||||
city_id int not null,
|
||||
logdate int not null,
|
||||
peaktemp int,
|
||||
unitsales int
|
||||
);
|
||||
CREATE OR REPLACE FUNCTION measurement_insert_trigger()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
INSERT INTO measurement_movement VALUES (NEW.*);
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER insert_measurement_trigger
|
||||
BEFORE INSERT ON measurement
|
||||
FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();
|
||||
COPY measurement from stdin;
|
||||
select * from measurement_movement order by city_id;
|
||||
city_id | logdate | peaktemp | unitsales
|
||||
---------+---------+----------+-----------
|
||||
10001 | 22 | 32 | 42
|
||||
10002 | 23 | 33 | 43
|
||||
10003 | 24 | 34 | 44
|
||||
10004 | 25 | 35 | 45
|
||||
10005 | 26 | 36 | 46
|
||||
(5 rows)
|
||||
|
||||
select * from measurement order by city_id;
|
||||
city_id | logdate | peaktemp | unitsales
|
||||
---------+---------+----------+-----------
|
||||
(0 rows)
|
||||
|
||||
drop trigger insert_measurement_trigger on measurement;
|
||||
drop function measurement_insert_trigger;
|
||||
drop table measurement;
|
||||
drop table measurement_movement;
|
||||
|
||||
@ -228,3 +228,46 @@ DROP TABLE x;
|
||||
DROP TABLE y;
|
||||
DROP FUNCTION fn_x_before();
|
||||
DROP FUNCTION fn_x_after();
|
||||
|
||||
|
||||
CREATE TABLE measurement (
|
||||
city_id int not null,
|
||||
logdate int not null,
|
||||
peaktemp int,
|
||||
unitsales int
|
||||
);
|
||||
|
||||
CREATE TABLE measurement_movement (
|
||||
city_id int not null,
|
||||
logdate int not null,
|
||||
peaktemp int,
|
||||
unitsales int
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION measurement_insert_trigger()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
INSERT INTO measurement_movement VALUES (NEW.*);
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER insert_measurement_trigger
|
||||
BEFORE INSERT ON measurement
|
||||
FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();
|
||||
|
||||
COPY measurement from stdin;
|
||||
10001 22 32 42
|
||||
10002 23 33 43
|
||||
10003 24 34 44
|
||||
10004 25 35 45
|
||||
10005 26 36 46
|
||||
\.
|
||||
|
||||
select * from measurement_movement order by city_id;
|
||||
select * from measurement order by city_id;
|
||||
|
||||
drop trigger insert_measurement_trigger on measurement;
|
||||
drop function measurement_insert_trigger;
|
||||
drop table measurement;
|
||||
drop table measurement_movement;
|
||||
|
||||
Reference in New Issue
Block a user