Add shard and domain_shard to tables
This change adds shard to domains and domain_shard to records / recordsets as a prerequisite for the designate-zm service. Change-Id: Ieb6eee611bf7b87fef79e3a108294bc0769cd685
This commit is contained in:
parent
77783cb377
commit
ca19abf311
@ -24,6 +24,13 @@ from designate.objects.domain_attribute import DomainAttributeList
|
|||||||
class Domain(base.DictObjectMixin, base.SoftDeleteObjectMixin,
|
class Domain(base.DictObjectMixin, base.SoftDeleteObjectMixin,
|
||||||
base.PersistentObjectMixin, base.DesignateObject):
|
base.PersistentObjectMixin, base.DesignateObject):
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
|
'shard': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'integer',
|
||||||
|
'minimum': 0,
|
||||||
|
'maximum': 4095
|
||||||
|
}
|
||||||
|
},
|
||||||
'tenant_id': {
|
'tenant_id': {
|
||||||
'schema': {
|
'schema': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
|
@ -20,6 +20,13 @@ class Record(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||||||
# TODO(kiall): `hash` is an implementation detail of our SQLA driver,
|
# TODO(kiall): `hash` is an implementation detail of our SQLA driver,
|
||||||
# so we should remove it.
|
# so we should remove it.
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
|
'shard': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'integer',
|
||||||
|
'minimum': 0,
|
||||||
|
'maximum': 4095
|
||||||
|
}
|
||||||
|
},
|
||||||
'data': {},
|
'data': {},
|
||||||
'domain_id': {
|
'domain_id': {
|
||||||
'schema': {
|
'schema': {
|
||||||
|
@ -68,6 +68,13 @@ class RecordSet(base.DictObjectMixin, base.PersistentObjectMixin,
|
|||||||
return status
|
return status
|
||||||
|
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
|
'shard': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'integer',
|
||||||
|
'minimum': 0,
|
||||||
|
'maximum': 4095
|
||||||
|
}
|
||||||
|
},
|
||||||
'tenant_id': {
|
'tenant_id': {
|
||||||
'schema': {
|
'schema': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from oslo_log import log as logging
|
||||||
|
from sqlalchemy import Column, MetaData, Table, SmallInteger
|
||||||
|
from sqlalchemy.sql import select, update
|
||||||
|
|
||||||
|
from designate import i18n
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
meta = MetaData()
|
||||||
|
|
||||||
|
|
||||||
|
def _add_shards(engine, table, dst_col, src_col):
|
||||||
|
dialect = engine.url.get_dialect().name
|
||||||
|
if dialect.startswith('mysql'):
|
||||||
|
sql = "UPDATE %s SET %s = CONV(SUBSTR(%s, 1, 3), 16, 10)"
|
||||||
|
engine.execute(sql % (table.name, dst_col.name, src_col.name))
|
||||||
|
elif dialect.startswith('postgres'):
|
||||||
|
sql = "UPDATE %s SET %s = ('x'||lpad(substr(%s::text, 1, 3), 8, '0')"\
|
||||||
|
")::bit(32)::int"
|
||||||
|
engine.execute(sql % (table.name, dst_col.name, src_col.name))
|
||||||
|
else:
|
||||||
|
rows = select(columns=[table.c.id]).execute().fetchall()
|
||||||
|
for r in rows:
|
||||||
|
shard = int(r.id[0:3], 16)
|
||||||
|
values = {dst_col.name: shard}
|
||||||
|
update(table).where(table.id == r.id).values(values)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(migrate_engine):
|
||||||
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
|
domains_table = Table('domains', meta, autoload=True)
|
||||||
|
recordsets_table = Table('recordsets', meta, autoload=True)
|
||||||
|
records_table = Table('records', meta, autoload=True)
|
||||||
|
|
||||||
|
domains_shard_col = Column('shard', SmallInteger(), nullable=True)
|
||||||
|
domains_shard_col.create(domains_table)
|
||||||
|
|
||||||
|
recordset_domain_shard_col = Column('domain_shard', SmallInteger(),
|
||||||
|
nullable=True)
|
||||||
|
recordset_domain_shard_col.create(recordsets_table)
|
||||||
|
|
||||||
|
records_domain_shard_col = Column('domain_shard', SmallInteger(),
|
||||||
|
nullable=True)
|
||||||
|
records_domain_shard_col.create(records_table)
|
||||||
|
|
||||||
|
def _set_default():
|
||||||
|
_add_shards(
|
||||||
|
migrate_engine,
|
||||||
|
domains_table,
|
||||||
|
domains_shard_col,
|
||||||
|
domains_table.c.id)
|
||||||
|
_add_shards(
|
||||||
|
migrate_engine,
|
||||||
|
recordsets_table,
|
||||||
|
recordset_domain_shard_col,
|
||||||
|
recordsets_table.c.domain_id)
|
||||||
|
_add_shards(
|
||||||
|
migrate_engine,
|
||||||
|
records_table,
|
||||||
|
records_domain_shard_col,
|
||||||
|
records_table.c.domain_id)
|
||||||
|
|
||||||
|
def _set_nullable():
|
||||||
|
domains_table.c.shard.alter(nullable=False)
|
||||||
|
recordsets_table.c.domain_shard.alter(nullable=False)
|
||||||
|
records_table.c.domain_shard.alter(nullable=False)
|
||||||
|
|
||||||
|
for i in range(0, 5):
|
||||||
|
try:
|
||||||
|
_set_default()
|
||||||
|
_set_nullable()
|
||||||
|
except Exception as e:
|
||||||
|
# The population default & enforcement of nullable=False failed,
|
||||||
|
# try again
|
||||||
|
msg = i18n._LW(
|
||||||
|
"Updating migration for sharding failed, retrying.")
|
||||||
|
LOG.warn(msg)
|
||||||
|
if i >= 4:
|
||||||
|
# Raise if we've reached max attempts causing migration to
|
||||||
|
# fail
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
# It was successful, no exception so we break the loop.
|
||||||
|
break
|
@ -13,9 +13,9 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
from sqlalchemy import (Table, MetaData, Column, String, Text, Integer, CHAR,
|
from sqlalchemy import (Table, MetaData, Column, String, Text, Integer,
|
||||||
DateTime, Enum, Boolean, Unicode, UniqueConstraint,
|
SmallInteger, CHAR, DateTime, Enum, Boolean, Unicode,
|
||||||
ForeignKeyConstraint)
|
UniqueConstraint, ForeignKeyConstraint)
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
@ -44,6 +44,11 @@ ZONE_TASK_TYPES = ['IMPORT']
|
|||||||
|
|
||||||
metadata = MetaData()
|
metadata = MetaData()
|
||||||
|
|
||||||
|
|
||||||
|
def default_shard(context, id_col):
|
||||||
|
return int(context.current_parameters[id_col][0:3], 16)
|
||||||
|
|
||||||
|
|
||||||
quotas = Table('quotas', metadata,
|
quotas = Table('quotas', metadata,
|
||||||
Column('id', UUID, default=utils.generate_uuid, primary_key=True),
|
Column('id', UUID, default=utils.generate_uuid, primary_key=True),
|
||||||
Column('version', Integer(), default=1, nullable=False),
|
Column('version', Integer(), default=1, nullable=False),
|
||||||
@ -80,6 +85,8 @@ domains = Table('domains', metadata,
|
|||||||
Column('deleted', CHAR(32), nullable=False, default='0',
|
Column('deleted', CHAR(32), nullable=False, default='0',
|
||||||
server_default='0'),
|
server_default='0'),
|
||||||
Column('deleted_at', DateTime, nullable=True, default=None),
|
Column('deleted_at', DateTime, nullable=True, default=None),
|
||||||
|
Column('shard', SmallInteger(), nullable=False,
|
||||||
|
default=lambda ctxt: default_shard(ctxt, 'id')),
|
||||||
|
|
||||||
Column('tenant_id', String(36), default=None, nullable=True),
|
Column('tenant_id', String(36), default=None, nullable=True),
|
||||||
Column('name', String(255), nullable=False),
|
Column('name', String(255), nullable=False),
|
||||||
@ -134,6 +141,8 @@ recordsets = Table('recordsets', metadata,
|
|||||||
Column('version', Integer(), default=1, nullable=False),
|
Column('version', Integer(), default=1, nullable=False),
|
||||||
Column('created_at', DateTime, default=lambda: timeutils.utcnow()),
|
Column('created_at', DateTime, default=lambda: timeutils.utcnow()),
|
||||||
Column('updated_at', DateTime, onupdate=lambda: timeutils.utcnow()),
|
Column('updated_at', DateTime, onupdate=lambda: timeutils.utcnow()),
|
||||||
|
Column('domain_shard', SmallInteger(), nullable=False,
|
||||||
|
default=lambda ctxt: default_shard(ctxt, 'domain_id')),
|
||||||
|
|
||||||
Column('tenant_id', String(36), default=None, nullable=True),
|
Column('tenant_id', String(36), default=None, nullable=True),
|
||||||
Column('domain_id', UUID, nullable=False),
|
Column('domain_id', UUID, nullable=False),
|
||||||
@ -155,6 +164,8 @@ records = Table('records', metadata,
|
|||||||
Column('version', Integer(), default=1, nullable=False),
|
Column('version', Integer(), default=1, nullable=False),
|
||||||
Column('created_at', DateTime, default=lambda: timeutils.utcnow()),
|
Column('created_at', DateTime, default=lambda: timeutils.utcnow()),
|
||||||
Column('updated_at', DateTime, onupdate=lambda: timeutils.utcnow()),
|
Column('updated_at', DateTime, onupdate=lambda: timeutils.utcnow()),
|
||||||
|
Column('domain_shard', SmallInteger(), nullable=False,
|
||||||
|
default=lambda ctxt: default_shard(ctxt, 'domain_id')),
|
||||||
|
|
||||||
Column('tenant_id', String(36), default=None, nullable=True),
|
Column('tenant_id', String(36), default=None, nullable=True),
|
||||||
Column('domain_id', UUID, nullable=False),
|
Column('domain_id', UUID, nullable=False),
|
||||||
|
Loading…
Reference in New Issue
Block a user