예제 #1
0
//This builds BinlogResponse for each transaction.
func (blp *Blp) buildTxnResponse() (txnResponseList []*mysqlctl.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, mysqlctl.BINLOG_BEGIN) {
			streamBuf := new(mysqlctl.BinlogResponse)
			streamBuf.BlPosition = event.BlPosition
			streamBuf.SqlType = mysqlctl.BEGIN
			txnResponseList = append(txnResponseList, streamBuf)
			continue
		}
		if bytes.HasPrefix(line, mysqlctl.BINLOG_COMMIT) {
			commitEvent := createCommitEvent(event)
			txnResponseList = append(txnResponseList, commitEvent)
			continue
		}
		sqlType := mysqlctl.GetSqlType(event.firstKw)
		if sqlType == mysqlctl.DML {
			keyspaceIdStr, keyspaceId = parseKeyspaceId(line, mysqlctl.GetDmlType(event.firstKw))
			if keyspaceIdStr == "" {
				continue
			}
			if !blp.keyspaceRange.Contains(keyspaceId) {
				dmlBuffer = dmlBuffer[:0]
				continue
			}
			dmlCount += 1
			//extract keyspace id - match it with client's request,
			//extract index ids.
			dmlBuffer = append(dmlBuffer, string(line))
			dmlEvent := blp.createDmlEvent(event, keyspaceIdStr)
			dmlEvent.Sql = make([]string, len(dmlBuffer))
			dmlLines := copy(dmlEvent.Sql, dmlBuffer)
			if dmlLines < len(dmlBuffer) {
				relog.Warning("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
}
예제 #2
0
func (blp *Blp) parseEventData(sendReply mysqlctl.SendUpdateStreamResponse, event *eventBuffer) {
	if bytes.HasPrefix(event.LogLine, mysqlctl.BINLOG_SET_TIMESTAMP) {
		blp.extractEventTimestamp(event)
		blp.initialSeek = false
		if blp.inTxn {
			blp.txnLineBuffer = append(blp.txnLineBuffer, event)
		}
	} else if bytes.HasPrefix(event.LogLine, mysqlctl.BINLOG_BEGIN) {
		blp.handleBeginEvent(event)
	} else if bytes.HasPrefix(event.LogLine, mysqlctl.BINLOG_ROLLBACK) {
		blp.inTxn = false
		blp.txnLineBuffer = blp.txnLineBuffer[:0]
	} else if bytes.HasPrefix(event.LogLine, mysqlctl.BINLOG_COMMIT) {
		blp.handleCommitEvent(sendReply, event)
		blp.inTxn = false
		blp.txnLineBuffer = blp.txnLineBuffer[:0]
	} else if len(event.LogLine) > 0 {
		sqlType := mysqlctl.GetSqlType(event.firstKw)
		if blp.inTxn && mysqlctl.IsTxnStatement(event.LogLine, event.firstKw) {
			blp.txnLineBuffer = append(blp.txnLineBuffer, event)
		} else if sqlType == mysqlctl.DDL {
			blp.handleDdlEvent(sendReply, event)
		} else {
			if sqlType == mysqlctl.DML {
				lineBuf := make([][]byte, 0, 10)
				for _, dml := range blp.txnLineBuffer {
					lineBuf = append(lineBuf, dml.LogLine)
				}
				panic(NewBinlogParseError(fmt.Sprintf("DML outside a txn - len %v, dml '%v', txn buffer '%v'", len(blp.txnLineBuffer), string(event.LogLine), string(bytes.Join(lineBuf, mysqlctl.SEMICOLON_BYTE)))))
			}
			//Ignore these often occuring statement types.
			if !mysqlctl.IgnoredStatement(event.LogLine) {
				relog.Warning("Unknown statement '%v'", string(event.LogLine))
			}
		}
	}
}