Thread
Commits
-
Fix new BRIN desummarize WAL record
- 817cb100136a 10.0 landed
-
BRIN desummarization writes junk WAL records
Tom Lane <tgl@sss.pgh.pa.us> — 2017-04-07T00:27:04Z
I am seeing the database fail to restart after a crash during the regression tests, due to a divide-by-zero fault in BRIN wal replay. Core was generated by `postgres: startup'. Program terminated with signal 8, Arithmetic exception. #0 brinSetHeapBlockItemptr (buf=<value optimized out>, pagesPerRange=0, heapBlk=0, tid=...) at brin_revmap.c:169 169 iptr += HEAPBLK_TO_REVMAP_INDEX(pagesPerRange, heapBlk); (gdb) bt #0 brinSetHeapBlockItemptr (buf=<value optimized out>, pagesPerRange=0, heapBlk=0, tid=...) at brin_revmap.c:169 #1 0x0000000000478cdc in brin_xlog_desummarize_page (record=0x2403ac8) at brin_xlog.c:274 #2 brin_redo (record=0x2403ac8) at brin_xlog.c:320 #3 0x0000000000513174 in StartupXLOG () at xlog.c:7171 #4 0x00000000006dea91 in StartupProcessMain () at startup.c:217 #5 0x000000000052214a in AuxiliaryProcessMain (argc=2, argv=0x7fff4bb8d1f0) at bootstrap.c:425 #6 0x00000000006d98b7 in StartChildProcess (type=StartupProcess) at postmaster.c:5256 #7 0x00000000006ddae6 in PostmasterMain (argc=3, argv=<value optimized out>) at postmaster.c:1329 #8 0x0000000000658038 in main (argc=3, argv=0x2402b20) at main.c:228 The proximate cause of the exception seems to be that brinSetHeapBlockItemptr is being passed pagesPerRange = 0, which is problematic since HEAPBLK_TO_REVMAP_INDEX tries to divide by that. Looking one level down, the bogus value seems to be coming out of an xl_brin_desummarize WAL record: (gdb) f 1 #1 0x0000000000478cdc in brin_xlog_desummarize_page (record=0x2403ac8) at brin_xlog.c:274 274 brinSetHeapBlockItemptr(buffer, xlrec->pagesPerRange, xlrec->heapBlk, iptr); (gdb) p *xlrec $1 = {pagesPerRange = 0, heapBlk = 0, regOffset = 1} This is, perhaps, not unrelated to the fact that brinRevmapDesummarizeRange doesn't seem to be bothering to fill that field of the record. BTW, is it actually sensible that xl_brin_desummarize's heapBlk is declared OffsetNumber and not BlockNumber? If there's a reason why that's correct, the field name seems damn misleading. regards, tom lane -
Re: BRIN desummarization writes junk WAL records
Alvaro Herrera <alvherre@2ndquadrant.com> — 2017-04-07T20:16:03Z
Tom Lane wrote: > The proximate cause of the exception seems to be that > brinSetHeapBlockItemptr is being passed pagesPerRange = 0, > which is problematic since HEAPBLK_TO_REVMAP_INDEX tries to > divide by that. Looking one level down, the bogus value > seems to be coming out of an xl_brin_desummarize WAL record: > > (gdb) f 1 > #1 0x0000000000478cdc in brin_xlog_desummarize_page (record=0x2403ac8) > at brin_xlog.c:274 > 274 brinSetHeapBlockItemptr(buffer, xlrec->pagesPerRange, xlrec->heapBlk, iptr); > (gdb) p *xlrec > $1 = {pagesPerRange = 0, heapBlk = 0, regOffset = 1} > > This is, perhaps, not unrelated to the fact that > brinRevmapDesummarizeRange doesn't seem to be bothering to fill > that field of the record. Absolutely. > BTW, is it actually sensible that xl_brin_desummarize's heapBlk > is declared OffsetNumber and not BlockNumber? If there's a reason > why that's correct, the field name seems damn misleading. Nah, just an oversight (against which the compiler doesn't protect.) Fixed both problems. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services