首页 > 网站 > 建站经验 > 正文

Openstack 使用migrate进行数据库升级实现方案详细介绍

2019-11-02 16:37:46
字体:
来源:转载
供稿:网友

Openstack 使用migrate进行数据库升级实现方案详细介绍

OpenStack中随着版本的切换,新版本加入一些数据库表或者增加字段等是必然的事情,如何比较容易的进行这些数据库升级的适配和管理,这里就要用到oslo_db中的migrate了,这里以为M版本的heat为例,讲解一下migrate管理db的原理。

我们使用migrate需要用到的主要包含以下两部分:1.versions里面的为版本号+数据库适配脚本;2.migrate.cfg为migrate需要用到的配置文件,两部分的命名是固定的。

使用migrate进行数据库升级非常简单,heat这边提供了heat-manage db_sync, db_version的命令用来升级db以及查看当前db的版本号,这里以执行heat-manages db_sync,看下migrate的过程。

def db_sync(engine, version=None):   path = os.path.join(os.path.abspath(os.path.dirname(__file__)),             'migrate_repo')   return oslo_migration.db_sync(engine, path, version,                  init_version=INIT_VERSION) 

heat代码的入口在这里,需要传入engine用来连接db,version为我们需要升级到的版本,这里没有传,可以看到heat这边是直接使用oslo_migrate的db_sync方法,我们看下三方库中的这个方法。

def db_sync(engine, abs_path, version=None, init_version=0, sanity_check=True):   """Upgrade or downgrade a database.    Function runs the upgrade() or downgrade() functions in change scripts.    :param engine:    SQLAlchemy engine instance for a given database   //连接数据库   :param abs_path:   Absolute path to migrate repository.         //migrate仓库的绝对路径   :param version:   Database will upgrade/downgrade until this version. //需要升级或者降级到的版本号,如果不传则默认升级到最新版本              If None - database will update to the latest              available version.   :param init_version: Initial database version               //数据库的初始版本号,会以该初始版本为起点升级   :param sanity_check: Require schema sanity checking for all tables    //合理性检查   """    if version is not None:     try:       version = int(version)     except ValueError:       raise exception.DBMigrationError(_("version should be an integer"))    current_version = db_version(engine, abs_path, init_version)   repository = _find_migrate_repo(abs_path)   if sanity_check:     _db_schema_sanity_check(engine)   if version is None or version > current_version:     migration = versioning_api.upgrade(engine, repository, version)   else:     migration = versioning_api.downgrade(engine, repository,                        version)   if sanity_check:     _db_schema_sanity_check(engine)    return migration 

代码很清晰,简洁。可以看到,整个过程就是先查询下当前db的版本,然后声明一个migrate仓库示例,对db做合理性检查(主要是针对mysql),然后根据传入的version和当前的version决定是升级或者降低,最后再次检查,整个migrate就完成了。

首先是查询当前数据库的版本,

def db_version(engine, abs_path, init_version):   """Show the current version of the repository.    :param engine: SQLAlchemy engine instance for a given database   :param abs_path: Absolute path to migrate repository   :param init_version: Initial database version   """   repository = _find_migrate_repo(abs_path)   try:     return versioning_api.db_version(engine, repository)   except versioning_exceptions.DatabaseNotControlledError:     meta = sqlalchemy.MetaData()     meta.reflect(bind=engine)     tables = meta.tables     if len(tables) == 0 or 'alembic_version' in tables:       db_version_control(engine, abs_path, version=init_version)       return versioning_api.db_version(engine, repository)     else:       raise exception.DBMigrationError(         _("The database is not under version control, but has "          "tables. Please stamp the current version of the schema "          "manually.")) 
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表