Exemplo n.º 1
0
//This builds BinlogResponse for each transaction.
func (blp *Bls) buildTxnResponse() (txnResponseList []*proto.BinlogResponse, dmlCount int64) {
	var line []byte
	var keyspaceIdStr string
	var keyspaceId key.KeyspaceId

	dmlBuffer := make([]string, 0, 10)

	for _, event := range blp.txnLineBuffer {
		line = event.LogLine
		if bytes.HasPrefix(line, BINLOG_BEGIN) {
			streamBuf := new(proto.BinlogResponse)
			streamBuf.Position = event.BinlogPosition
			streamBuf.Data.SqlType = proto.BEGIN
			txnResponseList = append(txnResponseList, streamBuf)
			continue
		}
		if bytes.HasPrefix(line, BINLOG_COMMIT) {
			commitEvent := blsCreateCommitEvent(event)
			txnResponseList = append(txnResponseList, commitEvent)
			continue
		}
		sqlType := proto.GetSqlType(event.firstKw)
		if sqlType == proto.DML {
			keyspaceIdStr, keyspaceId = parseKeyspaceId(line)
			if keyspaceIdStr == "" {
				continue
			}
			if !blp.keyRange.Contains(keyspaceId) {
				dmlBuffer = dmlBuffer[:0]
				continue
			}
			dmlCount += 1
			dmlBuffer = append(dmlBuffer, string(line))
			dmlEvent := blp.createDmlEvent(event, keyspaceIdStr)
			dmlEvent.Data.Sql = make([]string, len(dmlBuffer))
			dmlLines := copy(dmlEvent.Data.Sql, dmlBuffer)
			if dmlLines < len(dmlBuffer) {
				log.Warningf("The entire dml buffer was not properly copied")
			}
			txnResponseList = append(txnResponseList, dmlEvent)
			dmlBuffer = dmlBuffer[:0]
		} else {
			//add as prefixes to the DML from last DML.
			//start a new dml buffer and keep adding to it.
			dmlBuffer = append(dmlBuffer, string(line))
		}
	}
	return txnResponseList, dmlCount
}
Exemplo n.º 2
0
func (blp *Bls) parseEventData(sendReply proto.SendBinlogResponse, event *blsEventBuffer) {
	if bytes.HasPrefix(event.LogLine, BINLOG_SET_TIMESTAMP) {
		blp.extractEventTimestamp(event)
		blp.initialSeek = false
		if blp.inTxn {
			blp.txnLineBuffer = append(blp.txnLineBuffer, event)
		}
	} else if bytes.HasPrefix(event.LogLine, BINLOG_BEGIN) {
		blp.handleBeginEvent(event)
	} else if bytes.HasPrefix(event.LogLine, BINLOG_ROLLBACK) {
		blp.inTxn = false
		blp.txnLineBuffer = blp.txnLineBuffer[:0]
	} else if bytes.HasPrefix(event.LogLine, BINLOG_COMMIT) {
		blp.handleCommitEvent(sendReply, event)
		blp.inTxn = false
		blp.txnLineBuffer = blp.txnLineBuffer[:0]
	} else if len(event.LogLine) > 0 {
		if blp.inTxn && IsTxnStatement(event.LogLine, event.firstKw) {
			blp.txnLineBuffer = append(blp.txnLineBuffer, event)
		} else {
			sqlType := proto.GetSqlType(event.firstKw)
			switch sqlType {
			case proto.DDL:
				blp.handleDdlEvent(sendReply, event)
			case proto.DML:
				lineBuf := make([][]byte, 0, 10)
				for _, dml := range blp.txnLineBuffer {
					lineBuf = append(lineBuf, dml.LogLine)
				}
				// FIXME(alainjobart) in these cases, we
				// probably want to skip that event and keep
				// going. Or at least offer the option to do
				// so somewhere.
				panic(newBinlogServerError(fmt.Sprintf("DML outside a txn - len %v, dml '%v', txn buffer '%v'", len(blp.txnLineBuffer), string(event.LogLine), string(bytes.Join(lineBuf, SEMICOLON_BYTE)))))
			default:
				//Ignore these often occuring statement types.
				if !IgnoredStatement(event.LogLine) {
					log.Warningf("Unknown statement '%v'", string(event.LogLine))
				}
			}
		}
	}
}