提交 398ac2b7 编写于 作者: P Paul Guo

Fix potential panic in visibility check code. (#10589)

We've seen a panic case on gpdb 6 with stack as below,

3  markDirty (isXmin=0 '\000', tuple=0x7effe221b3c0, relation=0x0, buffer=16058) at tqual.c:105
4  SetHintBits (xid=<optimized out>, infomask=1024, rel=0x0, buffer=16058, tuple=0x7effe221b3c0) at tqual.c:199
5  HeapTupleSatisfiesMVCC (relation=0x0, htup=<optimized out>, snapshot=0x15f0dc0 <CatalogSnapshotData>, buffer=16058) at tqual.c:1200
6  0x00000000007080a8 in systable_recheck_tuple (sysscan=sysscan@entry=0x2e85940, tup=tup@entry=0x2e859e0) at genam.c:462
7  0x000000000078753b in findDependentObjects (object=0x2e856e0, flags=<optimized out>, stack=0x0, targetObjects=0x2e85b40, pendingObjects=0x2e856b0,
   depRel=0x7fff2608adc8) at dependency.c:793
8  0x00000000007883c7 in performMultipleDeletions (objects=objects@entry=0x2e856b0, behavior=DROP_RESTRICT, flags=flags@entry=0) at dependency.c:363
9  0x0000000000870b61 in RemoveRelations (drop=drop@entry=0x2e85000) at tablecmds.c:1313
10 0x0000000000a85e48 in ExecDropStmt (stmt=stmt@entry=0x2e85000, isTopLevel=isTopLevel@entry=0 '\000') at utility.c:1765
11 0x0000000000a87d03 in ProcessUtilitySlow (parsetree=parsetree@entry=0x2e85000,

The reason is that we pass a NULL relation to the visibility check code, which
might use the relation variable to determine if hint bit should be set or not.
Let's pass the correct relation variable even it might not be used finally.

I'm not able to reproduce the issue locally so I can not provide a test case
but that is surely a potential issue.
Reviewed-by: NAshwin Agrawal <aashwin@vmware.com>
(cherry picked from commit 85811692)
上级 f7dcbb5a
......@@ -459,7 +459,7 @@ systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Assert(BufferIsValid(scan->xs_cbuf));
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
result = HeapTupleSatisfiesVisibility(NULL, tup, freshsnap, scan->xs_cbuf);
result = HeapTupleSatisfiesVisibility(scan->heapRelation, tup, freshsnap, scan->xs_cbuf);
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
}
else
......@@ -471,7 +471,7 @@ systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Assert(BufferIsValid(scan->rs_cbuf));
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
result = HeapTupleSatisfiesVisibility(NULL, tup, freshsnap, scan->rs_cbuf);
result = HeapTupleSatisfiesVisibility(scan->rs_rd, tup, freshsnap, scan->rs_cbuf);
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
}
return result;
......
......@@ -100,12 +100,15 @@ markDirty(Buffer buffer, Relation relation, HeapTupleHeader tuple, bool isXmin)
* The GUC gp_disable_tuple_hints is on. Do further evaluation whether we
* want to write out the buffer or not.
*/
Assert(relation != NULL);
if (RelationGetRelid(relation) < FirstNormalObjectId ||
/*
* We always mark the buffer dirty for catalog tables. We do not expect
* relation to be NULL but in case of that always mark the buffer dirty.
*/
if (relation == NULL ||
RelationGetRelid(relation) < FirstNormalObjectId ||
RelationGetNamespace(relation) == PG_AOSEGMENT_NAMESPACE)
{
/* Assume we want to always mark the buffer dirty */
MarkBufferDirtyHint(buffer, true);
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册