2013-04-16 23:57:20 -04:00
# ifndef LOG_INTERNAL_H
# define LOG_INTERNAL_H
2007-11-29 14:18:54 +00:00
# ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
2008-04-25 13:45:55 +00:00
# include "brt-internal.h"
2008-02-08 03:17:38 +00:00
# include "log.h"
# include "toku_assert.h"
2008-02-14 19:23:25 +00:00
# include "list.h"
2008-07-11 22:00:06 +00:00
# include "memarena.h"
2007-08-10 21:15:17 +00:00
# include <stdio.h>
2013-04-16 23:57:27 -04:00
# include <toku_pthread.h>
2007-09-28 17:11:22 +00:00
# include <sys/types.h>
2008-04-02 23:40:36 +00:00
# include <string.h>
2007-09-28 17:11:22 +00:00
2008-03-12 17:55:11 +00:00
// Locking for the logger
// For most purposes we use the big ydb lock.
// To log: grab the buf lock
// If the buf would overflow, then grab the file lock, swap file&buf, release buf lock, write the file, write the entry, release the file lock
// else append to buf & release lock
2007-10-19 17:05:10 +00:00
# define LOGGER_BUF_SIZE (1<<24)
2008-03-12 17:55:11 +00:00
struct mylock {
2013-04-16 23:57:27 -04:00
toku_pthread_mutex_t lock ;
2008-03-12 17:55:11 +00:00
int is_locked ;
} ;
static inline int ml_init ( struct mylock * l ) {
l - > is_locked = 0 ;
2013-04-16 23:57:32 -04:00
memset ( & l - > lock , 0 , sizeof ( l - > lock ) ) ;
2013-04-16 23:57:27 -04:00
return toku_pthread_mutex_init ( & l - > lock , 0 ) ;
2008-03-12 17:55:11 +00:00
}
static inline int ml_lock ( struct mylock * l ) {
2013-04-16 23:57:27 -04:00
int r = toku_pthread_mutex_lock ( & l - > lock ) ;
2008-03-12 17:55:11 +00:00
assert ( l - > is_locked = = 0 ) ;
l - > is_locked = 1 ;
return r ;
}
static inline int ml_unlock ( struct mylock * l ) {
assert ( l - > is_locked = = 1 ) ;
l - > is_locked = 0 ;
2013-04-16 23:57:27 -04:00
return toku_pthread_mutex_unlock ( & l - > lock ) ;
2008-03-12 17:55:11 +00:00
}
static inline int ml_destroy ( struct mylock * l ) {
assert ( l - > is_locked = = 0 ) ;
2013-04-16 23:57:27 -04:00
return toku_pthread_mutex_destroy ( & l - > lock ) ;
2008-03-12 17:55:11 +00:00
}
2007-08-10 19:24:45 +00:00
struct tokulogger {
2008-03-12 17:55:11 +00:00
enum typ_tag tag ; // must be first
struct mylock input_lock , output_lock ; // acquired in that order
2008-01-08 22:18:42 +00:00
int is_open ;
int is_panicked ;
2008-05-19 16:42:38 +00:00
int write_log_files ;
2008-01-08 22:18:42 +00:00
int panic_errno ;
2007-08-10 19:24:45 +00:00
char * directory ;
2007-08-10 21:39:55 +00:00
int fd ;
2008-01-11 22:24:43 +00:00
CACHETABLE ct ;
2008-03-08 13:02:32 +00:00
int lg_max ; // The size of the single file in the log. Default is 100MB in TokuDB
2008-03-12 17:55:11 +00:00
// To access these, you must have the input lock
struct logbytes * head , * tail ;
LSN lsn ; // the next available lsn
struct list live_txns ; // just a linked list. Should be a hashtable.
int n_in_buf ;
// To access these, you must have the output lock
LSN written_lsn ; // the last lsn written
LSN fsynced_lsn ; // What is the LSN of the highest fsynced log entry
2013-04-16 23:57:47 -04:00
LSN checkpoint_lsn ; // What is the LSN of the most recent completed checkpoint.
2008-03-12 17:55:11 +00:00
long long next_log_file_number ;
char buf [ LOGGER_BUF_SIZE ] ; // used to marshall logbytes so we can use only a single write
int n_in_file ;
2013-04-16 23:57:38 -04:00
u_int32_t write_block_size ; // How big should the blocks be written to various logs?
2007-08-10 19:24:45 +00:00
} ;
2007-08-10 21:15:17 +00:00
2007-11-29 18:14:40 +00:00
int toku_logger_find_next_unused_log_file ( const char * directory , long long * result ) ;
2008-03-21 19:40:32 +00:00
int toku_logger_find_logfiles ( const char * directory , char * * * resultp ) ;
2007-09-28 17:11:22 +00:00
2008-04-25 13:45:55 +00:00
struct brtcachefile_pair {
BRT brt ;
CACHEFILE cf ;
} ;
2007-09-28 17:11:22 +00:00
struct tokutxn {
2008-02-14 19:23:25 +00:00
enum typ_tag tag ;
2008-03-21 21:02:30 +00:00
u_int64_t txnid64 ; /* this happens to be the first lsn */
2007-09-28 17:11:22 +00:00
TOKULOGGER logger ;
2007-10-19 17:05:10 +00:00
TOKUTXN parent ;
2007-11-24 03:50:28 +00:00
LSN last_lsn ; /* Everytime anything is logged, update the LSN. (We need to atomically record the LSN along with writing into the log.) */
2008-03-21 21:02:30 +00:00
LSN first_lsn ; /* The first lsn in the transaction. */
2008-02-26 15:51:15 +00:00
struct roll_entry * oldest_logentry , * newest_logentry ; /* Only logentries with rollbacks are here. There is a list going from newest to oldest. */
2008-02-14 19:23:25 +00:00
struct list live_txns_link ;
2008-07-11 22:00:06 +00:00
MEMARENA rollentry_arena ;
2008-04-21 04:22:45 +00:00
size_t rollentry_resident_bytecount ; // How many bytes for the rollentries that are stored in main memory.
char * rollentry_filename ;
int rollentry_fd ; // If we spill the roll_entries, we write them into this fd.
2013-04-16 23:57:38 -04:00
toku_off_t rollentry_filesize ; // How many bytes are in the rollentry file (this is the uncompressed bytes. If the file is compressed it may actually be smaller (or even larger with header information))
2013-04-16 23:57:38 -04:00
u_int64_t rollentry_raw_count ; // the total count of every byte in the transaction and all its children.
2008-04-26 03:16:30 +00:00
OMT open_brts ; // a collection of the brts that we touched. Indexed by filenum.
2007-09-28 17:11:22 +00:00
} ;
2007-11-22 07:13:08 +00:00
2008-03-12 17:55:11 +00:00
int toku_logger_finish ( TOKULOGGER logger , struct logbytes * logbytes , struct wbuf * wbuf , int do_fsync ) ;
2007-11-22 18:45:22 +00:00
2007-11-23 17:16:26 +00:00
static inline int toku_logsizeof_u_int8_t ( u_int32_t v __attribute__ ( ( __unused__ ) ) ) {
return 1 ;
}
2007-11-22 18:45:22 +00:00
static inline int toku_logsizeof_u_int32_t ( u_int32_t v __attribute__ ( ( __unused__ ) ) ) {
return 4 ;
}
static inline int toku_logsizeof_FILENUM ( FILENUM v __attribute__ ( ( __unused__ ) ) ) {
return 4 ;
}
static inline int toku_logsizeof_DISKOFF ( DISKOFF v __attribute__ ( ( __unused__ ) ) ) {
return 8 ;
}
2013-04-16 23:57:18 -04:00
static inline int toku_logsizeof_BLOCKNUM ( BLOCKNUM v __attribute__ ( ( __unused__ ) ) ) {
return 8 ;
}
2007-11-22 18:45:22 +00:00
static inline int toku_logsizeof_TXNID ( TXNID txnid __attribute__ ( ( __unused__ ) ) ) {
return 8 ;
}
static inline int toku_logsizeof_BYTESTRING ( BYTESTRING bs ) {
2007-11-22 20:30:38 +00:00
return 4 + bs . len ;
2007-11-22 18:45:22 +00:00
}
2007-11-22 21:11:21 +00:00
static inline int toku_logsizeof_LOGGEDBRTHEADER ( LOGGEDBRTHEADER bs ) {
2013-04-16 23:57:44 -04:00
int in_both = 4 + 4 + 4 + 8 + 8 + 4 + 8 ;
in_both + = 8 ; // for the number of block headers
assert ( bs . btt_size . b < 30000000 ) ; // otherwise we in trouble on the next line
in_both + = 12 * bs . btt_size . b ;
2013-04-16 23:57:47 -04:00
return in_both + 8 ;
2007-11-22 21:11:21 +00:00
}
2007-12-04 10:02:59 +00:00
static inline int toku_logsizeof_INTPAIRARRAY ( INTPAIRARRAY pa ) {
return 4 + ( 4 + 4 ) * pa . size ;
}
2008-02-14 19:23:25 +00:00
2008-03-14 19:14:31 +00:00
static inline char * fixup_fname ( BYTESTRING * f ) {
assert ( f - > len > 0 ) ;
char * fname = toku_malloc ( f - > len + 1 ) ;
memcpy ( fname , f - > data , f - > len ) ;
fname [ f - > len ] = 0 ;
return fname ;
}
2008-04-21 04:22:45 +00:00
2008-07-11 22:00:06 +00:00
int toku_read_rollback_backwards ( BREAD , struct roll_entry * * item , MEMARENA ) ;
2013-04-16 23:57:20 -04:00
# endif