openGauss源码解析(54)

openGauss源码解析:存储引擎源码解析(22)

4.2.10 主备机制

openGauss提供主备机制来保障数据的高可靠和数据库服务的高可用。如图4-37所示,在主、备实例之间通过日志复制来进行数据库数据和状态的一致性同步。日志同步是指将主机对数据的修改日志同步到备机,备机通过日志回放将日志重新还原为数据修改。

图4-37 主备机日志同步示意图

参与日志同步的主要有“wal sender”(主机端)和“wal receiver”(备机端)两个线程。一个主机上可以由多个“wal sender”线程同时存在,用于给不同的备机进行日志复制;一个备机上同一时刻只会有一个“wal receiver”线程,从唯一一个指定的主机上拷贝日志。

“wal sender”线程的所有关键信息均保存在knl_t_walsender_context结构体中,其定义代码如下:

typedef struct knl_t_walsender_context {

char* load_cu_buffer;

int load_cu_buffer_size;

struct WalSndCtlData* WalSndCtl;

struct WalSnd* MyWalSnd;

int logical_xlog_advanced_timeout;

DemoteMode Demotion;

bool wake_wal_senders;

bool wal_send_completed;

int sendFile;

XLogSegNo sendSegNo;

uint32 sendOff;

struct WSXLogJustSendRegion* wsXLogJustSendRegion;

XLogRecPtr sentPtr;

XLogRecPtr catchup_threshold;

struct StringInfoData* reply_message;

struct StringInfoData* tmpbuf;

char* output_xlog_message;

Size output_xlog_msg_prefix_len;

char* output_data_message;

uint32 output_data_msg_cur_len;

XLogRecPtr output_data_msg_start_xlog;

XLogRecPtr output_data_msg_end_xlog;

struct XLogReaderState* ws_xlog_reader;

TimestampTz last_reply_timestamp;

TimestampTz last_logical_xlog_advanced_timestamp;

bool waiting_for_ping_response;

volatile sig_atomic_t got_SIGHUP;

volatile sig_atomic_t walsender_shutdown_requested;

volatile sig_atomic_t walsender_ready_to_stop;

volatile sig_atomic_t response_switchover_requested;

ServerMode server_run_mode;

char gucconf_file[MAXPGPATH];

char gucconf_lock_file[MAXPGPATH];

FILE* ws_dummy_data_read_file_fd;

uint32 ws_dummy_data_read_file_num;

struct cbmarray* CheckCUArray;

struct LogicalDecodingContext* logical_decoding_ctx;

XLogRecPtr logical_startptr;

int remotePort;

bool walSndCaughtUp;

} knl_t_walsender_context;

其中:

(1) WalSndCtl指向保存全局所有“wal sender”线程控制状态的共享结构体,是一致性复制协议的关键所在。
(2) MyWalSnd指向上述全局共享结构体中当前“wal sender”线程的槽位。
(3) Demotion为当前主机降备模式,分为未降备(NoDemote)、优雅降备(SmartDemote)和快速降备(FastDemote)。
(4) sendFile、sendSegNo、sendOff用于保存当前复制的日志文件的文件操作状态。
(5) reply_message用于保存备机回复的消息。
(6) output_xlog_message为待发送的日志内容主体。
(7) server_run_mode为wal sender线程启动时的HA(high availability,HA)高可靠性)状态,即主机(primary)、备机(standby)或未决(pending)。
(8) walSndCaughtUp指示备机是否已经追赶上主机。
(9) remotePort为wal receiver线程的端口,用于身份验证。
(10) load_cu_buffer 、load_cu_buffer_size 、output_data_message、output_data_msg_cur_len、output_data_msg_start_xlog、output_data_msg_end_xlog、ws_xlog_reader、CheckCUArray为后续支持混合类型(日志+增量页面)复制的预留接口。

wal receiver线程的所有关键信息均保存在knl_t_walreceiver_context结构体中,其定义代码如下:

typedef struct knl_t_walreceiver_context {

volatile sig_atomic_t got_SIGHUP;

volatile sig_atomic_t got_SIGTERM;

volatile sig_atomic_t start_switchover;

char gucconf_file[MAXPGPATH];

char temp_guc_conf_file[MAXPGPATH];

char gucconf_lock_file[MAXPGPATH];

char** reserve_item;

time_t standby_config_modify_time;

time_t Primary_config_modify_time;

TimestampTz last_sendfilereply_timestamp;

int check_file_timeout;

struct WalRcvCtlBlock* walRcvCtlBlock;

struct StandbyReplyMessage* reply_message;

struct StandbyHSFeedbackMessage* feedback_message;

struct StandbySwitchRequestMessage* request_message;

struct ConfigModifyTimeMessage* reply_modify_message;

volatile bool WalRcvImmediateInterruptOK;

bool AmWalReceiverForFailover;

bool AmWalReceiverForStandby;

int control_file_writed;

} knl_t_walreceiver_context;

其中:

(1) walRcvCtlBlock指向“wal receiver”线程主控数据,保存当前日志复制进度,备机日志写盘、写入磁盘进度,以及接收日志缓冲区。
(2) reply_message保存用于回复主机的消息。
(3) feedback_message用于保存热备的相关信息,供主机空闲空间清理时参考。
(4) request_message用于保存主机降备请求的相关信息。
(5) reply_modify_message用于保存请求配置文件复制的相关信息。
(6) AmWalReceiverForFailover表示当前“wal receiver”线程处于failover场景下,连接从备进行日志追赶。
(7) AmWalReceiverForStandby表示当前“wal receiver”线程为连接备机进行日志复制的级联备机。
posted @ 2024-04-29 16:22  openGauss-bot  阅读(21)  评论(0编辑  收藏  举报