00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #pragma once
00035 #ifndef __TRANSLOG_MS_H__
00036 #define __TRANSLOG_MS_H__
00037 #include <stddef.h>
00038
00039 #include "cslib/CSDefs.h"
00040 #include "cslib/CSFile.h"
00041 #define CHECK_TIDS
00042 #define CRASH_TEST
00043
00044 #ifdef CRASH_TEST
00045 extern uint32_t trans_test_crash_point;
00046 #define MAX_CRASH_POINT 10
00047 #else
00048 #define MAX_CRASH_POINT 0
00049 #endif
00050
00051 typedef uint32_t TRef;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 typedef struct MSDiskTransHead {
00075 CSDiskValue4 th_magic_4;
00076 CSDiskValue2 th_version_2;
00077
00078 CSDiskValue4 th_next_txn_id_4;
00079
00080 CSDiskValue2 th_check_point_2;
00081
00082 CSDiskValue4 th_requested_cache_size_4;
00083
00084 CSDiskValue8 th_list_size_8;
00085 CSDiskValue8 th_requested_list_size_8;
00086
00087 CSDiskValue1 th_recovered_1;
00088
00089 CSDiskValue1 th_overflow_1;
00090
00091
00092 CSDiskValue8 th_start_8;
00093 CSDiskValue8 th_eol_8;
00094 CSDiskValue1 th_checksum_1;
00095 } MSDiskTransHeadRec, *MSDiskTransHeadPtr;
00096
00097
00098 typedef struct MSTrans_tag {
00099 uint32_t tr_id;
00100 uint8_t tr_type;
00101 uint32_t tr_db_id;
00102 uint32_t tr_tab_id;
00103 uint64_t tr_blob_id;
00104 uint64_t tr_blob_ref_id;
00105 uint8_t tr_check;
00106 } MSTransRec, *MSTransPtr;
00107
00108
00109 typedef struct MSTransStats {
00110 uint64_t ts_LogSize;
00111 uint32_t ts_PercentFull;
00112 uint64_t ts_MaxSize;
00113 uint32_t ts_OverflowCount;
00114 bool ts_IsOverflowing;
00115
00116 uint32_t ts_TransCacheSize;
00117 uint32_t ts_PercentTransCacheUsed;
00118 uint32_t ts_PercentCacheHit;
00119 } MSTransStatsRec, *MSTransStatsPtr;
00120
00121 typedef enum { MS_RollBackTxn = 0,
00122 MS_PartialRollBackTxn,
00123 MS_CommitTxn,
00124 MS_ReferenceTxn,
00125 MS_DereferenceTxn,
00126 MS_RecoveredTxn
00127 } MS_Txn;
00128
00129 typedef enum { MS_Running = 0,
00130 MS_RolledBack,
00131 MS_Committed,
00132 MS_Recovered
00133 } MS_TxnState;
00134
00135
00136 #define TRANS_SET_AUTOCOMMIT(t) (t |= 0X80)
00137 #define TRANS_IS_AUTOCOMMIT(t) (t & 0X80)
00138
00139 #define TRANS_SET_START(t) (t |= 0X40)
00140 #define TRANS_IS_START(t) (t & 0X40)
00141
00142 #define TRANS_TYPE_IS_TERMINATED(t) (((t) == MS_RollBackTxn) || ((t) == MS_CommitTxn) || ((t) == MS_RecoveredTxn))
00143 #define TRANS_IS_TERMINATED(t) (TRANS_TYPE_IS_TERMINATED(TRANS_TYPE(t)) || TRANS_IS_AUTOCOMMIT(t))
00144 #define TRANS_TYPE(t) (t & 0X0F)
00145
00146 typedef bool (*CanContinueFunc)();
00147 typedef void (*LoadFunc)(uint64_t log_position, MSTransPtr rec);
00148
00149 class MSTransCache;
00150 class MSTrans : public CSSharedRefObject {
00151
00152 public:
00153
00154 MSTrans();
00155 ~MSTrans();
00156
00157 void txn_LogTransaction(MS_Txn type, bool autocommit = false, uint32_t db_id = 0, uint32_t tab_id = 0, uint64_t blob_id = 0, uint64_t blob_ref_id = 0);
00158
00159 void txn_LogPartialRollBack(uint32_t rollBackCount)
00160 {
00161
00162 txn_LogTransaction(MS_PartialRollBackTxn, false, rollBackCount);
00163 }
00164
00165 void txn_SetCheckPoint(uint16_t checkpoint)
00166 {
00167 enter_();
00168
00169
00170
00171 lock_(txn_reader);
00172 lock_(this);
00173
00174 txn_MaxCheckPoint = checkpoint;
00175
00176 if (txn_MaxCheckPoint < 10)
00177 txn_MaxCheckPoint = 10;
00178
00179 if (txn_MaxCheckPoint > txn_MaxRecords)
00180 txn_MaxCheckPoint = txn_MaxRecords/2;
00181
00182 if (txn_MaxCheckPoint > txn_ReqestedMaxRecords)
00183 txn_MaxCheckPoint = txn_ReqestedMaxRecords/2;
00184
00185 CS_SET_DISK_2(txn_DiskHeader.th_check_point_2, txn_MaxCheckPoint);
00186
00187 txn_File->write(&(txn_DiskHeader.th_check_point_2), offsetof(MSDiskTransHeadRec, th_check_point_2), 2);
00188 txn_File->flush();
00189 txn_File->sync();
00190
00191 unlock_(this);
00192 unlock_(txn_reader);
00193
00194 exit_();
00195 }
00196
00197 void txn_SetCacheSize(uint32_t new_size);
00198
00199
00200
00201 void txn_SetLogSize(uint64_t new_size);
00202
00203 void txn_Close();
00204
00205 uint64_t txn_GetSize();
00206
00207 uint64_t txn_GetNumRecords()
00208 {
00209 uint64_t size;
00210 if (txn_Start == txn_EOL)
00211 size = 0;
00212 else if (txn_Start < txn_EOL)
00213 size = txn_EOL - txn_Start;
00214 else
00215 size = txn_MaxRecords - (txn_Start - txn_EOL);
00216
00217 return size;
00218 }
00219
00220
00221
00222 void txn_BackupStarting()
00223 {
00224 txn_Doingbackup = true;
00225 txn_reader->suspend();
00226 }
00227
00228 bool txn_haveNextTransaction();
00229
00230 void txn_BackupCompleted()
00231 {
00232 txn_Doingbackup = false;
00233 txn_reader->resume();
00234 }
00235
00236
00237
00238
00239
00240 void txn_GetNextTransaction(MSTransPtr tran, MS_TxnState *state);
00241
00242 void txn_SetReader(CSDaemon *reader) {txn_reader = reader;}
00243
00244
00245 bool txn_FindBlobRef(MS_TxnState *state, uint32_t db_id, uint32_t tab_id, uint64_t blob_id);
00246
00247
00248 void txn_dropDatabase(uint32_t db_id);
00249
00250
00251 uint64_t txn_GetStartPosition() { return txn_Start;}
00252
00253 const char *txn_GetTXNLogPath() {return txn_File->myFilePath->getCString();}
00254 private:
00255 friend class ReadTXNLog;
00256
00257 uint16_t txn_MaxCheckPoint;
00258
00259
00260 bool txn_Doingbackup;
00261 CSDaemon *txn_reader;
00262 bool txn_IsTxnValid;
00263 TRef txn_CurrentTxn;
00264 uint32_t txn_TxnIndex;
00265 int32_t txn_StartCheckPoint;
00266
00267 void txn_PerformIdleTasks();
00268
00269 MSTransCache *txn_TransCache;
00270
00271 void txn_ResizeLog();
00272
00273 void txn_NewTransaction();
00274
00275 bool txn_IsFull()
00276 {
00277 return (txn_HaveOverflow || ((txn_GetNumRecords() +1) == txn_MaxRecords));
00278 }
00279
00280
00281 uint32_t txn_BlockingTransaction;
00282
00283 MSDiskTransHeadRec txn_DiskHeader;
00284 CSFile *txn_File;
00285
00286 int32_t txn_EOLCheckPoint;
00287
00288
00289
00290 uint64_t txn_MaxRecords;
00291 uint64_t txn_ReqestedMaxRecords;
00292
00293 uint64_t txn_HighWaterMark;
00294 uint64_t txn_OverflowCount;
00295 #ifdef DEBUG
00296 public:
00297 void txn_DumpLog(const char *file);
00298 #endif
00299 uint32_t txn_MaxTID;
00300 bool txn_Recovered;
00301 bool txn_HaveOverflow;
00302 uint64_t txn_Overflow;
00303 uint64_t txn_EOL;
00304 uint64_t txn_Start;
00305
00306 public:
00307 void txn_GetStats(MSTransStatsPtr stats);
00308
00309 private:
00310 uint8_t txn_Checksum;
00311
00312 void txn_SetFile(CSFile *tr_file);
00313 bool txn_ValidRecord(MSTransPtr rec);
00314 void txn_GetRecordAt(uint64_t index, MSTransPtr rec);
00315 void txn_ResetReadPosition(uint64_t pos);
00316 void txn_ResetEOL();
00317
00318 void txn_Recover();
00319
00320 void txn_ReadLog(uint64_t read_start, bool log_locked, CanContinueFunc canContinue, LoadFunc load);
00321 void txn_LoadTransactionCache(uint64_t read_start);
00322
00323 void txn_AddTransaction(uint8_t tran_type, bool autocommit = false, uint32_t db_id = 0, uint32_t tab_id = 0, uint64_t blob_id = 0, uint64_t blob_ref_id = 0);
00324
00325
00326 public:
00327 static MSTrans* txn_NewMSTrans(const char *log_path, bool dump_log = false);
00328 };
00329
00330 class ReadTXNLog {
00331 public:
00332 ReadTXNLog(MSTrans *txn_log): rl_log(txn_log){}
00333 virtual ~ReadTXNLog(){}
00334
00335 MSTrans *rl_log;
00336 void rl_ReadLog(uint64_t read_start, bool log_locked);
00337 virtual bool rl_CanContinue();
00338 virtual void rl_Load(uint64_t log_position, MSTransPtr rec);
00339 void rl_Store(uint64_t log_position, MSTransPtr rec);
00340 void rl_Flush();
00341 };
00342
00343 #endif //__TRANSLOG_MS_H__