| 2059 | #define PSYNC_NOT_SUPPORTED 4 |
| 2060 | #define PSYNC_TRY_LATER 5 |
| 2061 | int slaveTryPartialResynchronization(connection *conn, int read_reply) { |
| 2062 | char *psync_replid; |
| 2063 | char psync_offset[32]; |
| 2064 | sds reply; |
| 2065 | |
| 2066 | /* Writing half */ |
| 2067 | if (!read_reply) { |
| 2068 | /* Initially set master_initial_offset to -1 to mark the current |
| 2069 | * master replid and offset as not valid. Later if we'll be able to do |
| 2070 | * a FULL resync using the PSYNC command we'll set the offset at the |
| 2071 | * right value, so that this information will be propagated to the |
| 2072 | * client structure representing the master into server.master. */ |
| 2073 | server.master_initial_offset = -1; |
| 2074 | |
| 2075 | if (server.cached_master) { |
| 2076 | psync_replid = server.cached_master->replid; |
| 2077 | snprintf(psync_offset,sizeof(psync_offset),"%lld", server.cached_master->reploff+1); |
| 2078 | serverLog(LL_NOTICE,"Trying a partial resynchronization (request %s:%s).", psync_replid, psync_offset); |
| 2079 | } else { |
| 2080 | serverLog(LL_NOTICE,"Partial resynchronization not possible (no cached master)"); |
| 2081 | psync_replid = "?"; |
| 2082 | memcpy(psync_offset,"-1",3); |
| 2083 | } |
| 2084 | |
| 2085 | /* Issue the PSYNC command, if this is a master with a failover in |
| 2086 | * progress then send the failover argument to the replica to cause it |
| 2087 | * to become a master */ |
| 2088 | if (server.failover_state == FAILOVER_IN_PROGRESS) { |
| 2089 | reply = sendCommand(conn,"PSYNC",psync_replid,psync_offset,"FAILOVER",NULL); |
| 2090 | } else { |
| 2091 | reply = sendCommand(conn,"PSYNC",psync_replid,psync_offset,NULL); |
| 2092 | } |
| 2093 | |
| 2094 | if (reply != NULL) { |
| 2095 | serverLog(LL_WARNING,"Unable to send PSYNC to master: %s",reply); |
| 2096 | sdsfree(reply); |
| 2097 | connSetReadHandler(conn, NULL); |
| 2098 | return PSYNC_WRITE_ERROR; |
| 2099 | } |
| 2100 | return PSYNC_WAIT_REPLY; |
| 2101 | } |
| 2102 | |
| 2103 | /* Reading half */ |
| 2104 | reply = receiveSynchronousResponse(conn); |
| 2105 | if (sdslen(reply) == 0) { |
| 2106 | /* The master may send empty newlines after it receives PSYNC |
| 2107 | * and before to reply, just to keep the connection alive. */ |
| 2108 | sdsfree(reply); |
| 2109 | return PSYNC_WAIT_REPLY; |
| 2110 | } |
| 2111 | |
| 2112 | connSetReadHandler(conn, NULL); |
| 2113 | |
| 2114 | if (!strncmp(reply,"+FULLRESYNC",11)) { |
| 2115 | char *replid = NULL, *offset = NULL; |
| 2116 | |
| 2117 | /* FULL RESYNC, parse the reply in order to extract the replid |
| 2118 | * and the replication offset. */ |
no test coverage detected