TIDB源码分析-分析每一次PR(10)

ddl: check constraint name. #72

修复了问题#66

出现原因:

	tbInfo, err := d.buildTableInfo(ident.Name, cols, newConstraints)
	if err != nil {
		return errors.Trace(err)
	}

https://github.com/pingcap/tidb/blob/1e4cdb813feab70b19487e1793eb51b87bc3bf7c/ddl/ddl.go#L324-L327

这里的newConstraints的ConstrName全部是””

导致kvIndex的KEY前缀都是相同的:

	err = d.updateInfoSchema(ctx, ident.Schema, tbInfo)
	return errors.Trace(err)
}

https://github.com/pingcap/tidb/blob/a54c896dcfde55ae97ffd5e0c14c895f13645f37/ddl/ddl.go#L367-L369

    d.infoHandle.Set(clonedInfo)
   return nil
}

https://github.com/pingcap/tidb/blob/a54c896dcfde55ae97ffd5e0c14c895f13645f37/ddl/ddl.go#L664-L666

			info.tables[t.ID] = table.TableFromMeta(di.Name.L, alloc, t)
			tname := tableName{di.Name.L, t.Name.L}

https://github.com/pingcap/tidb/blob/bb78a3414b6271c1cbbe8aebcc74e675de4d6fb9/infoschema/infoschema.go#L214-L215

func TableFromMeta(dbname string, alloc autoid.Allocator, tblInfo *model.TableInfo) table.Table {
	t := NewTable(tblInfo.ID, tblInfo.Name.O, dbname, nil, alloc)

	for _, colInfo := range tblInfo.Columns {
		c := column.Col{ColumnInfo: *colInfo}
		t.Columns = append(t.Columns, &c)
	}

	for _, idxInfo := range tblInfo.Indices {
		idx := &column.IndexedCol{
			IndexInfo: *idxInfo,
			X:         kv.NewKVIndex(t.indexPrefix, idxInfo.Name.L, idxInfo.Unique),
		}
		t.AddIndex(idx)
	}

	return t
}

https://github.com/pingcap/tidb/blob/8ad8452f5434c03cd600b68b50276530b912e486/table/tables/tables.go#L56-L73

// NewKVIndex builds a new kvIndex object.
func NewKVIndex(indexPrefix, indexName string, unique bool) Index {
	return &kvIndex{
		indexName: indexName,
		unique:    unique,
		prefix:    genIndexPrefix(indexPrefix, indexName),
	}
}

https://github.com/pingcap/tidb/blob/0d6f270068e8ff2aedc1c314e907771b6a508ebd/kv/index_iter.go#L112-L119

那么所有索引的prefix全部相同的话,每行数据都会插入对应的索引,在按照索引查询时就会出现索引个数个重复的行。

所以这里在创建索引前把indexName填上且不重复即可。

Parser: Adjust the syntax error log #65

调整了错误日志格式。

fix driver panic #78

为了解决issue https://github.com/pingcap/tidb/issues/57

这里还未完全解决,只是在newdriverRows中goroutine加了sync.WaitGroup

parser: resolve reduce/reduce conflicts #86

issue #73 ,解决了部分解析器上的冲突(这里还未最终解决)。

关于Lex和Yacc的内容,看这里有一系列详解http://blog.csdn.net/liwei_cmg/article/details/1530492

然后这里是用了golang版本的goyacc。

Retry transaction without for update #79

对修改操作支持冲突事务重新提交。

跟着这个test看一下:

// See: http://dev.mysql.com/doc/refman/5.7/en/commit.html
func (s *testSessionSuite) TestRowLock(c *C) {
	store := newStore(c, s.dbName)
	se := newSession(c, store, s.dbName)
	se1 := newSession(c, store, s.dbName)
	se2 := newSession(c, store, s.dbName)

	mustExecSQL(c, se, "drop table if exists t")
	c.Assert(se.(*session).txn, Equals, nil)
	mustExecSQL(c, se, "create table t (c1 int, c2 int, c3 int)")
	mustExecSQL(c, se, "insert t values (11, 2, 3)")
	mustExecSQL(c, se, "insert t values (12, 2, 3)")
	mustExecSQL(c, se, "insert t values (13, 2, 3)")

	mustExecSQL(c, se1, "begin")
	mustExecSQL(c, se1, "update t set c2=21 where c1=11")

	mustExecSQL(c, se2, "begin")
	mustExecSQL(c, se2, "update t set c2=211 where c1=11")
	mustExecSQL(c, se2, "commit")

	_, err := exec(c, se1, "commit")
	// row lock conflict but can still success
	if errors2.ErrorNotEqual(err, kv.ErrConditionNotMatch) {
		c.Fail()
	}
	// Retry should success
	err = se.Retry()
	c.Assert(err, IsNil)

	mustExecSQL(c, se1, "begin")
	mustExecSQL(c, se1, "update t set c2=21 where c1=11")

	mustExecSQL(c, se2, "begin")
	mustExecSQL(c, se2, "update t set c2=22 where c1=12")
	mustExecSQL(c, se2, "commit")

	mustExecSQL(c, se1, "commit")

	mustExecSQL(c, se, s.dropDBSQL)
}

在提交这个commit会失败,_, err := exec(c, se1, “commit”)。

这个PR就是让这个失败后重新提交。

	if !bytes.Equal(currValue, snapshotVal) {
		log.Warnf("txn:%d, tryLockKey condition not match for key %s, currValue:%s, snapshotVal:%s", tID, key, currValue, snapshotVal)
		return errors.Trace(kv.ErrConditionNotMatch)
	}

	s.keysLocked[key] = tID

	return nil
}

https://github.com/pingcap/tidb/blob/0d6f270068e8ff2aedc1c314e907771b6a508ebd/store/localstore/kv.go#L162-L170

在这里发现数据已经被修改过了,然后commit会失败。

 

发表评论

邮箱地址不会被公开。 必填项已用*标注

请输入正确的验证码