Upgrade SonarQube version 8.3 to 8.4

Upgrade SonarQube 8.3 to SonarQube 8.4

  • my current setup: SonarQube Community Edition 8.3, PostgreSQL 10
  • what I try to achieve: Upgrade SonarQube 8.3 to SonarQube 8.4

Hello, few days ago I received a MySQL dump of SQ database, and following the instructions for migration from MySQL 5.7.30 to PostgreSQL 10,and upgrade path for SQ Community 7.4 -> 7.9 -> 8.4, which failed, and was changed to 7.4 -> 7.9 -> 8.0 -> 8.3, now I have SQ 8.3 and PostgreSQL 10 working.My goal is to upgrade to 8.4.
So I try to perform the upgrade of SonarQube (standalone/community) from version sonarqube-8.3.0.34182 to sonarqube-8.4.0.35506. The database is PostgreSQL 10, and OS is Ubuntu 20.04.
Once I get to the step http://sonarqube/setup, and press the “Upgrade” button, a web page with following error is received:

Upgrade Failed
Database connection cannot be established. Please check database status and JDBC settings.

Lines below are from the SQ web.log:

2020.07.15 07:47:50 INFO  web[][DbMigrations] Executing DB migrations...
2020.07.15 07:47:50 INFO  web[][DbMigrations] #3400 'Drop primary key on 'ID' column of 'EVENTS' table'...
2020.07.15 07:47:50 TRACE web[][sql] time=5ms | sql=SELECT conname FROM pg_constraint WHERE conrelid = (SELECT oid FROM pg_class WHERE relname LIKE 'events')
2020.07.15 07:47:50 ERROR web[][DbMigrations] #3400 'Drop primary key on 'ID' column of 'EVENTS' table': failure | time=9ms
2020.07.15 07:47:50 ERROR web[][DbMigrations] Executed DB migrations: failure | time=11ms
2020.07.15 07:47:50 ERROR web[][o.s.s.p.d.m.DatabaseMigrationImpl] DB migration failed | time=64ms
2020.07.15 07:47:50 ERROR web[][o.s.s.p.d.m.DatabaseMigrationImpl] DB migration ended with an exception
org.sonar.server.platform.db.migration.step.MigrationStepExecutionException: Execution of migration step #3400 'Drop primary key on 'ID' column of 'EVENTS' table' failed
        at org.sonar.server.platform.db.migration.step.MigrationStepsExecutorImpl.execute(MigrationStepsExecutorImpl.java:79)
        at org.sonar.server.platform.db.migration.step.MigrationStepsExecutorImpl.execute(MigrationStepsExecutorImpl.java:67)
        at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:405)
        at org.sonar.server.platform.db.migration.step.MigrationStepsExecutorImpl.execute(MigrationStepsExecutorImpl.java:52)
        at org.sonar.server.platform.db.migration.engine.MigrationEngineImpl.execute(MigrationEngineImpl.java:68)
        at org.sonar.server.platform.db.migration.DatabaseMigrationImpl.doUpgradeDb(DatabaseMigrationImpl.java:105)
        at org.sonar.server.platform.db.migration.DatabaseMigrationImpl.doDatabaseMigration(DatabaseMigrationImpl.java:80)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.postgresql.util.PSQLException: ERROR: more than one row returned by a subquery used as an expression
  Location: File: nodeSubplan.c, Routine: ExecSetParamPlan, Line: 1037
  Server SQLState: 21000

Need your help to complete the upgrade.

Hi, welcome to the community forum. Could you please execute this query and share with us the result?

SELECT conname FROM pg_constraint WHERE conrelid = 
(SELECT oid FROM pg_class WHERE LOWER(relname) = 'events')

Also, could you please share what the table events looks like? I’m interested in the column list, index list, and the primary key.

result of this query is:
SQL Error [21000]: ERROR: more than one row returned by a subquery used as an expression

SELECT oid FROM pg_class WHERE LOWER(relname) = 'events'

returns two values for oid, and the result for those values is:

SELECT conname FROM pg_constraint WHERE conrelid = 29687 --> pk_events
SELECT conname FROM pg_constraint WHERE conrelid = 30685 --> idx_17206_primary

Below you can find description of table events:

                                         Table "sonar.events"
     Column     |          Type           | Collation | Nullable |              Default
----------------+-------------------------+-----------+----------+------------------------------------
 id             | bigint                  |           | not null | nextval('events_id_seq'::regclass)
 name           | character varying(400)  |           |          |
 category       | character varying(50)   |           |          |
 description    | character varying(4000) |           |          |
 event_data     | character varying(4000) |           |          |
 event_date     | numeric                 |           | not null |
 created_at     | numeric                 |           | not null |
 component_uuid | character varying(50)   |           | not null |
 analysis_uuid  | character varying(50)   |           | not null |
 uuid           | character varying(40)   |           | not null |
