下面我们来具体看看rocksdb维护了哪些元数据信息,从源码中看定义了以下类型,这些数据都以KV的形式存储在名叫__system__的系统column family中。
DDL_ENTRY_INDEX_START_NUMBER
表和索引之间的映射关系
key: Rdb_key_def::DDL_ENTRY_INDEX_START_NUMBER(0x1) + dbname.tablename
value: version + {global_index_id}*n_indexes_of_the_tableINDEX_INFO
索引id和索引属性的关系
key: Rdb_key_def::INDEX_INFO(0x2) + global_index_id
value: version, index_type, key_value_format_version
index_type:主键/二级索引/隐式主键
key_value_format_version: 记录存储格式的版本BINLOG_INFO_INDEX_NUMBER
binlog位点及gtid信息,binlog_commit更新此信息
key: Rdb_key_def::BINLOG_INFO_INDEX_NUMBER (0x4)
value: version, {binlog_name,binlog_pos,binlog_gtid}DDL_DROP_INDEX_ONGOING
等待删除的索引信息
key: Rdb_key_def::DDL_DROP_INDEX_ONGOING(0x5) + global_index_id
value: versionMAX_INDEX_ID
当前的index id,每次创建索引index id都从这个获取和更新
key: Rdb_key_def::CURRENT_MAX_INDEX_ID(0x7)
value: version, current max index id
这里以建表和删表来举例
- create table
通过以下步骤建表
创建column family (get_or_create_cf) primary key 存在default column family中,idx1存在cf_1中,需增加一条cf_1的,CF_DEFINITION的记录 {CF_DEFINITION(4)+cf_id(4)} —> {CF_DEFINITION_VERSION(2)+cf_flags(4)}
创建索引 两条索引 {INDEX_INFO(4)+cf_id(0)+index_id(260)—> { INDEX_INFO_VERSION_VERIFY_KV_FORMAT(1)+index_type(1)+kv_version(11) {INDEX_INFO(4)+cf_id(2)+index_id(261)—> { INDEX_INFO_VERSION_VERIFY_KV_FORMAT(2)+index_type(2)+kv_version(11)
以上信息通过同一batch一起存入rocksdb中。
另外,建索引时,会更新MAX_INDEX_ID信息,使用单独的batch写入,参考(Rdb_seq_generator::get_and_update_next_number)
实际数据分布如下图:
batch->Put 将索引加入到待删的kv队列中
{DDL_DROP_INDEX_ONGOING(4)+cf_id(0)+index_id(260)} –> {DDL_DROP_INDEX_ONGOING_VERSION(2)}
{DDL_DROP_INDEX_ONGOING(4)+cf_id(2)+index_id(261)} –> {DDL_DROP_INDEX_ONGOING_VERSION(2)}
batch->Delete 删除表的映射关系
表和索引的映射关系
后台线程再从待删的kv队列取出待删的索引,通过 DeleteFilesInRange, CompactRange 删除索引数据。
后台线程确定索引数据删除完成后,batch删除相应的DDL_DROP_INDEX_ONGOING和INDEX_INFO的索引信息。