How to fix duplicate entries in Bitbucket PostgreSQL database
Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Summary
Due to unique constraint violation in Postgres, duplicate records could exists in Bitbucket database tables such as sta_normal_user
, project
, & plugin_setting
.
This will result in a user who no longer exists been assigned as a default reviewer when creating a pull-request.
Environment
Bitbucket 7.17.4
PostgreSQL
Diagnosis
The
sta_normal_user table
has duplicate entry of the user. The entry has differentuser_id & slug
, but the samename
.- Duplicates are found in other tables such as
project
andplugin_setting
table.
Cause
This seems to have occurred due to the bug causing unique constraint violation in Postgres due to OS upgrade.
Solution
If you are unsure how to deal with the database, contact your DBA. Make sure to have the database backed up completely before going further. These SQL commands were tested in some environments and they worked as intended.
This solution is only for sta_normal_user
, project
, & plugin_setting
tables. DO NOT USE this for other tables.
Step 1:
- Set up a test instance.
Get all the users who are duplicated, in ascending order (older users first) of their
user_id
using the query below:SELECT * from sta_normal_user where name in (SELECT (sta_normal_user.name)::text from sta_normal_user GROUP BY sta_normal_user.name HAVING count(*) > 1) ORDER by user_id;
Locate the duplicated users which you no longer require. For example, if the first
17 users
seem to be the old users, rename the username which are duplicate entries with the query below:UPDATE sta_normal_user SET name = slug || '.dis', slug = slug || '.dis' where user_id in (SELECT user_id from sta_normal_user where name in (SELECT (sta_normal_user.name)::text from sta_normal_user GROUP BY sta_normal_user.name HAVING count(*) > 1) ORDER by user_id limit 17)
The above query would fix the duplicates for the sta_normal_user table
.
Step 2:
We still need to fix the duplicate entries for the table project
and plugin_setting
tables.
To find the duplicates of
project
table run the below query:select * from project pr where (select count(*) from project inr where inr.name = pr.name) > 1 ORDER by name;
Select the
id
of the duplicate project and delete it using the query below:DELETE FROM public.project WHERE id = project_id
The
project_id
is gotten from the query in step 1.To find the duplicates on the plugin_setting table run the query below:
select * from plugin_setting pr where (select count(*) from plugin_setting inr where inr.key_name = pr.key_name) > 1 ORDER by key_name;
To delete the duplicate entries execute the command below for all the entries:
DELETE FROM plugin_setting WHERE id = plugin_setting_id
The plugin_setting_id is gotten from the query in step 3.
Step 3:
Reindex all the tables using the command below:
REINDEX TABLE sta_normal_user; REINDEX TABLE project; REINDEX TABLE plugin_setting;
- Confirm if all duplicates are removed and your instance is fully functional.
- Perform the same steps on your
production instance
.