* The main loop of ReceiveXlogStream. Handles the COPY stream after * initiating streaming with the START_REPLICATION command. * * If the COPY ends (not necessarily successfully) due a message from the * server, returns a PGresult and sets *stoppos to the last byte written. * On any other sort of error, returns NULL. */
| 742 | * On any other sort of error, returns NULL. |
| 743 | */ |
| 744 | static PGresult * |
| 745 | HandleCopyStream(PGconn *conn, StreamCtl *stream, |
| 746 | XLogRecPtr *stoppos) |
| 747 | { |
| 748 | char *copybuf = NULL; |
| 749 | TimestampTz last_status = -1; |
| 750 | XLogRecPtr blockpos = stream->startpos; |
| 751 | |
| 752 | still_sending = true; |
| 753 | |
| 754 | while (1) |
| 755 | { |
| 756 | int r; |
| 757 | TimestampTz now; |
| 758 | long sleeptime; |
| 759 | |
| 760 | /* |
| 761 | * Check if we should continue streaming, or abort at this point. |
| 762 | */ |
| 763 | if (!CheckCopyStreamStop(conn, stream, blockpos)) |
| 764 | goto error; |
| 765 | |
| 766 | now = feGetCurrentTimestamp(); |
| 767 | |
| 768 | /* |
| 769 | * If synchronous option is true, issue sync command as soon as there |
| 770 | * are WAL data which has not been flushed yet. |
| 771 | */ |
| 772 | if (stream->synchronous && lastFlushPosition < blockpos && walfile != NULL) |
| 773 | { |
| 774 | if (stream->walmethod->sync(walfile) != 0) |
| 775 | { |
| 776 | pg_log_fatal("could not fsync file \"%s\": %s", |
| 777 | current_walfile_name, stream->walmethod->getlasterror()); |
| 778 | exit(1); |
| 779 | } |
| 780 | lastFlushPosition = blockpos; |
| 781 | |
| 782 | /* |
| 783 | * Send feedback so that the server sees the latest WAL locations |
| 784 | * immediately. |
| 785 | */ |
| 786 | if (!sendFeedback(conn, blockpos, now, false)) |
| 787 | goto error; |
| 788 | last_status = now; |
| 789 | } |
| 790 | |
| 791 | /* |
| 792 | * Potentially send a status message to the primary |
| 793 | */ |
| 794 | if (still_sending && stream->standby_message_timeout > 0 && |
| 795 | feTimestampDifferenceExceeds(last_status, now, |
| 796 | stream->standby_message_timeout)) |
| 797 | { |
| 798 | /* Time to send feedback! */ |
| 799 | if (!sendFeedback(conn, blockpos, now, false)) |
| 800 | goto error; |
| 801 | last_status = now; |
no test coverage detected