Hi, We came up with this patch in response to a problem reported to us by a client. They had a query which took an unacceptably long time to respond to a cancel request (SIGINT). The client uses 8.1.4, so the patch is against that.
Their work_mem setting was rather large (1000000). We determined that when it received SIGINT, the backend was always inside qsort(), so it wouldn't call ProcessInterrupts() again until it finished this large in-memory sort. Upon entering tuplesort_performsort(), state->memtupcount was 29247. The patch puts a CHECK_FOR_INTERRUPTS in qsort_comparetup. This solves their problem, at the cost of checking InterruptPending a lot. The "unlikely()" gcc directive might help there a bit. I'm not sure if this patch has general applicability - but it seems to solve the problem for our client. Does anyone think it might introduce any new problems? Thanks, -- Charles Duffy
Index: src/backend/utils/sort/tuplesort.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v retrieving revision 1.54.2.1 diff -c -r1.54.2.1 tuplesort.c *** src/backend/utils/sort/tuplesort.c 22 Nov 2005 18:23:25 -0000 1.54.2.1 --- src/backend/utils/sort/tuplesort.c 6 Jul 2006 06:53:47 -0000 *************** *** 1779,1785 **** qsort_comparetup(const void *a, const void *b) { /* The passed pointers are pointers to void * ... */ ! return COMPARETUP(qsort_tuplesortstate, *(void **) a, *(void **) b); } --- 1779,1785 ---- qsort_comparetup(const void *a, const void *b) { /* The passed pointers are pointers to void * ... */ ! CHECK_FOR_INTERRUPTS(); return COMPARETUP(qsort_tuplesortstate, *(void **) a, *(void **) b); }
---------------------------(end of broadcast)--------------------------- TIP 9: In versions below 8.0, the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match