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

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.")) 

首先是根据传入的绝对路径,构造一个仓库对象的示例,这里比较关键,初始化方法如下,可以看到我们前面提到migrate.cfg和versions就是在这里被使用的,而且名字也是固定的,必须为migrate.cfg和versions。

class Repository(pathed.Pathed):
  """A project's change script repository""" 

  _config = 'migrate.cfg'
  _versions = 'versions' 

  def __init__(self, path):
    log.debug('Loading repository %s...' % path)
    self.verify(path)
    super(Repository, self).__init__(path)
    self.config = cfgparse.Config(os.path.join(self.path, self._config))
    self.versions = version.Collection(os.path.join(self.path,
                           self._versions))
    log.debug('Repository %s loaded successfully' % path)
    log.debug('Config: %r' % self.config.to_dict())

这里会验证我们传入的path下面是否存在versions和migrate.cfg,因此我们的代码目录结构也必须按照这个放。self.config主要是用来管理migrate.cfg的配置,self.versions主要用来管理如何升级,repository对象另外还包含3个比较重要的属性,latest:最新的版本(versions中版本号最大的),这里是73,version_table:用来记录和管理migrate版本号的数据库表,这里是migrate_version,id用来存放我们管理的数据库标示,这里是heat,后两项都是从数据库里面取。

@property
  def latest(self):
    """API to :attr:`migrate.versioning.version.Collection.latest`"""
    return self.versions.latest 

  @property
  def version_table(self):
    """Returns version_table name specified in config"""
    return self.config.get('db_settings', 'version_table') 

  @property
  def id(self):
    """Returns repository id specified in config"""
    return self.config.get('db_settings', 'repository_id')

回到之前的代码

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."))

这里会根据数据库引擎和刚才的repository实例对象获取当前数据库的版本号,其实就是从migrate本身所在数据表中去查找当前的版本号(version_version),假如是第一次使用migrate,由于还没有建立migrate_version表,所以引发异常。这里会去查一下当前数据库中的所有数据表,如果已有其他数据库表,则会引发DBMigrationError的异常,因为migrate必须在建立其他数据表之前先建立才能管控所有的数据表,假如我们之前没有使用migrate机制但是想在后面的db控制中使用起来,这里有2个思路:手动插入migrate_version数据表并配置合适的版本或者手动插入alebic_version。

继续往下面看,如果是第一次使用migrate,


db_version_control(engine, abs_path, version=init_version)

会建立migrate_version,并设置合适的初始值,也就是传入的init_version,后续的数据库升级等操作就可以通过migrate管控起来了。migrate_version表建立起来后,就回到了最初的流程,根据我们db_sync传入的版本号和当前的版本号,migrate会执行versions里面每个版本的upgrade()方法直至升级完成并更新migrate_version中的版本号。

  使用migrate的好处在于,可以很方便的集中记录和管理每次对数据库的变动,在后续升级过程中,一键式完成对应的适配操作,非常方便,并且不会出现重复增加字段等操作,在开发过程中,我们只要知道了migrate的原理,就能很方便的使用起来了。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索openstack
, migrate
数据库升级
openstack 数据库升级、openstack migrate、openstack 数据库、openstack 数据库服务、openstack数据库模块,以便于您获取更多的相关知识。

时间: 2024-10-23 02:41:30

Openstack 使用migrate进行数据库升级实现方案详细介绍_OpenStack的相关文章

OpenStack之虚机热迁移的代码详细解析_OpenStack

话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移.实时迁移),即虚机保存/恢复(Save/Restore):将整个虚拟机的运行状态完整保存下来,同时可以快速的恢复到原有硬件平台甚至是不同硬件平台上.恢复以后,虚机仍旧平滑运行,用户不会察觉到任何差异.OpenStack的虚机迁移是基于Libvirt实现的,下面来看看Openstack虚机热迁移的具体代码实现. 首先,由API入口进入到nova/api/openstack/comput

Openstack 创建项目和虚拟机详细介绍_OpenStack

