Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_and_unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24"
go-version: "1.25"

- name: Set Environment
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repo is a fork of gpbackup, dedicated to supporting Cloudberry.

## Pre-Requisites

The project requires the Go Programming language version 1.21 or higher.
The project requires the Go Programming language version 1.25 or higher.
Follow the directions [here](https://golang.org/doc/) for installation, usage
and configuration instructions. Make sure to set the [Go PATH environment
variable](https://go.dev/doc/install) before starting the following steps.
Expand Down
2 changes: 1 addition & 1 deletion backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ type TableLocks struct {
}

func getTableLocks(table Table) []TableLocks {
conn := dbconn.NewDBConnFromEnvironment(MustGetFlagString(options.DBNAME))
conn := dbconn.NewDBConnFromEnvironment(connectionPool.DBName)
conn.MustConnect(1)
var query string
defer conn.Close()
Expand Down
12 changes: 9 additions & 3 deletions backup/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/apache/cloudberry-backup/utils"
"github.com/apache/cloudberry-go-libs/dbconn"
"github.com/apache/cloudberry-go-libs/gplog"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v5/pgconn"
"gopkg.in/cheggaaa/pb.v1"
)

Expand Down Expand Up @@ -214,13 +214,19 @@ func BackupDataForAllTables(tables []Table) []map[uint32]int64 {
// tables before the metadata dumping part.
err := LockTableNoWait(table, whichConn)
if err != nil {
if pgErr, ok := err.(*pgconn.PgError); ok && pgErr.Code != PG_LOCK_NOT_AVAILABLE {
lockErr := err
var pgErr *pgconn.PgError
if !errors.As(lockErr, &pgErr) || pgErr.Code != PG_LOCK_NOT_AVAILABLE {
isErroredBackup.Store(true)
err = connectionPool.Rollback(whichConn)
if err != nil {
gplog.Warn("Worker %d: %s", whichConn, err)
}
gplog.Fatal(fmt.Errorf("Unexpectedly unable to take lock on table %s, %s", table.FQN(), pgErr.Error()), "")
errMsg := lockErr.Error()
if pgErr != nil {
errMsg = pgErr.Error()
}
gplog.Fatal(fmt.Errorf("Unexpectedly unable to take lock on table %s, %s", table.FQN(), errMsg), "")
}
if gplog.GetVerbosity() < gplog.LOGVERBOSE {
// Add a newline to interrupt the progress bar so that
Expand Down
64 changes: 54 additions & 10 deletions end_to_end/end_to_end_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/apache/cloudberry-go-libs/operating"
"github.com/apache/cloudberry-go-libs/structmatcher"
"github.com/apache/cloudberry-go-libs/testhelper"
"github.com/blang/semver"
"github.com/blang/semver/v4"
_ "github.com/mattn/go-sqlite3"
"github.com/pkg/errors"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -1993,27 +1993,71 @@ 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",
"--backup-dir", backupDir,
"--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() {
Expand Down
2 changes: 1 addition & 1 deletion end_to_end/incremental_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/apache/cloudberry-backup/history"
"github.com/apache/cloudberry-go-libs/dbconn"
"github.com/apache/cloudberry-go-libs/testhelper"
"github.com/blang/semver"
"github.com/blang/semver/v4"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down
Loading
Loading