crdb代码阅读02——system数据库初始化流程

表描述定义

pkg/sql/sqlbase/system.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
UsersTable = TableDescriptor{
Name: "users",
ID: keys.UsersTableID,
ParentID: keys.SystemDatabaseID,
Version: 1,
Columns: []ColumnDescriptor{
{Name: "username", ID: 1, Type: colTypeString},
{Name: "hashedPassword", ID: 2, Type: colTypeBytes, Nullable: true},
},
NextColumnID: 3,
Families: []ColumnFamilyDescriptor{
{Name: "primary", ID: 0, ColumnNames: []string{"username"}, ColumnIDs: singleID1},
{Name: "fam_2_hashedPassword", ID: 2, ColumnNames: []string{"hashedPassword"}, ColumnIDs: []ColumnID{2}, DefaultColumnID: 2},
},
PrimaryIndex: pk("username"),
NextFamilyID: 3,
NextIndexID: 2,
Privileges: NewCustomRootPrivilegeDescriptor(SystemAllowedPrivileges[keys.UsersTableID]),
FormatVersion: InterleavedFormatVersion,
NextMutationID: 1,
}

初始化表描述为内存态KV pairs

pkg/server/node.go
pkg/sql/sqlbase/metadata.go

1
2
3
4
5
> server.bootstrapCluster
| > server.GetBootstrapSchema
| | > sqlbase.MakeMetadataSchema
| | | > sqlbase.addSystemDatabaseToSchema
| > sqlbase.MetadataSchema.GetInitialValues

将表定义描述转换成内存的kv形式,便于后面进行插入

初始化第一个range,写入到rocksdb

这里将上一步的所有kv对,直接插入rocksdb中

pkg/storage/store.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
func (s *Store) BootstrapRange(
initialValues []roachpb.KeyValue, bootstrapVersion roachpb.Version,
) error {
desc := &roachpb.RangeDescriptor{
RangeID: 1,
StartKey: roachpb.RKeyMin,
EndKey: roachpb.RKeyMax,
NextReplicaID: 2,
Replicas: []roachpb.ReplicaDescriptor{
{
NodeID: 1,
StoreID: 1,
ReplicaID: 1,
},
},
}
if err := desc.Validate(); err != nil {
return err
}
batch := s.engine.NewBatch()
defer batch.Close()
ms := &enginepb.MVCCStats{}
now := s.cfg.Clock.Now()
ctx := context.Background()
// Bootstrap version information. We don't do this if this is v1.0, which is
// never going to be true in versions that have this code in production, but
// can be true in tests.
if bootstrapVersion != cluster.VersionByKey(cluster.VersionBase) {
if err := engine.MVCCPutProto(ctx, batch, ms /* ms */, keys.BootstrapVersionKey, hlc.Timestamp{}, nil, &bootstrapVersion); err != nil {
return err
}
}
// Range descriptor.
if err := engine.MVCCPutProto(ctx, batch, ms, keys.RangeDescriptorKey(desc.StartKey), now, nil, desc); err != nil {
return err
}
// Replica GC timestamp.
if err := engine.MVCCPutProto(ctx, batch, nil /* ms */, keys.RangeLastReplicaGCTimestampKey(desc.RangeID), hlc.Timestamp{}, nil, &now); err != nil {
return err
}
// Range addressing for meta2.
meta2Key := keys.RangeMetaKey(roachpb.RKeyMax)
if err := engine.MVCCPutProto(ctx, batch, ms, meta2Key.AsRawKey(), now, nil, desc); err != nil {
return err
}
// Range addressing for meta1.
meta1Key := keys.RangeMetaKey(meta2Key)
if err := engine.MVCCPutProto(ctx, batch, ms, meta1Key.AsRawKey(), now, nil, desc); err != nil {
return err
}
// Now add all passed-in default entries.
for _, kv := range initialValues {
// Initialize the checksums.
kv.Value.InitChecksum(kv.Key)
if err := engine.MVCCPut(ctx, batch, ms, kv.Key, now, kv.Value, nil); err != nil {
return err
}
}
lease := roachpb.BootstrapLease()
updatedMS, err := writeInitialState(ctx, s.cfg.Settings, batch, *ms, *desc,
lease, hlc.Timestamp{}, hlc.Timestamp{})
if err != nil {
return err
}
*ms = updatedMS
return batch.Commit(true /* sync */)
}
  1. 初始化第一个range的desc
  2. 插入meta2的key
  3. 插入meta1的key
  4. 插入系统表描述的kv pair
  5. commit

本文标题:crdb代码阅读02——system数据库初始化流程

文章作者:Louis

发布时间:2018年04月16日 - 16:04

最后更新:2018年04月16日 - 16:04

原始链接:/2018/04/16/crdb02-dbinit/

许可协议: Louis-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。