@@ -11,10 +11,12 @@ import (
1111 "google.golang.org/protobuf/proto"
1212
1313 "github.com/PeerDB-io/peerdb/flow/connectors"
14+ connmysql "github.com/PeerDB-io/peerdb/flow/connectors/mysql"
1415 "github.com/PeerDB-io/peerdb/flow/generated/proto_conversions"
1516 "github.com/PeerDB-io/peerdb/flow/generated/protos"
1617 "github.com/PeerDB-io/peerdb/flow/internal"
1718 "github.com/PeerDB-io/peerdb/flow/pkg/common"
19+ mysql_validation "github.com/PeerDB-io/peerdb/flow/pkg/mysql"
1820 "github.com/PeerDB-io/peerdb/flow/shared"
1921 "github.com/PeerDB-io/peerdb/flow/shared/types"
2022)
@@ -186,6 +188,25 @@ func (h *FlowRequestHandler) checkSourcePeerReuse(
186188 return nil
187189 }
188190
191+ // beyond other PeerDB mirrors (checked below), the pinned server_id must not be already registered
192+ // as a replica on the source DB itself.
193+ mysqlConn , mysqlClose , err := connectors .GetAs [* connmysql.MySqlConnector ](ctx , cfg .Env , peer )
194+ if err != nil {
195+ return NewInternalApiError (fmt .Errorf ("failed to create MySQL connector for source peer %s: %w" , cfg .SourceName , err ))
196+ }
197+ defer mysqlClose (ctx )
198+
199+ if inUse , err := mysql_validation .HasReplicaWithServerId (mysqlConn .Conn (), * mysqlCfg .ServerId ); err != nil {
200+ return NewInternalApiError (fmt .Errorf ("failed to check replicas registered on source peer %s: %w" , cfg .SourceName , err ))
201+ } else if inUse {
202+ return NewFailedPreconditionApiError (
203+ fmt .Errorf ("source peer %q pins server_id=%d, which is already in use by a replica registered on the source database" ,
204+ cfg .SourceName , * mysqlCfg .ServerId ),
205+ NewMirrorErrorInfo (map [string ]string {
206+ common .ErrorMetadataOffendingField : "source_name" ,
207+ }))
208+ }
209+
189210 // CDC flows for this source peer other than the mirror being validated.
190211 // query_string IS NULL filters out QRep flows, which do
191212 // not stream the binlog.
0 commit comments