@@ -40,6 +40,7 @@ import org.apache.spark.sql.delta.metering.DeltaLogging
40
40
import org .apache .spark .sql .delta .schema .{SchemaMergingUtils , SchemaUtils }
41
41
import org .apache .spark .sql .delta .sources .DeltaSQLConf
42
42
import org .apache .spark .sql .delta .stats ._
43
+ import org .apache .spark .sql .util .ScalaExtensions ._
43
44
import org .apache .hadoop .fs .{FileStatus , Path }
44
45
45
46
import org .apache .spark .SparkException
@@ -296,7 +297,7 @@ trait OptimisticTransactionImpl extends TransactionalWrite
296
297
* Tracks the start time since we started trying to write a particular commit.
297
298
* Used for logging duration of retried transactions.
298
299
*/
299
- protected var commitAttemptStartTime : Long = _
300
+ protected var commitAttemptStartTimeMillis : Long = _
300
301
301
302
/**
302
303
* Tracks actions within the transaction, will commit along with the passed-in actions in the
@@ -371,6 +372,18 @@ trait OptimisticTransactionImpl extends TransactionalWrite
371
372
// will be detected as a conflict and the transaction will anyway fail.
372
373
private [delta] val preCommitCommitStoreOpt : Option [CommitStore ] = snapshot.commitStoreOpt
373
374
375
+ /**
376
+ * Generates a timestamp which is greater than the commit timestamp
377
+ * of the last snapshot. Note that this is only needed when the
378
+ * feature `inCommitTimestamps` is enabled.
379
+ */
380
+ protected [delta] def generateInCommitTimestampForFirstCommitAttempt (
381
+ currentTimestamp : Long ): Option [Long ] =
382
+ Option .when(DeltaConfigs .IN_COMMIT_TIMESTAMPS_ENABLED .fromMetaData(metadata)) {
383
+ val lastCommitTimestamp = snapshot.timestamp
384
+ math.max(currentTimestamp, lastCommitTimestamp + 1 )
385
+ }
386
+
374
387
/** The end to end execution time of this transaction. */
375
388
def txnExecutionTimeMs : Option [Long ] = if (commitEndNano == - 1 ) {
376
389
None
@@ -1086,31 +1099,50 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1086
1099
val readRowIdHighWatermark =
1087
1100
RowId .extractHighWatermark(snapshot).getOrElse(RowId .MISSING_HIGH_WATER_MARK )
1088
1101
1102
+ commitAttemptStartTimeMillis = clock.getTimeMillis()
1089
1103
commitInfo = CommitInfo (
1090
- clock.getTimeMillis(),
1091
- op.name,
1092
- op.jsonEncodedValues,
1093
- Map .empty,
1094
- Some (readVersion).filter(_ >= 0 ),
1095
- Option (isolationLevelToUse.toString),
1096
- Some (isBlindAppend),
1097
- getOperationMetrics(op),
1098
- getUserMetadata(op),
1104
+ time = commitAttemptStartTimeMillis,
1105
+ operation = op.name,
1106
+ inCommitTimestamp =
1107
+ generateInCommitTimestampForFirstCommitAttempt(commitAttemptStartTimeMillis),
1108
+ operationParameters = op.jsonEncodedValues,
1109
+ commandContext = Map .empty,
1110
+ readVersion = Some (readVersion).filter(_ >= 0 ),
1111
+ isolationLevel = Option (isolationLevelToUse.toString),
1112
+ isBlindAppend = Some (isBlindAppend),
1113
+ operationMetrics = getOperationMetrics(op),
1114
+ userMetadata = getUserMetadata(op),
1099
1115
tags = if (tags.nonEmpty) Some (tags) else None ,
1100
1116
txnId = Some (txnId))
1101
1117
1102
1118
// Validate that the [[DeltaConfigs.MANAGED_COMMIT_PROVIDER_CONF]] is json parse-able.
1103
1119
DeltaConfigs .MANAGED_COMMIT_OWNER_CONF .fromMetaData(metadata)
1104
1120
1121
+ val firstAttemptVersion = getFirstAttemptVersion
1122
+ val updatedMetadataOpt = commitInfo.inCommitTimestamp.flatMap { inCommitTimestamp =>
1123
+ InCommitTimestampUtils .getUpdatedMetadataWithICTEnablementInfo(
1124
+ inCommitTimestamp,
1125
+ snapshot,
1126
+ metadata,
1127
+ firstAttemptVersion)
1128
+ }
1129
+ val updatedActions = updatedMetadataOpt.map { updatedMetadata =>
1130
+ preparedActions.map {
1131
+ case _ : Metadata => updatedMetadata
1132
+ case other => other
1133
+ }
1134
+ }
1135
+ .getOrElse(preparedActions)
1136
+ val updatedMetadata = updatedMetadataOpt.getOrElse(metadata)
1105
1137
val currentTransactionInfo = CurrentTransactionInfo (
1106
1138
txnId = txnId,
1107
1139
readPredicates = readPredicates.toSeq,
1108
1140
readFiles = readFiles.toSet,
1109
1141
readWholeTable = readTheWholeTable,
1110
1142
readAppIds = readTxn.toSet,
1111
- metadata = metadata ,
1143
+ metadata = updatedMetadata ,
1112
1144
protocol = protocol,
1113
- actions = preparedActions ,
1145
+ actions = updatedActions ,
1114
1146
readSnapshot = snapshot,
1115
1147
commitInfo = Option (commitInfo),
1116
1148
readRowIdHighWatermark = readRowIdHighWatermark,
@@ -1125,15 +1157,14 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1125
1157
registerPostCommitHook(GenerateSymlinkManifest )
1126
1158
}
1127
1159
1128
- commitAttemptStartTime = clock.getTimeMillis()
1129
1160
if (preparedActions.isEmpty && canSkipEmptyCommits &&
1130
1161
skipRecordingEmptyCommitAllowed(isolationLevelToUse)) {
1131
1162
return None
1132
1163
}
1133
1164
1134
1165
val (commitVersion, postCommitSnapshot, updatedCurrentTransactionInfo) =
1135
1166
doCommitRetryIteratively(
1136
- getFirstAttemptVersion , currentTransactionInfo, isolationLevelToUse)
1167
+ firstAttemptVersion , currentTransactionInfo, isolationLevelToUse)
1137
1168
logInfo(s " Committed delta # $commitVersion to ${deltaLog.logPath}" )
1138
1169
(commitVersion, postCommitSnapshot, updatedCurrentTransactionInfo.actions)
1139
1170
} catch {
@@ -1182,15 +1213,17 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1182
1213
newProtocolOpt : Option [Protocol ],
1183
1214
op : DeltaOperations .Operation ,
1184
1215
context : Map [String , String ],
1185
- metrics : Map [String , String ]): (Long , Snapshot ) = {
1216
+ metrics : Map [String , String ]
1217
+ ): (Long , Snapshot ) = recordDeltaOperation(deltaLog, " delta.commit.large" ) {
1186
1218
assert(! committed, " Transaction already committed." )
1187
1219
commitStartNano = System .nanoTime()
1188
1220
val attemptVersion = getFirstAttemptVersion
1189
1221
try {
1190
1222
val tags = Map .empty[String , String ]
1191
1223
val commitInfo = CommitInfo (
1192
- time = clock.getTimeMillis( ),
1224
+ NANOSECONDS .toMillis(commitStartNano ),
1193
1225
operation = op.name,
1226
+ generateInCommitTimestampForFirstCommitAttempt(NANOSECONDS .toMillis(commitStartNano)),
1194
1227
operationParameters = op.jsonEncodedValues,
1195
1228
context,
1196
1229
readVersion = Some (readVersion),
@@ -1215,8 +1248,15 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1215
1248
// Initialize everything needed to maintain auto-compaction stats.
1216
1249
partitionsAddedToOpt = Some (new mutable.HashSet [Map [String , String ]])
1217
1250
val acStatsCollector = createAutoCompactStatsCollector()
1251
+ val updatedMetadataOpt = commitInfo.inCommitTimestamp.flatMap { inCommitTimestamp =>
1252
+ InCommitTimestampUtils .getUpdatedMetadataWithICTEnablementInfo(
1253
+ inCommitTimestamp,
1254
+ snapshot,
1255
+ metadata,
1256
+ attemptVersion)
1257
+ }
1218
1258
var allActions =
1219
- Seq (commitInfo, metadata).toIterator ++
1259
+ Seq (commitInfo, updatedMetadataOpt.getOrElse( metadata) ).toIterator ++
1220
1260
nonProtocolMetadataActions ++
1221
1261
newProtocolOpt.toIterator
1222
1262
allActions = allActions.map { action =>
@@ -1719,7 +1759,7 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1719
1759
}
1720
1760
}
1721
1761
// retries all failed
1722
- val totalCommitAttemptTime = clock.getTimeMillis() - commitAttemptStartTime
1762
+ val totalCommitAttemptTime = clock.getTimeMillis() - commitAttemptStartTimeMillis
1723
1763
throw DeltaErrors .maxCommitRetriesExceededException(
1724
1764
maxRetryAttempts + 1 ,
1725
1765
commitVersion,
@@ -1939,12 +1979,12 @@ trait OptimisticTransactionImpl extends TransactionalWrite
1939
1979
otherCommitFileStatus,
1940
1980
commitIsolationLevel)
1941
1981
logInfo(s " $logPrefixStr No conflicts in version $otherCommitVersion, " +
1942
- s " ${clock.getTimeMillis() - commitAttemptStartTime } ms since start " )
1982
+ s " ${clock.getTimeMillis() - commitAttemptStartTimeMillis } ms since start " )
1943
1983
}
1944
1984
1945
1985
logInfo(s " $logPrefixStr No conflicts with versions [ $checkVersion, $nextAttemptVersion) " +
1946
1986
s " with current txn having $txnDetailsLogStr, " +
1947
- s " ${clock.getTimeMillis() - commitAttemptStartTime } ms since start " )
1987
+ s " ${clock.getTimeMillis() - commitAttemptStartTimeMillis } ms since start " )
1948
1988
(nextAttemptVersion, updatedCurrentTransactionInfo)
1949
1989
}
1950
1990
}
0 commit comments