Esempio n. 1
0
func (s *Simulator) Depose(args []string) {
	cs := s.discoverd.ClusterState()
	if cs.State == nil {
		s.log.Error("cluster is not yet configured (try `bootstrap`)")
		return
	}
	if len(cs.State.Async) == 0 {
		s.log.Error("cannot depose with no asyncs")
		return
	}

	newWAL, err := xlog.Increment(cs.State.InitWAL, 10)
	if err != nil {
		panic(err)
	}
	cs.State = &state.State{
		Generation: cs.State.Generation + 1,
		Deposed:    append(cs.State.Deposed, cs.State.Primary),
		Primary:    cs.State.Sync,
		Sync:       cs.State.Async[0],
		Async:      cs.State.Async[1:],
		InitWAL:    newWAL,
	}
	s.discoverd.SetClusterState(cs)
	s.jsonDump(cs)
}
Esempio n. 2
0
func (p *postgresSimulatorClient) catchUp() {
	if p.XLogWaiting == "" {
		p.p.log.Error("catchUp when not sync or not currently waiting")
	}
	var err error
	p.XLog, err = xlog.Increment(p.XLogWaiting, 10)
	if err != nil {
		panic(err)
	}
	p.XLogWaiting = ""
}
Esempio n. 3
0
// Given the current state, figure out our current role and update our xlog
// position accordingly. This is used when we assume a new role or when postgres
// comes online in order to simulate client writes to the primary, synchronous
// replication (and catch-up) on the sync, and asynchronous replication on the
// other peers.
func (p *postgresSimulatorClient) updateXlog(ds *state.DiscoverdState) {
	if ds.State == nil || !p.Online || p.Config == nil {
		return
	}
	s := ds.State

	var role state.Role
	switch {
	case s.Primary.ID == p.inst.ID:
		role = state.RolePrimary
	case s.Sync.ID == p.inst.ID:
		role = state.RoleSync
	case p.Config.Role == state.RoleAsync:
		role = state.RoleAsync
	default:
		role = state.RoleNone
	}

	// If the peer we're testing is an async or unassigned, we don't modify the
	// transaction log position at all. We act as though these are getting
	// arbitrarily far behind (since that should be fine).
	if role == state.RoleAsync || role == state.RoleNone {
		return
	}

	// If the peer we're testing is a primary, we act as though the sync
	// instantly connected and caught up, and we start taking writes immediately
	// and bump the transaction log position.
	if role == state.RolePrimary {
		if cmp, err := xlog.Compare(s.InitWAL, p.XLog); err != nil {
			panic(err)
		} else if cmp > 0 {
			panic("primary is behind the generation's initial xlog")
		}
		var err error
		p.XLog, err = xlog.Increment(p.XLog, 10)
		if err != nil {
			panic(err)
		}
		return
	}

	// The most complicated case is the sync, for which we need to schedule the
	// wal position to catch up to the primary's.
	if role != state.RoleSync {
		panic("unexpected role")
	}
	if cmp, err := xlog.Compare(s.InitWAL, p.XLog); err != nil {
		panic(err)
	} else if cmp < 0 {
		panic("sync is ahead of primary")
	}
	p.XLogWaiting = s.InitWAL
}