github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/trace/metedata.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 trace 16 17 import ( 18 "time" 19 20 "github.com/matrixorigin/matrixone/pkg/common/util" 21 "github.com/matrixorigin/matrixone/pkg/pb/api" 22 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 23 "github.com/matrixorigin/matrixone/pkg/pb/txn" 24 ) 25 26 var ( 27 // cannot import catalog, because cycle import 28 29 complexPKColumnName = "__mo_cpkey_col" 30 rowIDColumn = "__mo_rowid" 31 deletePKColumn = "pk" 32 disableColumns = map[string]struct{}{ 33 "object_stats": {}, 34 "__mo_%1_commit_time": {}, 35 "%!%mo__meta_loc": {}, 36 "delta_loc": {}, 37 "segment_id": {}, 38 "trunc_pointt": {}, 39 } 40 41 txnCreateEvent = "created" 42 txnActiveEvent = "active" 43 txnClosedEvent = "closed" 44 txnUpdateSnapshotEvent = "update-snapshot" 45 txnExecuteEvent = "execute" 46 txnUpdateSnapshotReasonEvent = "update-snapshot-reason" 47 txnNoConflictChanged = "no-conflict-changed" 48 txnConflictChanged = "conflict-changed" 49 50 entryApplyEvent = "apply" 51 entryCommitEvent = "commit" 52 entryReadEvent = "read" 53 entryWriteEvent = "write" 54 entryWorkspaceEvent = "workspace" 55 entryReadBlockEvent = "read-block" 56 entryApplyFlushEvent = "apply-flush" 57 entryTransferRowIDEvent = "transfer-row-id" 58 entryDeleteObjectEvent = "apply-delete-object" 59 ) 60 61 func isComplexColumn(name string) bool { 62 return name == complexPKColumnName 63 } 64 65 func isRowIDColumn(name string) bool { 66 return name == rowIDColumn 67 } 68 69 func isDeletePKColumn(name string) bool { 70 return name == deletePKColumn 71 } 72 73 type txnEvent struct { 74 ts int64 75 eventType string 76 txnID []byte 77 txnStatus string 78 snapshotTS timestamp.Timestamp 79 commitTS timestamp.Timestamp 80 info string 81 } 82 83 func newTxnInfoEvent( 84 txn txn.TxnMeta, 85 eventType string, 86 info string) txnEvent { 87 e := newTxnEvent(txn, eventType) 88 e.info = info 89 return e 90 } 91 92 func newTxnCreated(txn txn.TxnMeta) txnEvent { 93 return newTxnEvent(txn, txnCreateEvent) 94 } 95 96 func newTxnActive(txn txn.TxnMeta) txnEvent { 97 return newTxnEvent(txn, txnActiveEvent) 98 } 99 100 func newTxnClosed(txn txn.TxnMeta) txnEvent { 101 return newTxnEvent(txn, txnClosedEvent) 102 } 103 104 func newTxnSnapshotUpdated(txn txn.TxnMeta) txnEvent { 105 return newTxnEvent(txn, txnUpdateSnapshotEvent) 106 } 107 108 func newTxnEvent( 109 txn txn.TxnMeta, 110 event string) txnEvent { 111 return txnEvent{ 112 ts: time.Now().UnixNano(), 113 eventType: event, 114 txnID: txn.ID, 115 snapshotTS: txn.SnapshotTS, 116 commitTS: txn.CommitTS, 117 txnStatus: txn.Status.String(), 118 } 119 } 120 121 func (e txnEvent) toCSVRecord( 122 cn string, 123 buf *buffer, 124 records []string) { 125 records[0] = buf.writeInt(e.ts) 126 records[1] = buf.writeHex(e.txnID) 127 records[2] = cn 128 records[3] = e.eventType 129 records[4] = e.txnStatus 130 records[5] = buf.writeTimestamp(e.snapshotTS) 131 records[6] = buf.writeTimestamp(e.commitTS) 132 records[7] = e.info 133 } 134 135 type dataEvent struct { 136 ts int64 137 eventType string 138 customEntry string 139 entryType api.Entry_EntryType 140 tableID uint64 141 txnID []byte 142 row []byte 143 commitTS timestamp.Timestamp 144 snapshotTS timestamp.Timestamp 145 } 146 147 func newApplyLogtailEvent( 148 ts int64, 149 tableID uint64, 150 entryType api.Entry_EntryType, 151 row []byte, 152 commitTS timestamp.Timestamp) dataEvent { 153 return dataEvent{ 154 ts: ts, 155 tableID: tableID, 156 entryType: entryType, 157 row: row, 158 commitTS: commitTS, 159 eventType: entryApplyEvent, 160 } 161 } 162 163 func newCommitEntryEvent( 164 ts int64, 165 txnID []byte, 166 tableID uint64, 167 entryType api.Entry_EntryType, 168 row []byte) dataEvent { 169 return dataEvent{ 170 ts: ts, 171 tableID: tableID, 172 entryType: entryType, 173 txnID: txnID, 174 row: row, 175 eventType: entryCommitEvent, 176 } 177 } 178 179 func newReadEntryEvent( 180 ts int64, 181 txnID []byte, 182 tableID uint64, 183 row []byte, 184 snapshotTS timestamp.Timestamp) dataEvent { 185 return dataEvent{ 186 ts: ts, 187 tableID: tableID, 188 customEntry: "read", 189 txnID: txnID, 190 row: row, 191 eventType: entryReadEvent, 192 snapshotTS: snapshotTS, 193 } 194 } 195 196 func newWriteEntryEvent( 197 ts int64, 198 txnID []byte, 199 typ string, 200 tableID uint64, 201 row []byte) dataEvent { 202 return dataEvent{ 203 ts: ts, 204 tableID: tableID, 205 customEntry: typ, 206 txnID: txnID, 207 row: row, 208 eventType: entryWriteEvent, 209 } 210 } 211 212 func newWorkspaceEntryEvent( 213 ts int64, 214 txnID []byte, 215 typ string, 216 tableID uint64, 217 row []byte) dataEvent { 218 return dataEvent{ 219 ts: ts, 220 tableID: tableID, 221 customEntry: typ, 222 txnID: txnID, 223 row: row, 224 eventType: entryWorkspaceEvent, 225 } 226 } 227 228 func newFlushEvent( 229 ts int64, 230 txnID []byte, 231 tableID uint64, 232 row []byte) dataEvent { 233 return dataEvent{ 234 ts: ts, 235 txnID: txnID, 236 tableID: tableID, 237 row: row, 238 eventType: entryApplyFlushEvent, 239 } 240 } 241 242 func newReadBlockEvent( 243 ts int64, 244 txnID []byte, 245 tableID uint64, 246 row []byte) dataEvent { 247 return dataEvent{ 248 ts: ts, 249 txnID: txnID, 250 tableID: tableID, 251 row: row, 252 eventType: entryReadBlockEvent, 253 } 254 } 255 256 func newTransferEvent( 257 ts int64, 258 txnID []byte, 259 tableID uint64, 260 row []byte) dataEvent { 261 return dataEvent{ 262 ts: ts, 263 txnID: txnID, 264 tableID: tableID, 265 row: row, 266 eventType: entryTransferRowIDEvent, 267 } 268 } 269 270 func newDeleteObjectEvent( 271 ts int64, 272 tableID uint64, 273 row []byte) dataEvent { 274 return dataEvent{ 275 ts: ts, 276 tableID: tableID, 277 row: row, 278 eventType: entryDeleteObjectEvent, 279 } 280 } 281 282 func (e dataEvent) toCSVRecord( 283 cn string, 284 buf *buffer, 285 records []string) { 286 records[0] = buf.writeInt(e.ts) 287 records[1] = cn 288 records[2] = e.eventType 289 if e.customEntry != "" { 290 records[3] = e.customEntry 291 } else { 292 records[3] = e.entryType.String() 293 } 294 records[4] = buf.writeUint(e.tableID) 295 records[5] = buf.writeHex(e.txnID) 296 records[6] = util.UnsafeBytesToString(e.row) 297 records[7] = buf.writeTimestamp(e.commitTS) 298 records[8] = buf.writeTimestamp(e.snapshotTS) 299 } 300 301 type actionEvent struct { 302 ts int64 303 txnID []byte 304 action string 305 tableID uint64 306 actionSeq uint64 307 value int64 308 unit string 309 err string 310 } 311 312 func (e actionEvent) toCSVRecord( 313 cn string, 314 buf *buffer, 315 records []string) { 316 records[0] = buf.writeInt(e.ts) 317 records[1] = buf.writeHex(e.txnID) 318 records[2] = cn 319 records[3] = buf.writeUint(e.tableID) 320 records[4] = e.action 321 records[5] = buf.writeUint(e.actionSeq) 322 records[6] = buf.writeInt(e.value) 323 records[7] = e.unit 324 if len(e.err) > 100 { 325 e.err = e.err[:100] 326 } 327 records[8] = e.err 328 } 329 330 type statement struct { 331 ts int64 332 txnID []byte 333 sql string 334 cost int64 335 } 336 337 func newStatement( 338 txnID []byte, 339 sql string, 340 cost time.Duration) statement { 341 return statement{ 342 ts: time.Now().UnixNano(), 343 txnID: txnID, 344 sql: sql, 345 cost: cost.Microseconds(), 346 } 347 } 348 349 func (e statement) toCSVRecord( 350 cn string, 351 buf *buffer, 352 records []string) { 353 records[0] = buf.writeInt(e.ts) 354 records[1] = buf.writeHex(e.txnID) 355 records[2] = e.sql 356 records[3] = buf.writeInt(e.cost) 357 } 358 359 func truncateSQL(sql string) string { 360 if len(sql) > 1000 { 361 return sql[:1000] 362 } 363 return sql 364 }