On 2020-01-28 4:14 a.m., Daniel Verite wrote:
David Zhang wrote:
The error "No space left on device" can be logged by fprintf() which is
redefined as pg_fprintf() when print_aligned_text() is called
Are you sure? I don't find that redefinition. Besides
print_aligned_text() also calls putc and puts.
Yes, below is the gdb debug message when psql first time detects the
error "No space left on device". Test case, "postgres=# select
repeat('111', 1000000) \g /mnt/ramdisk/file"
bt
#0 flushbuffer (target=0x7ffd6a709ad0) at snprintf.c:313
#1 0x000055ba90b88b6c in dopr_outchmulti (c=32, slen=447325,
target=0x7ffd6a709ad0) at snprintf.c:1435
#2 0x000055ba90b88d5e in trailing_pad (padlen=-1499997,
target=0x7ffd6a709ad0) at snprintf.c:1514
#3 0x000055ba90b87f36 in fmtstr (value=0x55ba90bb4f9a "", leftjust=1,
minlen=1499997, maxwidth=0, pointflag=0, target=0x7ffd6a709ad0) at
snprintf.c:994
#4 0x000055ba90b873c6 in dopr (target=0x7ffd6a709ad0,
format=0x55ba90bb5083 "%s%-*s", args=0x7ffd6a709f40) at snprintf.c:675
#5 0x000055ba90b865b5 in pg_vfprintf (stream=0x55ba910cf240,
fmt=0x55ba90bb507f "%-*s%s%-*s", args=0x7ffd6a709f40) at snprintf.c:257
#6 0x000055ba90b866aa in pg_fprintf (stream=0x55ba910cf240,
fmt=0x55ba90bb507f "%-*s%s%-*s") at snprintf.c:270
#7 0x000055ba90b75d22 in print_aligned_text (cont=0x7ffd6a70a210,
fout=0x55ba910cf240, is_pager=false) at print.c:937
#8 0x000055ba90b7ba19 in printTable (cont=0x7ffd6a70a210,
fout=0x55ba910cf240, is_pager=false, flog=0x0) at print.c:3378
#9 0x000055ba90b7bedc in printQuery (result=0x55ba910f9860,
opt=0x7ffd6a70a2c0, fout=0x55ba910cf240, is_pager=false, flog=0x0) at
print.c:3496
#10 0x000055ba90b39560 in PrintQueryTuples (results=0x55ba910f9860) at
common.c:874
#11 0x000055ba90b39d55 in PrintQueryResults (results=0x55ba910f9860) at
common.c:1262
#12 0x000055ba90b3a343 in SendQuery (query=0x55ba910f2590 "select
repeat('111', 1000000) ") at common.c:1446
#13 0x000055ba90b51f36 in MainLoop (source=0x7f1623a9ea00
<_IO_2_1_stdin_>) at mainloop.c:505
#14 0x000055ba90b5c4da in main (argc=3, argv=0x7ffd6a70a738) at
startup.c:445
(gdb) l
308 size_t written;
309
310 written = fwrite(target->bufstart, 1, nc,
target->stream);
311 target->nchars += written;
312 if (written != nc)
313 target->failed = true;
314 }
315 target->bufptr = target->bufstart;
316 }
317
(gdb) p written
$2 = 1023
(gdb) p nc
$3 = 1024
(gdb) p strerror(errno)
$4 = 0x7f16238672c9 "No space left on device"
(gdb)
Will that be a better solution if redefine fputs similar to fprintf and
log the exact error when first time discovered?
I think we can assume it's not acceptable to have pg_fprintf()
to print anything to stderr, or to set a flag through a global
variable. So even if using pg_fprintf() for all the printing, no matter
how (through #defines or otherwise), there's still the problem that the
error needs to be propagated up the call chain to be processed by psql.
The concern is that if we can't provide a more accurate
information to the end user when error happens, sometimes the
end user might got even confused.
It's better to have a more informative message, but I'm for
not having the best be the enemy of the good.
The first concern is that at the moment, we have no error
report at all in the case when the output can be opened
but the error happens later along the writes.
Best regards,
--
David
Software Engineer
Highgo Software Inc. (Canada)
www.highgo.ca