#kvrocks ```mermaid sequenceDiagram actor User participant Slave participant Master User -) Slave: SLAVEOF opt AUTH Slave ->> Master: AUTH xxx Master -->> Slave: OK end Slave ->> Master: _db_name Master -->> Slave: master's dbname Slave ->> Slave: 检验 dbname 相同 Slave ->> Master: replconf listening-port {slave-port} Master -->> Slave: OK Note over Slave,Master: 尝试进行 PSYNC Slave ->> Master: PSYNC {next_seq} Master ->> Master: WAL 中是否有<br/> next_seq alt 有,psync rect rgb(191, 230, 158) Master ->> Master: 开启<br/> FeedSlaveThread rect rgb(193, 245, 204) loop batch loop Master ->> Master: 迭代 WAL Master -) Slave: write batches Slave ->> Slave: ApplyWriteBatch Note right of Slave: 定时或 master 要求时发送 ack Master -) Slave: _getack Slave -) Master: replconf ack {cur_seq} end end end else 没有,full sync rect rgb(191, 223, 255) Slave ->> Master: _fetch_meta Master ->> Master: 检查或创建<br/> checkpoint Master -->> Slave: checkpoint file list Slave ->> Master: _fetch_file file1,file2,... Master -->> Slave: <file_size, file_data>, ... Slave ->> Slave: restoreFromCheckpoint Slave ->> Slave: 重试 PSYNC end end ``` - dbname 校验: - slave 和 master 配置文件里的 db-name 必须相同才能复制,避免集群 mismatch - replconf listening-port - 向 master 通告 slave 的监听端口,用于 info 等命令展示 - 当 slave 配置了 replica-announce-ip 选项后,还会发送 ip 地址,格式: - `replconf listening-port {port} ip-address {ip}` - 用于应对 NAT 等场景。默认不启用,master 从 slave 链接上获取 ip - [Support for replica-announce-ip and replica-announce-port #481](https://github.com/apache/kvrocks/discussions/481) - psync 命令 - 可以携带 **`replication_id`**: `psync replication_id next_seq` - [PSYNC based on Unique Replication Sequence ID #538](https://github.com/apache/kvrocks/pull/538) - master 换了,同一个seq 前后两个master上的内容可能不同,因此每个变更添加此ID(PutLogData),同步时同时校验 id + seq,不同 master 的 replication_id 不同 - replica_id + seq 都相同表示数据一样 - 重启或提升为 master 后重置 - **`next_seq`**: `db_->GetLatestSequenceNumber() + 1` - full sync - master 生成 checkpoint 再传输目录下的文件 - 相对 backup,checkpoint 使用硬链接,磁盘占用很小 - fetch files - 多线程并行执行 - 保存目录:sync_checkpoint - 如果目录中有同名文件且 *crc 相同* 则表示已经 fetch 过,无需再次 fetch - 附加条件:ReplicationThread::Start 时需要清理 sync 目录,删除旧 master 同步过来的数据。(不同 master 的文件名相同,但内容可能不同)。 - restoreFromCheckpoint - 先重命令老DB,如果 restore 失败则回滚(恢复老DB) - restore 成功则删除老DB