Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyObjects(ctx context.Context, taskID string, accountID uint32, ...) (err error)
- func BuildBloomFilterFromObjectMap(objectMap map[objectio.ObjectId]*ObjectWithTableInfo, mp *mpool.MPool) (string, error)
- func CheckIterationStatus(ctx context.Context, executor SQLExecutor, taskID string, ...) error
- func CheckStateBeforeUpdate(ctx context.Context, executor SQLExecutor, taskID string, ...) error
- func CleanPrevData(ctx context.Context, cnEngine engine.Engine, executor SQLExecutor, ...) error
- func ExecuteIteration(ctx context.Context, cnUUID string, cnEngine engine.Engine, ...) (err error)
- func FillDDLOperation(ctx context.Context, cnEngine engine.Engine, ...) (err error)
- func GC(ctx context.Context, txnEngine engine.Engine, cnTxnClient client.TxnClient, ...) (err error)
- func GCSnapshots(ctx context.Context, txnEngine engine.Engine, cnTxnClient client.TxnClient, ...) error
- func GenerateSnapshotName(taskID string, iterationLSN uint64) string
- func GetBloomFilterExpectedItems() int
- func GetBloomFilterFalsePositiveRate() float64
- func GetFilterObjectWorkerThread() int
- func GetGCInterval() time.Duration
- func GetGCTTL() time.Duration
- func GetGetChunkMaxMemory() int64
- func GetGetChunkSize() int64
- func GetGetChunkWorkerThread() int
- func GetObjectListMap(ctx context.Context, iterationCtx *IterationContext, cnEngine engine.Engine) (map[objectio.ObjectId]*ObjectWithTableInfo, error)
- func GetPublicationWorkerThread() int
- func GetRetryInterval() time.Duration
- func GetRetryThreshold() int
- func GetRetryTimes() int
- func GetSyncProtectionRenewInterval() time.Duration
- func GetSyncProtectionTTLDuration() time.Duration
- func GetSyncTaskInterval() time.Duration
- func GetUpstreamDDLUsingGetDdl(ctx context.Context, iterationCtx *IterationContext) (map[string]map[string]*TableDDLInfo, error)
- func GetWriteObjectWorkerThread() int
- func IsGCRunningError(err error) bool
- func IsRetryableError(err error) bool
- func IsSyncProtectionExistsError(err error) bool
- func IsSyncProtectionInvalidError(err error) bool
- func IsSyncProtectionMaxCountError(err error) bool
- func IsSyncProtectionNotFoundError(err error) bool
- func IsSyncProtectionSoftDeleteError(err error) bool
- func ProcessDDLChanges(ctx context.Context, cnEngine engine.Engine, iterationCtx *IterationContext) error
- func PublicationTaskExecutorFactory(txnEngine engine.Engine, cnTxnClient client.TxnClient, ...) func(ctx context.Context, task task.Task) (err error)
- func RegisterSyncProtection(ctx context.Context, executor SQLExecutor, jobID string, bfBase64 string, ...) error
- func RegisterSyncProtectionOnDownstream(ctx context.Context, downstreamExecutor SQLExecutor, ...) (jobID string, ttlExpireTS int64, retryable bool, err error)
- func RegisterSyncProtectionWithRetry(ctx context.Context, downstreamExecutor SQLExecutor, ...) (jobID string, ttlExpireTS int64, err error)
- func ReleaseAObjectMapping(mapping *AObjectMapping)
- func ReleaseFilterObjectJob(job *FilterObjectJob)
- func ReleaseFilterObjectJobResult(res *FilterObjectJobResult)
- func ReleaseGetChunkJob(job *GetChunkJob)
- func ReleaseGetChunkJobResult(res *GetChunkJobResult)
- func ReleaseGetMetaJob(job *GetMetaJob)
- func ReleaseGetMetaJobResult(res *GetMetaJobResult)
- func ReleaseWriteObjectJob(job *WriteObjectJob)
- func ReleaseWriteObjectJobResult(res *WriteObjectJobResult)
- func RenewSyncProtection(ctx context.Context, executor SQLExecutor, jobID string, ttlExpireTS int64) error
- func RequestUpstreamSnapshot(ctx context.Context, iterationCtx *IterationContext) error
- func SetGetParameterUnitWrapper(fn func(cnUUID string) *config.ParameterUnit)
- func SetGlobalConfig(cfg *CCPRConfig) error
- func SetGlobalMemoryController(mc *MemoryController)
- func UnregisterSyncProtection(ctx context.Context, executor SQLExecutor, jobID string) error
- func UpdateGlobalConfig(updater func(*CCPRConfig)) error
- func UpdateIterationState(ctx context.Context, executor SQLExecutor, taskID string, iterationState int8, ...) error
- func UpdateIterationStateNoSubscriptionState(ctx context.Context, executor SQLExecutor, taskID string, iterationState int8, ...) error
- func WaitForSnapshotFlushed(ctx context.Context, iterationCtx *IterationContext, interval time.Duration, ...) error
- type AObjectMap
- type AObjectMapping
- type AObjectMappingJSON
- type ActiveRoutine
- type AlterInplaceType
- type BackoffStrategy
- type CCPRConfig
- type CCPRTxnCacheWriter
- type CommitErrorClassifier
- type DatabaseMetadata
- type DefaultClassifier
- type DownstreamCommitClassifier
- type DownstreamConnectionClassifier
- type ErrorClassifier
- type ErrorMetadata
- type ExecutorRetryOption
- type ExponentialBackoff
- type FilterObjectJob
- type FilterObjectJobResult
- type FilterObjectResult
- type FilterObjectWorker
- type GCRunningClassifier
- type GCStatus
- type GetChunkJob
- type GetChunkJobDuration
- type GetChunkJobInfo
- type GetChunkJobResult
- type GetChunkWorker
- type GetMetaJob
- type GetMetaJobResult
- type InternalResult
- type InternalSQLExecutor
- func (e *InternalSQLExecutor) Close() error
- func (e *InternalSQLExecutor) Connect() error
- func (e *InternalSQLExecutor) EndTxn(ctx context.Context, commit bool) error
- func (e *InternalSQLExecutor) ExecSQL(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, ...) (*Result, context.CancelFunc, error)
- func (e *InternalSQLExecutor) ExecSQLInDatabase(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, ...) (*Result, context.CancelFunc, error)
- func (e *InternalSQLExecutor) GetInternalExec() executor.SQLExecutor
- func (e *InternalSQLExecutor) GetTxnClient() client.TxnClient
- func (e *InternalSQLExecutor) SetTxn(txnOp client.TxnOperator)
- func (e *InternalSQLExecutor) SetUTHelper(helper UTHelper)
- func (e *InternalSQLExecutor) SetUpstreamSQLHelper(helper UpstreamSQLHelper)
- type IterationContext
- type IterationContextJSON
- type Job
- type JobStats
- func (s *JobStats) DecrementFilterObjectRunning()
- func (s *JobStats) DecrementGetChunkRunning()
- func (s *JobStats) DecrementGetMetaRunning()
- func (s *JobStats) DecrementWriteObjectRunning()
- func (s *JobStats) GetTopGetChunkDurations() []*GetChunkJobDuration
- func (s *JobStats) GetTopWriteObjectDurations() []*WriteObjectJobDuration
- func (s *JobStats) IncrementFilterObjectPending()
- func (s *JobStats) IncrementFilterObjectRunning()
- func (s *JobStats) IncrementGetChunkPending()
- func (s *JobStats) IncrementGetChunkRunning()
- func (s *JobStats) IncrementGetMetaPending()
- func (s *JobStats) IncrementGetMetaRunning()
- func (s *JobStats) IncrementWriteObjectPending()
- func (s *JobStats) IncrementWriteObjectRunning()
- func (s *JobStats) RecordGetChunkDuration(objectName string, chunkIndex int64, duration time.Duration)
- func (s *JobStats) RecordWriteObjectDuration(objectName string, size int64, duration time.Duration)
- func (s *JobStats) ResetTopGetChunkDurations()
- func (s *JobStats) ResetTopWriteObjectDurations()
- type MemoryController
- type MemoryStats
- type MemoryType
- type MoCtlResponse
- type MoCtlResultEntry
- type MockResultScanner
- type MultiClassifier
- type MySQLErrorClassifier
- type ObjectStats
- type ObjectWithTableInfo
- type Operation
- type Policy
- type PublicationExecutorOption
- type PublicationTaskExecutor
- func (exec *PublicationTaskExecutor) Cancel() error
- func (exec *PublicationTaskExecutor) GCInMemoryTask(threshold time.Duration)
- func (exec *PublicationTaskExecutor) GetTask(taskID string) (TaskEntry, bool)
- func (exec *PublicationTaskExecutor) IsRunning() bool
- func (exec *PublicationTaskExecutor) Pause() error
- func (exec *PublicationTaskExecutor) Restart() error
- func (exec *PublicationTaskExecutor) Resume() error
- func (exec *PublicationTaskExecutor) Start() error
- func (exec *PublicationTaskExecutor) Stop()
- type Result
- type SQLExecutor
- type SQLExecutorRetryOption
- type SrcInfo
- type StaleReadClassifier
- type SyncProtectionResponse
- type SyncProtectionRetryOption
- type SyncProtectionTTLClassifier
- type TTLChecker
- type TableDDLInfo
- type TableKey
- type TableMetadata
- type TaskContext
- type TaskEntry
- type UTHelper
- type UTInjectionClassifier
- type UpstreamConnConfig
- type UpstreamConnectionClassifier
- type UpstreamExecutor
- func (e *UpstreamExecutor) Close() error
- func (e *UpstreamExecutor) Connect() error
- func (e *UpstreamExecutor) EndTxn(ctx context.Context, commit bool) error
- func (e *UpstreamExecutor) ExecSQL(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, ...) (*Result, context.CancelFunc, error)
- func (e *UpstreamExecutor) ExecSQLInDatabase(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, ...) (*Result, context.CancelFunc, error)
- type UpstreamSQLHelper
- type UpstreamSQLHelperFactory
- type Worker
- type WriteObjectJob
- type WriteObjectJobDuration
- type WriteObjectJobInfo
- type WriteObjectJobResult
- type WriteObjectWorker
Constants ¶
const ( // GetChunkSize is the default size of each chunk (100MB) GetChunkSize int64 = 100 * 1024 * 1024 // GetChunkMaxMemory is the default maximum memory for concurrent GetChunkJob operations (3GB) GetChunkMaxMemory int64 = 3 * 1024 * 1024 * 1024 )
Constants for backward compatibility (used by frontend/get_object.go)
const ( // These are kept for backward compatibility, prefer using config center DefaultRetryDuration = time.Minute * 10 SnapshotThreshold = time.Hour * 24 // 1 day SnapshotGCThreshold = time.Hour * 24 * 3 // 3 days for ccpr snapshot GC )
const ( JobTypeGetMeta int8 = 1 JobTypeGetChunk int8 = 2 JobTypeFilterObject int8 = 3 JobTypeWriteObject int8 = 4 )
Job types
const ( IterationStatePending int8 = 0 // 'pending' IterationStateRunning int8 = 1 // 'running' IterationStateCompleted int8 = 2 // 'complete' IterationStateError int8 = 3 // 'error' IterationStateCanceled int8 = 4 // 'cancel' )
IterationState represents the state of an iteration
const ( // Create CCPR snapshot SQL template // Uses standard CREATE SNAPSHOT syntax with FROM account PUBLICATION // Format: CREATE SNAPSHOT IF NOT EXISTS `snapshotName` FOR {ACCOUNT|DATABASE db|TABLE db table} FROM account PUBLICATION pubname PublicationCreateCcprSnapshotForAccountSqlTemplate = "CREATE SNAPSHOT IF NOT EXISTS `%s` FOR ACCOUNT FROM %s PUBLICATION %s" PublicationCreateCcprSnapshotForDatabaseSqlTemplate = "CREATE SNAPSHOT IF NOT EXISTS `%s` FOR DATABASE %s FROM %s PUBLICATION %s" PublicationCreateCcprSnapshotForTableSqlTemplate = "CREATE SNAPSHOT IF NOT EXISTS `%s` FOR TABLE %s %s FROM %s PUBLICATION %s" // Drop CCPR snapshot SQL template // Uses DROP SNAPSHOT FROM account PUBLICATION pubname syntax PublicationDropCcprSnapshotSqlTemplate = "DROP SNAPSHOT IF EXISTS `%s` FROM %s PUBLICATION %s" // Query mo_catalog tables SQL templates using internal command with publication permission check // Format: __++__internal_get_mo_indexes <tableId> <subscriptionAccountName> <publicationName> <snapshotName> PublicationQueryMoIndexesSqlTemplate = `__++__internal_get_mo_indexes %d %s %s %s` // Object list SQL template using internal command with publication permission check // Format: __++__internal_object_list <snapshotName> <againstSnapshotName> <subscriptionAccountName> <publicationName> // Note: againstSnapshotName can be "-" to indicate empty PublicationObjectListSqlTemplate = `__++__internal_object_list %s %s %s %s` // Get object SQL template using internal command with publication permission check // Format: __++__internal_get_object <subscriptionAccountName> <publicationName> <objectName> <chunkIndex> PublicationGetObjectSqlTemplate = `__++__internal_get_object %s %s %s %d` // Get DDL SQL template using internal command with publication permission check // Format: __++__internal_get_ddl <snapshotName> <subscriptionAccountName> <publicationName> <level> <dbName> <tableName> PublicationGetDdlSqlTemplate = `__++__internal_get_ddl %s %s %s %s %s %s` // Query mo_ccpr_log SQL template PublicationQueryMoCcprLogSqlTemplate = `SELECT ` + `cn_uuid, ` + `iteration_state, ` + `iteration_lsn, ` + `state ` + `FROM mo_catalog.mo_ccpr_log ` + `WHERE task_id = '%s'` // Query mo_ccpr_log full SQL template (includes subscription_name, subscription_account_name, sync_level, account_id, db_name, table_name, upstream_conn, context, error_message, state) PublicationQueryMoCcprLogFullSqlTemplate = `SELECT ` + `subscription_name, ` + `subscription_account_name, ` + `sync_level, ` + `account_id, ` + `db_name, ` + `table_name, ` + `upstream_conn, ` + `context, ` + `error_message, ` + `state ` + `FROM mo_catalog.mo_ccpr_log ` + `WHERE task_id = '%s'` // Query snapshot TS SQL template using internal command with publication permission check // Format: __++__internal_get_snapshot_ts <snapshotName> <accountName> <publicationName> PublicationQuerySnapshotTsSqlTemplate = `__++__internal_get_snapshot_ts %s %s %s` // Query databases covered by snapshot using internal command with publication permission check // Format: __++__internal_get_databases <snapshotName> <accountName> <publicationName> <level> <dbName> <tableName> PublicationGetDatabasesSqlTemplate = `__++__internal_get_databases %s %s %s %s %s %s` // Check snapshot flushed SQL template using internal command with publication permission check // Format: __++__internal_check_snapshot_flushed <snapshotName> <subscriptionAccountName> <publicationName> PublicationCheckSnapshotFlushedSqlTemplate = `__++__internal_check_snapshot_flushed %s %s %s` // Update mo_ccpr_log SQL template PublicationUpdateMoCcprLogSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `iteration_lsn = %d, ` + `context = '%s', ` + `error_message = '%s', ` + `state = %d ` + `WHERE task_id = '%s'` // Update mo_ccpr_log SQL template without context (preserves existing context value) PublicationUpdateMoCcprLogNoContextSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `iteration_lsn = %d, ` + `error_message = '%s', ` + `state = %d ` + `WHERE task_id = '%s'` // Update mo_ccpr_log iteration_state (and lsn) only PublicationUpdateMoCcprLogStateSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `iteration_lsn = %d, ` + `cn_uuid = '%s' ` + `WHERE task_id = '%s'` // Query mo_ccpr_log state before update SQL template PublicationQueryMoCcprLogStateBeforeUpdateSqlTemplate = `SELECT ` + `state, ` + `iteration_state, ` + `iteration_lsn ` + `FROM mo_catalog.mo_ccpr_log ` + `WHERE task_id = '%s'` // Update mo_ccpr_log without state SQL template (for successful iterations) PublicationUpdateMoCcprLogNoStateSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `iteration_lsn = %d, ` + `watermark = %d, ` + `context = '%s', ` + `error_message = '%s' ` + `WHERE task_id = '%s'` // Update mo_ccpr_log without state and context SQL template (for retryable errors) PublicationUpdateMoCcprLogNoStateNoContextSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `iteration_lsn = %d, ` + `watermark = %d, ` + `error_message = '%s' ` + `WHERE task_id = '%s'` // Update mo_ccpr_log iteration_state only PublicationUpdateMoCcprLogIterationStateOnlySqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d ` + `WHERE task_id = '%s'` // Update mo_ccpr_log iteration_state and cn_uuid (without lsn) PublicationUpdateMoCcprLogIterationStateAndCnUuidSqlTemplate = `UPDATE mo_catalog.mo_ccpr_log ` + `SET iteration_state = %d, ` + `cn_uuid = '%s' ` + `WHERE task_id = '%s'` // Sync protection SQL templates using mo_ctl internal commands // GC status query: SELECT mo_ctl('dn', 'diskcleaner', 'gc_status') // Returns: {"running": bool, "protections": int, "ts": int64} PublicationGCStatusSqlTemplate = `SELECT mo_ctl('dn', 'diskcleaner', 'gc_status')` // Register sync protection: SELECT mo_ctl('dn', 'diskcleaner', 'register_sync_protection.{"job_id": "xxx", "bf": "base64...", "ts": 123, "valid_ts": 456, "task_id": "taskID-123"}') // Returns: {"status": "ok"} or {"status": "error", "code": "ErrGCRunning", "message": "..."} PublicationRegisterSyncProtectionSqlTemplate = `` /* 134-byte string literal not displayed */ // Renew sync protection: SELECT mo_ctl('dn', 'diskcleaner', 'renew_sync_protection.{"job_id": "xxx", "valid_ts": 456}') // Returns: {"status": "ok"} or {"status": "error", "code": "ErrProtectionNotFound", "message": "..."} PublicationRenewSyncProtectionSqlTemplate = `SELECT mo_ctl('dn', 'diskcleaner', 'renew_sync_protection.{"job_id": "%s", "valid_ts": %d}')` // Unregister sync protection: SELECT mo_ctl('dn', 'diskcleaner', 'unregister_sync_protection.{"job_id": "xxx"}') // Returns: {"status": "ok"} PublicationUnregisterSyncProtectionSqlTemplate = `SELECT mo_ctl('dn', 'diskcleaner', 'unregister_sync_protection.{"job_id": "%s"}')` )
const ( PublicationQueryMoIndexesSqlTemplate_Idx = iota PublicationObjectListSqlTemplate_Idx PublicationGetObjectSqlTemplate_Idx PublicationGetDdlSqlTemplate_Idx PublicationQueryMoCcprLogSqlTemplate_Idx PublicationQueryMoCcprLogFullSqlTemplate_Idx PublicationQuerySnapshotTsSqlTemplate_Idx PublicationGetDatabasesSqlTemplate_Idx PublicationUpdateMoCcprLogSqlTemplate_Idx PublicationUpdateMoCcprLogNoContextSqlTemplate_Idx PublicationUpdateMoCcprLogStateSqlTemplate_Idx PublicationCheckSnapshotFlushedSqlTemplate_Idx PublicationQueryMoCcprLogStateBeforeUpdateSqlTemplate_Idx PublicationUpdateMoCcprLogNoStateSqlTemplate_Idx PublicationUpdateMoCcprLogNoStateNoContextSqlTemplate_Idx PublicationUpdateMoCcprLogIterationStateOnlySqlTemplate_Idx PublicationUpdateMoCcprLogIterationStateAndCnUuidSqlTemplate_Idx PublicationSqlTemplateCount )
const ( SyncLevelAccount = "account" SyncLevelDatabase = "database" SyncLevelTable = "table" )
SyncLevel represents the level of synchronization
const ( DDLOperationCreate int8 = 1 DDLOperationAlter int8 = 2 DDLOperationDrop int8 = 3 DDLOperationAlterInplace int8 = 4 )
DDL operation types
const ( SubscriptionStateRunning int8 = 0 // running SubscriptionStateError int8 = 1 // error SubscriptionStatePause int8 = 2 // pause SubscriptionStateDropped int8 = 3 // dropped )
Subscription state types
const ( SubmitRetryTimes = 1000 SubmitRetryDuration = time.Hour StatsPrintInterval = 10 * time.Second )
const (
InternalSQLExecutorType = "internal_sql_executor"
)
const InvalidAccountID uint32 = 0xFFFFFFFF
InvalidAccountID represents an invalid account ID that should be ignored
const (
MOCcprLogTableName = catalog.MO_CCPR_LOG
)
Variables ¶
var CheckLeaseWithRetry = func( ctx context.Context, cnUUID string, txnEngine engine.Engine, cnTxnClient client.TxnClient, ) (ok bool, err error) { defer func() { if err != nil || !ok { logutil.Error( "Publication-Task check lease failed", zap.Error(err), zap.Bool("ok", ok), zap.String("cnUUID", cnUUID), ) } }() err = retryPublication( ctx, func() error { ok, err = checkLease(ctx, cnUUID, txnEngine, cnTxnClient) return err }, DefaultExecutorRetryOption(), ) return }
var CollectChanges = func(ctx context.Context, rel engine.Relation, fromTs, toTs types.TS, mp *mpool.MPool) (engine.ChangesHandle, error) { return rel.CollectChanges(ctx, fromTs, toTs, false, mp) }
Helper functions that need to be implemented or imported
var ErrNonRetryable = moerr.NewInternalErrorNoCtx("non-retryable error")
ErrNonRetryable indicates the operation should not be retried.
var ErrSyncProtectionTTLExpired = moerr.NewInternalErrorNoCtx("sync protection TTL expired")
ErrSyncProtectionTTLExpired is returned when sync protection TTL has expired
var ExecWithResult = func( ctx context.Context, sql string, cnUUID string, txn client.TxnOperator, ) (executor.Result, error) { v, ok := moruntime.ServiceRuntime(cnUUID).GetGlobalVariables(moruntime.InternalSQLExecutor) if !ok { return executor.Result{}, moerr.NewInternalErrorNoCtx("missing internal sql executor") } exec := v.(executor.SQLExecutor) opts := executor.Options{}. WithDisableIncrStatement(). WithTxn(txn) return exec.Exec(ctx, sql, opts) }
var GetObjectFromUpstreamWithWorker = func( ctx context.Context, upstreamExecutor SQLExecutor, objectName string, getChunkWorker GetChunkWorker, subscriptionAccountName string, pubName string, ) ([]byte, error) { if upstreamExecutor == nil { return nil, moerr.NewInternalError(ctx, "upstream executor is nil") } metaResult, err := getMetaWithRetry(ctx, upstreamExecutor, objectName, getChunkWorker, subscriptionAccountName, pubName) if err != nil { return nil, err } totalChunks := metaResult.TotalChunks allChunks := make([][]byte, totalChunks) chunkJobs := make([]*GetChunkJob, totalChunks) for i := int64(1); i <= totalChunks; i++ { chunkJob := NewGetChunkJob(ctx, upstreamExecutor, objectName, i, subscriptionAccountName, pubName) chunkJobs[i-1] = chunkJob if getChunkWorker != nil { getChunkWorker.SubmitGetChunk(chunkJob) } else { chunkJob.Execute() } } for i := int64(0); i < totalChunks; i++ { chunkResult := chunkJobs[i].WaitDone().(*GetChunkJobResult) if chunkResult.Err != nil { chunkData, err := getChunkWithRetry(ctx, upstreamExecutor, objectName, i+1, getChunkWorker, subscriptionAccountName, pubName) if err != nil { return nil, err } allChunks[i] = chunkData } else { allChunks[i] = chunkResult.ChunkData } } totalLen := 0 for _, chunk := range allChunks { totalLen += len(chunk) } objectContent := make([]byte, 0, totalLen) for _, chunk := range allChunks { objectContent = append(objectContent, chunk...) } return objectContent, nil }
GetObjectFromUpstreamWithWorker gets object file from upstream using GETOBJECT SQL with worker pool
var PublicationSQLBuilder = publicationSQLBuilder{}
var PublicationSQLTemplates = [PublicationSqlTemplateCount]struct { SQL string OutputAttrs []string }{ PublicationQueryMoIndexesSqlTemplate_Idx: { SQL: PublicationQueryMoIndexesSqlTemplate, OutputAttrs: []string{ "table_id", "name", "algo_table_type", "index_table_name", }, }, PublicationObjectListSqlTemplate_Idx: { SQL: PublicationObjectListSqlTemplate, }, PublicationGetObjectSqlTemplate_Idx: { SQL: PublicationGetObjectSqlTemplate, }, PublicationGetDdlSqlTemplate_Idx: { SQL: PublicationGetDdlSqlTemplate, }, PublicationQueryMoCcprLogSqlTemplate_Idx: { SQL: PublicationQueryMoCcprLogSqlTemplate, OutputAttrs: []string{ "cn_uuid", "iteration_state", "iteration_lsn", "state", }, }, PublicationQueryMoCcprLogFullSqlTemplate_Idx: { SQL: PublicationQueryMoCcprLogFullSqlTemplate, OutputAttrs: []string{ "subscription_name", "subscription_account_name", "sync_level", "account_id", "db_name", "table_name", "upstream_conn", "context", "error_message", }, }, PublicationQuerySnapshotTsSqlTemplate_Idx: { SQL: PublicationQuerySnapshotTsSqlTemplate, OutputAttrs: []string{ "ts", }, }, PublicationGetDatabasesSqlTemplate_Idx: { SQL: PublicationGetDatabasesSqlTemplate, OutputAttrs: []string{ "datname", }, }, PublicationUpdateMoCcprLogSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogSqlTemplate, }, PublicationUpdateMoCcprLogNoContextSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogNoContextSqlTemplate, }, PublicationUpdateMoCcprLogStateSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogStateSqlTemplate, }, PublicationCheckSnapshotFlushedSqlTemplate_Idx: { SQL: PublicationCheckSnapshotFlushedSqlTemplate, }, PublicationQueryMoCcprLogStateBeforeUpdateSqlTemplate_Idx: { SQL: PublicationQueryMoCcprLogStateBeforeUpdateSqlTemplate, OutputAttrs: []string{ "state", "iteration_state", "iteration_lsn", }, }, PublicationUpdateMoCcprLogNoStateSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogNoStateSqlTemplate, }, PublicationUpdateMoCcprLogNoStateNoContextSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogNoStateNoContextSqlTemplate, }, PublicationUpdateMoCcprLogIterationStateOnlySqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogIterationStateOnlySqlTemplate, }, PublicationUpdateMoCcprLogIterationStateAndCnUuidSqlTemplate_Idx: { SQL: PublicationUpdateMoCcprLogIterationStateAndCnUuidSqlTemplate, }, }
var RegisterSyncProtectionOnDownstreamFn = func( ctx context.Context, downstreamExecutor SQLExecutor, objectMap map[objectio.ObjectId]*ObjectWithTableInfo, mp *mpool.MPool, taskID string, ) (jobID string, ttlExpireTS int64, retryable bool, err error) { return registerSyncProtectionOnDownstreamImpl(ctx, downstreamExecutor, objectMap, mp, taskID) }
RegisterSyncProtectionOnDownstreamFn is a function variable that can be stubbed in tests
Functions ¶
func ApplyObjects ¶
func ApplyObjects( ctx context.Context, taskID string, accountID uint32, indexTableMappings map[string]string, objectMap map[objectio.ObjectId]*ObjectWithTableInfo, upstreamExecutor SQLExecutor, localExecutor SQLExecutor, currentTS types.TS, txn client.TxnOperator, cnEngine engine.Engine, mp *mpool.MPool, fs fileservice.FileService, filterObjectWorker FilterObjectWorker, getChunkWorker GetChunkWorker, writeObjectWorker WriteObjectWorker, subscriptionAccountName string, pubName string, ccprCache CCPRTxnCacheWriter, aobjectMap *AObjectMap, ttlChecker TTLChecker, ) (err error)
ApplyObjects applies object changes to the downstream cluster
func BuildBloomFilterFromObjectMap ¶
func BuildBloomFilterFromObjectMap(objectMap map[objectio.ObjectId]*ObjectWithTableInfo, mp *mpool.MPool) (string, error)
BuildBloomFilterFromObjectMap builds a bloom filter from the object map using object name strings TODO(M4): Bloom filter false positive rate may cause unnecessary GC protection retention. Consider evaluating the impact and tuning parameters, or using an exact-match structure when the object count is small enough.
func CheckIterationStatus ¶
func CheckIterationStatus( ctx context.Context, executor SQLExecutor, taskID string, expectedCNUUID string, expectedIterationLSN uint64, ) error
CheckIterationStatus checks the iteration status in mo_ccpr_log table It verifies that cn_uuid, iteration_lsn match the expected values, and that iteration_state is pending If all checks pass, it updates iteration_state to running using the existing executor
func CheckStateBeforeUpdate ¶
func CheckStateBeforeUpdate( ctx context.Context, executor SQLExecutor, taskID string, expectedIterationLSN uint64, ) error
CheckStateBeforeUpdate checks the state, iteration_state, and iteration_lsn in mo_ccpr_log table before update It verifies that state is running, iteration_state is running, and iteration_lsn matches the expected value This check uses a separate executor (new transaction) to ensure isolation
func CleanPrevData ¶
func CleanPrevData( ctx context.Context, cnEngine engine.Engine, executor SQLExecutor, txn client.TxnOperator, taskID string, accountID uint32, ) error
CleanPrevData cleans previous data by dropping all tables and databases associated with the given task_id. It queries mo_ccpr_tables and mo_ccpr_dbs to get the table IDs, database IDs, and their names, then drops them. Tables are dropped first, then databases.
func ExecuteIteration ¶
func ExecuteIteration( ctx context.Context, cnUUID string, cnEngine engine.Engine, cnTxnClient client.TxnClient, taskID string, iterationLSN uint64, upstreamSQLHelperFactory UpstreamSQLHelperFactory, mp *mpool.MPool, utHelper UTHelper, snapshotFlushInterval time.Duration, filterObjectWorker FilterObjectWorker, getChunkWorker GetChunkWorker, writeObjectWorker WriteObjectWorker, syncProtectionWorker Worker, syncProtectionRetryOpt *SyncProtectionRetryOption, sqlExecutorRetryOpts ...*SQLExecutorRetryOption, ) (err error)
ExecuteIteration executes a complete iteration according to the design document It follows the sequence: initialization -> DDL -> snapshot diff -> object processing -> cleanup -> update system table
Parameters:
- snapshotFlushInterval: interval between retries when waiting for snapshot to be flushed (default: 1min if 0)
- syncProtectionWorker: worker for sync protection keepalive management
- syncProtectionRetryOpt: retry options for sync protection registration (nil to use default: 1s initial, 5min total)
- sqlExecutorRetryOpts: retry options for SQL executor operations (nil to use default)
func FillDDLOperation ¶
func FillDDLOperation( ctx context.Context, cnEngine engine.Engine, ddlMap map[string]map[string]*TableDDLInfo, tableIDs map[TableKey]uint64, txn client.TxnOperator, iterationCtx *IterationContext, ) (err error)
FillDDLOperation fills DDL operation type for each table in the ddlMap It determines the operation type (DDLOperationCreate, DDLOperationAlter, DDLOperationDrop) based on table existence and ID comparison: - If table doesn't exist and table ID doesn't exist in TableIDs: DDLOperationCreate - If table doesn't exist but table ID exists in TableIDs: DDLOperationAlter - If table exists but table ID changed: DDLOperationDrop (then will be followed by create) - If table exists and ID matches: empty string (no operation needed) Additionally, it traverses local tables based on iterationCtx.SrcInfo and marks tables that exist locally but not in ddlMap as DDLOperationDrop The ddlMap is modified in-place with operation types filled
func GCSnapshots ¶
func GCSnapshots( ctx context.Context, txnEngine engine.Engine, cnTxnClient client.TxnClient, cnUUID string, ) error
GCSnapshots deletes old ccpr snapshots that are older than the threshold (3 days)
func GenerateSnapshotName ¶
GenerateSnapshotName generates a snapshot name using a rule-based encoding Format: ccpr_<taskID>_<iterationLSN>
func GetBloomFilterExpectedItems ¶
func GetBloomFilterExpectedItems() int
GetBloomFilterExpectedItems returns the configured bloom filter expected items
func GetBloomFilterFalsePositiveRate ¶
func GetBloomFilterFalsePositiveRate() float64
GetBloomFilterFalsePositiveRate returns the configured bloom filter false positive rate
func GetFilterObjectWorkerThread ¶
func GetFilterObjectWorkerThread() int
GetFilterObjectWorkerThread returns the configured filter object worker thread count
func GetGCInterval ¶
GetGCInterval returns the configured GC interval
func GetGetChunkMaxMemory ¶
func GetGetChunkMaxMemory() int64
GetGetChunkMaxMemory returns the configured max memory for chunk operations
func GetGetChunkSize ¶
func GetGetChunkSize() int64
GetGetChunkSize returns the configured chunk size
func GetGetChunkWorkerThread ¶
func GetGetChunkWorkerThread() int
GetGetChunkWorkerThread returns the configured get chunk worker thread count
func GetObjectListMap ¶
func GetObjectListMap(ctx context.Context, iterationCtx *IterationContext, cnEngine engine.Engine) (map[objectio.ObjectId]*ObjectWithTableInfo, error)
GetObjectListMap retrieves the object list from snapshot diff and returns a map
func GetPublicationWorkerThread ¶
func GetPublicationWorkerThread() int
GetPublicationWorkerThread returns the configured publication worker thread count
func GetRetryInterval ¶
GetRetryInterval returns the configured retry interval
func GetRetryThreshold ¶
func GetRetryThreshold() int
GetRetryThreshold returns the configured retry threshold
func GetSyncProtectionRenewInterval ¶
GetSyncProtectionRenewInterval returns the configured sync protection renew interval
func GetSyncProtectionTTLDuration ¶
GetSyncProtectionTTLDuration returns the configured sync protection TTL duration
func GetSyncTaskInterval ¶
GetSyncTaskInterval returns the configured sync task interval
func GetUpstreamDDLUsingGetDdl ¶
func GetUpstreamDDLUsingGetDdl( ctx context.Context, iterationCtx *IterationContext, ) (map[string]map[string]*TableDDLInfo, error)
GetUpstreamDDLUsingGetDdl queries upstream DDL using internal GETDDL command Uses internal command: __++__internal_get_ddl <snapshotName> <subscriptionAccountName> <publicationName> The internal command checks publication permission and uses the snapshot's level to determine dbName and tableName scope Returns a map: map[dbname][table name] *TableDDLInfo{TableID, TableCreateSQL}
func GetWriteObjectWorkerThread ¶
func GetWriteObjectWorkerThread() int
GetWriteObjectWorkerThread returns the configured write object worker thread count
func IsGCRunningError ¶
IsGCRunningError checks if the error is a GC running error
func IsRetryableError ¶
IsRetryableError determines if an error is retryable Returns true if the error is a transient error that may succeed on retry, such as network errors, timeouts, or temporary system unavailability This function uses DownstreamCommitClassifier for consistency
func IsSyncProtectionExistsError ¶
IsSyncProtectionExistsError checks if the error indicates sync protection already exists
func IsSyncProtectionInvalidError ¶
IsSyncProtectionInvalidError checks if the error indicates invalid sync protection request
func IsSyncProtectionMaxCountError ¶
IsSyncProtectionMaxCountError checks if the error indicates max count reached
func IsSyncProtectionNotFoundError ¶
IsSyncProtectionNotFoundError checks if the error indicates sync protection not found
func IsSyncProtectionSoftDeleteError ¶
IsSyncProtectionSoftDeleteError checks if the error indicates sync protection is soft deleted
func ProcessDDLChanges ¶
func ProcessDDLChanges( ctx context.Context, cnEngine engine.Engine, iterationCtx *IterationContext, ) error
ProcessDDLChanges processes DDL changes by: 1. Getting database differences (databases to create and drop) 2. Creating databases that exist upstream but not locally 3. Getting upstream DDL map using GetUpstreamDDLUsingGetDdl 4. Filling DDL operations using FillDDLOperation 5. Executing DDL operations for tables with non-empty operations:
- create/drop: execute directly
- alter: drop first, then create
6. Dropping databases that exist locally but not upstream
func PublicationTaskExecutorFactory ¶
func PublicationTaskExecutorFactory( txnEngine engine.Engine, cnTxnClient client.TxnClient, attachToTask func(context.Context, uint64, taskservice.ActiveRoutine) error, cdUUID string, mp *mpool.MPool, upstreamSQLHelperFactory UpstreamSQLHelperFactory, pu *config.ParameterUnit, ) func(ctx context.Context, task task.Task) (err error)
func RegisterSyncProtection ¶
func RegisterSyncProtection( ctx context.Context, executor SQLExecutor, jobID string, bfBase64 string, gcTS int64, ttlExpireTS int64, taskID string, ) error
RegisterSyncProtection registers a sync protection with the upstream GC
func RegisterSyncProtectionOnDownstream ¶
func RegisterSyncProtectionOnDownstream( ctx context.Context, downstreamExecutor SQLExecutor, objectMap map[objectio.ObjectId]*ObjectWithTableInfo, mp *mpool.MPool, taskID string, ) (jobID string, ttlExpireTS int64, retryable bool, err error)
RegisterSyncProtectionOnDownstream registers sync protection on the downstream cluster It generates a new UUID for the jobID and sends all commands to downstream No retry is performed here - executor already has retry mechanism Returns retryable=true if the error is retriable (GC running, max count reached)
func RegisterSyncProtectionWithRetry ¶
func RegisterSyncProtectionWithRetry( ctx context.Context, downstreamExecutor SQLExecutor, objectMap map[objectio.ObjectId]*ObjectWithTableInfo, mp *mpool.MPool, retryOpt *SyncProtectionRetryOption, taskID string, ) (jobID string, ttlExpireTS int64, err error)
RegisterSyncProtectionWithRetry registers sync protection with timeout-based retry Similar to WaitForSnapshotFlushed, it retries on ErrGCRunning and ErrMaxCountReached until the total timeout is reached.
TODO(LOW): Current sync protection is at the object level via bloom filter. Consider adding table-level merge exclusion to prevent merges on downstream tables during active replication, which could cause object ID conflicts.
Parameters:
- ctx: context for cancellation
- downstreamExecutor: SQL executor for downstream cluster
- objectMap: map of objects to protect
- mp: memory pool
- retryOpt: retry options (nil to use default: 1s initial, 5min total timeout)
- taskID: CCPR iteration task ID with LSN (e.g., "taskID-123")
Returns:
- jobID: the registered job ID
- ttlExpireTS: the TTL expiration timestamp
- err: error if registration failed after all retries
func ReleaseAObjectMapping ¶
func ReleaseAObjectMapping(mapping *AObjectMapping)
ReleaseAObjectMapping returns an AObjectMapping to the pool
func ReleaseFilterObjectJob ¶
func ReleaseFilterObjectJob(job *FilterObjectJob)
ReleaseFilterObjectJob returns a FilterObjectJob to the pool
func ReleaseFilterObjectJobResult ¶
func ReleaseFilterObjectJobResult(res *FilterObjectJobResult)
ReleaseFilterObjectJobResult returns a FilterObjectJobResult to the pool
func ReleaseGetChunkJob ¶
func ReleaseGetChunkJob(job *GetChunkJob)
ReleaseGetChunkJob returns a GetChunkJob to the pool
func ReleaseGetChunkJobResult ¶
func ReleaseGetChunkJobResult(res *GetChunkJobResult)
ReleaseGetChunkJobResult returns a GetChunkJobResult to the pool
func ReleaseGetMetaJob ¶
func ReleaseGetMetaJob(job *GetMetaJob)
ReleaseGetMetaJob returns a GetMetaJob to the pool
func ReleaseGetMetaJobResult ¶
func ReleaseGetMetaJobResult(res *GetMetaJobResult)
ReleaseGetMetaJobResult returns a GetMetaJobResult to the pool
func ReleaseWriteObjectJob ¶
func ReleaseWriteObjectJob(job *WriteObjectJob)
ReleaseWriteObjectJob returns a WriteObjectJob to the pool
func ReleaseWriteObjectJobResult ¶
func ReleaseWriteObjectJobResult(res *WriteObjectJobResult)
ReleaseWriteObjectJobResult returns a WriteObjectJobResult to the pool
func RenewSyncProtection ¶
func RenewSyncProtection( ctx context.Context, executor SQLExecutor, jobID string, ttlExpireTS int64, ) error
RenewSyncProtection renews the TTL of a sync protection
func RequestUpstreamSnapshot ¶
func RequestUpstreamSnapshot( ctx context.Context, iterationCtx *IterationContext, ) error
RequestUpstreamSnapshot requests a snapshot from upstream cluster It creates a snapshot using CREATE SNAPSHOT SQL and stores the snapshot name in the context Uses: CREATE SNAPSHOT IF NOT EXISTS `snapshotName` FOR {ACCOUNT|DATABASE|TABLE} FROM account PUBLICATION pubname
func SetGetParameterUnitWrapper ¶
func SetGetParameterUnitWrapper(fn func(cnUUID string) *config.ParameterUnit)
SetGetParameterUnitWrapper sets the wrapper function to get ParameterUnit from cnUUID This should be called during initialization to provide a way to get ParameterUnit
func SetGlobalConfig ¶
func SetGlobalConfig(cfg *CCPRConfig) error
SetGlobalConfig sets the global CCPR configuration This should be called during service initialization
func SetGlobalMemoryController ¶
func SetGlobalMemoryController(mc *MemoryController)
SetGlobalMemoryController sets the global memory controller instance
func UnregisterSyncProtection ¶
func UnregisterSyncProtection( ctx context.Context, executor SQLExecutor, jobID string, ) error
UnregisterSyncProtection unregisters a sync protection
func UpdateGlobalConfig ¶
func UpdateGlobalConfig(updater func(*CCPRConfig)) error
UpdateGlobalConfig updates specific fields in the global configuration This allows for runtime configuration updates
func UpdateIterationState ¶
func UpdateIterationState( ctx context.Context, executor SQLExecutor, taskID string, iterationState int8, iterationLSN uint64, iterationCtx *IterationContext, errorMessage string, useTxn bool, subscriptionState int8, updateContext bool, ) error
UpdateIterationState updates iteration state, iteration LSN, iteration context, error message, and subscription state in mo_ccpr_log table It serializes the relevant parts of IterationContext to JSON and updates the corresponding fields If updateContext is false, the context field will not be updated (preserves existing value)
func UpdateIterationStateNoSubscriptionState ¶
func UpdateIterationStateNoSubscriptionState( ctx context.Context, executor SQLExecutor, taskID string, iterationState int8, iterationLSN uint64, watermark int64, iterationCtx *IterationContext, useTxn bool, errorMessage string, updateContext bool, ) error
UpdateIterationStateNoSubscriptionState updates iteration state, iteration LSN, iteration context, and error message in mo_ccpr_log table It does NOT update the subscription state field - used for successful iterations If updateContext is false, the context field will not be updated (preserves existing value)
func WaitForSnapshotFlushed ¶
func WaitForSnapshotFlushed( ctx context.Context, iterationCtx *IterationContext, interval time.Duration, totalTimeout time.Duration, ) error
WaitForSnapshotFlushed waits for the snapshot to be flushed with fixed interval It checks if the snapshot is flushed, and if not, waits and retries interval: fixed wait time between retries (default: 1min) totalTimeout: total time to wait before giving up (default: 30min)
Types ¶
type AObjectMap ¶
type AObjectMap struct {
// contains filtered or unexported fields
}
AObjectMap stores the mapping from upstream aobj to downstream object stats Key: upstreamID (string), Value: *AObjectMapping This map is used to track appendable object transformations during CCPR sync
func NewAObjectMap ¶
func NewAObjectMap() *AObjectMap
NewAObjectMap creates a new AObjectMap instance
func (*AObjectMap) Delete ¶
func (am *AObjectMap) Delete(upstreamID string)
Delete removes the mapping for an upstream aobj
func (*AObjectMap) Get ¶
func (am *AObjectMap) Get(upstreamID string) (*AObjectMapping, bool)
Get retrieves the mapping for an upstream aobj
func (*AObjectMap) Range ¶
func (am *AObjectMap) Range(f func(upstreamID string, mapping *AObjectMapping))
Range iterates over all entries in the map, calling f for each. The callback receives a copy of each key-value pair.
func (*AObjectMap) Set ¶
func (am *AObjectMap) Set(upstreamID string, mapping *AObjectMapping)
Set stores or updates the mapping for an upstream aobj
type AObjectMapping ¶
type AObjectMapping struct {
DownstreamStats objectio.ObjectStats
IsTombstone bool
DBName string
TableName string
// RowOffsetMap maps original rowoffset to new rowoffset after sorting
// Key: original rowoffset, Value: new rowoffset
RowOffsetMap map[uint32]uint32
}
AObjectMapping represents a mapping from upstream aobj to downstream object stats
func AcquireAObjectMapping ¶
func AcquireAObjectMapping() *AObjectMapping
AcquireAObjectMapping gets an AObjectMapping from the pool
type AObjectMappingJSON ¶
type AObjectMappingJSON struct {
DownstreamStats string `json:"downstream_stats"` // ObjectStats as base64-encoded string
IsTombstone bool `json:"is_tombstone"`
DBName string `json:"db_name"`
TableName string `json:"table_name"`
}
AObjectMappingJSON represents the serializable part of AObjectMapping
type ActiveRoutine ¶
ActiveRoutine represents an active routine that can be paused or cancelled
func NewActiveRoutine ¶
func NewActiveRoutine() *ActiveRoutine
NewActiveRoutine creates a new ActiveRoutine
func (*ActiveRoutine) CloseCancel ¶
func (ar *ActiveRoutine) CloseCancel()
CloseCancel closes the cancel channel
func (*ActiveRoutine) ClosePause ¶
func (ar *ActiveRoutine) ClosePause()
ClosePause closes the pause channel
type AlterInplaceType ¶
type AlterInplaceType int
AlterInplaceType represents the type of inplace alter operation
const ( AlterInplaceDropForeignKey AlterInplaceType = iota AlterInplaceAddForeignKey AlterInplaceDropIndex AlterInplaceAddIndex AlterInplaceAlterIndexVisibility AlterInplaceAlterComment AlterInplaceRenameColumn )
type BackoffStrategy ¶
type BackoffStrategy interface {
// Next returns the wait duration before the given attempt (1-indexed).
Next(attempt int) time.Duration
}
BackoffStrategy calculates the waiting duration before the next retry attempt.
type CCPRConfig ¶
type CCPRConfig struct {
// PublicationWorkerThread is the number of threads for publication worker pool
PublicationWorkerThread int `toml:"publication-worker-thread"`
// FilterObjectWorkerThread is the number of threads for filter object worker pool
FilterObjectWorkerThread int `toml:"filter-object-worker-thread"`
// GetChunkWorkerThread is the number of threads for get chunk worker pool
GetChunkWorkerThread int `toml:"get-chunk-worker-thread"`
// WriteObjectWorkerThread is the number of threads for write object worker pool
WriteObjectWorkerThread int `toml:"write-object-worker-thread"`
// GetChunkMaxMemory is the maximum memory for concurrent GetChunkJob operations
GetChunkMaxMemory int64 `toml:"get-chunk-max-memory"`
// GetChunkSize is the size of each chunk
GetChunkSize int64 `toml:"get-chunk-size"`
// GCInterval is the interval for garbage collection
GCInterval toml.Duration `toml:"gc-interval"`
// GCTTL is the time-to-live for garbage collection items
GCTTL toml.Duration `toml:"gc-ttl"`
// SyncTaskInterval is the interval for sync task execution
SyncTaskInterval toml.Duration `toml:"sync-task-interval"`
// RetryTimes is the number of retry attempts for failed operations
RetryTimes int `toml:"retry-times"`
// RetryInterval is the interval between retries
RetryInterval toml.Duration `toml:"retry-interval"`
// SyncProtectionTTLDuration is the TTL duration for sync protection
SyncProtectionTTLDuration toml.Duration `toml:"sync-protection-ttl-duration"`
// SyncProtectionRenewInterval is the interval for renewing sync protection
SyncProtectionRenewInterval toml.Duration `toml:"sync-protection-renew-interval"`
// BloomFilterExpectedItems is the expected number of items in bloom filter
BloomFilterExpectedItems int `toml:"bloom-filter-expected-items"`
// BloomFilterFalsePositiveRate is the false positive rate for bloom filter
BloomFilterFalsePositiveRate float64 `toml:"bloom-filter-false-positive-rate"`
// RetryThreshold is the maximum number of retries before stopping
RetryThreshold int `toml:"retry-threshold"`
}
CCPRConfig holds all configuration parameters for CCPR (Cross-Cluster Publication Replication)
func DefaultCCPRConfig ¶
func DefaultCCPRConfig() *CCPRConfig
DefaultCCPRConfig returns the default CCPR configuration
func GetGlobalConfig ¶
func GetGlobalConfig() *CCPRConfig
GetGlobalConfig returns the global CCPR configuration instance If not initialized, returns the default configuration
func (*CCPRConfig) GetChunkMaxConcurrent ¶
func (c *CCPRConfig) GetChunkMaxConcurrent() int
GetChunkMaxConcurrent returns the maximum number of concurrent chunk operations
func (*CCPRConfig) Validate ¶
func (c *CCPRConfig) Validate() error
Validate validates the CCPR configuration
type CCPRTxnCacheWriter ¶
type CCPRTxnCacheWriter interface {
// WriteObject checks if an object needs to be written and registers it in the cache.
// Does NOT write the file - caller should write the file when isNewFile=true.
// Returns isNewFile (true if file needs to be written) and any error.
WriteObject(ctx context.Context, objectName string, txnID []byte) (isNewFile bool, err error)
// OnFileWritten is called after the file has been successfully written to fileservice.
OnFileWritten(objectName string)
}
CCPRTxnCacheWriter is an interface for writing objects to CCPR transaction cache This interface is implemented by disttae.CCPRTxnCache
type CommitErrorClassifier ¶
type CommitErrorClassifier struct{}
CommitErrorClassifier recognises errors that are retryable during commit operations. It checks for RC mode transaction retry errors (ErrTxnNeedRetry, ErrTxnNeedRetryWithDefChanged).
func (CommitErrorClassifier) IsRetryable ¶
func (CommitErrorClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type DatabaseMetadata ¶
type DatabaseMetadata struct {
DatID uint64
DatName string
DatCreateSQL sql.NullString
AccountID uint32
}
DatabaseMetadata represents metadata from mo_databases table
type DefaultClassifier ¶
type DefaultClassifier struct{}
DefaultClassifier recognises common transient network errors and connection issues. It handles basic network retry scenarios like connection timeouts, EOF errors, etc.
func (DefaultClassifier) IsRetryable ¶
func (DefaultClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type DownstreamCommitClassifier ¶
type DownstreamCommitClassifier struct {
MultiClassifier
}
DownstreamCommitClassifier is used when committing to downstream. It combines default, mysql, commit, ut injection, stale read, and GC running classifiers.
func NewDownstreamCommitClassifier ¶
func NewDownstreamCommitClassifier() *DownstreamCommitClassifier
NewDownstreamCommitClassifier creates a new DownstreamCommitClassifier.
type DownstreamConnectionClassifier ¶
type DownstreamConnectionClassifier struct {
MultiClassifier
}
DownstreamConnectionClassifier is used when connecting to downstream. It combines default, mysql, and commit classifiers. CommitErrorClassifier is included to handle ErrTxnNeedRetry errors during statement execution.
func NewDownstreamConnectionClassifier ¶
func NewDownstreamConnectionClassifier() *DownstreamConnectionClassifier
NewDownstreamConnectionClassifier creates a new DownstreamConnectionClassifier.
type ErrorClassifier ¶
type ErrorClassifier interface {
// IsRetryable returns true if the error is transient and worth retrying.
IsRetryable(error) bool
}
ErrorClassifier determines whether a failure is retryable.
type ErrorMetadata ¶
type ErrorMetadata struct {
IsRetryable bool // Whether this error is retryable
RetryCount int // Number of retry attempts
FirstSeen time.Time // When first seen
LastSeen time.Time // When last seen
Message string // Error message
}
ErrorMetadata stores error metadata
func BuildErrorMetadata ¶
func BuildErrorMetadata(old *ErrorMetadata, err error, classifier ErrorClassifier) (*ErrorMetadata, bool)
BuildErrorMetadata builds new metadata based on old metadata and new error It uses the classifier to determine if the error is retryable Returns the error metadata and a boolean indicating if retry should continue Retry will stop if retry count exceeds RetryThreshold
func Parse ¶
func Parse(errMsg string) *ErrorMetadata
Parse parses error metadata from string Format:
- Retryable: "R:count:firstSeen:lastSeen:message"
- Non-retryable: "N:firstSeen:message"
func (*ErrorMetadata) Format ¶
func (m *ErrorMetadata) Format() string
Format formats error metadata to string
type ExecutorRetryOption ¶
type ExecutorRetryOption struct {
RetryTimes int // Maximum number of retries (-1 for infinite)
RetryInterval time.Duration // Base interval between retries
RetryDuration time.Duration // Maximum total retry duration
}
ExecutorRetryOption configures retry behavior for executor operations
func DefaultExecutorRetryOption ¶
func DefaultExecutorRetryOption() *ExecutorRetryOption
DefaultExecutorRetryOption returns default retry options for executor
type ExponentialBackoff ¶
type ExponentialBackoff struct {
// Base delay before the first retry attempt.
Base time.Duration
// Factor to multiply delays by each attempt (>1).
Factor float64
// Max caps the computed delay (optional).
Max time.Duration
// Jitter adds randomization in range [0, Jitter] (optional).
Jitter time.Duration
// contains filtered or unexported fields
}
ExponentialBackoff implements BackoffStrategy with exponential growth and optional jitter.
type FilterObjectJob ¶
type FilterObjectJob struct {
// contains filtered or unexported fields
}
FilterObjectJob is a job for filtering an object
func AcquireFilterObjectJob ¶
func AcquireFilterObjectJob() *FilterObjectJob
AcquireFilterObjectJob gets a FilterObjectJob from the pool
func NewFilterObjectJob ¶
func NewFilterObjectJob( ctx context.Context, objectStatsBytes []byte, snapshotTS types.TS, upstreamExecutor SQLExecutor, isTombstone bool, localFS fileservice.FileService, mp *mpool.MPool, getChunkWorker GetChunkWorker, writeObjectWorker WriteObjectWorker, subscriptionAccountName string, pubName string, ccprCache CCPRTxnCacheWriter, txnID []byte, aobjectMap *AObjectMap, ttlChecker TTLChecker, ) *FilterObjectJob
NewFilterObjectJob creates a new FilterObjectJob
func (*FilterObjectJob) Execute ¶
func (j *FilterObjectJob) Execute()
Execute runs the FilterObjectJob
func (*FilterObjectJob) GetType ¶
func (j *FilterObjectJob) GetType() int8
GetType returns the job type
func (*FilterObjectJob) WaitDone ¶
func (j *FilterObjectJob) WaitDone() any
WaitDone waits for the job to complete and returns the result
type FilterObjectJobResult ¶
type FilterObjectJobResult struct {
Err error
HasMappingUpdate bool
UpstreamAObjUUID *objectio.ObjectId
PreviousStats objectio.ObjectStats
CurrentStats objectio.ObjectStats
// DownstreamStats holds the stats for non-appendable objects that were written to fileservice
DownstreamStats objectio.ObjectStats
// RowOffsetMap maps original rowoffset to new rowoffset after sorting
// Key: original rowoffset, Value: new rowoffset
RowOffsetMap map[uint32]uint32
}
FilterObjectJobResult holds the result of FilterObjectJob
func AcquireFilterObjectJobResult ¶
func AcquireFilterObjectJobResult() *FilterObjectJobResult
AcquireFilterObjectJobResult gets a FilterObjectJobResult from the pool
type FilterObjectResult ¶
type FilterObjectResult struct {
HasMappingUpdate bool
UpstreamAObjUUID *objectio.ObjectId
PreviousStats objectio.ObjectStats
CurrentStats objectio.ObjectStats
// DownstreamStats holds the stats for non-appendable objects that were written to fileservice
DownstreamStats objectio.ObjectStats
// RowOffsetMap maps original rowoffset to new rowoffset after sorting
// Key: original rowoffset, Value: new rowoffset
RowOffsetMap map[uint32]uint32
}
FilterObjectResult holds the result of FilterObject
func FilterObject ¶
func FilterObject( ctx context.Context, objectStatsBytes []byte, snapshotTS types.TS, upstreamExecutor SQLExecutor, isTombstone bool, localFS fileservice.FileService, mp *mpool.MPool, getChunkWorker GetChunkWorker, writeObjectWorker WriteObjectWorker, subscriptionAccountName string, pubName string, ccprCache CCPRTxnCacheWriter, txnID []byte, aobjectMap *AObjectMap, ttlChecker TTLChecker, ) (*FilterObjectResult, error)
FilterObject filters an object based on snapshot TS Input: object stats (as bytes), snapshot TS, and whether it's an aobj (checked from object stats) For aobj: gets object file, converts to batch, filters by snapshot TS, creates new object The mapping between new UUID and upstream aobj is stored in ccprCache.aobjectMap For nobj: writes directly to fileservice with new UUID ccprCache: optional CCPR transaction cache for atomic write and registration (can be nil) txnID: transaction ID for CCPR cache registration (can be nil) aobjectMap: mapping from upstream aobj to downstream object stats (used for tombstone rowid rewriting) ttlChecker: optional function to check if sync protection TTL has expired (can be nil)
type FilterObjectWorker ¶
FilterObjectWorker is the interface for filter object worker pool
func NewFilterObjectWorker ¶
func NewFilterObjectWorker() FilterObjectWorker
NewFilterObjectWorker creates a new filter object worker pool
type GCRunningClassifier ¶
type GCRunningClassifier struct{}
GCRunningClassifier recognises GC running errors that are retryable. When GC is running on downstream, sync protection registration should retry.
func (GCRunningClassifier) IsRetryable ¶
func (GCRunningClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type GCStatus ¶
type GCStatus struct {
Running bool `json:"running"`
Protections int `json:"protections"`
TS int64 `json:"ts"`
}
GCStatus represents the response from gc_status mo_ctl command
func QueryGCStatus ¶
func QueryGCStatus(ctx context.Context, executor SQLExecutor) (*GCStatus, error)
QueryGCStatus queries the GC status from upstream
type GetChunkJob ¶
type GetChunkJob struct {
// contains filtered or unexported fields
}
GetChunkJob is a job for getting a single chunk
func AcquireGetChunkJob ¶
func AcquireGetChunkJob() *GetChunkJob
AcquireGetChunkJob gets a GetChunkJob from the pool
func NewGetChunkJob ¶
func NewGetChunkJob(ctx context.Context, upstreamExecutor SQLExecutor, objectName string, chunkIndex int64, subscriptionAccountName string, pubName string) *GetChunkJob
NewGetChunkJob creates a new GetChunkJob
func (*GetChunkJob) Execute ¶
func (j *GetChunkJob) Execute()
Execute runs the GetChunkJob with retry logic
func (*GetChunkJob) GetChunkIndex ¶
func (j *GetChunkJob) GetChunkIndex() int64
GetChunkIndex returns the chunk index
func (*GetChunkJob) GetObjectName ¶
func (j *GetChunkJob) GetObjectName() string
GetObjectName returns the object name
func (*GetChunkJob) WaitDone ¶
func (j *GetChunkJob) WaitDone() any
WaitDone waits for the job to complete and returns the result
type GetChunkJobDuration ¶
GetChunkJobDuration holds duration info for a GetChunk job
type GetChunkJobInfo ¶
GetChunkJobInfo is the interface for jobs that have object name and chunk index
type GetChunkJobResult ¶
GetChunkJobResult holds the result of GetChunkJob
func AcquireGetChunkJobResult ¶
func AcquireGetChunkJobResult() *GetChunkJobResult
AcquireGetChunkJobResult gets a GetChunkJobResult from the pool
type GetChunkWorker ¶
GetChunkWorker is the interface for get upstream chunk worker pool
func NewGetChunkWorker ¶
func NewGetChunkWorker() GetChunkWorker
NewGetChunkWorker creates a new get chunk worker pool
type GetMetaJob ¶
type GetMetaJob struct {
// contains filtered or unexported fields
}
GetMetaJob is a job for getting metadata (chunk 0)
func AcquireGetMetaJob ¶
func AcquireGetMetaJob() *GetMetaJob
AcquireGetMetaJob gets a GetMetaJob from the pool
func NewGetMetaJob ¶
func NewGetMetaJob(ctx context.Context, upstreamExecutor SQLExecutor, objectName string, subscriptionAccountName string, pubName string) *GetMetaJob
NewGetMetaJob creates a new GetMetaJob
func (*GetMetaJob) Execute ¶
func (j *GetMetaJob) Execute()
Execute runs the GetMetaJob with retry logic
func (*GetMetaJob) WaitDone ¶
func (j *GetMetaJob) WaitDone() any
WaitDone waits for the job to complete and returns the result
type GetMetaJobResult ¶
type GetMetaJobResult struct {
MetadataData []byte
TotalSize int64
ChunkIndex int64
TotalChunks int64
IsComplete bool
Err error
}
GetMetaJobResult holds the result of GetMetaJob
func AcquireGetMetaJobResult ¶
func AcquireGetMetaJobResult() *GetMetaJobResult
AcquireGetMetaJobResult gets a GetMetaJobResult from the pool
type InternalResult ¶
type InternalResult struct {
// contains filtered or unexported fields
}
InternalResult wraps executor.Result to provide sql.Rows-like interface
func (*InternalResult) Close ¶
func (r *InternalResult) Close() error
Close closes the result and releases resources
func (*InternalResult) Err ¶
func (r *InternalResult) Err() error
Err returns any error encountered during iteration
func (*InternalResult) Scan ¶
func (r *InternalResult) Scan(dest ...interface{}) error
Scan scans the current row into the provided destinations
type InternalSQLExecutor ¶
type InternalSQLExecutor struct {
// contains filtered or unexported fields
}
InternalSQLExecutor implements SQLExecutor interface using MatrixOne's internal SQL executor It supports retry for RC mode transaction errors (txn need retry errors) If upstreamSQLHelper is provided, special statements (CREATE/DROP SNAPSHOT, OBJECTLIST, GET OBJECT) will be routed through the helper
func NewInternalSQLExecutor ¶
func NewInternalSQLExecutor( cnUUID string, txnClient client.TxnClient, engine engine.Engine, accountID uint32, retryOpt *SQLExecutorRetryOption, useAccountID bool, ) (*InternalSQLExecutor, error)
NewInternalSQLExecutor creates a new InternalSQLExecutor txnClient is optional - if provided, transactions can be created via SetTxn engine is required for registering transactions with the engine accountID is the tenant account ID to use when executing SQL retryOpt is optional - if nil, default retry options will be used upstreamSQLHelper is optional - if provided, special SQL statements will be handled by it
func (*InternalSQLExecutor) Close ¶
func (e *InternalSQLExecutor) Close() error
Close is a no-op for internal executor (connection is managed by runtime)
func (*InternalSQLExecutor) Connect ¶
func (e *InternalSQLExecutor) Connect() error
Connect is a no-op for internal executor (connection is managed by runtime)
func (*InternalSQLExecutor) EndTxn ¶
func (e *InternalSQLExecutor) EndTxn(ctx context.Context, commit bool) error
EndTxn ends the current transaction It commits or rolls back the transaction set via SetTxn
func (*InternalSQLExecutor) ExecSQL ¶
func (e *InternalSQLExecutor) ExecSQL( ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, useTxn bool, needRetry bool, timeout time.Duration, ) (*Result, context.CancelFunc, error)
ExecSQL executes a SQL statement with options accountID: the account ID to use for tenant context; use InvalidAccountID to use executor's default accountID useTxn: if true, execute within a transaction (requires active transaction, will error if txnOp is nil) if false, execute as autocommit (will create and commit transaction automatically) It supports automatic retry for RC mode transaction errors (txn need retry errors) If session is set and the statement is CREATE/DROP SNAPSHOT, OBJECTLIST, or GET OBJECT, it will be routed through frontend layer timeout: if > 0, each retry attempt will use a new context with this timeout; if 0, use the provided ctx directly Returns: result, cancel function (empty func if no timeout context was created), error IMPORTANT: caller MUST call the cancel function after finishing with the result
func (*InternalSQLExecutor) ExecSQLInDatabase ¶
func (e *InternalSQLExecutor) ExecSQLInDatabase( ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, database string, useTxn bool, needRetry bool, timeout time.Duration, ) (*Result, context.CancelFunc, error)
ExecSQLInDatabase executes SQL with a specific default database set. This is useful for DDL statements that may require a default database context.
func (*InternalSQLExecutor) GetInternalExec ¶
func (e *InternalSQLExecutor) GetInternalExec() executor.SQLExecutor
GetInternalExec returns the internal executor (for creating helper)
func (*InternalSQLExecutor) GetTxnClient ¶
func (e *InternalSQLExecutor) GetTxnClient() client.TxnClient
GetTxnClient returns the txnClient (for creating helper)
func (*InternalSQLExecutor) SetTxn ¶
func (e *InternalSQLExecutor) SetTxn(txnOp client.TxnOperator)
SetTxn sets an external transaction operator for the executor This allows the executor to use a transaction created outside of it
func (*InternalSQLExecutor) SetUTHelper ¶
func (e *InternalSQLExecutor) SetUTHelper(helper UTHelper)
SetUTHelper sets the unit test helper
func (*InternalSQLExecutor) SetUpstreamSQLHelper ¶
func (e *InternalSQLExecutor) SetUpstreamSQLHelper(helper UpstreamSQLHelper)
SetUpstreamSQLHelper sets the upstream SQL helper
type IterationContext ¶
type IterationContext struct {
// Task identification
TaskID string
SubscriptionName string
SubscriptionAccountName string // The subscription account name for FROM clause
SrcInfo SrcInfo
// Upstream connection
LocalTxn client.TxnOperator
UpstreamExecutor SQLExecutor
LocalExecutor SQLExecutor
// Execution state
IterationLSN uint64
SubscriptionState int8 // subscription state: 0=running, 1=error, 2=pause, 3=dropped
// Context information
PrevSnapshotName string
PrevSnapshotTS types.TS
CurrentSnapshotName string
CurrentSnapshotTS types.TS
// AObjectMap stores the mapping from upstream aobj to downstream object stats
// This map is used to track appendable object transformations during CCPR sync
AObjectMap *AObjectMap
TableIDs map[TableKey]uint64
IndexTableMappings map[string]string // Maps upstream_index_table_name to downstream_index_table_name
ErrorMetadata *ErrorMetadata // Error metadata parsed from error_message
IsStale bool // Whether the iteration is stale
}
IterationContext contains context information for an iteration
func InitializeIterationContext ¶
func InitializeIterationContext( ctx context.Context, cnUUID string, cnEngine engine.Engine, cnTxnClient client.TxnClient, taskID string, iterationLSN uint64, upstreamSQLHelperFactory UpstreamSQLHelperFactory, sqlExecutorRetryOpt *SQLExecutorRetryOption, utHelper UTHelper, ) (*IterationContext, error)
InitializeIterationContext initializes IterationContext from mo_ccpr_log table It reads subscription_name, srcinfo, upstream_conn, and context from the table, creates local executor and upstream executor, creates a local transaction, and sets up the local executor to use that transaction. iterationLSN is passed in as a parameter. AObjectMap and TableIDs are read from the context JSON field. sqlExecutorRetryOpt: retry options for SQL executor operations (nil to use default) utHelper: optional unit test helper for injecting errors
func (*IterationContext) Close ¶
func (iterCtx *IterationContext) Close(commit bool) error
func (*IterationContext) String ¶
func (iterCtx *IterationContext) String() string
type IterationContextJSON ¶
type IterationContextJSON struct {
// Task identification
TaskID string `json:"task_id"`
SubscriptionName string `json:"subscription_name"`
SrcInfo SrcInfo `json:"src_info"`
// Context information
AObjectMap map[string]AObjectMappingJSON `json:"aobject_map"` // AObjectMap as serializable map (key is upstream ObjectId as string)
TableIDs map[string]uint64 `json:"table_ids"`
IndexTableMappings map[string]string `json:"index_table_mappings"` // IndexTableMappings as serializable map (key is upstream_index_table_name, value is downstream_index_table_name)
}
IterationContextJSON represents the serializable part of IterationContext This structure is used to store iteration context in mo_ccpr_log.context field
type JobStats ¶
type JobStats struct {
FilterObjectPending atomic.Int64
FilterObjectRunning atomic.Int64
FilterObjectCompleted atomic.Int64
GetChunkPending atomic.Int64
GetChunkRunning atomic.Int64
GetChunkCompleted atomic.Int64
GetMetaPending atomic.Int64
GetMetaRunning atomic.Int64
GetMetaCompleted atomic.Int64
WriteObjectPending atomic.Int64
WriteObjectRunning atomic.Int64
WriteObjectCompleted atomic.Int64
// contains filtered or unexported fields
}
JobStats holds statistics for job tracking using atomic counters for thread safety
func (*JobStats) DecrementFilterObjectRunning ¶
func (s *JobStats) DecrementFilterObjectRunning()
DecrementFilterObjectRunning decrements the filter object running counter
func (*JobStats) DecrementGetChunkRunning ¶
func (s *JobStats) DecrementGetChunkRunning()
DecrementGetChunkRunning decrements the get chunk running counter
func (*JobStats) DecrementGetMetaRunning ¶
func (s *JobStats) DecrementGetMetaRunning()
DecrementGetMetaRunning decrements the get meta running counter
func (*JobStats) DecrementWriteObjectRunning ¶
func (s *JobStats) DecrementWriteObjectRunning()
DecrementWriteObjectRunning decrements the write object running counter
func (*JobStats) GetTopGetChunkDurations ¶
func (s *JobStats) GetTopGetChunkDurations() []*GetChunkJobDuration
GetTopGetChunkDurations returns a copy of top 3 longest GetChunk job durations
func (*JobStats) GetTopWriteObjectDurations ¶
func (s *JobStats) GetTopWriteObjectDurations() []*WriteObjectJobDuration
GetTopWriteObjectDurations returns a copy of top 3 longest WriteObject job durations
func (*JobStats) IncrementFilterObjectPending ¶
func (s *JobStats) IncrementFilterObjectPending()
IncrementFilterObjectPending increments the filter object pending counter
func (*JobStats) IncrementFilterObjectRunning ¶
func (s *JobStats) IncrementFilterObjectRunning()
IncrementFilterObjectRunning increments the filter object running counter and decrements pending
func (*JobStats) IncrementGetChunkPending ¶
func (s *JobStats) IncrementGetChunkPending()
IncrementGetChunkPending increments the get chunk pending counter
func (*JobStats) IncrementGetChunkRunning ¶
func (s *JobStats) IncrementGetChunkRunning()
IncrementGetChunkRunning increments the get chunk running counter and decrements pending
func (*JobStats) IncrementGetMetaPending ¶
func (s *JobStats) IncrementGetMetaPending()
IncrementGetMetaPending increments the get meta pending counter
func (*JobStats) IncrementGetMetaRunning ¶
func (s *JobStats) IncrementGetMetaRunning()
IncrementGetMetaRunning increments the get meta running counter and decrements pending
func (*JobStats) IncrementWriteObjectPending ¶
func (s *JobStats) IncrementWriteObjectPending()
IncrementWriteObjectPending increments the write object pending counter
func (*JobStats) IncrementWriteObjectRunning ¶
func (s *JobStats) IncrementWriteObjectRunning()
IncrementWriteObjectRunning increments the write object running counter and decrements pending
func (*JobStats) RecordGetChunkDuration ¶
func (s *JobStats) RecordGetChunkDuration(objectName string, chunkIndex int64, duration time.Duration)
RecordGetChunkDuration records a GetChunk job duration and keeps top 3 longest
func (*JobStats) RecordWriteObjectDuration ¶
RecordWriteObjectDuration records a WriteObject job duration and keeps top 3 longest
func (*JobStats) ResetTopGetChunkDurations ¶
func (s *JobStats) ResetTopGetChunkDurations()
ResetTopGetChunkDurations resets the top durations (called after printing)
func (*JobStats) ResetTopWriteObjectDurations ¶
func (s *JobStats) ResetTopWriteObjectDurations()
ResetTopWriteObjectDurations resets the top durations (called after printing)
type MemoryController ¶
type MemoryController struct {
// contains filtered or unexported fields
}
MemoryController manages memory allocation for CCPR operations It provides memory tracking, limits, and metrics collection
func GetGlobalMemoryController ¶
func GetGlobalMemoryController() *MemoryController
GetGlobalMemoryController returns the global memory controller instance
func InitGlobalMemoryController ¶
func InitGlobalMemoryController(mp *mpool.MPool, maxBytes int64) *MemoryController
InitGlobalMemoryController initializes the global memory controller. Uses double-checked locking to ensure only one controller is created.
func NewMemoryController ¶
func NewMemoryController(mp *mpool.MPool, maxBytes int64) *MemoryController
NewMemoryController creates a new MemoryController
func (*MemoryController) Alloc ¶
func (mc *MemoryController) Alloc(ctx context.Context, size int, memType MemoryType) ([]byte, error)
Alloc allocates memory from the pool with tracking
func (*MemoryController) Free ¶
func (mc *MemoryController) Free(data []byte, memType MemoryType)
Free releases memory back to the pool with tracking
func (*MemoryController) GetStats ¶
func (mc *MemoryController) GetStats() MemoryStats
GetStats returns current memory statistics
type MemoryStats ¶
type MemoryStats struct {
ObjectContentBytes int64
DecompressBufferBytes int64
SortIndexBytes int64
RowOffsetMapBytes int64
TotalBytes int64
MaxBytes int64
}
MemoryStats holds memory usage statistics
type MemoryType ¶
type MemoryType int
MemoryType represents different types of memory allocations in CCPR
const ( MemoryTypeObjectContent MemoryType = iota MemoryTypeDecompressBuffer MemoryTypeSortIndex MemoryTypeRowOffsetMap )
func (MemoryType) String ¶
func (t MemoryType) String() string
type MoCtlResponse ¶
type MoCtlResponse struct {
Method string `json:"method"`
Result []MoCtlResultEntry `json:"result"`
}
MoCtlResponse represents the outer response from mo_ctl commands Format: {"method":"...", "result":[{"ReturnStr":"..."}]}
type MoCtlResultEntry ¶
type MoCtlResultEntry struct {
ReturnStr string `json:"ReturnStr"`
}
MoCtlResultEntry represents a single result entry from mo_ctl
type MockResultScanner ¶
type MockResultScanner interface {
Close() error
Next() bool
Scan(dest ...interface{}) error
Err() error
}
MockResultScanner is an interface for testing purposes
type MultiClassifier ¶
type MultiClassifier []ErrorClassifier
MultiClassifier chains multiple classifiers; returns true if any classifier deems the error retryable.
func (MultiClassifier) IsRetryable ¶
func (m MultiClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type MySQLErrorClassifier ¶
type MySQLErrorClassifier struct{}
MySQLErrorClassifier recognises transient MySQL errors that are worth retrying.
func (MySQLErrorClassifier) IsRetryable ¶
func (MySQLErrorClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type ObjectStats ¶
type ObjectStats struct {
Stats string // Object stats information
CreateAt types.TS // Creation timestamp
DeleteAt types.TS // Deletion timestamp (0 if not deleted)
IsTombstone bool // Whether this is a tombstone (deleted object)
}
ObjectStats represents object statistics
type ObjectWithTableInfo ¶
type ObjectWithTableInfo struct {
Stats objectio.ObjectStats
DBName string
TableName string
IsTombstone bool
Delete bool
FilterJob *FilterObjectJob
}
ObjectWithTableInfo contains ObjectStats with its table and database information
type Operation ¶
type Operation func() error
Operation defines the callable that will be executed with retry semantics.
type Policy ¶
type Policy struct {
// MaxAttempts defines how many times the operation should be attempted in total.
// Must be >= 1.
MaxAttempts int
// Backoff decides how long to wait between attempts. Optional; zero value means no backoff.
Backoff BackoffStrategy
// Classifier decides whether an error warrants another attempt. Optional; defaults to never retry.
Classifier ErrorClassifier
}
Policy controls the retry behaviour for an operation.
func (Policy) Do ¶
Do executes the given Operation following the retry policy.
Behaviour:
- Executes op up to MaxAttempts times.
- If op returns nil, Do returns nil immediately.
- If op returns non-retryable error, Do returns it without further attempts.
- Between retryable failures, waits according to Backoff (if provided).
- Context cancellation aborts waiting and returns ctx.Err().
type PublicationExecutorOption ¶
type PublicationExecutorOption struct {
GCInterval time.Duration
GCTTL time.Duration
SyncTaskInterval time.Duration
RetryOption *ExecutorRetryOption // Retry configuration for executor operations
SQLExecutorRetryOpt *SQLExecutorRetryOption // Retry configuration for SQL executor operations
}
type PublicationTaskExecutor ¶
type PublicationTaskExecutor struct {
// contains filtered or unexported fields
}
PublicationTaskExecutor manages publication tasks
func NewPublicationTaskExecutor ¶
func NewPublicationTaskExecutor( ctx context.Context, txnEngine engine.Engine, cnTxnClient client.TxnClient, cdUUID string, option *PublicationExecutorOption, mp *mpool.MPool, upstreamSQLHelperFactory UpstreamSQLHelperFactory, ) (exec *PublicationTaskExecutor, err error)
func (*PublicationTaskExecutor) Cancel ¶
func (exec *PublicationTaskExecutor) Cancel() error
func (*PublicationTaskExecutor) GCInMemoryTask ¶
func (exec *PublicationTaskExecutor) GCInMemoryTask(threshold time.Duration)
func (*PublicationTaskExecutor) GetTask ¶
func (exec *PublicationTaskExecutor) GetTask(taskID string) (TaskEntry, bool)
GetTask returns a copy of the task entry for the given taskID. This is a public method for testing purposes.
func (*PublicationTaskExecutor) IsRunning ¶
func (exec *PublicationTaskExecutor) IsRunning() bool
func (*PublicationTaskExecutor) Pause ¶
func (exec *PublicationTaskExecutor) Pause() error
func (*PublicationTaskExecutor) Restart ¶
func (exec *PublicationTaskExecutor) Restart() error
func (*PublicationTaskExecutor) Resume ¶
func (exec *PublicationTaskExecutor) Resume() error
func (*PublicationTaskExecutor) Start ¶
func (exec *PublicationTaskExecutor) Start() error
func (*PublicationTaskExecutor) Stop ¶
func (exec *PublicationTaskExecutor) Stop()
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result wraps sql.Rows or InternalResult to provide query result access
func GetObjectListFromSnapshotDiff ¶
func GetObjectListFromSnapshotDiff( ctx context.Context, iterationCtx *IterationContext, ) (*Result, context.CancelFunc, error)
GetObjectListFromSnapshotDiff calculates snapshot diff and gets object list from upstream It executes: OBJECTLIST DATABASE db1 TABLE t1 SNAPSHOT sp2 AGAINST SNAPSHOT sp1 Returns: query result containing db name, table name, object list (stats, create_at, delete_at, is_tombstone) The caller is responsible for closing the result and calling cancel function
func NewResultFromExecutorResult ¶
NewResultFromExecutorResult creates a new Result from executor.Result This is exported so that external packages (like test helpers) can create Result objects
type SQLExecutor ¶
type SQLExecutor interface {
Close() error
Connect() error
EndTxn(ctx context.Context, commit bool) error
// ExecSQL executes a SQL statement with options
// accountID: the account ID to use for tenant context; use InvalidAccountID if not applicable (e.g., for UpstreamExecutor)
// useTxn: if true, execute within a transaction (must have active transaction for InternalSQLExecutor, not allowed for UpstreamExecutor)
// if false, execute as autocommit (will create and commit transaction automatically for InternalSQLExecutor)
// timeout: if > 0, each retry attempt will use a new context with this timeout; if 0, use the provided ctx directly
// Returns: result, cancel function (may be nil if no timeout context was created), error
// IMPORTANT: caller MUST call the cancel function after finishing with the result (if cancel is not nil)
ExecSQL(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, useTxn bool, needRetry bool, timeout time.Duration) (*Result, context.CancelFunc, error)
// ExecSQLInDatabase executes a SQL statement with a specific default database context
// This is useful for DDL statements that may require a default database to be set
ExecSQLInDatabase(ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, database string, useTxn bool, needRetry bool, timeout time.Duration) (*Result, context.CancelFunc, error)
}
type SQLExecutorRetryOption ¶
type SQLExecutorRetryOption struct {
MaxRetries int // Maximum number of retries for retryable errors
RetryInterval time.Duration // Interval between retries
Classifier ErrorClassifier // Error classifier for retry logic
}
SQLExecutorRetryOption configures retry behavior for SQL executor operations
func DefaultSQLExecutorRetryOption ¶
func DefaultSQLExecutorRetryOption() *SQLExecutorRetryOption
DefaultSQLExecutorRetryOption returns default retry options for SQL executor
type SrcInfo ¶
type SrcInfo struct {
SyncLevel string // 'account', 'database', or 'table'
DBName string // Required for database/table level
TableName string // Required for table level
AccountID uint32 // Account ID for downstream operations
}
SrcInfo contains source information for subscription It can be account/database/table level
type StaleReadClassifier ¶
type StaleReadClassifier struct{}
StaleReadClassifier recognises stale read errors that are retryable.
func (StaleReadClassifier) IsRetryable ¶
func (StaleReadClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type SyncProtectionResponse ¶
type SyncProtectionResponse struct {
Status string `json:"status"`
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
SyncProtectionResponse represents the response from sync protection mo_ctl commands
type SyncProtectionRetryOption ¶
type SyncProtectionRetryOption struct {
// InitialInterval is the initial retry interval (default: 1s)
InitialInterval time.Duration
// MaxTotalTime is the maximum total time to retry (default: 5min)
// If 0 or negative, no retry is performed (fail immediately on first error)
MaxTotalTime time.Duration
}
SyncProtectionRetryOption configures retry behavior for sync protection registration
func DefaultSyncProtectionRetryOption ¶
func DefaultSyncProtectionRetryOption() *SyncProtectionRetryOption
DefaultSyncProtectionRetryOption returns the default retry option Default: initial 1s, exponential backoff (x2), max total time 5min
type SyncProtectionTTLClassifier ¶
type SyncProtectionTTLClassifier struct{}
SyncProtectionTTLClassifier recognises sync protection TTL expired errors. These errors are retryable because the sync protection can be re-registered.
func (SyncProtectionTTLClassifier) IsRetryable ¶
func (SyncProtectionTTLClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type TTLChecker ¶
type TTLChecker func() bool
TTLChecker is a function type for checking if sync protection TTL has expired Returns true if TTL has expired and the job should abort
type TableDDLInfo ¶
type TableDDLInfo struct {
TableID uint64
TableCreateSQL string
Operation int8 // DDLOperationCreate (1), DDLOperationAlter (2), DDLOperationDrop (3), DDLOperationAlterInplace (4), 0 means no operation
AlterStatements []string // ALTER TABLE statements for inplace alter operations
}
TableDDLInfo contains table DDL information
type TableMetadata ¶
type TableMetadata struct {
RelID uint64
RelName string
RelDatabaseID uint64
RelDatabase string
RelCreateSQL sql.NullString
AccountID uint32
}
TableMetadata represents metadata from mo_tables table
type TaskContext ¶
type TaskEntry ¶
type TaskEntry struct {
TaskID string
LSN uint64
State int8 // iteration_state from mo_ccpr_log
SubscriptionState int8 // subscription state: 0=running, 1=error, 2=pause, 3=dropped
DropAt *time.Time // drop timestamp from mo_ccpr_log
}
TaskEntry represents a task entry in the executor Only stores taskid, lsn, state, subscriptionState
type UTHelper ¶
type UTHelper interface {
// OnSnapshotCreated is called after a snapshot is created in the upstream
OnSnapshotCreated(ctx context.Context, snapshotName string, snapshotTS types.TS) error
// OnSQLExecFailed is called before each SQL execution attempt
// errorCount: current error count for this SQL query (resets to 0 for each new query)
// Returns: error to inject (nil means no error injection)
OnSQLExecFailed(ctx context.Context, query string, errorCount int) error
}
UTHelper is an interface for unit test helpers It provides hooks for testing purposes
type UTInjectionClassifier ¶
type UTInjectionClassifier struct{}
UTInjectionClassifier recognises UT injection errors that are retryable.
func (UTInjectionClassifier) IsRetryable ¶
func (UTInjectionClassifier) IsRetryable(err error) bool
IsRetryable implements ErrorClassifier.
type UpstreamConnConfig ¶
type UpstreamConnConfig struct {
Account string // Account name (may be empty)
User string
Password string
Host string
Port int
Timeout string
}
UpstreamConnConfig represents parsed upstream connection configuration
func ParseUpstreamConn ¶
func ParseUpstreamConn(connStr string) (*UpstreamConnConfig, error)
ParseUpstreamConn parses upstream connection string Format: mysql://account#user:password@host:port (unified format, account may be empty) If password appears to be encrypted (hex string), it will be decrypted if ctx and executor are provided KeyEncryptionKey will be read from context (similar to CDC)
func ParseUpstreamConnWithDecrypt ¶
func ParseUpstreamConnWithDecrypt(ctx context.Context, connStr string, executor SQLExecutor, cnUUID string) (*UpstreamConnConfig, error)
ParseUpstreamConnWithDecrypt parses upstream connection string with optional password decryption Format: mysql://account#user:password@host:port or mysql://user:password@host:port If account is provided, uses account#user format for MatrixOne authentication (in DSN) If account is not provided (standard MySQL format), account will be empty and uses user format If executor and cnUUID are provided, encrypted passwords will be decrypted using KeyEncryptionKey Similar to CDC's implementation using getGlobalPuWrapper
type UpstreamConnectionClassifier ¶
type UpstreamConnectionClassifier struct {
MultiClassifier
}
UpstreamConnectionClassifier is used when connecting to upstream. It combines default, mysql, and commit classifiers.
func NewUpstreamConnectionClassifier ¶
func NewUpstreamConnectionClassifier() *UpstreamConnectionClassifier
NewUpstreamConnectionClassifier creates a new UpstreamConnectionClassifier.
type UpstreamExecutor ¶
type UpstreamExecutor struct {
// contains filtered or unexported fields
}
UpstreamExecutor manages database connection, transaction lifecycle, and SQL execution for upstream MatrixOne cluster operations.
func NewUpstreamExecutor ¶
func NewUpstreamExecutor( account, user, password string, ip string, port int, retryTimes int, retryDuration time.Duration, timeout string, classifier ErrorClassifier, ) (*UpstreamExecutor, error)
NewUpstreamExecutor creates a new UpstreamExecutor with database connection
func (*UpstreamExecutor) Close ¶
func (e *UpstreamExecutor) Close() error
Close closes the database connection and rolls back any active transaction
func (*UpstreamExecutor) Connect ¶
func (e *UpstreamExecutor) Connect() error
Connect establishes a database connection
func (*UpstreamExecutor) EndTxn ¶
func (e *UpstreamExecutor) EndTxn(ctx context.Context, commit bool) error
EndTxn ends the current transaction (implements UpstreamExecutor interface)
func (*UpstreamExecutor) ExecSQL ¶
func (e *UpstreamExecutor) ExecSQL( ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, useTxn bool, needRetry bool, timeout time.Duration, ) (*Result, context.CancelFunc, error)
ExecSQL executes a SQL statement with options accountID: ignored for UpstreamExecutor (upstream account ID is invalid/not applicable) useTxn: must be false for UpstreamExecutor (transaction not supported, will error if true) UpstreamExecutor always uses connection-level autocommit (no explicit transactions) timeout: if > 0, each retry attempt will use a new context with this timeout; if 0, use the provided ctx directly Returns: result, cancel function (empty func if no timeout context was created), error IMPORTANT: caller MUST call the cancel function after finishing with the result
func (*UpstreamExecutor) ExecSQLInDatabase ¶
func (e *UpstreamExecutor) ExecSQLInDatabase( ctx context.Context, ar *ActiveRoutine, accountID uint32, query string, database string, useTxn bool, needRetry bool, timeout time.Duration, ) (*Result, context.CancelFunc, error)
ExecSQLInDatabase executes SQL with a specific default database context. For UpstreamExecutor, the database parameter is ignored since the connection string already specifies the database, and table names should be fully qualified.
type UpstreamSQLHelper ¶
type UpstreamSQLHelper interface {
// HandleSpecialSQL checks if the SQL is a special statement and handles it directly
// Returns (handled, result, error) where handled indicates if the statement was handled
HandleSpecialSQL(ctx context.Context, query string) (bool, *Result, error)
}
UpstreamSQLHelper interface for handling special SQL statements (CREATE/DROP SNAPSHOT, OBJECTLIST, GET OBJECT) without requiring Session
type UpstreamSQLHelperFactory ¶
type UpstreamSQLHelperFactory func( txnOp client.TxnOperator, engine engine.Engine, accountID uint32, executor executor.SQLExecutor, txnClient client.TxnClient, ) UpstreamSQLHelper
UpstreamSQLHelperFactory is a function type that creates an UpstreamSQLHelper Parameters: txnOp, engine, accountID, executor, txnClient (optional)
type Worker ¶
type Worker interface {
Submit(taskID string, lsn uint64, state int8) error
Stop()
// RegisterSyncProtection registers a sync protection job for keepalive
RegisterSyncProtection(jobID string, ttlExpireTS int64)
// UnregisterSyncProtection unregisters a sync protection job
UnregisterSyncProtection(jobID string)
// GetSyncProtectionTTL returns the current TTL expiration timestamp for a job
GetSyncProtectionTTL(jobID string) int64
}
type WriteObjectJob ¶
type WriteObjectJob struct {
// contains filtered or unexported fields
}
WriteObjectJob is a job for writing object to fileservice
func AcquireWriteObjectJob ¶
func AcquireWriteObjectJob() *WriteObjectJob
AcquireWriteObjectJob gets a WriteObjectJob from the pool
func NewWriteObjectJob ¶
func NewWriteObjectJob( ctx context.Context, localFS fileservice.FileService, objectName string, objectContent []byte, ccprCache CCPRTxnCacheWriter, txnID []byte, ) *WriteObjectJob
NewWriteObjectJob creates a new WriteObjectJob
func (*WriteObjectJob) GetObjectName ¶
func (j *WriteObjectJob) GetObjectName() string
GetObjectName returns the object name for WriteObjectJobInfo interface
func (*WriteObjectJob) GetObjectSize ¶
func (j *WriteObjectJob) GetObjectSize() int64
GetObjectSize returns the object content size for WriteObjectJobInfo interface
func (*WriteObjectJob) GetType ¶
func (j *WriteObjectJob) GetType() int8
GetType returns the job type
func (*WriteObjectJob) WaitDone ¶
func (j *WriteObjectJob) WaitDone() any
WaitDone waits for the job to complete and returns the result
type WriteObjectJobDuration ¶
WriteObjectJobDuration holds duration info for a WriteObject job
type WriteObjectJobInfo ¶
WriteObjectJobInfo is the interface for jobs that have object name and size
type WriteObjectJobResult ¶
type WriteObjectJobResult struct {
Err error
}
WriteObjectJobResult holds the result of WriteObjectJob
func AcquireWriteObjectJobResult ¶
func AcquireWriteObjectJobResult() *WriteObjectJobResult
AcquireWriteObjectJobResult gets a WriteObjectJobResult from the pool
type WriteObjectWorker ¶
WriteObjectWorker is the interface for write object worker pool
func NewWriteObjectWorker ¶
func NewWriteObjectWorker() WriteObjectWorker
NewWriteObjectWorker creates a new write object worker pool