Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4d63e26

Browse files
committed
Further hacking on performance of COPY OUT. It seems that fwrite()'s
per-call overhead is quite significant, at least on Linux: whateverit's doing is more than just shoving the bytes into a buffer. Bufferingthe data so we can call fwrite() just once per row seems to be a win.
1 parent223ae69 commit4d63e26

File tree

1 file changed

+40
-45
lines changed

1 file changed

+40
-45
lines changed

‎src/backend/commands/copy.c

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.265 2006/05/25 18:42:17 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.266 2006/05/26 22:50:02 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -95,7 +95,8 @@ typedef struct CopyStateData
9595
/* low-level state data */
9696
CopyDestcopy_dest;/* type of copy source/destination */
9797
FILE*copy_file;/* used if copy_dest == COPY_FILE */
98-
StringInfofe_msgbuf;/* used if copy_dest == COPY_NEW_FE */
98+
StringInfofe_msgbuf;/* used for all dests during COPY TO, only
99+
* for dest == COPY_NEW_FE in COPY FROM */
99100
boolfe_copy;/* true for all FE copy dests */
100101
boolfe_eof;/* true if detected end of copy data */
101102
EolTypeeol_type;/* EOL type of input */
@@ -287,7 +288,6 @@ SendCopyBegin(CopyState cstate)
287288
pq_sendint(&buf,format,2);/* per-column formats */
288289
pq_endmessage(&buf);
289290
cstate->copy_dest=COPY_NEW_FE;
290-
cstate->fe_msgbuf=makeStringInfo();
291291
}
292292
elseif (PG_PROTOCOL_MAJOR(FrontendProtocol) >=2)
293293
{
@@ -364,23 +364,16 @@ SendCopyEnd(CopyState cstate)
364364
{
365365
if (cstate->copy_dest==COPY_NEW_FE)
366366
{
367-
if (cstate->binary)
368-
{
369-
/* Need to flush out file trailer word */
370-
CopySendEndOfRow(cstate);
371-
}
372-
else
373-
{
374-
/* Shouldn't have any unsent data */
375-
Assert(cstate->fe_msgbuf->len==0);
376-
}
367+
/* Shouldn't have any unsent data */
368+
Assert(cstate->fe_msgbuf->len==0);
377369
/* Send Copy Done message */
378370
pq_putemptymessage('c');
379371
}
380372
else
381373
{
382-
/* The FE/BE protocol uses \n as newline for all platforms */
383-
CopySendData(cstate,"\\.\n",3);
374+
CopySendData(cstate,"\\.",2);
375+
/* Need to flush out the trailer (this also appends a newline) */
376+
CopySendEndOfRow(cstate);
384377
pq_endcopyout(false);
385378
}
386379
}
@@ -390,53 +383,34 @@ SendCopyEnd(CopyState cstate)
390383
* CopySendString does the same for null-terminated strings
391384
* CopySendChar does the same for single characters
392385
* CopySendEndOfRow does the appropriate thing at end of each data row
386+
*(data is not actually flushed except by CopySendEndOfRow)
393387
*
394388
* NB: no data conversion is applied by these functions
395389
*----------
396390
*/
397391
staticvoid
398392
CopySendData(CopyStatecstate,void*databuf,intdatasize)
399393
{
400-
switch (cstate->copy_dest)
401-
{
402-
caseCOPY_FILE:
403-
fwrite(databuf,datasize,1,cstate->copy_file);
404-
if (ferror(cstate->copy_file))
405-
ereport(ERROR,
406-
(errcode_for_file_access(),
407-
errmsg("could not write to COPY file: %m")));
408-
break;
409-
caseCOPY_OLD_FE:
410-
if (pq_putbytes((char*)databuf,datasize))
411-
{
412-
/* no hope of recovering connection sync, so FATAL */
413-
ereport(FATAL,
414-
(errcode(ERRCODE_CONNECTION_FAILURE),
415-
errmsg("connection lost during COPY to stdout")));
416-
}
417-
break;
418-
caseCOPY_NEW_FE:
419-
appendBinaryStringInfo(cstate->fe_msgbuf,
420-
(char*)databuf,datasize);
421-
break;
422-
}
394+
appendBinaryStringInfo(cstate->fe_msgbuf, (char*)databuf,datasize);
423395
}
424396

425397
staticvoid
426398
CopySendString(CopyStatecstate,constchar*str)
427399
{
428-
CopySendData(cstate, (void*)str,strlen(str));
400+
appendBinaryStringInfo(cstate->fe_msgbuf,str,strlen(str));
429401
}
430402

431403
staticvoid
432404
CopySendChar(CopyStatecstate,charc)
433405
{
434-
CopySendData(cstate,&c,1);
406+
appendStringInfoCharMacro(cstate->fe_msgbuf,c);
435407
}
436408

437409
staticvoid
438410
CopySendEndOfRow(CopyStatecstate)
439411
{
412+
StringInfofe_msgbuf=cstate->fe_msgbuf;
413+
440414
switch (cstate->copy_dest)
441415
{
442416
caseCOPY_FILE:
@@ -449,24 +423,40 @@ CopySendEndOfRow(CopyState cstate)
449423
CopySendString(cstate,"\r\n");
450424
#endif
451425
}
426+
427+
(void)fwrite(fe_msgbuf->data,fe_msgbuf->len,
428+
1,cstate->copy_file);
429+
if (ferror(cstate->copy_file))
430+
ereport(ERROR,
431+
(errcode_for_file_access(),
432+
errmsg("could not write to COPY file: %m")));
452433
break;
453434
caseCOPY_OLD_FE:
454435
/* The FE/BE protocol uses \n as newline for all platforms */
455436
if (!cstate->binary)
456437
CopySendChar(cstate,'\n');
438+
439+
if (pq_putbytes(fe_msgbuf->data,fe_msgbuf->len))
440+
{
441+
/* no hope of recovering connection sync, so FATAL */
442+
ereport(FATAL,
443+
(errcode(ERRCODE_CONNECTION_FAILURE),
444+
errmsg("connection lost during COPY to stdout")));
445+
}
457446
break;
458447
caseCOPY_NEW_FE:
459448
/* The FE/BE protocol uses \n as newline for all platforms */
460449
if (!cstate->binary)
461450
CopySendChar(cstate,'\n');
451+
462452
/* Dump the accumulated row as one CopyData message */
463-
(void)pq_putmessage('d',cstate->fe_msgbuf->data,
464-
cstate->fe_msgbuf->len);
465-
/* Reset fe_msgbuf to empty */
466-
cstate->fe_msgbuf->len=0;
467-
cstate->fe_msgbuf->data[0]='\0';
453+
(void)pq_putmessage('d',fe_msgbuf->data,fe_msgbuf->len);
468454
break;
469455
}
456+
457+
/* Reset fe_msgbuf to empty */
458+
fe_msgbuf->len=0;
459+
fe_msgbuf->data[0]='\0';
470460
}
471461

472462
/*
@@ -1237,6 +1227,9 @@ CopyTo(CopyState cstate)
12371227
attr_count=list_length(cstate->attnumlist);
12381228
null_print_client=cstate->null_print;/* default */
12391229

1230+
/* We use fe_msgbuf as a per-row buffer regardless of copy_dest */
1231+
cstate->fe_msgbuf=makeStringInfo();
1232+
12401233
/* Get info about the columns we need to process. */
12411234
out_functions= (FmgrInfo*)palloc(num_phys_attrs*sizeof(FmgrInfo));
12421235
force_quote= (bool*)palloc(num_phys_attrs*sizeof(bool));
@@ -1423,6 +1416,8 @@ CopyTo(CopyState cstate)
14231416
{
14241417
/* Generate trailer for a binary copy */
14251418
CopySendInt16(cstate,-1);
1419+
/* Need to flush out the trailer */
1420+
CopySendEndOfRow(cstate);
14261421
}
14271422

14281423
MemoryContextDelete(mycontext);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp