** Changed in: nova
       Status: Fix Committed => Fix Released

** Changed in: nova
    Milestone: None => liberty-1

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Compute (nova).
https://bugs.launchpad.net/bugs/1445675

Title:
  missing index on virtual_interfaces can cause long queries that can
  cause timeouts in launching instances

Status in OpenStack Compute (Nova):
  Fix Released

Bug description:
  In a load test where a nova environment w/ networking enabled was set
  up to have ~250K instances,  attempting to launch 50 instances would
  cause many to time out, with the error "Timeout while waiting on RPC
  response - topic: "network", RPC method: "allocate_for_instance".
  The tester isolated the latency here to queries against the
  virtual_interfaces table, which in this test is executed some 500
  times, spending ~.5 seconds per query for a total of 200 seconds.  An
  example query looks like:

  SELECT virtual_interfaces.created_at , virtual_interfaces.updated_at , 
virtual_interfaces.deleted_at , virtual_interfaces.deleted , 
virtual_interfaces.id , virtual_interfaces.address , 
virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'9774e729-7695-4e2b-a9b2-a104a4b020d0'
  LIMIT 1;

  Query profiling against this table /query directly proceeded as
  follows:

  I scripted up direct DB access to get 250K rows in a blank database:

  MariaDB [nova]> select count(*) from virtual_interfaces;
  +----------+
  | count(*) |
  +----------+
  |   250000 |
  +----------+
  1 row in set (0.09 sec)

  emitting the query when the row is found, on this particular system is
  returning in .03 sec:

  MariaDB [nova]> SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c4'  LIMIT 1;
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  | created_at          | updated_at | deleted_at | deleted | id    | address   
    | network_id | instance_uuid                        | uuid                  
               |
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  | 2014-08-12 22:22:14 | NULL       | NULL       |       0 | 58393 | 
address_58393 |         22 | 41f1b859-8c5d-4c27-a52e-3e97652dfe7a | 
0a269012-cbc7-4093-9602-35f003a766c4 |
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  1 row in set (0.03 sec)

  
  we can see that for a row not found, where it has to scan the whole table, 
it's 10x longer:

  MariaDB [nova]> SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c5'  LIMIT 1;
  Empty set (0.14 sec)

  
  There's nothing mysterious going on here as an EXPLAIN shows plainly that we 
are doing a full table scan:

  MariaDB [nova]> EXPLAIN SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c4'  LIMIT 1;
  
+------+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
  | id   | select_type | table              | type | possible_keys | key  | 
key_len | ref  | rows   | Extra       |
  
+------+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
  |    1 | SIMPLE      | virtual_interfaces | ALL  | NULL          | NULL | 
NULL    | NULL | 250170 | Using where |
  
+------+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
  1 row in set (0.00 sec)

  
  adding an index on the uuid field via "create index vuidx on 
virtual_interfaces(uuid)", the EXPLAIN now shows the index used:

  MariaDB [nova]> EXPLAIN SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c4'  LIMIT 1;
  
+------+-------------+--------------------+------+---------------+-------+---------+-------+------+------------------------------------+
  | id   | select_type | table              | type | possible_keys | key   | 
key_len | ref   | rows | Extra                              |
  
+------+-------------+--------------------+------+---------------+-------+---------+-------+------+------------------------------------+
  |    1 | SIMPLE      | virtual_interfaces | ref  | vuidx         | vuidx | 
111     | const |    1 | Using index condition; Using where |
  
+------+-------------+--------------------+------+---------------+-------+---------+-------+------+------------------------------------+
  1 row in set (0.00 sec)

  
  and we get 0.00 response time for both queries:

  MariaDB [nova]> SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c5'  LIMIT 1;
  Empty set (0.00 sec)

  MariaDB [nova]> SELECT virtual_interfaces.created_at , 
virtual_interfaces.updated_at , virtual_interfaces.deleted_at , 
virtual_interfaces.deleted , virtual_interfaces.id , virtual_interfaces.address 
, virtual_interfaces.network_id , virtual_interfaces.instance_uuid , 
virtual_interfaces.uuid FROM virtual_interfaces WHERE 
virtual_interfaces.deleted = 0 AND virtual_interfaces.uuid = 
'0a269012-cbc7-4093-9602-35f003a766c4'  LIMIT 1;
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  | created_at          | updated_at | deleted_at | deleted | id    | address   
    | network_id | instance_uuid                        | uuid                  
               |
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  | 2014-08-12 22:22:14 | NULL       | NULL       |       0 | 58393 | 
address_58393 |         22 | 41f1b859-8c5d-4c27-a52e-3e97652dfe7a | 
0a269012-cbc7-4093-9602-35f003a766c4 |
  
+---------------------+------------+------------+---------+-------+---------------+------------+--------------------------------------+--------------------------------------+
  1 row in set (0.00 sec)

  
  whether or not the index includes "deleted" doesn't really matter.  If we're 
searching for UUIDs, we get that UUID row first, then the "deleted=0" is 
checked, not a big deal.

  For an immediate fix,  I propose to add the aforementioned index to
  the virtual_interfaces.uuid column.

To manage notifications about this bug go to:
https://bugs.launchpad.net/nova/+bug/1445675/+subscriptions

-- 
Mailing list: https://launchpad.net/~yahoo-eng-team
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yahoo-eng-team
More help   : https://help.launchpad.net/ListHelp

Reply via email to