~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/trans_log_ms.h

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2009 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Barry Leslie
20
 
 *
21
 
 * 2009-06-09
22
 
 *
23
 
 * H&G2JCtL
24
 
 *
25
 
 * PBMS transaction handling.
26
 
 *
27
 
 * PBMS uses 1 circular transaction log. All BLOB reference operations are written to this log
28
 
 * and are applied to the repository when committed. There is 1 thread dedicated to reading the 
29
 
 * transaction log and applying the changes. During an engine level backup this thread is suspended 
30
 
 * so that no transactions will be applied to the repository files as they are backed up.
31
 
 *
32
 
 */
33
 
 
34
 
#pragma once
35
 
#ifndef __TRANSLOG_MS_H__
36
 
#define __TRANSLOG_MS_H__
37
 
#include <stddef.h>
38
 
 
39
 
#include "cslib/CSDefs.h"
40
 
#include "cslib/CSFile.h"
41
 
#define CHECK_TIDS
42
 
#define CRASH_TEST
43
 
 
44
 
#ifdef CRASH_TEST
45
 
extern uint32_t trans_test_crash_point;
46
 
#define MAX_CRASH_POINT 10
47
 
#else
48
 
#define MAX_CRASH_POINT 0
49
 
#endif
50
 
 
51
 
typedef uint32_t TRef;
52
 
 
53
 
/*
54
 
        Transaction log info:
55
 
        
56
 
        The transaction log is a circular log of fixed length records. There is assumed to be one 
57
 
        reader thread and multiple writer threads. As records are written the 'eol' (End Of Log)
58
 
        marker is advanced and as they are read the 'start' marker is advanved. When iether marker
59
 
        reaches the end of the log a wrap around is done the marker is position back to the top of
60
 
        the list.
61
 
        
62
 
        When both markers are at the same location then the log is empty. The log is full if the 
63
 
        eol marker is just behind the start marker.
64
 
        
65
 
        If an overflow occurs then the overflow flag in the log header is set and records are written 
66
 
        to the end of the log. New records will continue to be written to the end of log until the 
67
 
        reader thread has read ALL of the records in the non overflow portion of the list. When all 
68
 
        of these records have been read then the list size will be adjusted to include the overflow
69
 
        record and the start and eol markers are repositioned and the overflow flag in the 
70
 
        header is switched off.
71
 
        
72
 
        
73
 
*/
74
 
typedef struct MSDiskTransHead {
75
 
        CSDiskValue4                    th_magic_4;                                     /* Table magic number. */
76
 
        CSDiskValue2                    th_version_2;                           /* The header version. */
77
 
 
78
 
        CSDiskValue4                    th_next_txn_id_4;                       /* The next valid transaction ID. */
79
 
 
80
 
        CSDiskValue2                    th_check_point_2;                       /* The frequency whith which the start/end positions are updated in the header. */
81
 
        
82
 
        CSDiskValue4                    th_requested_cache_size_4;      /* The transaction cache list size in transaction. */
83
 
 
84
 
        CSDiskValue8                    th_list_size_8;                         /* The transaction log list size in records. */
85
 
        CSDiskValue8                    th_requested_list_size_8;       /* The desired list size. The log will be adjusted to this size as soon as it is convenient.*/
86
 
 
87
 
        CSDiskValue1                    th_recovered_1;                         /* A flag to indicate if the log was closed properly. */
88
 
 
89
 
        CSDiskValue1                    th_overflow_1;                          /* A flag to indicate if overflow has occurred. */
90
 
 
91
 
        // th_start_8 and th_eol_8 are always written at the same time.
92
 
        CSDiskValue8                    th_start_8;                                     /* The index of the first valid record. */
93
 
        CSDiskValue8                    th_eol_8;                                       /* The index of the first unused record or End Of Log (eol). */
94
 
        CSDiskValue1                    th_checksum_1;                          /* The current record checksum seed. */
95
 
} MSDiskTransHeadRec, *MSDiskTransHeadPtr;
96
 
 
97
 
 
98
 
