设计目的

  • IoTDB的版本从0.8.x更新到0.9.x,数据文件tsfile发生了比较大的变化,当用户在使用0.8.x一段时间后,希望能够使用0.9.x的最新功能,此时可能希望对于旧文件进行升级。

    故0.9.x版本提供从0.8.x的在线升级工具

用户使用

  • 为了减少用户的使用成本,当用户从官网或者github下载了最新的0.9.x版本,将iotdb-engine.properties中的data_dirs参数设置为旧数据文件的路径,在启动过程中,会启动后台线程对于底层的tsfile进行更新。

在线升级过程

  1. 在IoTDB.java的setUp()函数中注册upgrade的服务;
  2. 判断是否在system文件夹中是否存在upgrade.txt文件,如果存在,启动恢复流程(后续详细讲解),不存在则跳过;
  3. 启动upgrade服务,获取用户在iotdb-engine.properties中指定的升级线程数,设置一个升级线程池;
  4. 对于所有需要upgrade的tsfile进行计数,目的是给用户提供一个升级的进度;
  5. 对于每个需要更新的文件,向第三步创建的升级线程池中提交一个升级线程;
  6. 升级线程得到调用,读取旧tsfile文件,在对应的tmp文件夹中写入升级的文件,并维护upgrade.txt(后续详细讲解);
  7. 升级文件完成后将旧数据文件删除,将tmp文件下的新数据文件拷贝到旧文件的位置,该文件更新结束;
  8. 重复6-7步直至所有的升级线程执行完毕。

文件判断过程

  • 判断文件是否为旧tsfile文件,仅需读取tsfile的version,当version为0.8.0时,则该数据文件为旧文件,需要升级。

文件升级过程

  1. 对于需要更新的tsfile,数据升级前,我们在upgrade.txt中记录一行,指定该文件处于BEGINUPGRADEFILE阶段;
  2. 我们使用旧的tsfile读取接口对于其中的数据进行读取,并进行缓存,每当读取到一个CHUNKGROUPFOOTER时,我们将缓存的数据使用新的写接口刷到新的tsfile中,重复上述过程直至所有的data写入到新的数据文件,调用endFile关闭文件;
  3. 到这一步,在tmp文件夹下已经生成了完整的升级文件,我们在upgrade.txt中记录一行,指定该文件处于AFTERUPGRADEFILE阶段;
  4. 我们将旧数据文件删除,将新数据文件拷贝到旧数据文件的位置;
  5. 到这一步,该数据文件已经完全升级成功并替换,我们在upgrade.txt中记录一行,指定该文件处于UPGRADE_SUCCESS阶段;

注意事项

​ 值得注意的是,我们不直接放弃掉文件底部的matadata,然后进行重写的主要原因是在数据文件中存在大小端的问题。如对于一个INT值1来说,采用小端存储,则计算机记录为00000001000000000000000000000000。而使用大端存储,计算机记录为00000000000000000000000000000001。大小端的不匹配会导致文件读取发生问题。

升级恢复过程

我们在系统启动时读取upgrade.txt,遍历读取该文件,判断一个数据文件的更新状态

  • 如果更新状态为BEGINUPGRADEFILE阶段,那么说明旧文件没有完整更新到tmp文件夹,删除tmp文件夹中的对应文件,重新进行更新操作;
  • 如果更新状态为AFTERUPGRADEFILE阶段,那么说明旧文件已经升级到tmp文件夹但是没有拷贝完毕,那么此时先删除旧数据文件,将tmp中的对应文件拷贝到旧数据文件位置即可;
  • 如果更新状态为UPGRADE_SUCCESS阶段,那么说明旧文件已经更新替换完毕,不作任何操作。
  • No labels