This is an automated email from the ASF dual-hosted git repository. woblerr pushed a commit to branch upgrade-go-1.25 in repository https://gitbox.apache.org/repos/asf/cloudberry-backup.git
commit 3570a0200b8ce4dbec68451e3b13ca5ced26d377 Author: woblerr <[email protected]> AuthorDate: Fri Jun 26 19:05:44 2026 +0300 Fix gp_segment_configuration lock e2e test. The test intended to verify that gpbackup does not keep a lock on pg_catalog.gp_segment_configuration after passing that metadata query and blocking later on pg_catalog.pg_trigger. However, the old test did not actually exercise that state: it used raw BEGIN/COMMIT SQL through DBConn, committed before gpbackup was started, queried pg_locks in an unsynchronized goroutine, and ignored query errors while scanning SELECT * into an int. Use an explicit DBConn transaction on a dedicated lock connection, start gpbackup while the pg_trigger lock is still held, wait until gpbackup is visibly blocked on pg_trigger, and then synchronously assert that no gp_segment_configuration locks remain. Finally release pg_trigger and verify gpbackup completes successfully. --- end_to_end/end_to_end_suite_test.go | 62 +++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/end_to_end/end_to_end_suite_test.go b/end_to_end/end_to_end_suite_test.go index 76a5b370..cbbfc90f 100644 --- a/end_to_end/end_to_end_suite_test.go +++ b/end_to_end/end_to_end_suite_test.go @@ -1993,7 +1993,16 @@ LANGUAGE plpgsql NO SQL;`) Skip("This test is not needed for old backup versions") } // Block on pg_trigger, which gpbackup queries after gp_segment_configuration - backupConn.MustExec("BEGIN; LOCK TABLE pg_trigger IN ACCESS EXCLUSIVE MODE") + lockConn := testutils.SetupTestDbConn("testdb") + defer lockConn.Close() + lockConn.MustBegin() + lockReleased := false + defer func() { + if !lockReleased { + _ = lockConn.Rollback() + } + }() + lockConn.MustExec("LOCK TABLE pg_catalog.pg_trigger IN ACCESS EXCLUSIVE MODE") args := []string{ "--dbname", "testdb", @@ -2001,19 +2010,54 @@ LANGUAGE plpgsql NO SQL;`) "--verbose"} cmd := exec.Command(gpbackupPath, args...) - backupConn.MustExec("COMMIT") - anotherConn := testutils.SetupTestDbConn("testdb") - defer anotherConn.Close() - var lockCount int + type commandResult struct { + output []byte + err error + } + gpbackupResultChan := make(chan commandResult, 1) go func() { - gpSegConfigQuery := `SELECT * FROM pg_locks l, pg_class c, pg_namespace n WHERE l.relation = c.oid AND n.oid = c.relnamespace AND c.relname = 'gp_segment_configuration';` - _ = anotherConn.Get(&lockCount, gpSegConfigQuery) + output, err := cmd.CombinedOutput() + gpbackupResultChan <- commandResult{output: output, err: err} }() + pollConn := testutils.SetupTestDbConn("testdb") + defer pollConn.Close() + + triggerLockQuery := `SELECT count(*) FROM pg_locks l, pg_class c, pg_namespace n WHERE l.relation = c.oid AND n.oid = c.relnamespace AND n.nspname = 'pg_catalog' AND c.relname = 'pg_trigger' AND l.granted = 'f' AND l.mode = 'AccessShareLock'` + var gpbackupBlockedLockCount int + var earlyResult *commandResult + for iterations := 100; iterations > 0; iterations-- { + select { + case result := <-gpbackupResultChan: + earlyResult = &result + default: + } + if earlyResult != nil { + break + } + + Expect(pollConn.Get(&gpbackupBlockedLockCount, triggerLockQuery)).To(Succeed()) + if gpbackupBlockedLockCount > 0 { + break + } + time.Sleep(100 * time.Millisecond) + } + if earlyResult != nil { + Fail(fmt.Sprintf("gpbackup finished before blocking on pg_trigger: %v\n%s", earlyResult.err, string(earlyResult.output))) + } + Expect(gpbackupBlockedLockCount).To(BeNumerically(">", 0), "gpbackup did not block on pg_trigger") + + var lockCount int + gpSegConfigQuery := `SELECT count(*) FROM pg_locks l, pg_class c, pg_namespace n WHERE l.relation = c.oid AND n.oid = c.relnamespace AND n.nspname = 'pg_catalog' AND c.relname = 'gp_segment_configuration'` + Expect(pollConn.Get(&lockCount, gpSegConfigQuery)).To(Succeed()) Expect(lockCount).To(Equal(0)) - output, _ := cmd.CombinedOutput() - stdout := string(output) + lockConn.MustCommit() + lockReleased = true + + result := <-gpbackupResultChan + stdout := string(result.output) + Expect(result.err).ToNot(HaveOccurred(), "%s", stdout) Expect(stdout).To(ContainSubstring("Backup completed successfully")) }) It("properly handles various implicit casts on pg_catalog.text", func() { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
