Checkpoint the log and write a checkpoint record.
()
| 312 | |
| 313 | /** Checkpoint the log and write a checkpoint record. */ |
| 314 | public void logCheckpoint() throws IOException { |
| 315 | //make sure we have buffer pool lock before proceeding |
| 316 | synchronized (Database.getBufferPool()) { |
| 317 | synchronized (this) { |
| 318 | //Debug.log("CHECKPOINT, offset = " + raf.getFilePointer()); |
| 319 | preAppend(); |
| 320 | long startCpOffset, endCpOffset; |
| 321 | Set<Long> keys = tidToFirstLogRecord.keySet(); |
| 322 | Iterator<Long> els = keys.iterator(); |
| 323 | force(); |
| 324 | Database.getBufferPool().flushAllPages(); |
| 325 | startCpOffset = raf.getFilePointer(); |
| 326 | raf.writeInt(CHECKPOINT_RECORD); |
| 327 | raf.writeLong(-1); //no tid , but leave space for convenience |
| 328 | |
| 329 | //write list of outstanding transactions |
| 330 | raf.writeInt(keys.size()); |
| 331 | while (els.hasNext()) { |
| 332 | Long key = els.next(); |
| 333 | Debug.log("WRITING CHECKPOINT TRANSACTION ID: " + key); |
| 334 | raf.writeLong(key); |
| 335 | //Debug.log("WRITING CHECKPOINT TRANSACTION OFFSET: " + tidToFirstLogRecord.get(key)); |
| 336 | raf.writeLong(tidToFirstLogRecord.get(key)); |
| 337 | } |
| 338 | |
| 339 | //once the CP is written, make sure the CP location at the |
| 340 | // beginning of the log file is updated |
| 341 | endCpOffset = raf.getFilePointer(); |
| 342 | raf.seek(0); |
| 343 | raf.writeLong(startCpOffset); |
| 344 | raf.seek(endCpOffset); |
| 345 | raf.writeLong(currentOffset); |
| 346 | currentOffset = raf.getFilePointer(); |
| 347 | //Debug.log("CP OFFSET = " + currentOffset); |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | logTruncate(); |
| 352 | } |
| 353 | |
| 354 | /** Truncate any unneeded portion of the log to reduce its space |
| 355 | consumption */ |