/*
 * Copyright (c) 2016, PostgreSQL Global Development Group
 * See the LICENSE file in the project root for more information.
 */

package org.postgresql.replication;

import org.postgresql.replication.fluent.CommonOptions;
import org.postgresql.replication.fluent.logical.LogicalReplicationOptions;

import java.nio.ByteBuffer;
import java.sql.SQLException;

Not tread safe replication stream (though certain methods can be safely called by different threads). After complete streaming should be close, for free resource on backend. Periodical status update work only when use read() method. It means that process wal record should be fast as possible, because during process wal record lead to disconnect by timeout from server.
/** * Not tread safe replication stream (though certain methods can be safely called by different * threads). After complete streaming should be close, for free resource on backend. Periodical * status update work only when use {@link PGReplicationStream#read()} method. It means that * process wal record should be fast as possible, because during process wal record lead to * disconnect by timeout from server. */
public interface PGReplicationStream //JCP! if mvn.project.property.postgresql.jdbc.spec >= "JDBC4.1" extends AutoCloseable //JCP! endif /* hi, checkstyle */ {

Read next wal record from backend. It method can be block until new message will not get from server.

A single WAL record is never split across two XLogData messages. When a WAL record crosses a WAL page boundary, and is therefore already split using continuation records, it can be split at the page boundary. In other words, the first main WAL record and its continuation records can be sent in different XLogData messages.

Throws:
  • SQLException – when some internal exception occurs during read from stream
Returns:not null byte array received by replication protocol, return ByteBuffer wrap around received byte array with use offset, so, use ByteBuffer.array() carefully
/** * <p>Read next wal record from backend. It method can be block until new message will not get * from server.</p> * * <p>A single WAL record is never split across two XLogData messages. When a WAL record crosses a * WAL page boundary, and is therefore already split using continuation records, it can be split * at the page boundary. In other words, the first main WAL record and its continuation records * can be sent in different XLogData messages.</p> * * @return not null byte array received by replication protocol, return ByteBuffer wrap around * received byte array with use offset, so, use {@link ByteBuffer#array()} carefully * @throws SQLException when some internal exception occurs during read from stream */
ByteBuffer read() throws SQLException;

Read next wal record from backend. It method can't be block and in contrast to read(). If message from backend absent return null. It allow periodically check message in stream and if they absent sleep some time, but it time should be less than CommonOptions.getStatusInterval() to avoid disconnect from the server.

A single WAL record is never split across two XLogData messages. When a WAL record crosses a WAL page boundary, and is therefore already split using continuation records, it can be split at the page boundary. In other words, the first main WAL record and its continuation records can be sent in different XLogData messages.

Throws:
  • SQLException – when some internal exception occurs during read from stream
Returns:byte array received by replication protocol or null if pending message from server absent. Returns ByteBuffer wrap around received byte array with use offset, so, use ByteBuffer.array() carefully.
/** * <p>Read next wal record from backend. It method can't be block and in contrast to {@link * PGReplicationStream#read()}. If message from backend absent return null. It allow periodically * check message in stream and if they absent sleep some time, but it time should be less than * {@link CommonOptions#getStatusInterval()} to avoid disconnect from the server.</p> * * <p>A single WAL record is never split across two XLogData messages. When a WAL record crosses a * WAL page boundary, and is therefore already split using continuation records, it can be split * at the page boundary. In other words, the first main WAL record and its continuation records * can be sent in different XLogData messages.</p> * * @return byte array received by replication protocol or null if pending message from server * absent. Returns ByteBuffer wrap around received byte array with use offset, so, use {@link * ByteBuffer#array()} carefully. * @throws SQLException when some internal exception occurs during read from stream */
ByteBuffer readPending() throws SQLException;

Parameter updates by execute read() method.

It is safe to call this method in a thread different than the main thread. However, usually this method is called in the main thread after a successful read() or readPending(), to get the LSN corresponding to the received record.

Returns:not null LSN position that was receive last time via read() method
/** * <p>Parameter updates by execute {@link PGReplicationStream#read()} method.</p> * * <p>It is safe to call this method in a thread different than the main thread. However, usually this * method is called in the main thread after a successful {@link PGReplicationStream#read()} or * {@link PGReplicationStream#readPending()}, to get the LSN corresponding to the received record.</p> * * @return not null LSN position that was receive last time via {@link PGReplicationStream#read()} * method */
LogSequenceNumber getLastReceiveLSN();

Last flushed lsn send in update message to backend. Parameter updates only via setFlushedLSN(LogSequenceNumber)