typedef struct MSTrans_tag {
99
 
        uint32_t        tr_id;                  // The transaction ID
100
 
        uint8_t tr_type;                // The transaction type. If the first bit is set then the transaction is an autocommit.
101
 
        uint32_t        tr_db_id;               // The database ID for the operation.
102
 
        uint32_t        tr_tab_id;              // The table ID for the operation.
103
 
        uint64_t        tr_blob_id;             // The blob ID for the operation.
104
 
        uint64_t        tr_blob_ref_id; // The blob reference id.
105
 
        uint8_t tr_check;               // The transaction record checksum.
106
 
} MSTransRec, *MSTransPtr;
107
 
 
108
 
 
109
 
typedef struct MSTransStats {
110
 
        uint64_t        ts_LogSize;                     // The number of records in the transaction log.
111
 
        uint32_t        ts_PercentFull;         // The % of the desired log size in use. This can be > 100%.
112
 
        uint64_t        ts_MaxSize;                     // The log size high water mark.
113
 
        uint32_t        ts_OverflowCount;       // The number of times the log has overflowen.
114
 
        bool    ts_IsOverflowing;
115
 
        
116
 
        uint32_t ts_TransCacheSize;     // The number of transactions currently in the cache.
117
 
        uint32_t ts_PercentTransCacheUsed;      // The number of transactions currently in the cache.
118
 
        uint32_t        ts_PercentCacheHit; // The % of the transactions that were cached on writing.
119
 
} MSTransStatsRec, *MSTransStatsPtr;
120
 
 
121
 
typedef enum {  MS_RollBackTxn = 0, 
122
 
                                MS_PartialRollBackTxn,
123
 
                                MS_CommitTxn, 
124
 
                                MS_ReferenceTxn, 
125
 
                                MS_DereferenceTxn, 
126
 
                                MS_RecoveredTxn                 
127
 
} MS_Txn;
128
 
 
129
 
typedef enum {  MS_Running = 0,
130
 
                                MS_RolledBack, 
131
 
                                MS_Committed, 
132
 
                                MS_Recovered                    
133
 
} MS_TxnState;
134
 
 
135
 
 
136
 
#define TRANS_SET_AUTOCOMMIT(t) (t |= 0X80)     
137
 
#define TRANS_IS_AUTOCOMMIT(t) (t & 0X80)       
138
 
 
139
 
#define TRANS_SET_START(t) (t |= 0X40)  
140
 
#define TRANS_IS_START(t) (t & 0X40)    
141
 
 
142
 
#define TRANS_TYPE_IS_TERMINATED(t) (((t) == MS_RollBackTxn) || ((t) == MS_CommitTxn) || ((t) == MS_RecoveredTxn))      
143
 
#define TRANS_IS_TERMINATED(t) (TRANS_TYPE_IS_TERMINATED(TRANS_TYPE(t))  || TRANS_IS_AUTOCOMMIT(t))     
144
 
#define TRANS_TYPE(t) (t & 0X0F)        
145
 
 
146
 
typedef bool (*CanContinueFunc)();
147
 
typedef void (*LoadFunc)(uint64_t log_position, MSTransPtr rec);
148
 
 
149
 
class MSTransCache;
150
 
class MSTrans : public CSSharedRefObject {
151
 
 
152
 
public:
153
 
        
154
 
        MSTrans();
155
 
        ~MSTrans();
156
 
        
157
 
        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);
158
 
 
159
 
        void txn_LogPartialRollBack(uint32_t rollBackCount)
160
 
        {
161
 
                /* Partial rollbacks store the rollback count in the place of the database id. */
162
 
                txn_LogTransaction(MS_PartialRollBackTxn, false, rollBackCount);
163
 
        }
164
 
        
165
 
        void txn_SetCheckPoint(uint16_t checkpoint)
