publication

package
v0.0.0-debug-20260702 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 56 Imported by: 0

Documentation

Index

Constants

View Source
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)

View Source
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
)
View Source
const (
	JobTypeGetMeta      int8 = 1
	JobTypeGetChunk     int8 = 2
	JobTypeFilterObject int8 = 3
	JobTypeWriteObject  int8 = 4
)

Job types

View Source
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

View Source
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"}')`
)
View Source
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
)
View Source
const (
	SyncLevelAccount  = "account"
	SyncLevelDatabase = "database"
	SyncLevelTable    = "table"
)

SyncLevel represents the level of synchronization

View Source
const (
	DDLOperationCreate       int8 = 1
	DDLOperationAlter        int8 = 2
	DDLOperationDrop         int8 = 3
	DDLOperationAlterInplace int8 = 4
)

DDL operation types

View Source
const (
	SubscriptionStateRunning int8 = 0 // running
	SubscriptionStateError   int8 = 1 // error
	SubscriptionStatePause   int8 = 2 // pause
	SubscriptionStateDropped int8 = 3 // dropped
)

Subscription state types

View Source
const (
	SubmitRetryTimes    = 1000
	SubmitRetryDuration = time.Hour

	StatsPrintInterval = 10 * time.Second
)
View Source
const (
	InternalSQLExecutorType = "internal_sql_executor"
)
View Source
const InvalidAccountID uint32 = 0xFFFFFFFF

InvalidAccountID represents an invalid account ID that should be ignored

View Source
const (
	MOCcprLogTableName = catalog.MO_CCPR_LOG
)

Variables

View Source
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
}
View Source
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

View Source
var ErrNonRetryable = moerr.NewInternalErrorNoCtx("non-retryable error")

ErrNonRetryable indicates the operation should not be retried.

View Source
var ErrSyncProtectionTTLExpired = moerr.NewInternalErrorNoCtx("sync protection TTL expired")

ErrSyncProtectionTTLExpired is returned when sync protection TTL has expired

View Source
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)
}
View Source
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

View Source
var PublicationSQLBuilder = publicationSQLBuilder{}
View Source
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,
	},
}
View Source
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 GC

func GC(
	ctx context.Context,
	txnEngine engine.Engine,
	cnTxnClient client.TxnClient,
	cnUUID string,
	upstreamSQLHelperFactory UpstreamSQLHelperFactory,
	cleanupThreshold time.Duration,
) (err error)

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

func GenerateSnapshotName(taskID string, iterationLSN uint64) string

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

func GetGCInterval() time.Duration

GetGCInterval returns the configured GC interval

func GetGCTTL

func GetGCTTL() time.Duration

GetGCTTL returns the configured GC TTL

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

func GetRetryInterval() time.Duration

GetRetryInterval returns the configured retry interval

func GetRetryThreshold

func GetRetryThreshold() int

GetRetryThreshold returns the configured retry threshold

func GetRetryTimes

func GetRetryTimes() int

GetRetryTimes returns the configured retry times

func GetSyncProtectionRenewInterval

func GetSyncProtectionRenewInterval() time.Duration

GetSyncProtectionRenewInterval returns the configured sync protection renew interval

func GetSyncProtectionTTLDuration

func GetSyncProtectionTTLDuration() time.Duration

GetSyncProtectionTTLDuration returns the configured sync protection TTL duration

func GetSyncTaskInterval

func GetSyncTaskInterval() time.Duration

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

func IsGCRunningError(err error) bool

IsGCRunningError checks if the error is a GC running error

func IsRetryableError

func IsRetryableError(err error) bool

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

func IsSyncProtectionExistsError(err error) bool

IsSyncProtectionExistsError checks if the error indicates sync protection already exists

func IsSyncProtectionInvalidError

func IsSyncProtectionInvalidError(err error) bool

IsSyncProtectionInvalidError checks if the error indicates invalid sync protection request

func IsSyncProtectionMaxCountError

func IsSyncProtectionMaxCountError(err error) bool

IsSyncProtectionMaxCountError checks if the error indicates max count reached

