Frage

I would like to get some information out of the openstack MySQL database, however my query skills are limited and I think I need to do a join on three tables from two different databases.

The structure of the tables is as follows:

mysql> describe neutron.ipallocations;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| port_id    | varchar(36) | YES  | MUL | NULL    |       |
| ip_address | varchar(64) | NO   | PRI | NULL    |       |
| subnet_id  | varchar(36) | NO   | PRI | NULL    |       |
| network_id | varchar(36) | NO   | PRI | NULL    |       |
+------------+-------------+------+-----+---------+-------+

mysql> describe neutron.ports;
+----------------+--------------+------+-----+---------+-------+
| Field          | Type         | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| tenant_id      | varchar(255) | YES  |     | NULL    |       |
| id             | varchar(36)  | NO   | PRI | NULL    |       |
| name           | varchar(255) | YES  |     | NULL    |       |
| network_id     | varchar(36)  | NO   | MUL | NULL    |       |
| mac_address    | varchar(32)  | NO   |     | NULL    |       |
| admin_state_up | tinyint(1)   | NO   |     | NULL    |       |
| status         | varchar(16)  | NO   |     | NULL    |       |
| device_id      | varchar(255) | NO   |     | NULL    |       |
| device_owner   | varchar(255) | NO   |     | NULL    |       |
+----------------+--------------+------+-----+---------+-------+

mysql> describe nova.instances;
+----------------------+-----------------------+------+-----+---------+----------------+
| Field                | Type                  | Null | Key | Default | Extra          |
+----------------------+-----------------------+------+-----+---------+----------------+
| uuid                 | varchar(36)           | YES  | UNI | NULL    |                |
| hostname             | varchar(255)          | YES  |     | NULL    |                | 
| deleted              | int(11)               | YES  |     | NULL    |                |
+----------------------+-----------------------+------+-----+---------+----------------+

As the nova table schema is quite large I have truncated it to just contain the fields I need.

What I would like to do is associate all the instances hostnames (nova.instance table) with their ip_address (neutron.ipallocation table). The instances should have a 0 in there deleted field to show that they are live.

however there is no direct mapping between the two. the link table is neutron.ports. In neutron.ports the device_id is a one to one relationship with the instance uuid and also the neutron.ipaccolcation port_id

So I have tried the following:

SELECT a.ip_address,c.hostname 
FROM neutron.ipallocations a, neutron.ports b,nova.instances c 
WHERE c.deleted='0' 
AND b.device_id = c.uuid 
AND a.port_id = b.device_id;

This does not return any results so something is probably very wrong with it.

also tried to use LEFT and INNER JOINS

SELECT ni.hostname, i.ip_address 
FROM nova.instances ni
LEFT JOIN neutron.ports p 
INNER JOIN neutron.ipallocations i 
ON i.port_id = p.device_id 
ON ni.uuid = p.device_id WHERE ni.deleted ='0';

This query returns the hostnames but the ip_address column is NULL so I think I'm missing something.

I don't really know if I need to use joins for this or could it be done in a simpler way. If any one has any pointers or a solution to this I would be very grateful.

Sorry for the confusion below is some sample data:

select * from neutron.ipallocations;
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+
| port_id                              | ip_address   | subnet_id                            | network_id                           |
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+
| 13433d6d-bf47-476b-a841-324aba4a902d | 192.168.14.5 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
| 5b66e69f-829d-419e-8116-889e0ad36c35 | 192.168.14.7 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
| 8e32216f-11db-437f-981d-cfe03e90baed | 192.168.14.4 | 07e516af-1162-4bfc-946b-fdc259b013c9 | bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 |
| 92a45ed8-a472-4845-841f-604259c07ab2 | 192.168.14.6 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+

The port_id from this table maps to the id field in neutron.ports:

 select * from neutron.ports;
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+
| tenant_id                        | id                                   | name | network_id                           | mac_address       | admin_state_up | status | device_id                                                                     | device_owner |
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+
| 9a111d6e4dd0440fab4cc7b610efd2bf | 13433d6d-bf47-476b-a841-324aba4a902d |      | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:6b:ed:5d |              1 | ACTIVE | dhcpc7e0c2c5-8a56-5b48-a120-03c05bff04a5-96a8fd64-8a94-476d-b9c8-c28055d39041 | network:dhcp |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 5b66e69f-829d-419e-8116-889e0ad36c35 |      | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:b9:4d:2e |              1 | ACTIVE | 578485e5-9f5f-405c-a09a-24f89b81a43c                                          | compute:nova |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 8e32216f-11db-437f-981d-cfe03e90baed |      | bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 | fa:16:3e:55:af:d5 |              1 | ACTIVE | dhcpc7e0c2c5-8a56-5b48-a120-03c05bff04a5-bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 | network:dhcp |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 92a45ed8-a472-4845-841f-604259c07ab2 |      | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:06:ad:13 |              1 | ACTIVE | 221a44fe-23e6-4003-8170-dafedeeaf333                                          | compute:nova |
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+

and the device_id from neutron.ports maps to the uuid in nova.instances:

mysql> select uuid,hostname,deleted from nova.instances where deleted ='0';
+--------------------------------------+--------------------------------+---------+
| uuid                                 | hostname                       | deleted |
+--------------------------------------+--------------------------------+---------+
| 221a44fe-23e6-4003-8170-dafedeeaf333 | host1.test.net                 |       0 |
| 578485e5-9f5f-405c-a09a-24f89b81a43c | host2.test.net                 |       0 |
+--------------------------------------+--------------------------------+---------+
War es hilfreich?

Lösung

Brent,

The problem we're having answering this question is that we don't understand what data in nova.instances matches data neutron.ports. From your attempts it looks like you expect nova.instances.uuid to match up to neutron.ports.device_id. If that is the case, your first query should work.

Can you provide some sample data and your expected output? I think that could clear up our confusion.


Edit

About your question of preferred syntax, I suspect Barmar was cringing at cartesian joins limited by a where clause. Consider the below query instead:

SELECT ip.ip_address
    ,i.hostname
FROM neutron.ipallocations ip
JOIN neutron.ports p ON ip.port_id = p.id
JOIN nova.instances i ON p.device_id = i.uuid
WHERE i.deleted = '0';

To be clear, the optimizer should choose the same execution path for both queries, but using on clauses makes the query more readable. I also changed the aliases; personally I prefer aliases with meaningful names.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top