Optimize the extend_router_dict() call

1. Only query the needed fields instead of the whole DB objects
to avoid the unnecessary join operations done at the
sqlalchemy layer.
2. Use the default lazy loading for the AddressScopeMapping to
address_scope relationship to avoid the unnecessary loadings.

Change-Id: Ie5bb9d1278cadeb97b5aabfe6cf2d0641acbaeca
(cherry picked from commit 1d0494e8ed)
(cherry picked from commit bfab33ec993cf383fec931a3809fc0e7d78ca035)
(cherry picked from commit e0b77722df31e59dea2eca1b3152d4cb08be284b)
This commit is contained in:
Kent Wu 2019-07-29 18:02:22 -07:00
parent 23f479dd74
commit b75d06f7d5
2 changed files with 24 additions and 25 deletions

View File

@ -34,7 +34,7 @@ class AddressScopeMapping(model_base.BASEV2):
primary_key=True)
address_scope = orm.relationship(
as_db.AddressScope, lazy='joined',
as_db.AddressScope,
backref=orm.backref(
'aim_mapping', lazy='joined', uselist=False, cascade='delete'))
@ -51,7 +51,7 @@ class NetworkMapping(model_base.BASEV2):
primary_key=True)
network = orm.relationship(
models_v2.Network, lazy='joined',
models_v2.Network,
backref=orm.backref(
'aim_mapping', lazy='joined', uselist=False, cascade='delete'))

View File

@ -1604,14 +1604,19 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
query = BAKERY(lambda s: s.query(
models_v2.IPAllocation.ip_address,
models_v2.Subnet,
models_v2.Network))
models_v2.Subnet.cidr,
models_v2.Subnet.network_id,
models_v2.SubnetPool.address_scope_id,
db.NetworkMapping))
query += lambda q: q.join(
models_v2.Subnet,
models_v2.Subnet.id == models_v2.IPAllocation.subnet_id)
query += lambda q: q.join(
models_v2.Network,
models_v2.Network.id == models_v2.Subnet.network_id)
query += lambda q: q.outerjoin(
models_v2.SubnetPool,
models_v2.SubnetPool.id == models_v2.Subnet.subnetpool_id)
query += lambda q: q.outerjoin(
db.NetworkMapping,
db.NetworkMapping.network_id == models_v2.Subnet.network_id)
query += lambda q: q.join(
l3_db.RouterPort,
l3_db.RouterPort.port_id == models_v2.IPAllocation.port_id)
@ -1620,26 +1625,21 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
l3_db.RouterPort.port_type == n_constants.DEVICE_OWNER_ROUTER_INTF)
for intf in query(session).params(
router_id=router_db.id):
ip_address, subnet_db, network_db = intf
if not network_db.aim_mapping:
ip_address, subnet_cidr, net_id, scope_id, net_mapping = intf
if not net_mapping:
LOG.warning(
"Mapping missing for network %s in extend_router_dict" %
network_db.id)
net_id)
continue
if network_db.aim_mapping.bd_name:
bd = self._get_network_bd(network_db.aim_mapping)
sn = self._map_subnet(subnet_db, intf.ip_address, bd)
if net_mapping.bd_name:
bd = self._get_network_bd(net_mapping)
sn = self._map_subnet({'cidr': subnet_cidr}, ip_address, bd)
dist_names[intf.ip_address] = sn.dn
sync_state = self._merge_status(aim_ctx, sync_state, sn)
scope_id = (subnet_db.subnetpool and
subnet_db.subnetpool.address_scope_id)
if scope_id:
scope_ids.add(scope_id)
else:
vrf = self._get_network_vrf(network_db.aim_mapping)
vrf = self._get_network_vrf(net_mapping)
if unscoped_vrf and unscoped_vrf.identity != vrf.identity:
# This should never happen. If it does, it
# indicates an inconsistency in the DB state
@ -1649,16 +1649,15 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
LOG.error("Inconsistent unscoped VRFs %s and %s for "
"router %s.", vrf, unscoped_vrf, router_db)
unscoped_vrf = vrf
for scope_id in scope_ids:
scope_db = self._scope_by_id(session, scope_id)
if not scope_db.aim_mapping:
addr_scope_mapping = self._get_address_scope_mapping(session,
scope_id)
if not addr_scope_mapping:
LOG.warning(
"Mapping missing for address scope %s in "
"extend_router_dict" % scope_db.id)
"extend_router_dict" % scope_id)
continue
vrf = self._get_address_scope_vrf(scope_db.aim_mapping)
vrf = self._get_address_scope_vrf(addr_scope_mapping)
dist_names[a_l3.SCOPED_VRF % scope_id] = vrf.dn
sync_state = self._merge_status(aim_ctx, sync_state, vrf)