Indexes:
    "idx_17206_primary" PRIMARY KEY, btree (id)
    "idx_17205_events_uuid" UNIQUE, btree (uuid)
    "idx_17206_events_uuid" UNIQUE, btree (uuid)
    "idx_17205_events_analysis" btree (analysis_uuid)
    "idx_17205_events_component_uuid" btree (component_uuid)
    "idx_17206_events_analysis" btree (analysis_uuid)
    "idx_17206_events_component_uuid" btree (component_uuid)

Hi,

I’m having the same problem. For now I reverted to 8.3. I could also chip in if more tests need to be done for resolving this problem.

Thanks.

Hi @Jean-Philippe_Shield,

Do you confirm that you were also using MySQL, and then you’ve migrated to PostgresSQL ?
it will help us understand more from where this strange issue is coming.

Thanks !

I have the exact same issue upgrading from 7.9.1 to 8.4 and my 7.9.1 installation was definitely PostgreSQL. I can’t verify what it was prior to that however as it was migrated from a different VM which is no longer available. Any help would be appreciated! If I solve my own issue I will post the resolution here.

I also did a describe of the events table and it looks different than does the table from @Radoslav:

\d events

                                        Table "public.events"
     Column     |          Type           | Collation | Nullable |              Default
----------------+-------------------------+-----------+----------+------------------------------------
 id             | integer                 |           | not null | nextval('events_id_seq'::regclass)
 name           | character varying(400)  |           |          |
 category       | character varying(50)   |           |          |
 description    | character varying(4000) |           |          |
 event_data     | character varying(4000) |           |          |
 event_date     | bigint                  |           | not null |
 created_at     | bigint                  |           | not null |
 component_uuid | character varying(50)   |           | not null |
 analysis_uuid  | character varying(50)   |           | not null |
 uuid           | character varying(40)   |           | not null |
Indexes:
    "pk_events" PRIMARY KEY, btree (id)
    "events_uuid" UNIQUE, btree (uuid)
    "events_analysis" btree (analysis_uuid)
    "events_component_uuid" btree (component_uuid) 

Thank you!

@julienlancelot. We have been on PostgreSQL since our first installation (around version 6.x)

@Jean-Philippe_Shield, @Eric_Amell, could you please execute the following SQL queries ?

SELECT conname FROM pg_constraint WHERE conrelid in (SELECT oid FROM pg_class WHERE relname LIKE ‘events’)

Thanks !

@julienlancelot here you are and I also tried adding a LOWER around relname in the inner query but the result was the same:

psql (10.12 (Ubuntu 10.12-0ubuntu0.18.04.1))
Type “help” for help.

postgres=# SELECT conname FROM pg_constraint WHERE conrelid in (SELECT oid FROM pg_class WHERE relname LIKE ‘events’);
conname
---------
(0 rows)

Thank you

@Eric_Amell @Jean-Philippe_Shield @Radoslav

could you please execute this and share with us the result?

select kcu.table_name,
       tco.constraint_name,
       kcu.column_name as key_column
from information_schema.table_constraints tco
join information_schema.key_column_usage kcu 
     on kcu.constraint_name = tco.constraint_name
     and kcu.constraint_schema = tco.constraint_schema
     and kcu.constraint_name = tco.constraint_name
where tco.constraint_type = 'PRIMARY KEY'
order by kcu.table_schema,
         kcu.table_name;

@pierreguillot There were 135 rows so I have attached it: primary_keys.txt (8.9 KB)

@julienlancelot I just realized in my haste before I ran the last query you asked me to run as the wrong PostgreSQL user. Here is the correct result:

 SELECT conname FROM pg_constraint WHERE conrelid in (SELECT oid FROM pg_class WHERE relname LIKE 'events');
      conname
--------------------
 pk_events
 idx_287598_primary
(2 rows)

Sorry about any confusion.

Great, this is really helping, thanks :slight_smile: So here you have almost all your indexes duplicated. Some start with idx_, and some with pk_.

The pk_ indexes are totally normal, they are the one we expect.

The idx_ indexes must be coming from something else than SonarQube himself: a restore tool, a migration in the past from another DB vendor (From MySQL ?). Do you know, by any chance, if your database has been migrated from MySQL before the 7.9 version? (and if yes, how was done the migration?)

@pierreguillot I can check tomorrow. I thought I had deleted the old server but I think I found it in the archives so I should be able to restore it and check. It is very likely it was MySQL as we have been using SonarQube for a long time and MySQL was our standard back then. I am not as confident that I can track down how I did the migration though. It was most likely done by me but maintaining these servers isn’t my day job so I am not always as diligent in documenting my successes as I should be.

