Exemple #1
0
func (p *Postgres) reconfigure(config *state.Config) (err error) {
	log := p.log.New("fn", "reconfigure")

	defer func() {
		if err == nil {
			p.setConfig(config)
			p.configApplied = true
		}
	}()

	if config != nil && config.Role == state.RoleNone {
		log.Info("nothing to do", "reason", "null role")
		return nil
	}

	// If we've already applied the same postgres config, we don't need to do anything
	if p.configApplied && config != nil && p.config() != nil && config.Equal(p.config()) {
		log.Info("nothing to do", "reason", "config already applied")
		return nil
	}

	// If we're already running and it's just a change from async to sync with the same node, we don't need to restart
	if p.configApplied && p.running() && p.config() != nil && config != nil &&
		p.config().Role == state.RoleAsync && config.Role == state.RoleSync && config.Upstream.Meta[pgIdKey] == p.config().Upstream.Meta[pgIdKey] {
		log.Info("nothing to do", "reason", "becoming sync with same upstream")
		return nil
	}

	// Make sure that we don't keep waiting for replication sync while reconfiguring
	p.cancelSyncWait()
	p.setSyncedDownstream(nil)

	// If we're already running and this is only a sync change, we just need to update the config.
	if p.running() && p.config() != nil && config != nil && p.config().Role == state.RolePrimary && config.Role == state.RolePrimary {
		return p.updateSync(config.Downstream)
	}

	// If we're already running and this is only a downstream change, just wait for the new downstream to catch up
	if p.running() && p.config().IsNewDownstream(config) {
		log.Info("downstream changed", "to", config.Downstream.Addr)
		p.waitForSync(config.Downstream, false)
		return
	}

	if config == nil {
		config = p.config()
	}

	if config.Role == state.RolePrimary {
		return p.assumePrimary(config.Downstream)
	}

	return p.assumeStandby(config.Upstream, config.Downstream)
}
Exemple #2
0
func (p *Process) reconfigure(config *state.Config) error {
	logger := p.Logger.New("fn", "reconfigure")

	if err := func() error {
		if config != nil && config.Role == state.RoleNone {
			logger.Info("nothing to do", "reason", "null role")
			return nil
		}

		// If we've already applied the same config, we don't need to do anything
		if p.configApplied && config != nil && p.config() != nil && config.Equal(p.config()) {
			logger.Info("nothing to do", "reason", "config already applied")
			return nil
		}

		// If we're already running and it's just a change from async to sync with the same node, we don't need to restart
		if p.configApplied && p.running() && p.config() != nil && config != nil &&
			p.config().Role == state.RoleAsync && config.Role == state.RoleSync && config.Upstream.Meta["MYSQL_ID"] == p.config().Upstream.Meta["MYSQL_ID"] {
			logger.Info("nothing to do", "reason", "becoming sync with same upstream")
			return nil
		}

		// Make sure that we don't keep waiting for replication sync while reconfiguring
		p.cancelSyncWait()
		p.syncedDownstreamValue.Store((*discoverd.Instance)(nil))

		// If we're already running and this is only a downstream change, just wait for the new downstream to catch up
		if p.running() && p.config().IsNewDownstream(config) {
			logger.Info("downstream changed", "to", config.Downstream.Addr)
			p.waitForSync(config.Downstream, false)
			return nil
		}

		if config == nil {
			config = p.config()
		}

		if config.Role == state.RolePrimary {
			return p.assumePrimary(config.Downstream)
		}

		return p.assumeStandby(config.Upstream, config.Downstream)
	}(); err != nil {
		return err
	}

	// Apply configuration.
	p.configValue.Store(config)
	p.configApplied = true

	return nil
}