diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index d68d6a4a37..3dfd92f8c2 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -f105ffea9daca8d5c18ba6e0d604f7eb6df4cb58 \ No newline at end of file +bc3ef08c8e4233508c023e6ee847a3cd0b8be43b diff --git a/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.down.sql b/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.down.sql index e9104f4d1c..ebe897537f 100644 --- a/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.down.sql +++ b/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.down.sql @@ -1,2 +1 @@ DROP INDEX IF EXISTS ix_audit_partitioned_workspace_operation; -DROP INDEX IF EXISTS ix_audit_workspace_operation; diff --git a/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.up.sql b/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.up.sql index 74aa7340a6..4d07e66f5a 100644 --- a/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.up.sql +++ b/backend/migrations/20260918173412_audit_partitioned_workspace_operation_index.up.sql @@ -1,8 +1,6 @@ --- The backend builds these with CREATE INDEX CONCURRENTLY instead (per partition for --- audit_partitioned), see create_audit_operation_index_concurrently in windmill-api/src/db.rs. +-- The backend builds this per partition with CREATE INDEX CONCURRENTLY instead, +-- see create_audit_operation_index_concurrently in windmill-api/src/db.rs. -- id matches list_audit's order and before_id cursor. timestamp trails it so a -- time window is checked in the index rather than on every row it reads. -CREATE INDEX IF NOT EXISTS ix_audit_workspace_operation - ON audit (workspace_id, operation, id DESC, "timestamp"); CREATE INDEX IF NOT EXISTS ix_audit_partitioned_workspace_operation ON audit_partitioned (workspace_id, operation, id DESC, "timestamp"); diff --git a/backend/tests/list_audit.rs b/backend/tests/list_audit.rs deleted file mode 100644 index a7b284dd8c..0000000000 --- a/backend/tests/list_audit.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![cfg(feature = "private")] - -use sqlx::{Pool, Postgres}; - -use windmill_test_utils::*; - -/// Each table is limited on its own before the union is paginated, so a page past the first must -/// still see every row ranked ahead of it in both tables. -#[sqlx::test(fixtures("base"))] -async fn test_list_audit_paginates_across_legacy_and_partitioned( - db: Pool, -) -> anyhow::Result<()> { - initialize_tracing().await; - - let server = ApiServer::start(db.clone()).await?; - let port = server.addr.port(); - let client = windmill_api_client::create_client( - &format!("http://localhost:{port}"), - "SECRET_TOKEN".to_string(), - ); - - for (table, id) in [ - ("audit", 1), - ("audit", 2), - ("audit", 3), - ("audit_partitioned", 101), - ("audit_partitioned", 102), - ("audit_partitioned", 103), - ] { - sqlx::query(&format!( - "INSERT INTO {table} (workspace_id, id, username, operation, action_kind) - VALUES ('test-workspace', $1, 'test-user', 'test.op', 'execute')" - )) - .bind(id as i64) - .execute(&db) - .await?; - } - - let mut ids = vec![]; - for page in 1..=4 { - let response = client - .client() - .get(format!( - "{}/w/test-workspace/audit/list?operation=test.op&per_page=2&page={page}", - client.baseurl() - )) - .send() - .await?; - assert!( - response.status().is_success(), - "page {page}: {}", - response.text().await? - ); - let rows = response.json::>().await?; - ids.extend(rows.iter().map(|r| r["id"].as_i64().unwrap())); - } - assert_eq!(ids, vec![103, 102, 101, 3, 2, 1]); - - Ok(()) -} diff --git a/backend/windmill-api/src/db.rs b/backend/windmill-api/src/db.rs index fbb8b29415..36dd4af1e1 100644 --- a/backend/windmill-api/src/db.rs +++ b/backend/windmill-api/src/db.rs @@ -40,27 +40,6 @@ const AUDIT_OPERATION_INDEX_KEY: &str = r#"(workspace_id, operation, id DESC, "t async fn create_audit_operation_index_concurrently( conn: &mut PgConnection, ) -> Result<(), MigrateError> { - // list_audit reads the legacy table too, which holds up to a retention period of rows - // written before partitioning. - let legacy_valid: Option = sqlx::query_scalar( - "SELECT indisvalid FROM pg_index - WHERE indexrelid = to_regclass('ix_audit_workspace_operation')", - ) - .fetch_optional(&mut *conn) - .await?; - if legacy_valid != Some(true) { - conn.execute("DROP INDEX CONCURRENTLY IF EXISTS ix_audit_workspace_operation") - .await?; - conn.execute( - format!( - "CREATE INDEX CONCURRENTLY ix_audit_workspace_operation \ - ON audit {AUDIT_OPERATION_INDEX_KEY}" - ) - .as_str(), - ) - .await?; - } - conn.execute( format!( "CREATE INDEX IF NOT EXISTS ix_audit_partitioned_workspace_operation \