It is safe to call this method in a thread different than the main thread.

Returns:not null location of the last WAL flushed to disk in the standby.
/** * <p>Last flushed lsn send in update message to backend. Parameter updates only via {@link * PGReplicationStream#setFlushedLSN(LogSequenceNumber)}</p> * * <p>It is safe to call this method in a thread different than the main thread.</p> * * @return not null location of the last WAL flushed to disk in the standby. */
LogSequenceNumber getLastFlushedLSN();

Last applied lsn send in update message to backed. Parameter updates only via setAppliedLSN(LogSequenceNumber)

It is safe to call this method in a thread different than the main thread.

Returns:not null location of the last WAL applied in the standby.
/** * <p>Last applied lsn send in update message to backed. Parameter updates only via {@link * PGReplicationStream#setAppliedLSN(LogSequenceNumber)}</p> * * <p>It is safe to call this method in a thread different than the main thread.</p> * * @return not null location of the last WAL applied in the standby. */
LogSequenceNumber getLastAppliedLSN();

Set flushed LSN. It parameter will be send to backend on next update status iteration. Flushed LSN position help backend define which wal can be recycle.

It is safe to call this method in a thread different than the main thread. The updated value will be sent to the backend in the next status update run.

Params:
  • flushed – not null location of the last WAL flushed to disk in the standby.
See Also:
/** * <p>Set flushed LSN. It parameter will be send to backend on next update status iteration. Flushed * LSN position help backend define which wal can be recycle.</p> * * <p>It is safe to call this method in a thread different than the main thread. The updated value * will be sent to the backend in the next status update run.</p> * * @param flushed not null location of the last WAL flushed to disk in the standby. * @see PGReplicationStream#forceUpdateStatus() */
void setFlushedLSN(LogSequenceNumber flushed);

Parameter used only physical replication and define which lsn already was apply on standby. Feedback will send to backend on next update status iteration.

It is safe to call this method in a thread different than the main thread. The updated value will be sent to the backend in the next status update run.

Params:
  • applied – not null location of the last WAL applied in the standby.
See Also:
/** * <p>Parameter used only physical replication and define which lsn already was apply on standby. * Feedback will send to backend on next update status iteration.</p> * * <p>It is safe to call this method in a thread different than the main thread. The updated value * will be sent to the backend in the next status update run.</p> * * @param applied not null location of the last WAL applied in the standby. * @see PGReplicationStream#forceUpdateStatus() */
void setAppliedLSN(LogSequenceNumber applied);
Force send to backend status about last received, flushed and applied LSN. You can not use it method explicit, because PGReplicationStream send status to backend periodical by configured interval via CommonOptions.getStatusInterval
Throws:
  • SQLException – when some internal exception occurs during read from stream
See Also:
/** * Force send to backend status about last received, flushed and applied LSN. You can not use it * method explicit, because {@link PGReplicationStream} send status to backend periodical by * configured interval via {@link LogicalReplicationOptions#getStatusInterval} * * @throws SQLException when some internal exception occurs during read from stream * @see LogicalReplicationOptions#getStatusInterval() */
void forceUpdateStatus() throws SQLException;
Returns:true if replication stream was already close, otherwise return false
/** * @return {@code true} if replication stream was already close, otherwise return {@code false} */
boolean isClosed();

Stop replication changes from server and free resources. After that connection can be reuse to another queries. Also after close current stream they cannot be used anymore.

Note: This method can spend much time for logical replication stream on postgresql version 9.6 and lower, because postgresql have bug - during decode big transaction to logical form and during wait new changes postgresql ignore messages from client. As workaround you can close replication connection instead of close replication stream. For more information about it problem see mailing list thread Stopping logical replication protocol

Throws:
  • SQLException – when some internal exception occurs during end streaming
/** * <p>Stop replication changes from server and free resources. After that connection can be reuse * to another queries. Also after close current stream they cannot be used anymore.</p> * * <p><b>Note:</b> This method can spend much time for logical replication stream on postgresql * version 9.6 and lower, because postgresql have bug - during decode big transaction to logical * form and during wait new changes postgresql ignore messages from client. As workaround you can * close replication connection instead of close replication stream. For more information about it * problem see mailing list thread <a href="http://www.postgresql.org/message-id/CAFgjRd3hdYOa33m69TbeOfNNer2BZbwa8FFjt2V5VFzTBvUU3w@mail.gmail.com"> * Stopping logical replication protocol</a></p> * * @throws SQLException when some internal exception occurs during end streaming */
void close() throws SQLException; }