This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 808fcb5c5b [MINOR] fix(core): Index role relations by role_id (#14356)
808fcb5c5b is described below
commit 808fcb5c5b63e22293866115375e42dd0596c67f
Author: roryqi <[email protected]>
AuthorDate: Thu Oct 29 16:50:09 2026 +0800
[MINOR] fix(core): Index role relations by role_id (#14356)
### What changes were proposed in this pull request?
Add indexes leading with `role_id` in the 2.0.0 schemas and
1.3.0-to-2.0.0 upgrades:
- PostgreSQL: `user_role_rel` and `group_role_rel`.
- MySQL and H2: `group_role_rel`; `user_role_rel` already has the index.
Keep the MySQL upgrade retryable by checking for an existing index
leading with `role_id`. Extend `TestSQLScripts` to verify these indexes
after fresh installation and upgrade.
### Why are the changes needed?
Deleting a role soft-deletes both relation tables by `role_id`. Without
a leading index, these updates scan the relation tables and slow down
role deletion as assignments grow.
### Does this PR introduce _any_ user-facing change?
No API or configuration changes.
### How was this patch tested?
24 tests passed across H2, MySQL 8.0, and PostgreSQL 13. Formatting and
diff checks passed.
---
.../apache/gravitino/storage/TestSQLScripts.java | 37 ++++++++++++++++++++--
scripts/h2/schema-2.0.0-h2.sql | 3 +-
scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql | 3 ++
scripts/mysql/schema-2.0.0-mysql.sql | 3 +-
scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql | 9 ++++++
scripts/postgresql/schema-2.0.0-postgresql.sql | 2 ++
.../upgrade-1.3.0-to-2.0.0-postgresql.sql | 4 +++
7 files changed, 57 insertions(+), 4 deletions(-)
diff --git
a/core/src/test/java/org/apache/gravitino/storage/TestSQLScripts.java
b/core/src/test/java/org/apache/gravitino/storage/TestSQLScripts.java
index a79089aa8b..008b5b75a2 100644
--- a/core/src/test/java/org/apache/gravitino/storage/TestSQLScripts.java
+++ b/core/src/test/java/org/apache/gravitino/storage/TestSQLScripts.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -32,6 +33,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -96,11 +98,14 @@ public class TestSQLScripts extends TestJDBCBackend {
}
}
- for (List<File> scripts : versionScrips.values()) {
+ for (Map.Entry<String, List<File>> versionScripts :
versionScrips.entrySet()) {
dropAllTables();
- for (File scriptFile : scripts) {
+ for (File scriptFile : versionScripts.getValue()) {
executeScript(scriptFile);
}
+ if ("2.0.0".equals(versionScripts.getKey())) {
+ assertRoleRelationsIndexedByRoleId("schema " +
versionScripts.getKey());
+ }
}
}
@@ -131,6 +136,9 @@ public class TestSQLScripts extends TestJDBCBackend {
dropAllTables();
executeScript(sourceSchema);
executeScript(upgradeScript);
+ if ("2.0.0".equals(upgradeMatcher.group(2))) {
+ assertRoleRelationsIndexedByRoleId(upgradeScript.getName());
+ }
}
}
@@ -558,6 +566,31 @@ public class TestSQLScripts extends TestJDBCBackend {
}
}
+ private void assertRoleRelationsIndexedByRoleId(String source) throws
SQLException {
+ try (SqlSession sqlSession =
+
SqlSessionFactoryHelper.getInstance().getSqlSessionFactory().openSession(true);
+ Connection connection = sqlSession.getConnection()) {
+ DatabaseMetaData metaData = connection.getMetaData();
+ for (String table : List.of("user_role_rel", "group_role_rel")) {
+ String tableName =
+ metaData.storesUpperCaseIdentifiers() ?
table.toUpperCase(Locale.ROOT) : table;
+ boolean indexed = false;
+ try (ResultSet indexes =
+ metaData.getIndexInfo(connection.getCatalog(), null, tableName,
false, false)) {
+ while (indexes.next()) {
+ if (indexes.getShort("ORDINAL_POSITION") == 1
+ &&
"role_id".equalsIgnoreCase(indexes.getString("COLUMN_NAME"))) {
+ indexed = true;
+ break;
+ }
+ }
+ }
+ Assertions.assertTrue(
+ indexed, "No index leading with role_id on " + table + " after " +
source);
+ }
+ }
+ }
+
private void assertSchemaMatchesFreshInstall(
Map<String, Set<String>> upgradedColumns, List<String> upgradedIndexes)
throws SQLException, IOException {
diff --git a/scripts/h2/schema-2.0.0-h2.sql b/scripts/h2/schema-2.0.0-h2.sql
index a3fda62695..1e1d2954f7 100644
--- a/scripts/h2/schema-2.0.0-h2.sql
+++ b/scripts/h2/schema-2.0.0-h2.sql
@@ -248,7 +248,8 @@ CREATE TABLE IF NOT EXISTS `group_role_rel` (
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'relation
deleted at',
PRIMARY KEY (`id`),
CONSTRAINT `uk_gi_ri_del` UNIQUE (`group_id`, `role_id`, `deleted_at`),
- KEY `idx_gid` (`group_id`)
+ KEY `idx_gid` (`group_id`),
+ KEY `group_role_rel_idx_role_id` (`role_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `idp_user_meta` (
diff --git a/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
b/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
index 4a80bab24f..542d229459 100644
--- a/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
+++ b/scripts/h2/upgrade-1.3.0-to-2.0.0-h2.sql
@@ -226,3 +226,6 @@ ALTER TABLE `fileset_meta`
ALTER TABLE `policy_meta`
ADD COLUMN IF NOT EXISTS `occ_version` INT UNSIGNED NOT NULL DEFAULT 1
COMMENT 'policy optimistic concurrency version' AFTER `last_version`;
+
+-- Role deletion soft-deletes relation rows by role_id.
+CREATE INDEX IF NOT EXISTS `group_role_rel_idx_role_id` ON `group_role_rel`
(`role_id`);
diff --git a/scripts/mysql/schema-2.0.0-mysql.sql
b/scripts/mysql/schema-2.0.0-mysql.sql
index b8e79b9afa..f868bfe339 100644
--- a/scripts/mysql/schema-2.0.0-mysql.sql
+++ b/scripts/mysql/schema-2.0.0-mysql.sql
@@ -239,7 +239,8 @@ CREATE TABLE IF NOT EXISTS `group_role_rel` (
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'relation
deleted at',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_gi_ri_del` (`group_id`, `role_id`, `deleted_at`),
- KEY `group_role_rel_idx_rid` (`group_id`)
+ KEY `group_role_rel_idx_rid` (`group_id`),
+ KEY `group_role_rel_idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT 'group
role relation';
CREATE TABLE IF NOT EXISTS `idp_user_meta` (
diff --git a/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
b/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
index 77ea3e487f..2a71058df3 100644
--- a/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
+++ b/scripts/mysql/upgrade-1.3.0-to-2.0.0-mysql.sql
@@ -685,3 +685,12 @@ SET @ddl = IF(EXISTS(SELECT 1 FROM
information_schema.columns
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
+
+-- Role deletion soft-deletes relation rows by role_id.
+SET @ddl = IF(EXISTS(SELECT 1 FROM information_schema.statistics
+ WHERE table_schema = DATABASE() AND table_name = 'group_role_rel' AND
column_name = 'role_id' AND seq_in_index = 1),
+ 'SELECT 1',
+ 'ALTER TABLE `group_role_rel` ADD INDEX `group_role_rel_idx_role_id`
(`role_id`)');
+PREPARE stmt FROM @ddl;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
diff --git a/scripts/postgresql/schema-2.0.0-postgresql.sql
b/scripts/postgresql/schema-2.0.0-postgresql.sql
index 109b8bc456..788e4a15d6 100644
--- a/scripts/postgresql/schema-2.0.0-postgresql.sql
+++ b/scripts/postgresql/schema-2.0.0-postgresql.sql
@@ -374,6 +374,7 @@ CREATE TABLE IF NOT EXISTS user_role_rel (
);
CREATE INDEX IF NOT EXISTS user_role_rel_idx_user_id ON user_role_rel
(user_id);
+CREATE INDEX IF NOT EXISTS user_role_rel_idx_role_id ON user_role_rel
(role_id);
COMMENT ON TABLE user_role_rel IS 'user role relation metadata';
COMMENT ON COLUMN user_role_rel.id IS 'auto increment id';
@@ -422,6 +423,7 @@ CREATE TABLE IF NOT EXISTS group_role_rel (
);
CREATE INDEX IF NOT EXISTS group_role_rel_idx_group_id ON group_role_rel
(group_id);
+CREATE INDEX IF NOT EXISTS group_role_rel_idx_role_id ON group_role_rel
(role_id);
COMMENT ON TABLE group_role_rel IS 'relation between group and role';
COMMENT ON COLUMN group_role_rel.id IS 'auto increment id';
COMMENT ON COLUMN group_role_rel.group_id IS 'group id';
diff --git a/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
b/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
index b5a70c34ed..237902df9f 100644
--- a/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
+++ b/scripts/postgresql/upgrade-1.3.0-to-2.0.0-postgresql.sql
@@ -337,3 +337,7 @@ COMMENT ON COLUMN fileset_meta.occ_version IS 'fileset
optimistic concurrency ve
ALTER TABLE policy_meta ADD COLUMN IF NOT EXISTS occ_version INT NOT NULL
DEFAULT 1;
COMMENT ON COLUMN policy_meta.occ_version IS 'policy optimistic concurrency
version';
+
+-- Role deletion soft-deletes relation rows by role_id.
+CREATE INDEX IF NOT EXISTS user_role_rel_idx_role_id ON user_role_rel
(role_id);
+CREATE INDEX IF NOT EXISTS group_role_rel_idx_role_id ON group_role_rel
(role_id);