关于pipelineDB调用GetLocalStreamReaders的BUG
如果想獲取一個stream所有的reader,那么必須調用這個函數:
Bitmapset *targets = GetLocalStreamReaders(relid);
如果stream下面沒有reader,那么這個targets返回NULL。
我們跟到GetLocalStreamReaders里面看看
Bitmapset * GetLocalStreamReaders(Oid relid) {Bitmapset *readers = GetAllStreamReaders(relid);if (stream_targets && readers){.....
}return readers; }
中間的if不看,這個readers是通過調用GetAllStreamReaders來獲取的,我們繼續跟進去看看。
Bitmapset * GetAllStreamReaders(Oid relid) { HeapTuple tup = SearchSysCache1(PIPELINESTREAMRELID, ObjectIdGetDatum(relid)); bool isnull;.....raw = SysCacheGetAttr(PIPELINESTREAMRELID, tup, Anum_pipeline_stream_queries, &isnull);if (isnull)return NULL;......ReleaseSysCache(tup);return result; }這段代碼就很有意思了。
如果isnull直接return,而后面的ReleaseSysCaceh沒有執行。
這樣上面的tup就一直存在,沒有釋放掉。
這樣會導致后面的一個斷言錯誤。
來看看下面堆棧信息。
TRAP: FailedAssertion("!(ct->refcount == 0)", File: "catcache.c", Line: 588, PID: 3829, Query: (null))
assertion failure at:
pipeline: bgworker: worker?[postgres]?(ExceptionalCondition+0xaf)[0x906b0f]
pipeline: bgworker: worker?[postgres]?(AtEOXact_CatCache+0x1e6)[0x8eb735]
pipeline: bgworker: worker?[postgres]?[0x4fe75a]
pipeline: bgworker: worker?[postgres]?(CommitTransactionCommand+0x72)[0x4ff19c]
pipeline: bgworker: worker?[postgres]?(ContinuousQueryWorkerMain+0x6cd)[0x7366a1]
pipeline: bgworker: worker?[postgres]?[0x7343f9]
pipeline: bgworker: worker?[postgres]?(StartBackgroundWorker+0x2bd)[0x7427ea]
pipeline: bgworker: worker?[postgres]?[0x75532a]
pipeline: bgworker: worker?[postgres]?[0x755646]
pipeline: bgworker: worker?[postgres]?[0x750473]
pipeline: bgworker: worker?[postgres]?(PostmasterMain+0x110c)[0x74f92a]
pipeline: bgworker: worker?[postgres]?[0x694f85]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fb8eb84caf5]
pipeline: bgworker: worker?[postgres]?[0x462e09]
?
我們看看catcache.c:588
582 dlist_foreach(iter, bucket)583 {584 CatCTup *ct;585 586 ct = dlist_container(CatCTup, cache_elem, iter.cur);587 Assert(ct->ct_magic == CT_MAGIC);588 Assert(ct->refcount == 0);589 Assert(!ct->dead);590 }我們看看ct->refcount的解釋:
int refcount; /* number of active references */
這其實跟我修改的代碼有關系,我們從上面堆棧信息分析。
ContinuousQueryWorkerMain-->CommitTransactionCommand
我在ContinuousQueryWorkerMain里面自己調用了
Bitmapset *targets =?GetLocalStreamReaders(relid);
而我判斷targets的時候,
if (!targets) {donothing... }我特意看了一下官方的用法。
src/backend/pipeline/stream.c:200
?
if (targets == NULL){char *name = get_rel_name(pstmt->relid);ereport(ERROR,(errcode(ERRCODE_INVALID_PARAMETER_VALUE),errmsg("no continuous views are currently reading from stream %s", name),errhint("Use CREATE CONTINUOUS VIEW to create a continuous view that includes %s in its FROM clause.", name)));}很清楚的看到,這個里面直接丟了個ERROR,
直接abort,這樣就不會像我上面堆棧信息那樣,后面commit就會斷言異常。
話說,一個stream下面沒有readers是很正常的,但是這么明顯是代碼有錯誤,該釋放的沒有釋放。
?
修改如下:
src/backend/catalog/pipeline_stream.c
GetAllStreamReaders函數
if (isnull)return NULL;修改成
if (isnull){ReleaseSysCache(tup);return NULL; }這樣在返回的時候就直接釋放了tup。
這個里面還有別的問題。后面再寫。
轉載于:https://www.cnblogs.com/sangli/p/4848554.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的关于pipelineDB调用GetLocalStreamReaders的BUG的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 06-图2 Saving James B
- 下一篇: 数字图像处理(一):灰度变换和直方图处理