Openstack 创建项目和虚拟机                    最新学习Openstack 的知识,因为在公司新项目中使用,于是在网上学习如何创建项目,这里记录下,希望也能帮助到大家. 正规教程:Running an Instance 创建项目 1. 点击左边的 Identity–>Projects,并点击面板右上方创建项目 2. 创建一个属于你的项目并且在配额中调整你所需要的资源 创建用户 1. 点击左边的 Identity–>Users,并点击面板右上方创建用户 2. 设置密码

OpenStack 工作流workflows使用原理详细介绍_OpenStack

Workflows 工作流是复杂的forms(表单)和tabs,每一个workflow必须包含 Workflow,Step 和 Action 下面举例讲解workflow用法: 接下来的例子讲解了数据是如何从urls.views.workflows.templates之间互相传递的 在 urls.py中, 定义了一个参数. 例如. resource_class_id. RESOURCE_CLASS = r'^(?P<resource_class_id>[^/]+)/%s$' urlpatter

OpenStack Keystone的基本概念详细介绍_OpenStack

OpenStack Keystone的基本概念理解 Keystone简介 Keystone(OpenStack Identity Service)是OpenStack框架中,负责身份验证.服务规则和服务令牌的功能, 它实现了OpenStack的Identity API.Keystone类似一个服务总线, 或者说是整个Openstack框架的注册表, 其他服务通过keystone来注册其服务的Endpoint(服务访问的URL),任何服务之间相互的调用, 需要经过Keystone的身份验证, 来获

OpenStack之日志详细介绍_OpenStack

OpenStack日志                 最近做项目用到OpenStack,由于刚刚开始使用,有很多错误,然后查询日志,抽空把日志系统的资料整理下来,大家可以看下. 日志对于一个稳定的系统来说相当重要,对于OpenStack这样一个大型的系统,日志当然也是必不可少,理解Openstack系统的日志对于保证OpenStack环境稳定非常重要.对于出现系统错误,查看日志是一个很好的习惯. OpenStack通过生成大量日志信息来帮助排查系统安装运行期间出现的问题,接下来介绍几个常见服务

CentOS 一键安装Openstack详细介绍_OpenStack

 CentOS 一键安装Openstack       最近再看Openstack相关知识,一直想试试安装一下,可是参考了很多资料,并不如人意.由于一直用的Linux版本为CentOS,大部分Openstack安装都要求在Ubuntu上进行.我也不知到什么原因,并不喜欢Ubuntu,可能是觉得太花哨了,而且总提示更新什么的,好了,废话不多说.        找到一个网站,国外的,  http://openstack.redhat.com/Main_Page,进入到quickstart页面中,简单

Oracle数据库升级或数据迁移方法研究_oracle

一.数据库升级的必要性 数据库升级是数据库管理员经常要面对的问题,如果你的应用要使用新版本数据库的新特性:如果数据库运行负载过重,而通过软硬件调整又不能有根本性的改善:如果要更换操作系统平台:如果要增强数据库的安全性:还有一个原因是随着新版本数据库的出现与成熟,oracle停止了对旧版本数据库的技术支持,升级到高版本,可以继续获得oracle的支持,还可以利用新版本数据库的新特新,可以改善系统的性能,健壮性,可扩张性和可用性,等等,面对这些问题,需要通过数据库升级才得以解决.不过,如果你的系统运

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤   说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance.  Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含

探索Oracle之数据库升级六 11.2.0.4.3 Upgrade12c(12.1.0.1)

探索Oracle之数据库升级六11.2.0.4.3 Upgrade12c(12.1.0.1) 一.前言:       Oracle 12c发布距今已经一年有余了,其最大亮点是一个可以插拔的数据库(PDB),这是在之前版本没有的:但是如果我们要将以前版本的数据库升级到12c来,那么也应顺其自然的将其变成一个pdb,那么我们的工作不仅包含了数据库软件的升级,同时也包含如何将一个NO-CDB的数据库plug to CDB none. 二.升级要求:   三.升级前准备:          3.1.查看