166
 
        {
167
 
                enter_();
168
 
                
169
 
                // Important lock order. Writer threads never lock the reader but the reader
170
 
                // may lock this object so always lock the reader first.
171
 
                lock_(txn_reader);
172
 
                lock_(this);
173
 
                
174
 
                txn_MaxCheckPoint = checkpoint;
175
 
                
176
 
                if (txn_MaxCheckPoint < 10)
177
 
                        txn_MaxCheckPoint = 10;
178
 
                        
179
 
                if (txn_MaxCheckPoint > txn_MaxRecords)
180
 
                        txn_MaxCheckPoint = txn_MaxRecords/2;
181
 
                
182
 
                if (txn_MaxCheckPoint > txn_ReqestedMaxRecords)
183
 
                        txn_MaxCheckPoint = txn_ReqestedMaxRecords/2;
184
 
                
185
 
                CS_SET_DISK_2(txn_DiskHeader.th_check_point_2, txn_MaxCheckPoint);
186
 
                
187
 
                txn_File->write(&(txn_DiskHeader.th_check_point_2), offsetof(MSDiskTransHeadRec, th_check_point_2), 2);
188
 
                txn_File->flush();
189
 
                txn_File->sync();
190
 
                
191
 
                unlock_(this);
192
 
                unlock_(txn_reader);
193
 
                
194
 
                exit_();
195
 
        }
196
 
        
197
 
        void txn_SetCacheSize(uint32_t new_size);
198
 
        
199
 
        // txn_SetLogSize() may not take effect immediately but will be done
200
 
        // when there is free space at the end of the log.
201
 
        void txn_SetLogSize(uint64_t new_size);
202
 
        
203
 
        void txn_Close();       
204
 
        
205
 
        uint64_t        txn_GetSize();          // Returns the size of the log in transaction records.
206
 
        
207
 
        uint64_t        txn_GetNumRecords()     // Returns the number of transactions records waiting to be processed.
208
 
        {                                                       // This doesn't include overflow.
209
 
                uint64_t size;
210
 
                if (txn_Start == txn_EOL)
211
 
                        size = 0;
212
 
                else if (txn_Start < txn_EOL) 
213
 
                        size = txn_EOL - txn_Start;
214
 
                else 
215
 
                        size = txn_MaxRecords - (txn_Start - txn_EOL);
216
 
                        
217
 
                return size;
218
 
        }
219
 
 
220
 
        // While a backup is in progress the transaction thread will not be signaled 
221
 
        // about completed transactions.
222
 
        void txn_BackupStarting() 
223
 
        {
224
 
                txn_Doingbackup = true;
225
 
                txn_reader->suspend();
226
 
        }
227
 
        
228
 
        bool txn_haveNextTransaction();
229
 
        
230
 
        void txn_BackupCompleted()
231
 
        {
232
 
                txn_Doingbackup = false;
233
 
                txn_reader->resume();
234
 
        }
235
 
        
236
 
        // The following should only be called by the transaction processing thread.
237
 
        
238
 
        // txn_GetNextTransaction() gets the next completed transaction.
239
 
        // If there is none ready it waits for one.     
240
 
        void txn_GetNextTransaction(MSTransPtr tran, MS_TxnState *state); 
241
 
                
242
 
        void txn_SetReader(CSDaemon *reader) {txn_reader = reader;}
243
 
        
244
 
        // Search the transaction log for a MS_ReferenceTxn record for the given BLOB.
245
 
        bool txn_FindBlobRef(MS_TxnState *state, uint32_t db_id, uint32_t tab_id, uint64_t blob_id);
246
 
        
247
 
        // Mark all transactions for a given database as dropped. Including commited transactions.
248
 
        void txn_dropDatabase(uint32_t db_id);
249
 
        
250
 
 
251
 
        uint64_t txn_GetStartPosition() { return txn_Start;}
252
 
        
253
 
        const char      *txn_GetTXNLogPath() {return txn_File->myFilePath->getCString();}
254
 
private:
255
 
        friend class ReadTXNLog;
256
 
        
257
 
        uint16_t                txn_MaxCheckPoint;      // The maximum records to be written ore read before the positions in the header are updated.
258
 
 
259
 
        // These fields are only used by the reader thread:
260
 
        bool            txn_Doingbackup;// Is the database being backed up.
261
 
        CSDaemon        *txn_reader;    // THe transaction log reader daemon. (unreferenced)
262
 
        bool            txn_IsTxnValid; // Is the current transaction valid.
263
 
        TRef            txn_CurrentTxn; // The current transaction.
264
 
        uint32_t                txn_TxnIndex;   // The record index into the current transaction.
265
 
        int32_t         txn_StartCheckPoint; // Counter to determin when the read position should be flushed.