Thanks for your answer. To be more specific, do you remember if you used the tool provided by SonarSource, https://github.com/SonarSource/mysql-migrator ?

@pierreguillot I can verify we were on MySQL and although I can’t be certain of this it looks as if pgloader was used to migrate the data. Now that I am paying attention to when this was done I now know who did it so I can double check with him when he comes online.

Assuming this was the case what would the fix be? I do understand it would most likely involve some messy manual intervention.

@pierreguillot that is the output of
select kcu.table_name,
tco.constraint_name,
kcu.column_name as key_column
from information_schema.table_constraints tco
join information_schema.key_column_usage kcu
on kcu.constraint_name = tco.constraint_name
and kcu.constraint_schema = tco.constraint_schema
and kcu.constraint_name = tco.constraint_name
where tco.constraint_type = ‘PRIMARY KEY’
order by kcu.table_schema,
kcu.table_name;

		table_name         |       constraint_name        |    key_column
---------------------------+------------------------------+-------------------
active_rule_parameters    | pk_active_rule_parameters    | id
active_rules              | pk_active_rules              | id
alm_app_installs          | pk_alm_app_installs          | uuid
alm_pats                  | pk_alm_pats                  | uuid
alm_settings              | pk_alm_settings              | uuid
analysis_properties       | pk_analysis_properties       | uuid
ce_activity               | pk_ce_activity               | id
ce_queue                  | pk_ce_queue                  | id
ce_scanner_context        | pk_ce_scanner_context        | task_uuid
ce_task_characteristics   | pk_ce_task_characteristics   | uuid
ce_task_input             | pk_ce_task_input             | task_uuid
ce_task_message           | pk_ce_task_message           | uuid
default_qprofiles         | pk_default_qprofiles         | organization_uuid
default_qprofiles         | pk_default_qprofiles         | language
deprecated_rule_keys      | pk_deprecated_rule_keys      | uuid
duplications_index        | pk_duplications_index        | id
es_queue                  | pk_es_queue                  | uuid
event_component_changes   | pk_event_component_changes   | uuid
events                    | pk_events                    | id
file_sources              | pk_file_sources              | id
group_roles               | pk_group_roles               | id
groups                    | pk_groups                    | id
internal_component_props  | pk_internal_component_props  | uuid
internal_properties       | pk_internal_properties       | kee
issue_changes             | pk_issue_changes             | id
issues                    | pk_issues                    | id
live_measures             | pk_live_measures             | uuid
manual_measures           | pk_manual_measures           | id
metrics                   | pk_metrics                   | id
new_code_periods          | pk_new_code_periods          | uuid
notifications             | pk_notifications             | id
organization_alm_bindings | pk_organization_alm_bindings | uuid
organization_members      | pk_organization_members      | organization_uuid
organization_members      | pk_organization_members      | user_id
organizations             | pk_organizations             | uuid
org_qprofiles             | pk_org_qprofiles             | uuid
org_quality_gates         | pk_org_quality_gates         | uuid
permission_templates      | pk_permission_templates      | id
perm_templates_groups     | pk_perm_templates_groups     | id
perm_templates_users      | pk_perm_templates_users      | id
perm_tpl_characteristics  | pk_perm_tpl_characteristics  | id
plugins                   | pk_plugins                   | uuid
project_alm_bindings      | pk_project_alm_bindings      | uuid
project_alm_settings      | pk_project_alm_settings      | uuid
project_branches          | pk_project_branches          | uuid
project_links             | pk_project_links             | uuid
project_mappings          | pk_project_mappings          | uuid
project_measures          | pk_project_measures          | id
project_qgates            | pk_project_qgates            | project_uuid
project_qprofiles         | pk_project_qprofiles         | id
projects                  | pk_new_projects              | uuid
properties                | pk_properties                | id
qprofile_changes          | pk_qprofile_changes          | kee
qprofile_edit_groups      | pk_qprofile_edit_groups      | uuid
qprofile_edit_users       | pk_qprofile_edit_users       | uuid
quality_gate_conditions   | pk_quality_gate_conditions   | id
quality_gates             | pk_quality_gates             | id
rule_repositories         | pk_rule_repositories         | kee
rules                     | pk_rules                     | id
rules_metadata            | pk_rules_metadata            | rule_id
rules_metadata            | pk_rules_metadata            | organization_uuid
rules_parameters          | pk_rules_parameters          | id
rules_profiles            | pk_rules_profiles            | id
snapshots                 | pk_snapshots                 | id
user_properties           | pk_user_properties           | uuid
user_roles                | pk_user_roles                | id
users                     | pk_users                     | id
user_tokens               | pk_user_tokens               | id
webhook_deliveries        | pk_webhook_deliveries        | uuid
webhooks                  | pk_webhooks                  | uuid
active_rule_parameters    | idx_17119_primary            | id
active_rules              | idx_17110_primary            | id
alm_app_installs          | idx_17126_primary            | uuid
alm_pats                  | pk_alm_pats                  | uuid
alm_settings              | pk_alm_settings              | uuid
analysis_properties       | idx_17132_primary            | uuid
ce_activity               | idx_17140_primary            | id
ce_queue                  | idx_17149_primary            | id
ce_scanner_context        | idx_17156_primary            | task_uuid
ce_task_characteristics   | idx_17162_primary            | uuid
ce_task_input             | idx_17168_primary            | task_uuid
ce_task_message           | idx_17174_primary            | uuid
default_qprofiles         | idx_17180_primary            | organization_uuid
default_qprofiles         | idx_17180_primary            | language
deprecated_rule_keys      | idx_17186_primary            | uuid
duplications_index        | idx_17194_primary            | id
es_queue                  | idx_17198_primary            | uuid
event_component_changes   | pk_event_component_changes   | uuid
events                    | idx_17206_primary            | id
file_sources              | idx_17215_primary            | id
group_roles               | idx_17239_primary            | id
groups                    | idx_17224_primary            | id
internal_component_props  | pk_internal_component_props  | uuid
internal_properties       | idx_17243_primary            | kee
issue_changes             | idx_17260_primary            | id
issues                    | idx_17251_primary            | id
live_measures             | idx_17267_primary            | uuid
manual_measures           | idx_17275_primary            | id
metrics                   | idx_17284_primary            | id
new_code_periods          | pk_new_code_periods          | uuid
notifications             | idx_17294_primary            | id
organization_alm_bindings | pk_organization_alm_bindings | uuid
organization_members      | idx_17307_primary            | user_id
organization_members      | idx_17307_primary            | organization_uuid
organizations             | idx_17301_primary            | uuid
org_qprofiles             | idx_17310_primary            | uuid
org_quality_gates         | idx_17316_primary            | uuid
permission_templates      | idx_17321_primary            | id
perm_templates_groups     | idx_17330_primary            | id
perm_templates_users      | idx_17336_primary            | id
perm_tpl_characteristics  | idx_17342_primary            | id
plugins                   | idx_17350_primary            | uuid
project_alm_bindings      | idx_17366_primary            | uuid
project_alm_settings      | pk_project_alm_settings      | uuid
project_branches          | idx_17372_primary            | uuid
project_links             | idx_17378_primary            | uuid
project_mappings          | idx_17384_primary            | uuid
project_measures          | idx_17392_primary            | id
project_qgates            | pk_project_qgates            | project_uuid
project_qprofiles         | idx_17401_primary            | id
projects                  | pk_new_projects              | uuid
properties                | idx_17407_primary            | id
qprofile_changes          | idx_17414_primary            | kee
qprofile_edit_groups      | idx_17420_primary            | uuid
qprofile_edit_users       | idx_17426_primary            | uuid
quality_gate_conditions   | idx_17440_primary            | id
quality_gates             | idx_17434_primary            | id
rule_repositories         | idx_17475_primary            | kee
rules                     | idx_17446_primary            | id
rules_metadata            | idx_17454_primary            | rule_id
rules_metadata            | idx_17454_primary            | organization_uuid
rules_parameters          | idx_17462_primary            | id
rules_profiles            | idx_17471_primary            | id
snapshots                 | idx_17486_primary            | id
user_properties           | pk_user_properties           | uuid
user_roles                | idx_17507_primary            | id
users                     | idx_17497_primary            | id
user_tokens               | idx_17513_primary            | id
webhook_deliveries        | idx_17526_primary            | uuid
webhooks                  | idx_17520_primary            | uuid
(140 rows)

Yes it will :smiley: Basically we have two possibility here:

  1. your strange indexes are coming from SQ or our tool mysql-migrator, and I have to fix a bug in our code
  2. your strange indexes are coming from pgLoader or another tool, and i will do my best to help you, but that won’t impact SonarQube sourcecode (nothing to “fix” on our side).

Thanks a lot @Radoslav, you are exactly in the same situation as @Eric_Amell. The fix will be the same for you both.

Ok so for both @Radoslav and @Eric_Amell, you are in the same situation: you have unexpected indexes in your database, created by the migration from MySQL. We do provide a tool for this migration, that guarantee the schema to remain valid. With other tools such as PgLoader, we have no control on the target schema, hence the errors you face now.

you have two possibilities here:

  • Engage with SonarSource paying support that will individually guide you through this. The remediation may consist of using one of our internal tool to recreate a clean new database schema and migrate your data to it.
  • Delete manually all your indexes starting with idx_, and hope that there is no other issue with your schema.

If you choose the second option, maybe this can help you to fix your schema: This is the expected schema for 8.3.

3 Likes