| 3230 | #define PSYNC_NOT_SUPPORTED 4 |
| 3231 | #define PSYNC_TRY_LATER 5 |
| 3232 | int slaveTryPartialResynchronization(redisMaster *mi, connection *conn, int read_reply) { |
| 3233 | const char *psync_replid; |
| 3234 | char psync_offset[32]; |
| 3235 | sds reply; |
| 3236 | |
| 3237 | /* Writing half */ |
| 3238 | if (!read_reply) { |
| 3239 | /* Initially set master_initial_offset to -1 to mark the current |
| 3240 | * master replid and offset as not valid. Later if we'll be able to do |
| 3241 | * a FULL resync using the PSYNC command we'll set the offset at the |
| 3242 | * right value, so that this information will be propagated to the |
| 3243 | * client structure representing the master into g_pserver->master. */ |
| 3244 | mi->master_initial_offset = -1; |
| 3245 | |
| 3246 | if (mi->cached_master) { |
| 3247 | psync_replid = mi->cached_master->replid; |
| 3248 | snprintf(psync_offset,sizeof(psync_offset),"%lld", mi->cached_master->reploff+1); |
| 3249 | serverLog(LL_NOTICE,"Trying a partial resynchronization (request %s:%s).", psync_replid, psync_offset); |
| 3250 | } else { |
| 3251 | serverLog(LL_NOTICE,"Partial resynchronization not possible (no cached master)"); |
| 3252 | psync_replid = "?"; |
| 3253 | memcpy(psync_offset,"-1",3); |
| 3254 | } |
| 3255 | |
| 3256 | /* Issue the PSYNC command, if this is a master with a failover in |
| 3257 | * progress then send the failover argument to the replica to cause it |
| 3258 | * to become a master */ |
| 3259 | if (g_pserver->failover_state == FAILOVER_IN_PROGRESS) { |
| 3260 | reply = sendCommand(conn,"PSYNC",psync_replid,psync_offset,"FAILOVER",NULL); |
| 3261 | } else { |
| 3262 | reply = sendCommand(conn,"PSYNC",psync_replid,psync_offset,NULL); |
| 3263 | } |
| 3264 | |
| 3265 | if (reply != NULL) { |
| 3266 | serverLog(LL_WARNING,"Unable to send PSYNC to master: %s",reply); |
| 3267 | sdsfree(reply); |
| 3268 | connSetReadHandler(conn, NULL); |
| 3269 | return PSYNC_WRITE_ERROR; |
| 3270 | } |
| 3271 | return PSYNC_WAIT_REPLY; |
| 3272 | } |
| 3273 | |
| 3274 | /* Reading half */ |
| 3275 | reply = receiveSynchronousResponse(mi, conn); |
| 3276 | if (sdslen(reply) == 0) { |
| 3277 | /* The master may send empty newlines after it receives PSYNC |
| 3278 | * and before to reply, just to keep the connection alive. */ |
| 3279 | sdsfree(reply); |
| 3280 | return PSYNC_WAIT_REPLY; |
| 3281 | } |
| 3282 | |
| 3283 | connSetReadHandler(conn, NULL); |
| 3284 | |
| 3285 | if (!strncmp(reply,"+FULLRESYNC",11)) { |
| 3286 | char *replid = NULL, *offset = NULL; |
| 3287 | |
| 3288 | /* FULL RESYNC, parse the reply in order to extract the replid |
| 3289 | * and the replication offset. */ |
no test coverage detected