func IsSyncProtectionNotFoundError

func IsSyncProtectionNotFoundError(err error) bool

IsSyncProtectionNotFoundError checks if the error indicates sync protection not found

func IsSyncProtectionSoftDeleteError

func IsSyncProtectionSoftDeleteError(err error) bool

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

type ActiveRoutine struct {
	sync.Mutex
	Pause  chan struct{}
	Cancel chan struct{}
}

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.

func (ExponentialBackoff) Next

func (b ExponentialBackoff) Next(attempt int) time.Duration

Next implements BackoffStrategy.

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

type FilterObjectWorker interface {
	SubmitFilterObject(job Job) error
	Stop()
}

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) GetType

func (j *GetChunkJob) GetType() int8

GetType returns the job type

func (*GetChunkJob) WaitDone

func (j *GetChunkJob) WaitDone() any

WaitDone waits for the job to complete and returns the result

type GetChunkJobDuration

type GetChunkJobDuration struct {
	ObjectName string
	ChunkIndex int64
	Duration   time.Duration
}

GetChunkJobDuration holds duration info for a GetChunk job

type GetChunkJobInfo

type GetChunkJobInfo interface {
	GetObjectName() string
	GetChunkIndex() int64
}

GetChunkJobInfo is the interface for jobs that have object name and chunk index

type GetChunkJobResult

type GetChunkJobResult struct {
	ChunkData  []byte
	ChunkIndex int64
	Err        error
}

GetChunkJobResult holds the result of GetChunkJob

func AcquireGetChunkJobResult

func AcquireGetChunkJobResult() *GetChunkJobResult

AcquireGetChunkJobResult gets a GetChunkJobResult from the pool

type GetChunkWorker

type GetChunkWorker interface {
	SubmitGetChunk(job Job) error
	Stop()
}

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) GetType

func (j *GetMetaJob) GetType() int8

GetType returns the job type

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) Next

func (r *InternalResult) Next() bool

Next moves to the next row

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 Job

type Job interface {
	Execute()
	WaitDone() any
	GetType() int8
}

Job is an interface for async jobs

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 GetJobStats

func GetJobStats() *JobStats

GetJobStats returns the global job stats

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

func (s *JobStats) RecordWriteObjectDuration(objectName string, size int64, duration time.Duration)

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

func (p Policy) Do(ctx context.Context, op Operation) error

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

func NewResultFromExecutorResult(execResult executor.Result) *Result

NewResultFromExecutorResult creates a new Result from executor.Result This is exported so that external packages (like test helpers) can create Result objects

func (*Result) Close

func (r *Result) Close() error

Close closes the result rows

func (*Result) Err

func (r *Result) Err() error

Err returns any error encountered during iteration

func (*Result) Next

func (r *Result) Next() bool

Next moves to the next row

func (*Result) Scan

func (r *Result) Scan(dest ...interface{}) error

Scan scans the current row into the provided destinations

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 TableKey

type TableKey struct {
	DBName    string // Database name
	TableName string // Table name
}

TableKey represents a key for TableIDs map

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 TaskContext struct {
	TaskID string
	LSN    uint64
}

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
}

func NewWorker

func NewWorker(
	cnUUID string,
	cnEngine engine.Engine,
	cnTxnClient client.TxnClient,
	mp *mpool.MPool,
	upstreamSQLHelperFactory UpstreamSQLHelperFactory,
) Worker

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) Execute

func (j *WriteObjectJob) Execute()

Execute runs the 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

type WriteObjectJobDuration struct {
	ObjectName string
	Size       int64
	Duration   time.Duration
}

WriteObjectJobDuration holds duration info for a WriteObject job

type WriteObjectJobInfo

type WriteObjectJobInfo interface {
	GetObjectName() string
	GetObjectSize() int64
}

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

type WriteObjectWorker interface {
	SubmitWriteObject(job Job) error
	Stop()
}

WriteObjectWorker is the interface for write object worker pool

func NewWriteObjectWorker

func NewWriteObjectWorker() WriteObjectWorker

NewWriteObjectWorker creates a new write object worker pool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL