Exemplo n.º 1
0
static void
process_recovery_request(PCP_CONNECTION *frontend,char *buf)
{
	int wsize;
	char code[] = "CommandComplete";
	int node_id = atoi(buf);

	if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) )
		ereport(ERROR,
			(errmsg("process recovery request failed"),
				 errdetail("node id %d is not valid", node_id)));

	if ((!REPLICATION &&
		 !(MASTER_SLAVE &&
		   !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))) ||
		(MASTER_SLAVE &&
		 !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
		 node_id == PRIMARY_NODE_ID))
	{
		if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP))
			ereport(ERROR,
				(errmsg("process recovery request failed"),
					 errdetail("primary server cannot be recovered by online recovery.")));
		else
			ereport(ERROR,
				(errmsg("process recovery request failed"),
					 errdetail("recovery request is accepted only in replication mode or stereaming replication mode.")));
	}
	else
	{
		if (pcp_mark_recovery_in_progress() == false)
			ereport(FATAL,
				(errmsg("process recovery request failed"),
					 errdetail("pgpool-II is already processing another recovery request.")));

		ereport(DEBUG1,
			(errmsg("PCP: processing recovery request"),
				 errdetail("start online recovery")));

		PG_TRY();
		{
			start_recovery(node_id);
			finish_recovery();
			pcp_write(frontend, "c", 1);
			wsize = htonl(sizeof(code) + sizeof(int));
			pcp_write(frontend, &wsize, sizeof(int));
			pcp_write(frontend, code, sizeof(code));
			do_pcp_flush(frontend);
			pcp_mark_recovery_finished();
		}
		PG_CATCH();
		{
			finish_recovery();
			pcp_mark_recovery_finished();
			PG_RE_THROW();
			
		}PG_END_TRY();
	}
	do_pcp_flush(frontend);
}
Exemplo n.º 2
0
static inline void kick_recover(void)
{
	struct vnode_info *vinfo = get_vnode_info();

	start_recovery(vinfo, vinfo);
	put_vnode_info(vinfo);
}
Exemplo n.º 3
0
static void update_cluster_info(struct join_message *msg,
				struct sd_node *joined, struct sd_node *nodes,
				size_t nr_nodes)
{
	struct vnode_info *old_vnode_info = NULL;

	eprintf("status = %d, epoch = %d, finished: %d\n", msg->cluster_status,
		msg->epoch, sys->join_finished);

	sys->disable_recovery = msg->disable_recovery;

	if (!sys->join_finished)
		finish_join(msg, joined, nodes, nr_nodes);

	if (!sys->disable_recovery) {
		old_vnode_info = current_vnode_info;
		current_vnode_info = alloc_vnode_info(nodes, nr_nodes);
	}

	switch (msg->cluster_status) {
	case SD_STATUS_OK:
	case SD_STATUS_HALT:
		switch (sys->status) {
		case SD_STATUS_WAIT_FOR_FORMAT:
			sys->nr_copies = msg->nr_copies;
			sys->flags = msg->cluster_flags;

			set_cluster_copies(sys->nr_copies);
			set_cluster_flags(sys->flags);
			set_cluster_ctime(msg->ctime);
			/*FALLTHROUGH*/
		case SD_STATUS_WAIT_FOR_JOIN:
			get_vdi_bitmap(nodes, nr_nodes);
			break;
		default:
			break;
		}

		sys->status = msg->cluster_status;

		if (msg->inc_epoch) {
			if (!sys->disable_recovery) {
				uatomic_inc(&sys->epoch);
				log_current_epoch();
				clear_exceptional_node_lists();

				if (!old_vnode_info) {
					old_vnode_info =
						alloc_old_vnode_info(joined,
							nodes, nr_nodes);
				}

				start_recovery(current_vnode_info,
					       old_vnode_info);
			} else
				prepare_recovery(joined, nodes, nr_nodes);
		}

		if (have_enough_zones())
			sys->status = SD_STATUS_OK;
		break;
	default:
		sys->status = msg->cluster_status;
		break;
	}

	put_vnode_info(old_vnode_info);

	sockfd_cache_add(&joined->nid);
}