relcache reference leak on refresh materialized view concurrently - Mailing list pgsql-bugs
From | yamamoto@valinux.co.jp (YAMAMOTO Takashi) |
---|---|
Subject | relcache reference leak on refresh materialized view concurrently |
Date | |
Msg-id | 20140317054945.BD7AB71A4D@kuma.localdomain Whole thread Raw |
Responses |
Re: relcache reference leak on refresh materialized view concurrently
|
List | pgsql-bugs |
the following patch fixes missing index_close in case the mv has non-unique indexes. YAMAMOTO Takashi diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index d64f165..83efab1 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -611,6 +611,8 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid) Relation indexRel; HeapTuple indexTuple; Form_pg_index indexStruct; + int numatts; + int i; indexRel = index_open(indexoid, RowExclusiveLock); indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid)); @@ -619,61 +621,63 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid) indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); /* We're only interested if it is unique and valid. */ - if (indexStruct->indisunique && IndexIsValid(indexStruct)) + if (!indexStruct->indisunique || !IndexIsValid(indexStruct)) { - int numatts = indexStruct->indnatts; - int i; - - /* Skip any index on an expression. */ - if (RelationGetIndexExpressions(indexRel) != NIL) - { - index_close(indexRel, NoLock); - ReleaseSysCache(indexTuple); - continue; - } + index_close(indexRel, NoLock); + ReleaseSysCache(indexTuple); + continue; + } - /* Skip partial indexes. */ - if (RelationGetIndexPredicate(indexRel) != NIL) - { - index_close(indexRel, NoLock); - ReleaseSysCache(indexTuple); - continue; - } + /* Skip any index on an expression. */ + if (RelationGetIndexExpressions(indexRel) != NIL) + { + index_close(indexRel, NoLock); + ReleaseSysCache(indexTuple); + continue; + } - /* Hold the locks, since we're about to run DML which needs them. */ + /* Skip partial indexes. */ + if (RelationGetIndexPredicate(indexRel) != NIL) + { index_close(indexRel, NoLock); + ReleaseSysCache(indexTuple); + continue; + } - /* Add quals for all columns from this index. */ - for (i = 0; i < numatts; i++) - { - int attnum = indexStruct->indkey.values[i]; - Oid type; - Oid op; - const char *colname; - - /* - * Only include the column once regardless of how many times - * it shows up in how many indexes. - */ - if (usedForQual[attnum - 1]) - continue; - usedForQual[attnum - 1] = true; - - /* - * Actually add the qual, ANDed with any others. - */ - if (foundUniqueIndex) - appendStringInfoString(&querybuf, " AND "); - - colname = quote_identifier(NameStr((tupdesc->attrs[attnum - 1])->attname)); - appendStringInfo(&querybuf, "newdata.%s ", colname); - type = attnumTypeId(matviewRel, attnum); - op = lookup_type_cache(type, TYPECACHE_EQ_OPR)->eq_opr; - mv_GenerateOper(&querybuf, op); - appendStringInfo(&querybuf, " mv.%s", colname); - - foundUniqueIndex = true; - } + /* Hold the locks, since we're about to run DML which needs them. */ + index_close(indexRel, NoLock); + + /* Add quals for all columns from this index. */ + numatts = indexStruct->indnatts; + for (i = 0; i < numatts; i++) + { + int attnum = indexStruct->indkey.values[i]; + Oid type; + Oid op; + const char *colname; + + /* + * Only include the column once regardless of how many times + * it shows up in how many indexes. + */ + if (usedForQual[attnum - 1]) + continue; + usedForQual[attnum - 1] = true; + + /* + * Actually add the qual, ANDed with any others. + */ + if (foundUniqueIndex) + appendStringInfoString(&querybuf, " AND "); + + colname = quote_identifier(NameStr((tupdesc->attrs[attnum - 1])->attname)); + appendStringInfo(&querybuf, "newdata.%s ", colname); + type = attnumTypeId(matviewRel, attnum); + op = lookup_type_cache(type, TYPECACHE_EQ_OPR)->eq_opr; + mv_GenerateOper(&querybuf, op); + appendStringInfo(&querybuf, " mv.%s", colname); + + foundUniqueIndex = true; } ReleaseSysCache(indexTuple); }
pgsql-bugs by date: