devstack fails for duplicated check constraint name in gnocchi

Bug #1889732 reported by Yasufumi Ogawa
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Ceilometer
New
Undecided
Unassigned
tacker
Fix Released
Critical
Yasufumi Ogawa

Bug Description

Tacker's monitoring depends on ceilometer and it uses gnocchi as a TDBaaS [1]. On Ubuntu20.04, devstack installation fails for duplicated check constraint name in `gnocchi-upgrade` which is an initialization command for gnocchi. It doesn't happen on Ubuntu18.04.

In my install log below, it says "Duplicate check constraint name 'ck_started_before_ended'.". Although I don't know how `gnocchi-upgrade` works so much, it seems the schema is defined in [2]. The same symbol `ck_started_before_ended` is used for two tables, `resource` and `resource_history`, and failed to create second one.

[1] https://wiki.openstack.org/wiki/Gnocchi
[2] https://github.com/gnocchixyz/gnocchi/blob/master/gnocchi/indexer/alembic/versions/40c6aae14c3f_ck_started_before_ended.py

---------------------------------------------- Here is my log ----------------------------------------
2020-07-30 14:27:10,341 [143612] INFO gnocchi.cli.manage: Upgrading indexer SQLAlchemyIndexer: mysql+pymysql://***:***@127.0.0.1/gnocchi?charset=utf8
2020-07-30 14:27:10,351 [143612] WARNING py.warnings: /usr/local/lib/python3.8/dist-packages/pymysql/cursors.py:170: Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.")
  result = self._query(query)

2020-07-30 14:27:10,385 [143612] WARNING oslo_db.sqlalchemy.exc_filters: DBAPIError exception wrapped.
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1277, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/default.py", line 593, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.InternalError: (3822, "Duplicate check constraint name 'ck_started_before_ended'.")
2020-07-30 14:27:10,392 [143612] CRITICAL root: Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1277, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/default.py", line 593, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.InternalError: (3822, "Duplicate check constraint name 'ck_started_before_ended'.")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/bin/gnocchi-upgrade", line 11, in <module>
    load_entry_point('gnocchi', 'console_scripts', 'gnocchi-upgrade')()
  File "/opt/stack/devstack/src/gnocchi/gnocchi/cli/manage.py", line 69, in upgrade
    index.upgrade()
  File "/opt/stack/devstack/src/gnocchi/gnocchi/indexer/sqlalchemy.py", line 334, in upgrade
    Base.metadata.create_all(connection)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/schema.py", line 4546, in create_all
    bind._run_visitor(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1657, in _run_visitor
    visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/visitors.py", line 144, in traverse_single
    return meth(obj, **kw)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/ddl.py", line 783, in visit_metadata
    self.traverse_single(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/visitors.py", line 144, in traverse_single
    return meth(obj, **kw)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/ddl.py", line 827, in visit_table
    self.connection.execute(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1014, in execute
    return meth(self, multiparams, params)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/ddl.py", line 72, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1071, in _execute_ddl
    ret = self._execute_context(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1317, in _execute_context
    self._handle_dbapi_exception(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1509, in _handle_dbapi_exception
    util.raise_(newraise, with_traceback=exc_info[2], from_=e)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1277, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/default.py", line 593, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 732, in _read_query_result
    result.read()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 684, in _read_packet
    packet.check_error()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
oslo_db.exception.DBError: (pymysql.err.InternalError) (3822, "Duplicate check constraint name 'ck_started_before_ended'.")
[SQL:
CREATE TABLE resource_history (
 creator VARCHAR(255),
 started_at DATETIME(6) NOT NULL,
 revision_start DATETIME(6) NOT NULL,
 ended_at DATETIME(6),
 user_id VARCHAR(255),
 project_id VARCHAR(255),
 original_resource_id VARCHAR(255) NOT NULL,
 revision INTEGER NOT NULL AUTO_INCREMENT,
 id BINARY(16) NOT NULL,
 revision_end DATETIME(6) NOT NULL,
 type VARCHAR(255) NOT NULL,
 PRIMARY KEY (revision),
 CONSTRAINT ck_started_before_ended CHECK (started_at <= ended_at),
 CONSTRAINT fk_rh_id_resource_id FOREIGN KEY(id) REFERENCES resource (id) ON DELETE CASCADE,
 CONSTRAINT fk_resource_history_resource_type_name FOREIGN KEY(type) REFERENCES resource_type (name) ON DELETE RESTRICT
)CHARSET=utf8 ENGINE=InnoDB

]
(Background on this error at: http://sqlalche.me/e/13/2j85)

Yasufumi Ogawa (yasufum)
Changed in tacker:
importance: Undecided → High
assignee: nobody → Yasufumi Ogawa (yasufum)
Revision history for this message
Itsuro Oda (oda-g) wrote :

It is just an information. I found it depends on mysql version.

For example;
--- bionic mysql 5.7.29 ---
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.7.29-0ubuntu0.18.04.1 |
+-------------------------+
1 row in set (0.00 sec)

mysql> use neutron
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> create table x1 ( a int, constraint ct1 check (a in (1, 2)) );
Query OK, 0 rows affected (0.47 sec)

mysql> create table x2 ( b int, constraint ct1 check (b in (3, 4)) );
Query OK, 0 rows affected (1.65 sec)
---

--- focal mysql 8.0.21 ---
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 8.0.21-0ubuntu0.20.04.4 |
+-------------------------+
1 row in set (0.00 sec)

mysql> use neutron
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> create table x1 ( a int, constraint ct1 check (a in (1, 2)) );
Query OK, 0 rows affected (2.05 sec)

mysql> create table x2 ( b int, constraint ct1 check (b in (3, 4)) );
ERROR 3822 (HY000): Duplicate check constraint name 'ct1'.
mysql>
---

Yasufumi Ogawa (yasufum)
Changed in tacker:
importance: High → Critical
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Related fix merged to tacker (master)

Reviewed: https://review.opendev.org/751965
Committed: https://git.openstack.org/cgit/openstack/tacker/commit/?id=959da510b56bba982179f5f08b2cb1bca05cbc1e
Submitter: Zuul
Branch: master

commit 959da510b56bba982179f5f08b2cb1bca05cbc1e
Author: Toshiaki Takahashi <email address hidden>
Date: Tue Sep 15 13:10:09 2020 +0900

    Temporarily remove ceilometer install

    We temporarily remove Ceilometer and Barbican install to execute FT
    because Gnocchi and Barbican cannot be installed by some error.

    Related to https://storyboard.openstack.org/#!/story/2007732
    Related to https://storyboard.openstack.org/#!/story/2008121
    Related-Bug: #1889732
    Change-Id: I93dbd84cec252bb93257b852aa171d9ca89665c2

Yasufumi Ogawa (yasufum)
Changed in tacker:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.