github.com/matrixorigin/matrixone@v1.2.0/pkg/bootstrap/versions/version_upgrade.go (about)

     1  // Copyright 2024 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package versions
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/catalog"
    21  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    22  	"github.com/matrixorigin/matrixone/pkg/util/executor"
    23  )
    24  
    25  func GetUpgradeVersions(
    26  	finalVersion string,
    27  	finalVersionOffset uint32,
    28  	txn executor.TxnExecutor,
    29  	forUpdate bool,
    30  	mustHave bool) ([]VersionUpgrade, error) {
    31  	sql := fmt.Sprintf(`select 
    32  			id,
    33  			from_version, 
    34  			to_version, 
    35  			final_version, 
    36  			final_version_offset, 
    37  			state, 
    38  			upgrade_order,
    39  			upgrade_cluster,
    40  			upgrade_tenant,
    41  			total_tenant,
    42  			ready_tenant from %s 
    43  			where final_version = '%s' and final_version_offset = %d
    44  			order by upgrade_order asc`,
    45  		catalog.MOUpgradeTable,
    46  		finalVersion,
    47  		finalVersionOffset)
    48  
    49  	if forUpdate {
    50  		sql = fmt.Sprintf("%s for update", sql)
    51  	}
    52  	values, err := getVersionUpgradesBySQL(sql, txn)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	if len(values) == 0 && mustHave {
    57  		panic("BUG: missing version upgrade")
    58  	}
    59  	return values, nil
    60  }
    61  
    62  func GetUpgradeVersionsByOrder(
    63  	finalVersion string,
    64  	order int32,
    65  	txn executor.TxnExecutor) ([]VersionUpgrade, error) {
    66  	sql := fmt.Sprintf(`select 
    67  			id,
    68  			from_version, 
    69  			to_version, 
    70  			final_version, 
    71  			final_version_offset, 
    72  			state, 
    73  			upgrade_order,
    74  			upgrade_cluster,
    75  			upgrade_tenant,
    76  			total_tenant,
    77  			ready_tenant from %s 
    78  			where final_version = '%s' and upgrade_order = %d`,
    79  		catalog.MOUpgradeTable,
    80  		finalVersion,
    81  		order)
    82  	values, err := getVersionUpgradesBySQL(sql, txn)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	return values, nil
    87  }
    88  
    89  func GetUpgradingTenantVersion(txn executor.TxnExecutor) (VersionUpgrade, bool, error) {
    90  	sql := fmt.Sprintf(`select 
    91  			id,
    92  			from_version, 
    93  			to_version, 
    94  			final_version, 
    95  			final_version_offset, 
    96  			state, 
    97  			upgrade_order,
    98  			upgrade_cluster,
    99  			upgrade_tenant,
   100  			total_tenant,
   101  			ready_tenant
   102  			from %s 
   103  			where state = %d 
   104  			order by upgrade_order asc`,
   105  		catalog.MOUpgradeTable,
   106  		StateUpgradingTenant)
   107  	values, err := getVersionUpgradesBySQL(sql, txn)
   108  	if err != nil {
   109  		return VersionUpgrade{}, false, err
   110  	}
   111  	if len(values) == 0 {
   112  		return VersionUpgrade{}, false, nil
   113  	}
   114  	if len(values) != 1 {
   115  		panic("BUG: invalid version upgrade")
   116  	}
   117  	return values[0], true, nil
   118  }
   119  
   120  func GetUpgradeVersionForUpdateByID(
   121  	id uint64,
   122  	txn executor.TxnExecutor) (VersionUpgrade, error) {
   123  	sql := fmt.Sprintf(`select 
   124  			id,
   125  			from_version, 
   126  			to_version, 
   127  			final_version, 
   128  			final_version_offset, 
   129  			state, 
   130  			upgrade_order,
   131  			upgrade_cluster,
   132  			upgrade_tenant,
   133  			total_tenant,
   134  			ready_tenant
   135  			from %s 
   136  			where id = %d for update`,
   137  		catalog.MOUpgradeTable,
   138  		id)
   139  	values, err := getVersionUpgradesBySQL(sql, txn)
   140  	if err != nil {
   141  		return VersionUpgrade{}, err
   142  	}
   143  	if len(values) != 1 {
   144  		panic(fmt.Sprintf("BUG: can not get version upgrade by primary key: %d", id))
   145  	}
   146  	return values[0], nil
   147  }
   148  
   149  func AddVersionUpgrades(
   150  	values []VersionUpgrade,
   151  	txn executor.TxnExecutor) error {
   152  	for _, v := range values {
   153  		sql := GetVersionUpgradeSQL(v)
   154  		res, err := txn.Exec(sql, executor.StatementOption{})
   155  		if err != nil {
   156  			return err
   157  		}
   158  		res.Close()
   159  	}
   160  	return nil
   161  }
   162  
   163  func UpdateVersionUpgradeState(
   164  	upgrade VersionUpgrade,
   165  	state int32,
   166  	txn executor.TxnExecutor) error {
   167  	sql := fmt.Sprintf("update %s set state = %d, update_at = current_timestamp() where final_version = '%s' and final_version_offset = %d and upgrade_order = %d",
   168  		catalog.MOUpgradeTable,
   169  		state,
   170  		upgrade.FinalVersion,
   171  		upgrade.FinalVersionOffset,
   172  		upgrade.UpgradeOrder)
   173  	res, err := txn.Exec(sql, executor.StatementOption{})
   174  	if err != nil {
   175  		return err
   176  	}
   177  	res.Close()
   178  	return nil
   179  }
   180  
   181  func UpdateVersionUpgradeTasks(
   182  	upgrade VersionUpgrade,
   183  	txn executor.TxnExecutor) error {
   184  	updateState := ""
   185  	if upgrade.TotalTenant == upgrade.ReadyTenant {
   186  		updateState = fmt.Sprintf("state = %d,", StateReady)
   187  	}
   188  	sql := fmt.Sprintf("update %s set total_tenant = %d, ready_tenant = %d,%s update_at = current_timestamp() where final_version = '%s' and final_version_offset = %d and upgrade_order = %d",
   189  		catalog.MOUpgradeTable,
   190  		upgrade.TotalTenant,
   191  		upgrade.ReadyTenant,
   192  		updateState,
   193  		upgrade.FinalVersion,
   194  		upgrade.FinalVersionOffset,
   195  		upgrade.UpgradeOrder)
   196  	res, err := txn.Exec(sql, executor.StatementOption{})
   197  	if err != nil {
   198  		return err
   199  	}
   200  	res.Close()
   201  	return nil
   202  }
   203  
   204  func GetVersionUpgradeSQL(v VersionUpgrade) string {
   205  	return fmt.Sprintf(`insert into %s (from_version, 
   206  		to_version, 
   207  		final_version, 
   208          final_version_offset, 
   209  		state, 
   210  		upgrade_cluster, 
   211  		upgrade_tenant, 
   212  		upgrade_order, 
   213  		total_tenant, 
   214  		ready_tenant, 
   215  		create_at, 
   216  		update_at) values ('%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, current_timestamp(), current_timestamp())`,
   217  		catalog.MOUpgradeTable,
   218  		v.FromVersion,
   219  		v.ToVersion,
   220  		v.FinalVersion,
   221  		v.FinalVersionOffset,
   222  		v.State,
   223  		v.UpgradeCluster,
   224  		v.UpgradeTenant,
   225  		v.UpgradeOrder,
   226  		v.TotalTenant,
   227  		v.ReadyTenant)
   228  }
   229  
   230  func getVersionUpgradesBySQL(
   231  	sql string,
   232  	txn executor.TxnExecutor) ([]VersionUpgrade, error) {
   233  	res, err := txn.Exec(sql, executor.StatementOption{})
   234  	if err != nil {
   235  		return nil, err
   236  	}
   237  	defer res.Close()
   238  
   239  	var values []VersionUpgrade
   240  	res.ReadRows(func(rows int, cols []*vector.Vector) bool {
   241  		for i := 0; i < rows; i++ {
   242  			value := VersionUpgrade{}
   243  			value.ID = vector.GetFixedAt[uint64](cols[0], i)
   244  			value.FromVersion = cols[1].GetStringAt(i)
   245  			value.ToVersion = cols[2].GetStringAt(i)
   246  			value.FinalVersion = cols[3].GetStringAt(i)
   247  			value.FinalVersionOffset = vector.GetFixedAt[uint32](cols[4], i)
   248  			value.State = vector.GetFixedAt[int32](cols[5], i)
   249  			value.UpgradeOrder = vector.GetFixedAt[int32](cols[6], i)
   250  			value.UpgradeCluster = vector.GetFixedAt[int32](cols[7], i)
   251  			value.UpgradeTenant = vector.GetFixedAt[int32](cols[8], i)
   252  			value.TotalTenant = vector.GetFixedAt[int32](cols[9], i)
   253  			value.ReadyTenant = vector.GetFixedAt[int32](cols[10], i)
   254  			values = append(values, value)
   255  		}
   256  
   257  		return true
   258  	})
   259  	return values, nil
   260  }