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 }