Beispiel #1
0
func TestTransactionString(t *testing.T) {
	txnID, err := uuid.FromBytes([]byte("ת\x0f^\xe4-Fؽ\xf7\x16\xe4\xf9\xbe^\xbe"))
	if err != nil {
		t.Fatal(err)
	}
	ts1 := makeTS(10, 11)
	txn := Transaction{
		TxnMeta: TxnMeta{
			Isolation: SERIALIZABLE,
			Key:       Key("foo"),
			ID:        txnID,
			Epoch:     2,
			Timestamp: makeTS(20, 21),
		},
		Name:          "name",
		Priority:      957356782,
		Status:        COMMITTED,
		LastHeartbeat: &ts1,
		OrigTimestamp: makeTS(30, 31),
		MaxTimestamp:  makeTS(40, 41),
	}
	expStr := `"name" id=d7aa0f5e key="foo" rw=false pri=44.58039917 iso=SERIALIZABLE stat=COMMITTED ` +
		`epo=2 ts=0.000000020,21 orig=0.000000030,31 max=0.000000040,41`

	if str := txn.String(); str != expStr {
		t.Errorf("expected txn %s; got %s", expStr, str)
	}

	var txnEmpty Transaction
	_ = txnEmpty.String() // prevent regression of NPE
}
Beispiel #2
0
func localRangeKeyPrint(key roachpb.Key) string {
	var buf bytes.Buffer

	for _, s := range rangeSuffixDict {
		if s.atEnd {
			if bytes.HasSuffix(key, s.suffix) {
				key = key[:len(key)-len(s.suffix)]
				fmt.Fprintf(&buf, "%s/%s", decodeKeyPrint(key), s.name)
				return buf.String()
			}
		} else {
			begin := bytes.Index(key, s.suffix)
			if begin > 0 {
				addrKey := key[:begin]
				txnID, err := uuid.FromBytes(key[(begin + len(s.suffix)):])
				if err != nil {
					return fmt.Sprintf("/%q/err:%v", key, err)
				}
				fmt.Fprintf(&buf, "%s/%s/addrKey:/id:%q", decodeKeyPrint(addrKey), s.name, txnID)
				return buf.String()
			}
		}
	}
	fmt.Fprintf(&buf, "%s", decodeKeyPrint(key))

	return buf.String()
}
Beispiel #3
0
func sequenceCacheKeyPrint(key roachpb.Key) string {
	b, id, err := encoding.DecodeBytesAscending([]byte(key), nil)
	if err != nil {
		return fmt.Sprintf("/%q/err:%v", key, err)
	}

	txnID, err := uuid.FromBytes(id)
	if err != nil {
		return fmt.Sprintf("/%q/err:%v", key, err)
	}

	if len(b) == 0 {
		return fmt.Sprintf("/%q", txnID)
	}

	b, epoch, err := encoding.DecodeUint32Descending(b)
	if err != nil {
		return fmt.Sprintf("/%q/err:%v", txnID, err)
	}

	_, seq, err := encoding.DecodeUint32Descending(b)
	if err != nil {
		return fmt.Sprintf("/%q/epoch:%d/err:%v", txnID, epoch, err)
	}

	return fmt.Sprintf("/%q/epoch:%d/seq:%d", txnID, epoch, seq)
}
Beispiel #4
0
// DecodeAbortCacheKey decodes the provided abort cache entry,
// returning the transaction ID.
func DecodeAbortCacheKey(key roachpb.Key, dest []byte) (*uuid.UUID, error) {
	// TODO(tschottdorf): redundant check.
	if !bytes.HasPrefix(key, LocalRangeIDPrefix) {
		return nil, util.Errorf("key %s does not have %s prefix", key, LocalRangeIDPrefix)
	}
	// Cut the prefix, the Range ID, and the infix specifier.
	b := key[len(LocalRangeIDPrefix):]
	b, _, err := encoding.DecodeUvarintAscending(b)
	if err != nil {
		return nil, err
	}
	b = b[1:]
	if !bytes.HasPrefix(b, LocalAbortCacheSuffix) {
		return nil, util.Errorf("key %s does not contain the abort cache suffix %s",
			key, LocalAbortCacheSuffix)
	}
	// Cut the abort cache suffix.
	b = b[len(LocalAbortCacheSuffix):]
	// Decode the id.
	b, idBytes, err := encoding.DecodeBytesAscending(b, dest)
	if err != nil {
		return nil, err
	}
	if len(b) > 0 {
		return nil, util.Errorf("key %q has leftover bytes after decode: %s; indicates corrupt key", key, b)
	}
	txnID, err := uuid.FromBytes(idBytes)
	return txnID, err
}
Beispiel #5
0
func abortCacheKeyPrint(key roachpb.Key) string {
	_, id, err := encoding.DecodeBytesAscending([]byte(key), nil)
	if err != nil {
		return fmt.Sprintf("/%q/err:%v", key, err)
	}

	txnID, err := uuid.FromBytes(id)
	if err != nil {
		return fmt.Sprintf("/%q/err:%v", key, err)
	}

	return fmt.Sprintf("/%q", txnID)
}
Beispiel #6
0
// DecodeAbortCacheKey decodes the provided abort cache entry,
// returning the transaction ID.
func DecodeAbortCacheKey(key roachpb.Key, dest []byte) (*uuid.UUID, error) {
	_, _, suffix, detail, err := DecodeRangeIDKey(key)
	if err != nil {
		return nil, err
	}
	if !bytes.Equal(suffix, LocalAbortCacheSuffix) {
		return nil, errors.Errorf("key %s does not contain the abort cache suffix %s",
			key, LocalAbortCacheSuffix)
	}
	// Decode the id.
	detail, idBytes, err := encoding.DecodeBytesAscending(detail, dest)
	if err != nil {
		return nil, err
	}
	if len(detail) > 0 {
		return nil, errors.Errorf("key %q has leftover bytes after decode: %s; indicates corrupt key", key, detail)
	}
	txnID, err := uuid.FromBytes(idBytes)
	return txnID, err
}
Beispiel #7
0
func decodeSequenceCacheKey(key roachpb.Key, dest []byte) (*uuid.UUID, uint32, uint32, error) {
	// TODO(tschottdorf): redundant check.
	if !bytes.HasPrefix(key, keys.LocalRangeIDPrefix) {
		return nil, 0, 0, util.Errorf("key %s does not have %s prefix", key, keys.LocalRangeIDPrefix)
	}
	// Cut the prefix and the Range ID.
	b := key[len(keys.LocalRangeIDPrefix):]
	b, _, err := encoding.DecodeUvarintAscending(b)
	if err != nil {
		return nil, 0, 0, err
	}
	if !bytes.HasPrefix(b, keys.LocalSequenceCacheSuffix) {
		return nil, 0, 0, util.Errorf("key %s does not contain the sequence cache suffix %s",
			key, keys.LocalSequenceCacheSuffix)
	}
	// Cut the sequence cache suffix.
	b = b[len(keys.LocalSequenceCacheSuffix):]
	// Decode the id.
	b, idBytes, err := encoding.DecodeBytesAscending(b, dest)
	if err != nil {
		return nil, 0, 0, err
	}
	// Decode the epoch.
	b, epoch, err := encoding.DecodeUint32Descending(b)
	if err != nil {
		return nil, 0, 0, err
	}
	// Decode the sequence number.
	b, seq, err := encoding.DecodeUint32Descending(b)
	if err != nil {
		return nil, 0, 0, err
	}
	if len(b) > 0 {
		return nil, 0, 0, util.Errorf("key %q has leftover bytes after decode: %s; indicates corrupt key",
			key, b)
	}
	txnID, err := uuid.FromBytes(idBytes)
	return txnID, epoch, seq, err
}
Beispiel #8
0
func TestTransactionString(t *testing.T) {
	txnID, err := uuid.FromBytes([]byte("ת\x0f^\xe4-Fؽ\xf7\x16\xe4\xf9\xbe^\xbe"))
	if err != nil {
		t.Fatal(err)
	}
	ts1 := makeTS(10, 11)
	txn := Transaction{
		TxnMeta: enginepb.TxnMeta{
			Isolation: enginepb.SERIALIZABLE,
			Key:       Key("foo"),
			ID:        txnID,
			Epoch:     2,
			Timestamp: makeTS(20, 21),
			Priority:  957356782,
		},
		Name:          "name",
		Status:        COMMITTED,
		LastHeartbeat: &ts1,
		OrigTimestamp: makeTS(30, 31),
		MaxTimestamp:  makeTS(40, 41),
	}
	expStr := `"name" id=d7aa0f5e key="foo" rw=false pri=44.58039917 iso=SERIALIZABLE stat=COMMITTED ` +
		`epo=2 ts=0.000000020,21 orig=0.000000030,31 max=0.000000040,41 wto=false rop=false`

	if str := txn.String(); str != expStr {
		t.Errorf("expected txn %s; got %s", expStr, str)
	}

	var txnEmpty Transaction
	_ = txnEmpty.String() // prevent regression of NPE

	var cmd RaftCommand
	cmd.Cmd.Txn = &txn
	if actStr, idStr := fmt.Sprintf("%s", &cmd), txn.ID.String(); !strings.Contains(actStr, idStr) {
		t.Fatalf("expected to find '%s' in '%s'", idStr, actStr)
	}
}
Beispiel #9
0
// connectGossip connects to gossip network and reads cluster ID. If
// this node is already part of a cluster, the cluster ID is verified
// for a match. If not part of a cluster, the cluster ID is set. The
// node's address is gossiped with node ID as the gossip key.
func (n *Node) connectGossip() {
	log.Infof("connecting to gossip network to verify cluster ID...")
	// No timeout or stop condition is needed here. Log statements should be
	// sufficient for diagnosing this type of condition.
	<-n.ctx.Gossip.Connected

	uuidBytes, err := n.ctx.Gossip.GetInfo(gossip.KeyClusterID)
	if err != nil {
		log.Fatalf("unable to ascertain cluster ID from gossip network: %s", err)
	}
	gossipClusterIDPtr, err := uuid.FromBytes(uuidBytes)
	if err != nil {
		log.Fatalf("unable to ascertain cluster ID from gossip network: %s", err)
	}
	gossipClusterID := *gossipClusterIDPtr

	if n.ClusterID == *uuid.EmptyUUID {
		n.ClusterID = gossipClusterID
	} else if n.ClusterID != gossipClusterID {
		log.Fatalf("node %d belongs to cluster %q but is attempting to connect to a gossip network for cluster %q",
			n.Descriptor.NodeID, n.ClusterID, gossipClusterID)
	}
	log.Infof("node connected via gossip and verified as part of cluster %q", gossipClusterID)
}