266
 
        
267
 
        void txn_PerformIdleTasks();
268
 
        
269
 
        MSTransCache    *txn_TransCache;        // Transaction cache
270
 
        
271
 
        void txn_ResizeLog();
272
 
        
273
 
        void txn_NewTransaction(); // Clears the old transaction ID
274
 
        
275
 
        bool txn_IsFull()
276
 
        {
277
 
                return (txn_HaveOverflow || ((txn_GetNumRecords() +1) == txn_MaxRecords));
278
 
        }
279
 
        
280
 
        
281
 
        uint32_t                                txn_BlockingTransaction; // The transaction ID the transaction thread is waiting on.
282
 
 
283
 
        MSDiskTransHeadRec      txn_DiskHeader;
284
 
        CSFile                          *txn_File;
285
 
        
286
 
        int32_t                         txn_EOLCheckPoint; // Counter to determin when the EOL position should be flushed.
287
 
        
288
 
        // The size of the transaction log can be adjusted by setting txn_ReqestedMaxRecords.
289
 
        // The log size will be adjusted as soon as there are free slots at the bottom of the list.
290
 
        uint64_t                                txn_MaxRecords;                 // The number of record slots in the current list.
291
 
        uint64_t                                txn_ReqestedMaxRecords; // The number of record slots requested.        
292
 
 
293
 
        uint64_t                                txn_HighWaterMark; // Keeps track of the log size high water mark.
294
 
        uint64_t                                txn_OverflowCount; // A count of the number of times the transaction log has over flown.
295
 
#ifdef DEBUG    
296
 
public:
297
 
        void                            txn_DumpLog(const char *file);
298
 
#endif
299
 
        uint32_t                                txn_MaxTID;
300
 
        bool                            txn_Recovered;                          // Has the log been recovered.
301
 
        bool                            txn_HaveOverflow;                       // A flag to indicate the list has overfown.
302
 
        uint64_t                                txn_Overflow;                           // The index of the next overflow record. 
303
 
        uint64_t                                txn_EOL;                                        // The index of the first unused record or End Of Log (eol). 
304
 
        uint64_t                                txn_Start;                                      // The index of the first valid record. 
305
 
 
306
 
public: 
307
 
        void txn_GetStats(MSTransStatsPtr stats);               // Get the current performance statistics.
308
 
        
309
 
private:
310
 
        uint8_t                         txn_Checksum;                           // The current record checksum seed. 
311
 
        
312
 
        void txn_SetFile(CSFile *tr_file);              // Set the file to use for the transaction log.
313
 
        bool txn_ValidRecord(MSTransPtr rec);   // Check to see if a record is valid.
314
 
        void txn_GetRecordAt(uint64_t index, MSTransPtr rec); // Reads 1 record from the log.
315
 
        void txn_ResetReadPosition(uint64_t pos);       // Reset txn_Start
316
 
        void txn_ResetEOL();
317
 
                
318
 
        void txn_Recover();                                                     // Recover the transaction log.
319
 
        
320
 
        void txn_ReadLog(uint64_t read_start, bool log_locked, CanContinueFunc canContinue, LoadFunc load); // A generic method for reading the log
321
 
        void txn_LoadTransactionCache(uint64_t read_start);     // Load the transactions in the log into cache.
322
 
        
323
 
        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);
324
 
 
325
 
        
326
 
public:
327
 
        static MSTrans* txn_NewMSTrans(const char *log_path, bool dump_log = false);
328
 
};
329
 
 
330
 
class ReadTXNLog {
331
 
        public:
332
 
        ReadTXNLog(MSTrans *txn_log): rl_log(txn_log){}
333
 
        virtual ~ReadTXNLog(){}
334
 
                
335
 
        MSTrans *rl_log;
336
 
        void rl_ReadLog(uint64_t read_start, bool log_locked);
337
 
        virtual bool rl_CanContinue();
338
 
        virtual void rl_Load(uint64_t log_position, MSTransPtr rec);
339
 
        void rl_Store(uint64_t log_position, MSTransPtr rec);
340
 
        void rl_Flush();
341
 
};
342
 
 
343
 
#endif //__TRANSLOG_MS_H__