@@ -541,128 +541,114 @@ func (bd *BackupDestination) throttleSpeed(startTime time.Time, size int64, maxS
541541
542542func NewBackupDestination (ctx context.Context , cfg * config.Config , ch * clickhouse.ClickHouse , backupName string ) (* BackupDestination , error ) {
543543 var err error
544+ // Lock config to safely apply macros and modify config values
545+ cfg .Lock ()
546+ defer cfg .Unlock ()
547+
544548 switch cfg .General .RemoteStorage {
545549 case "azblob" :
546- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
547- azblobConfig := cfg .AzureBlob
548- azblobStorage := & AzureBlob {
549- Config : & azblobConfig ,
550- }
551- if azblobStorage .Config .Path , err = ch .ApplyMacros (ctx , azblobStorage .Config .Path ); err != nil {
550+ if cfg .AzureBlob .Path , err = ch .ApplyMacros (ctx , cfg .AzureBlob .Path ); err != nil {
552551 return nil , err
553552 }
554- if azblobStorage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , azblobStorage . Config .ObjectDiskPath ); err != nil {
553+ if cfg . AzureBlob .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . AzureBlob .ObjectDiskPath ); err != nil {
555554 return nil , err
556555 }
557-
556+ azblobStorage := & AzureBlob {
557+ Config : & cfg .AzureBlob ,
558+ }
558559 return & BackupDestination {
559560 azblobStorage ,
560561 cfg .AzureBlob .CompressionFormat ,
561562 cfg .AzureBlob .CompressionLevel ,
562563 }, nil
563564 case "s3" :
564- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
565- s3Config := cfg .S3
566- s3Storage := & S3 {
567- Config : & s3Config ,
568- Concurrency : cfg .S3 .Concurrency ,
569- BufferSize : 64 * 1024 ,
570- }
571- if s3Storage .Config .Path , err = ch .ApplyMacros (ctx , s3Storage .Config .Path ); err != nil {
565+ if cfg .S3 .Path , err = ch .ApplyMacros (ctx , cfg .S3 .Path ); err != nil {
572566 return nil , err
573567 }
574- if s3Storage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , s3Storage . Config .ObjectDiskPath ); err != nil {
568+ if cfg . S3 .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . S3 .ObjectDiskPath ); err != nil {
575569 return nil , err
576570 }
577571 // https://github.com/Altinity/clickhouse-backup/issues/588
578- if len (s3Storage .Config .ObjectLabels ) > 0 && backupName != "" {
579- objectLabels := s3Storage .Config .ObjectLabels
580- objectLabels , err = ch .ApplyMacrosToObjectLabels (ctx , objectLabels , backupName )
572+ if len (cfg .S3 .ObjectLabels ) > 0 && backupName != "" {
573+ cfg .S3 .ObjectLabels , err = ch .ApplyMacrosToObjectLabels (ctx , cfg .S3 .ObjectLabels , backupName )
581574 if err != nil {
582575 return nil , err
583576 }
584- s3Storage .Config .ObjectLabels = objectLabels
577+ }
578+ s3Storage := & S3 {
579+ Config : & cfg .S3 ,
580+ Concurrency : cfg .S3 .Concurrency ,
581+ BufferSize : 64 * 1024 ,
585582 }
586583 return & BackupDestination {
587584 s3Storage ,
588585 cfg .S3 .CompressionFormat ,
589586 cfg .S3 .CompressionLevel ,
590587 }, nil
591588 case "gcs" :
592- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
593- gcsConfig := cfg .GCS
594- googleCloudStorage := & GCS {Config : & gcsConfig }
595- if googleCloudStorage .Config .Path , err = ch .ApplyMacros (ctx , googleCloudStorage .Config .Path ); err != nil {
589+ if cfg .GCS .Path , err = ch .ApplyMacros (ctx , cfg .GCS .Path ); err != nil {
596590 return nil , err
597591 }
598- if googleCloudStorage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , googleCloudStorage . Config .ObjectDiskPath ); err != nil {
592+ if cfg . GCS .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . GCS .ObjectDiskPath ); err != nil {
599593 return nil , err
600594 }
601595 // https://github.com/Altinity/clickhouse-backup/issues/588
602- if len (googleCloudStorage .Config .ObjectLabels ) > 0 && backupName != "" {
603- objectLabels := googleCloudStorage .Config .ObjectLabels
604- objectLabels , err = ch .ApplyMacrosToObjectLabels (ctx , objectLabels , backupName )
596+ if len (cfg .GCS .ObjectLabels ) > 0 && backupName != "" {
597+ cfg .GCS .ObjectLabels , err = ch .ApplyMacrosToObjectLabels (ctx , cfg .GCS .ObjectLabels , backupName )
605598 if err != nil {
606599 return nil , err
607600 }
608- googleCloudStorage .Config .ObjectLabels = objectLabels
609601 }
602+ googleCloudStorage := & GCS {Config : & cfg .GCS }
610603 return & BackupDestination {
611604 googleCloudStorage ,
612605 cfg .GCS .CompressionFormat ,
613606 cfg .GCS .CompressionLevel ,
614607 }, nil
615608 case "cos" :
616- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
617- cosConfig := cfg .COS
618- tencentStorage := & COS {
619- Config : & cosConfig ,
620- BufferSize : 64 * 1024 ,
621- }
622- if tencentStorage .Config .Path , err = ch .ApplyMacros (ctx , tencentStorage .Config .Path ); err != nil {
609+ if cfg .COS .Path , err = ch .ApplyMacros (ctx , cfg .COS .Path ); err != nil {
623610 return nil , err
624611 }
625- if tencentStorage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , tencentStorage . Config .ObjectDiskPath ); err != nil {
612+ if cfg . COS .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . COS .ObjectDiskPath ); err != nil {
626613 return nil , err
627614 }
615+ tencentStorage := & COS {
616+ Config : & cfg .COS ,
617+ BufferSize : 64 * 1024 ,
618+ }
628619 return & BackupDestination {
629620 tencentStorage ,
630621 cfg .COS .CompressionFormat ,
631622 cfg .COS .CompressionLevel ,
632623 }, nil
633624 case "ftp" :
634- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
635- ftpConfig := cfg .FTP
636- if ftpConfig .Concurrency < cfg .General .ObjectDiskServerSideCopyConcurrency / 4 {
637- ftpConfig .Concurrency = cfg .General .ObjectDiskServerSideCopyConcurrency
638- }
639- ftpStorage := & FTP {
640- Config : & ftpConfig ,
625+ if cfg .FTP .Concurrency < cfg .General .ObjectDiskServerSideCopyConcurrency / 4 {
626+ cfg .FTP .Concurrency = cfg .General .ObjectDiskServerSideCopyConcurrency
641627 }
642- if ftpStorage . Config .Path , err = ch .ApplyMacros (ctx , ftpStorage . Config .Path ); err != nil {
628+ if cfg . FTP .Path , err = ch .ApplyMacros (ctx , cfg . FTP .Path ); err != nil {
643629 return nil , err
644630 }
645- if ftpStorage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , ftpStorage . Config .ObjectDiskPath ); err != nil {
631+ if cfg . FTP .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . FTP .ObjectDiskPath ); err != nil {
646632 return nil , err
647633 }
634+ ftpStorage := & FTP {
635+ Config : & cfg .FTP ,
636+ }
648637 return & BackupDestination {
649638 ftpStorage ,
650639 cfg .FTP .CompressionFormat ,
651640 cfg .FTP .CompressionLevel ,
652641 }, nil
653642 case "sftp" :
654- // Copy config to avoid data race when multiple goroutines call NewBackupDestination
655- sftpConfig := cfg .SFTP
656- sftpStorage := & SFTP {
657- Config : & sftpConfig ,
658- }
659- if sftpStorage .Config .Path , err = ch .ApplyMacros (ctx , sftpStorage .Config .Path ); err != nil {
643+ if cfg .SFTP .Path , err = ch .ApplyMacros (ctx , cfg .SFTP .Path ); err != nil {
660644 return nil , err
661645 }
662- if sftpStorage . Config .ObjectDiskPath , err = ch .ApplyMacros (ctx , sftpStorage . Config .ObjectDiskPath ); err != nil {
646+ if cfg . SFTP .ObjectDiskPath , err = ch .ApplyMacros (ctx , cfg . SFTP .ObjectDiskPath ); err != nil {
663647 return nil , err
664648 }
665-
649+ sftpStorage := & SFTP {
650+ Config : & cfg .SFTP ,
651+ }
666652 return & BackupDestination {
667653 sftpStorage ,
668654 cfg .SFTP .CompressionFormat ,
0 commit comments