File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -753,6 +753,17 @@ type Config struct {
753753 // in the Progress. This behaviour is perfectly okay and doesn't mean there are no rows being written
754754 // to the target DB.
755755 EnableRowBatchSize bool
756+
757+ // If the target DB is set to read_only ghostferry will throw an error during the initialization step.
758+ // AllowSuperUserOnReadOnly flag allows to run ghostferry even if the target DB is read_only. This is helpful in
759+ // scenarios where target DB needs to be restricted from writes made by any other user then the ghostferry user.
760+ //
761+ // Optional: Defaults to false.
762+ //
763+ // NOTE:
764+ // The ghostferry target user should have SUPER permissions to actually write to the target DB,
765+ // if ghostferry is ran with AllowSuperUserOnReadOnly = true and the target DB is set to read_only.
766+ AllowSuperUserOnReadOnly bool
756767}
757768
758769func (c * Config ) ValidateConfig () error {
Original file line number Diff line number Diff line change @@ -375,13 +375,15 @@ func (f *Ferry) Initialize() (err error) {
375375 return err
376376 }
377377
378- isReplica , err := CheckDbIsAReplica (f .TargetDB )
379- if err != nil {
380- f .logger .WithError (err ).Error ("cannot check if target db is writable" )
381- return err
382- }
383- if isReplica {
384- return fmt .Errorf ("@@read_only must be OFF on target db" )
378+ if ! f .Config .AllowSuperUserOnReadOnly {
379+ isReplica , err := CheckDbIsAReplica (f .TargetDB )
380+ if err != nil {
381+ f .logger .WithError (err ).Error ("cannot check if target db is writable" )
382+ return err
383+ }
384+ if isReplica {
385+ return fmt .Errorf ("@@read_only must be OFF on target db" )
386+ }
385387 }
386388
387389 // Check if we're running from a replica or not and sanity check
Original file line number Diff line number Diff line change @@ -34,6 +34,20 @@ func (t *FerryTestSuite) TestReadOnlyDatabaseFailsInitialization() {
3434 t .Require ().Nil (err )
3535}
3636
37+ func (t * FerryTestSuite ) TestReadOnlyDatabaseDoesNotFailInitializationWithAllowSuperUserOnReadOnlyFlag () {
38+ _ , err := t .Ferry .TargetDB .Exec ("SET GLOBAL read_only = ON" )
39+ t .Require ().Nil (err )
40+
41+ ferry := testhelpers .NewTestFerry ().Ferry
42+ ferry .Config .AllowSuperUserOnReadOnly = true
43+
44+ err = ferry .Initialize ()
45+ t .Require ().Nil (err )
46+
47+ _ , err = t .Ferry .TargetDB .Exec ("SET GLOBAL read_only = OFF" )
48+ t .Require ().Nil (err )
49+ }
50+
3751func (t * FerryTestSuite ) TestSourceDatabaseWithForeignKeyConstraintFailsInitialization () {
3852 createTableWithFkConstraint := `
3953 CREATE TABLE gftest.test_fk (
You can’t perform that action at this time.
0 commit comments