File log_impl.h¶
File List > cubrid > src > transaction > log_impl.h
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* log_impl.h -
*
*/
#ifndef _LOG_IMPL_H_
#define _LOG_IMPL_H_
#ident "$Id$"
#if !defined (SERVER_MODE) && !defined (SA_MODE)
#error Wrong module
#endif // not SERVER/SA modes
#include "boot.h"
#include "btree_unique.hpp"
#include "client_credentials.hpp"
#include "config.h"
#include "connection_globals.h"
#include "critical_section.h"
#include "es.h"
#include "file_io.h"
#include "lock_free.h"
#include "lock_manager.h"
#include "log_2pc.h"
#include "log_append.hpp"
#include "log_archives.hpp"
#include "log_comm.h"
#include "log_common_impl.h"
#include "log_lsa.hpp"
#include "log_postpone_cache.hpp"
#include "log_storage.hpp"
#include "mvcc.h"
#include "mvcc_table.hpp"
#include "porting.h"
#include "recovery.h"
#include "release_string.h"
#include "storage_common.h"
#include "tde.h"
#include "thread_entry.hpp"
#include "thread_manager.hpp"
#include "transaction_transient.hpp"
#include "lockfree_circular_queue.hpp"
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <assert.h>
#if defined(SOLARIS)
#include <netdb.h> /* for MAXHOSTNAMELEN */
#endif /* SOLARIS */
#include <signal.h>
// forward declarations
struct bo_restart_arg;
struct logwr_info;
#if defined(SERVER_MODE)
#define TR_TABLE_CS_ENTER(thread_p) \
csect_enter((thread_p), CSECT_TRAN_TABLE, INF_WAIT)
#define TR_TABLE_CS_ENTER_READ_MODE(thread_p) \
csect_enter_as_reader((thread_p), CSECT_TRAN_TABLE, INF_WAIT)
#define TR_TABLE_CS_EXIT(thread_p) \
csect_exit((thread_p), CSECT_TRAN_TABLE)
#define LOG_ARCHIVE_CS_ENTER(thread_p) \
csect_enter (thread_p, CSECT_LOG_ARCHIVE, INF_WAIT)
#define LOG_ARCHIVE_CS_ENTER_READ_MODE(thread_p) \
csect_enter_as_reader (thread_p, CSECT_LOG_ARCHIVE, INF_WAIT)
#define LOG_ARCHIVE_CS_EXIT(thread_p) \
csect_exit (thread_p, CSECT_LOG_ARCHIVE)
#else /* SERVER_MODE */
#define TR_TABLE_CS_ENTER(thread_p)
#define TR_TABLE_CS_ENTER_READ_MODE(thread_p)
#define TR_TABLE_CS_EXIT(thread_p)
#define LOG_ARCHIVE_CS_ENTER(thread_p)
#define LOG_ARCHIVE_CS_ENTER_READ_MODE(thread_p)
#define LOG_ARCHIVE_CS_EXIT(thread_p)
#endif /* SERVER_MODE */
#if defined(SERVER_MODE)
#define LOG_ARCHIVE_CS_OWN(thread_p) \
(csect_check (thread_p, CSECT_LOG_ARCHIVE) >= 1)
#define LOG_ARCHIVE_CS_OWN_WRITE_MODE(thread_p) \
(csect_check_own (thread_p, CSECT_LOG_ARCHIVE) == 1)
#define LOG_ARCHIVE_CS_OWN_READ_MODE(thread_p) \
(csect_check_own (thread_p, CSECT_LOG_ARCHIVE) == 2)
#else /* SERVER_MODE */
#define LOG_ARCHIVE_CS_OWN(thread_p) (true)
#define LOG_ARCHIVE_CS_OWN_WRITE_MODE(thread_p) (true)
#define LOG_ARCHIVE_CS_OWN_READ_MODE(thread_p) (true)
#endif /* !SERVER_MODE */
#define LOG_ESTIMATE_NACTIVE_TRANS 100 /* Estimate num of trans */
#define LOG_ESTIMATE_NOBJ_LOCKS 977 /* Estimate num of locks */
/* Log data area */
#define LOGAREA_SIZE (LOG_PAGESIZE - SSIZEOF(LOG_HDRPAGE))
/* check if group commit is active */
#define LOG_IS_GROUP_COMMIT_ACTIVE() \
(prm_get_integer_value (PRM_ID_LOG_GROUP_COMMIT_INTERVAL_MSECS) > 0)
#if defined(SERVER_MODE)
// todo - separate the client & server/sa_mode transaction index
#if !defined(LOG_FIND_THREAD_TRAN_INDEX)
#define LOG_FIND_THREAD_TRAN_INDEX(thrd) \
((thrd) ? (thrd)->tran_index : logtb_get_current_tran_index ())
#endif
#define LOG_SET_CURRENT_TRAN_INDEX(thrd, index) \
((thrd) ? (void) ((thrd)->tran_index = (index)) : logtb_set_current_tran_index ((thrd), (index)))
#else /* SERVER_MODE */
#if !defined(LOG_FIND_THREAD_TRAN_INDEX)
#define LOG_FIND_THREAD_TRAN_INDEX(thrd) (log_Tran_index)
#endif
#define LOG_SET_CURRENT_TRAN_INDEX(thrd, index) \
log_Tran_index = (index)
#endif /* SERVER_MODE */
#define LOG_ISTRAN_ACTIVE(tdes) \
((tdes)->state == TRAN_ACTIVE && LOG_ISRESTARTED ())
#define LOG_ISTRAN_COMMITTED(tdes) \
((tdes)->state == TRAN_UNACTIVE_COMMITTED \
|| (tdes)->state == TRAN_UNACTIVE_WILL_COMMIT \
|| (tdes)->state == TRAN_UNACTIVE_COMMITTED_WITH_POSTPONE \
|| (tdes)->state == TRAN_UNACTIVE_2PC_COMMIT_DECISION \
|| (tdes)->state == TRAN_UNACTIVE_COMMITTED_INFORMING_PARTICIPANTS)
#define LOG_ISTRAN_ABORTED(tdes) \
((tdes)->state == TRAN_UNACTIVE_ABORTED \
|| (tdes)->state == TRAN_UNACTIVE_UNILATERALLY_ABORTED \
|| (tdes)->state == TRAN_UNACTIVE_2PC_ABORT_DECISION \
|| (tdes)->state == TRAN_UNACTIVE_ABORTED_INFORMING_PARTICIPANTS)
#define LOG_ISTRAN_LOOSE_ENDS(tdes) \
((tdes)->state == TRAN_UNACTIVE_COMMITTED_INFORMING_PARTICIPANTS \
|| (tdes)->state == TRAN_UNACTIVE_ABORTED_INFORMING_PARTICIPANTS \
|| (tdes)->state == TRAN_UNACTIVE_2PC_COLLECTING_PARTICIPANT_VOTES \
|| (tdes)->state == TRAN_UNACTIVE_2PC_PREPARE)
#define LOG_ISTRAN_2PC_IN_SECOND_PHASE(tdes) \
((tdes)->state == TRAN_UNACTIVE_2PC_ABORT_DECISION \
|| (tdes)->state == TRAN_UNACTIVE_2PC_COMMIT_DECISION \
|| (tdes)->state == TRAN_UNACTIVE_WILL_COMMIT \
|| (tdes)->state == TRAN_UNACTIVE_COMMITTED_WITH_POSTPONE \
|| (tdes)->state == TRAN_UNACTIVE_ABORTED_INFORMING_PARTICIPANTS \
|| (tdes)->state == TRAN_UNACTIVE_COMMITTED_INFORMING_PARTICIPANTS)
#define LOG_ISTRAN_2PC(tdes) \
((tdes)->state == TRAN_UNACTIVE_2PC_COLLECTING_PARTICIPANT_VOTES \
|| (tdes)->state == TRAN_UNACTIVE_2PC_PREPARE \
|| LOG_ISTRAN_2PC_IN_SECOND_PHASE (tdes))
#define LOG_ISTRAN_2PC_PREPARE(tdes) \
((tdes)->state == TRAN_UNACTIVE_2PC_PREPARE)
#define LOG_ISTRAN_2PC_INFORMING_PARTICIPANTS(tdes) \
((tdes)->state == TRAN_UNACTIVE_COMMITTED_INFORMING_PARTICIPANTS \
|| (tdes)->state == TRAN_UNACTIVE_ABORTED_INFORMING_PARTICIPANTS)
const TRANID LOG_SYSTEM_WORKER_FIRST_TRANID = NULL_TRANID - 1;
const int LOG_SYSTEM_WORKER_INCR_TRANID = -1;
#define LOG_READ_NEXT_TRANID (log_Gl.hdr.next_trid)
#define LOG_READ_NEXT_MVCCID (log_Gl.hdr.mvcc_next_id)
#define LOG_HAS_LOGGING_BEEN_IGNORED() \
(log_Gl.hdr.has_logging_been_skipped == true)
#define LOG_ISRESTARTED() (log_Gl.rcv_phase == LOG_RESTARTED)
/* special action for log applier */
#if defined (SERVER_MODE)
#define LOG_CHECK_LOG_APPLIER(thread_p) \
(thread_p != NULL \
&& logtb_find_client_type (thread_p->tran_index) == DB_CLIENT_TYPE_LOG_APPLIER)
#else
#define LOG_CHECK_LOG_APPLIER(thread_p) (0)
#endif /* !SERVER_MODE */
#if !defined(_DB_DISABLE_MODIFICATIONS_)
#define _DB_DISABLE_MODIFICATIONS_
extern int db_Disable_modifications;
#endif /* _DB_DISABLE_MODIFICATIONS_ */
#ifndef CHECK_MODIFICATION_NO_RETURN
#if defined (SA_MODE)
#define CHECK_MODIFICATION_NO_RETURN(thread_p, error) \
(error) = NO_ERROR
#else /* SA_MODE */
#define CHECK_MODIFICATION_NO_RETURN(thread_p, error) \
do \
{ \
int mod_disabled; \
mod_disabled = logtb_is_tran_modification_disabled (thread_p); \
if (mod_disabled) \
{ \
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_DB_NO_MODIFICATIONS, \
0); \
er_log_debug (ARG_FILE_LINE, "tdes->disable_modification = %d\n", \
mod_disabled); \
error = ER_DB_NO_MODIFICATIONS; \
} \
else \
{ \
error = NO_ERROR; \
} \
} \
while (0)
#endif /* !SA_MODE */
#endif /* CHECK_MODIFICATION_NO_RETURN */
#define MAX_NUM_EXEC_QUERY_HISTORY 100
/*CDC defines*/
#define CDC_GET_TEMP_LOGPAGE(thread_p, process_lsa, log_page_p) \
do \
{ \
if (cdc_Gl.producer.temp_logbuf[(process_lsa)->pageid % 2].log_page_p->hdr.logical_pageid \
!= (process_lsa)->pageid) \
{ \
if (logpb_fetch_page ((thread_p), (process_lsa), LOG_CS_FORCE_USE, (log_page_p)) \
!= NO_ERROR) \
{ \
goto error; \
} \
memcpy (cdc_Gl.producer.temp_logbuf[(process_lsa)->pageid % 2].log_page_p, (log_page_p), IO_MAX_PAGE_SIZE); \
} \
else \
{ \
(log_page_p) = cdc_Gl.producer.temp_logbuf[(process_lsa)->pageid % 2].log_page_p ;\
} \
} \
while (0)
#define CDC_CHECK_TEMP_LOGPAGE(process_lsa, tmpbuf_index, log_page_p) \
do \
{ \
if (((process_lsa)->pageid % 2) != *(tmpbuf_index)) \
{ \
*(tmpbuf_index) = (*(tmpbuf_index) + 1) % 2; \
memcpy (cdc_Gl.producer.temp_logbuf[*(tmpbuf_index)].log_page_p, (log_page_p), IO_MAX_PAGE_SIZE); \
} \
} \
while (0)
#define CDC_UPDATE_TEMP_LOGPAGE(thread_p, process_lsa, log_page_p) \
do \
{ \
if (cdc_Gl.producer.temp_logbuf[(process_lsa)->pageid % 2].log_page_p->hdr.logical_pageid \
== (process_lsa)->pageid) \
{ \
if (logpb_fetch_page ((thread_p), (process_lsa), LOG_CS_FORCE_USE, (log_page_p)) \
!= NO_ERROR) \
{ \
goto error; \
} \
memcpy (cdc_Gl.producer.temp_logbuf[(process_lsa)->pageid % 2].log_page_p, (log_page_p), IO_MAX_PAGE_SIZE); \
} \
} \
while (0)
#define CDC_MAKE_SUPPLEMENT_DATA(supplement_data, recdes) \
do \
{ \
memcpy ((supplement_data), &(recdes).type, sizeof ((recdes).type)); \
memcpy ((supplement_data) + sizeof((recdes).type), (recdes).data, (recdes).length); \
} \
while (0)
#define cdc_log(...) if (cdc_Logging) _er_log_debug (ARG_FILE_LINE, "CDC: " __VA_ARGS__)
#define MAX_CDC_LOGINFO_QUEUE_ENTRY 2048
#define MAX_CDC_LOGINFO_QUEUE_SIZE 32 * 1024 * 1024 /*32 MB */
#define MAX_CDC_TRAN_USER_TABLE 4000
enum log_flush
{ LOG_DONT_NEED_FLUSH, LOG_NEED_FLUSH };
typedef enum log_flush LOG_FLUSH;
enum log_setdirty
{ LOG_DONT_SET_DIRTY, LOG_SET_DIRTY };
typedef enum log_setdirty LOG_SETDIRTY;
enum log_getnewtrid
{ LOG_DONT_NEED_NEWTRID, LOG_NEED_NEWTRID };
typedef enum log_getnewtrid LOG_GETNEWTRID;
enum log_wrote_eot_log
{ LOG_NEED_TO_WRITE_EOT_LOG, LOG_ALREADY_WROTE_EOT_LOG };
typedef enum log_wrote_eot_log LOG_WRITE_EOT_LOG;
/*
* Flush information shared by LFT and normal transaction.
* Transaction in commit phase has to flush all toflush array's pages.
*/
typedef struct log_flush_info LOG_FLUSH_INFO;
struct log_flush_info
{
/* Size of array to log append pages to flush */
int max_toflush;
/* Number of log append pages that can be flush Not all of the append pages may be full. */
int num_toflush;
/* A sorted order of log append free pages to flush */
LOG_PAGE **toflush;
#if defined(SERVER_MODE)
/* for protecting LOG_FLUSH_INFO */
pthread_mutex_t flush_mutex;
#endif /* SERVER_MODE */
};
typedef struct log_group_commit_info LOG_GROUP_COMMIT_INFO;
struct log_group_commit_info
{
/* group commit waiters count */
pthread_mutex_t gc_mutex;
pthread_cond_t gc_cond;
};
#define LOG_GROUP_COMMIT_INFO_INITIALIZER \
{ PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
typedef struct log_topops_addresses LOG_TOPOPS_ADDRESSES;
struct log_topops_addresses
{
LOG_LSA lastparent_lsa; /* The last address of the parent transaction. This is needed for undo of the top
* system action */
LOG_LSA posp_lsa; /* The first address of a postpone log record for top system operation. We add this
* since it is reset during recovery to the last reference postpone address. */
};
typedef struct log_topops_stack LOG_TOPOPS_STACK;
struct log_topops_stack
{
int max; /* Size of stack */
int last; /* Last entry in stack */
LOG_TOPOPS_ADDRESSES *stack; /* Stack for push and pop of top system actions */
};
enum tran_abort_reason
{
TRAN_NORMAL = 0,
TRAN_ABORT_DUE_DEADLOCK = 1,
TRAN_ABORT_DUE_ROLLBACK_ON_ESCALATION = 2
};
typedef enum tran_abort_reason TRAN_ABORT_REASON;
typedef struct log_unique_stats LOG_UNIQUE_STATS;
struct log_unique_stats
{
long long num_nulls; /* number of nulls */
long long num_keys; /* number of keys */
long long num_oids; /* number of oids */
};
typedef struct log_tran_btid_unique_stats LOG_TRAN_BTID_UNIQUE_STATS;
struct log_tran_btid_unique_stats
{
BTID btid; /* id of B-tree */
bool deleted; /* true if the B-tree was deleted */
LOG_UNIQUE_STATS tran_stats; /* statistics accumulated during entire transaction */
LOG_UNIQUE_STATS global_stats; /* statistics loaded from index */
};
enum count_optim_state
{
COS_NOT_LOADED = 0, /* the global statistics was not loaded yet */
COS_TO_LOAD = 1, /* the global statistics must be loaded when snapshot is taken */
COS_LOADED = 2 /* the global statistics were loaded */
};
typedef enum count_optim_state COUNT_OPTIM_STATE;
#define TRAN_UNIQUE_STATS_CHUNK_SIZE 128 /* size of the memory chunk for unique statistics */
/* LOG_TRAN_BTID_UNIQUE_STATS_CHUNK
* Represents a chunk of memory for transaction unique statistics
*/
typedef struct log_tran_btid_unique_stats_chunk LOG_TRAN_BTID_UNIQUE_STATS_CHUNK;
struct log_tran_btid_unique_stats_chunk
{
LOG_TRAN_BTID_UNIQUE_STATS_CHUNK *next_chunk; /* address of next chunk of memory */
LOG_TRAN_BTID_UNIQUE_STATS buffer[1]; /* more than one */
};
/* LOG_TRAN_CLASS_COS
* Structure used to store the state of the count optimization for classes.
*/
typedef struct log_tran_class_cos LOG_TRAN_CLASS_COS;
struct log_tran_class_cos
{
OID class_oid; /* class object identifier. */
COUNT_OPTIM_STATE count_state; /* count optimization state for class_oid */
};
#define COS_CLASSES_CHUNK_SIZE 64 /* size of the memory chunk for count optimization classes */
/* LOG_TRAN_CLASS_COS_CHUNK
* Represents a chunk of memory for count optimization states
*/
typedef struct log_tran_class_cos_chunk LOG_TRAN_CLASS_COS_CHUNK;
struct log_tran_class_cos_chunk
{
LOG_TRAN_CLASS_COS_CHUNK *next_chunk; /* address of next chunk of memory */
LOG_TRAN_CLASS_COS buffer[1]; /* more than one */
};
/* LOG_TRAN_UPDATE_STATS
* Structure used for transaction local unique statistics and count optimization
* management
*/
typedef struct log_tran_update_stats LOG_TRAN_UPDATE_STATS;
struct log_tran_update_stats
{
int cos_count; /* the number of hashed elements */
LOG_TRAN_CLASS_COS_CHUNK *cos_first_chunk; /* address of first chunk in the chunks list */
LOG_TRAN_CLASS_COS_CHUNK *cos_current_chunk; /* address of current chunk from which new elements are assigned */
MHT_TABLE *classes_cos_hash; /* hash of count optimization states for classes that were or will be subject to count
* optimization. */
int stats_count; /* the number of hashed elements */
LOG_TRAN_BTID_UNIQUE_STATS_CHUNK *stats_first_chunk; /* address of first chunk in the chunks list */
LOG_TRAN_BTID_UNIQUE_STATS_CHUNK *stats_current_chunk; /* address of current chunk from which new elements are
* assigned */
MHT_TABLE *unique_stats_hash; /* hash of unique statistics for indexes used during transaction. */
};
typedef struct log_rcv_tdes LOG_RCV_TDES;
struct log_rcv_tdes
{
/* structure stored in transaction descriptor and used for recovery purpose.
* currently we store the LSA of a system op start postpone. it is required to finish the system op postpone phase
* correctly */
LOG_LSA sysop_start_postpone_lsa;
/* we need to know where transaction postpone has started. */
LOG_LSA tran_start_postpone_lsa;
/* we need to know if file_perm_alloc or file_perm_dealloc operations have been interrupted. these operation must be
* executed atomically (all changes applied or all rollbacked) before executing finish all postpones. to know what
* to abort, we remember the starting LSA of such operation. */
LOG_LSA atomic_sysop_start_lsa;
LOG_LSA analysis_last_aborted_sysop_lsa; /* to recover logical redo operation. */
LOG_LSA analysis_last_aborted_sysop_start_lsa; /* to recover logical redo operation. */
};
typedef struct log_tdes LOG_TDES;
struct log_tdes
{
/* Transaction descriptor */
MVCC_INFO mvccinfo; /* MVCC info */
int tran_index; /* Index onto transaction table */
TRANID trid; /* Transaction identifier */
bool isloose_end;
TRAN_STATE state; /* Transaction state (e.g., Active, aborted) */
TRAN_ISOLATION isolation; /* Isolation level */
int wait_msecs; /* Wait until this number of milliseconds for locks; also see xlogtb_reset_wait_msecs */
LOG_LSA head_lsa; /* First log address of transaction */
LOG_LSA tail_lsa; /* Last log record address of transaction */
LOG_LSA undo_nxlsa; /* Next log record address of transaction for UNDO purposes. Needed since compensating
* log records are logged during UNDO */
LOG_LSA posp_nxlsa; /* Next address of a postpone record to be executed. Most of the time is the first
* address of a postpone log record */
LOG_LSA savept_lsa; /* Address of last savepoint */
LOG_LSA topop_lsa; /* Address of last top operation */
LOG_LSA tail_topresult_lsa; /* Address of last partial abort/commit */
LOG_LSA commit_abort_lsa; /* Address of the commit/abort operation. Used by checkpoint to decide whether to
* consider or not a transaction as concluded. */
int client_id; /* unique client id */
int gtrid; /* Global transaction identifier; used only if this transaction is a participant to a
* global transaction and it is prepared to commit. */
CLIENTIDS client; /* Client identification */
SYNC_RMUTEX rmutex_topop; /* reentrant mutex to serialize system top operations */
LOG_TOPOPS_STACK topops; /* Active top system operations. Used for system permanent nested operations which are
* independent from current transaction outcome. */
LOG_2PC_GTRINFO gtrinfo; /* Global transaction user information; used to store XID of XA interface. */
LOG_2PC_COORDINATOR *coord; /* Information about the participants of the distributed transactions. Used only if
* this site is the coordinator. Will be NULL if the transaction is a local one, or if
* this site is a participant. */
int num_unique_btrees; /* # of unique btrees contained in unique_stat_info array */
int max_unique_btrees; /* size of unique_stat_info array */
multi_index_unique_stats m_multiupd_stats;
#if defined(_AIX)
sig_atomic_t interrupt;
#else /* _AIX */
volatile sig_atomic_t interrupt;
#endif /* _AIX */
/* Set to one when the current execution must be stopped somehow. We stop it by sending an error message during
* fetching of a page. */
tx_transient_class_registry m_modified_classes; // list of classes made dirty
int num_transient_classnames; /* # of transient classnames by this transaction */
int num_repl_records; /* # of replication records */
int cur_repl_record; /* # of replication records */
int append_repl_recidx; /* index of append replication records */
int fl_mark_repl_recidx; /* index of flush marked replication record at first */
struct log_repl *repl_records; /* replication records */
LOG_LSA repl_insert_lsa; /* insert or mvcc update target lsa */
LOG_LSA repl_update_lsa; /* in-place update target lsa */
void *first_save_entry; /* first save entry for the transaction */
int suppress_replication; /* suppress writing replication logs when flag is set */
struct lob_rb_root lob_locator_root; /* all LOB locators to be created or delete during a transaction */
INT64 query_timeout; /* a query should be executed before query_timeout time. */
INT64 query_start_time;
INT64 tran_start_time;
XASL_ID xasl_id; /* xasl id of current query */
LK_RES *waiting_for_res; /* resource that i'm waiting for */
int disable_modifications; /* db_Disable_modification for each tran */
TRAN_ABORT_REASON tran_abort_reason;
/* bind values of executed queries in transaction */
int num_exec_queries;
DB_VALUE_ARRAY bind_history[MAX_NUM_EXEC_QUERY_HISTORY];
int num_log_records_written; /* # of log records generated */
LOG_TRAN_UPDATE_STATS log_upd_stats; /* Collects data about inserted/ deleted records during last
* command/transaction */
bool has_deadlock_priority;
bool block_global_oldest_active_until_commit;
bool is_user_active;
LOG_RCV_TDES rcv;
log_postpone_cache m_log_postpone_cache;
bool has_supplemental_log; /* Checks if supplemental log has been appended within the transaction */
char *ddl_sql_user_text; /* SQL user text for the transaction */
// *INDENT-OFF*
#if defined (SERVER_MODE) || (defined (SA_MODE) && defined (__cplusplus))
bool is_active_worker_transaction () const;
bool is_system_transaction () const;
bool is_system_main_transaction () const;
bool is_system_worker_transaction () const;
bool is_allowed_undo () const;
bool is_allowed_sysop () const;
bool is_under_sysop () const;
void lock_topop ();
void unlock_topop ();
void on_sysop_start ();
void on_sysop_end ();
// lock global oldest visible mvccid to current value; required for heavy operations that need to do their own
// vacuuming, like upgrade domain / reorganize partitions
void lock_global_oldest_visible_mvccid ();
void unlock_global_oldest_visible_mvccid ();
#endif
// *INDENT-ON*
void copy_to (LOG_TDES & dest) const;
};
typedef struct log_addr_tdesarea LOG_ADDR_TDESAREA;
struct log_addr_tdesarea
{
LOG_TDES *tdesarea;
LOG_ADDR_TDESAREA *next;
};
/* Transaction Table */
typedef struct trantable TRANTABLE;
struct trantable
{
int num_total_indices; /* Number of total transaction indices */
int num_assigned_indices; /* Number of assigned transaction indices (i.e., number of active thread/clients) */
/* Number of coordinator loose end indices */
int num_coord_loose_end_indices;
/* Number of prepared participant loose end indices */
int num_prepared_loose_end_indices;
int hint_free_index; /* Hint for a free index */
/* Number of transactions that must be interrupted */
#if defined(_AIX)
sig_atomic_t num_interrupts;
#else /* _AIX */
volatile sig_atomic_t num_interrupts;
#endif /* _AIX */
LOG_ADDR_TDESAREA *area; /* Contiguous area to transaction descriptors */
LOG_TDES **all_tdes; /* Pointers to all transaction descriptors */
};
#define TRANTABLE_INITIALIZER \
{ 0, 0, 0, 0, 0, 0, NULL, NULL }
/* state of recovery process */
enum log_recvphase
{
LOG_RESTARTED, /* Normal processing.. recovery has been executed. */
LOG_RECOVERY_ANALYSIS_PHASE, /* Start recovering. Find the transactions that were active at the time of the crash */
LOG_RECOVERY_REDO_PHASE, /* Redoing phase */
LOG_RECOVERY_UNDO_PHASE, /* Undoing phase */
LOG_RECOVERY_FINISH_2PC_PHASE /* Finishing up transactions that were in 2PC protocol at the time of the crash */
};
typedef enum log_recvphase LOG_RECVPHASE;
/* stores global statistics for a unique btree */
typedef struct global_unique_stats GLOBAL_UNIQUE_STATS;
struct global_unique_stats
{
BTID btid; /* btree id */
GLOBAL_UNIQUE_STATS *stack; /* used in freelist */
GLOBAL_UNIQUE_STATS *next; /* used in hash table */
pthread_mutex_t mutex; /* state mutex */
UINT64 del_id; /* delete transaction ID (for lock free) */
LOG_UNIQUE_STATS unique_stats; /* statistics for btid unique btree */
LOG_LSA last_log_lsa; /* The log lsa of the last RVBT_LOG_GLOBAL_UNIQUE_STATS_COMMIT record logged into the
* btree header page of btid */
};
/* stores global statistics for all unique btrees */
typedef struct global_unique_stats_table GLOBAL_UNIQUE_STATS_TABLE;
struct global_unique_stats_table
{
LF_HASH_TABLE unique_stats_hash; /* hash with btid as key and GLOBAL_UNIQUE_STATS as data */
LF_ENTRY_DESCRIPTOR unique_stats_descriptor; /* used by unique_stats_hash */
LF_FREELIST unique_stats_freelist; /* used by unique_stats_hash */
LOG_LSA curr_rcv_rec_lsa; /* This is used at recovery stage to pass the lsa of the log record to be processed, to
* the record processing funtion, in order to restore the last_log_lsa from
* GLOBAL_UNIQUE_STATS */
bool initialized; /* true if the current instance was initialized */
};
#define GLOBAL_UNIQUE_STATS_TABLE_INITIALIZER \
{ LF_HASH_TABLE_INITIALIZER, LF_ENTRY_DESCRIPTOR_INITIALIZER, LF_FREELIST_INITIALIZER, LSA_INITIALIZER, false }
#define GLOBAL_UNIQUE_STATS_HASH_SIZE 1000
/* Global structure to trantable, log buffer pool, etc */
typedef struct log_global LOG_GLOBAL;
struct log_global
{
TRANTABLE trantable; /* Transaction table */
LOG_APPEND_INFO append; /* The log append info */
LOG_PRIOR_LSA_INFO prior_info;
LOG_HEADER hdr; /* The log header */
LOG_ARCHIVES archive; /* Current archive information */
LOG_PAGEID run_nxchkpt_atpageid;
#if defined(SERVER_MODE)
LOG_LSA flushed_lsa_lower_bound; /* lsa */
pthread_mutex_t chkpt_lsa_lock;
#endif /* SERVER_MODE */
LOG_LSA chkpt_redo_lsa;
DKNPAGES chkpt_every_npages; /* How frequent a checkpoint should be taken ? */
LOG_RECVPHASE rcv_phase; /* Phase of the recovery */
LOG_LSA rcv_phase_lsa; /* LSA of phase (e.g. Restart) */
#if defined(SERVER_MODE)
bool backup_in_progress;
#else /* SERVER_MODE */
LOG_LSA final_restored_lsa;
#endif /* SERVER_MODE */
/* Buffer for log hdr I/O, size : SIZEOF_LOG_PAGE_SIZE */
LOG_PAGE *loghdr_pgptr;
/* Flush information for dirty log pages */
LOG_FLUSH_INFO flush_info;
/* group commit information */
LOG_GROUP_COMMIT_INFO group_commit_info;
/* remote log writer information */
logwr_info *writer_info;
/* background log archiving info */
BACKGROUND_ARCHIVING_INFO bg_archive_info;
mvcctable mvcc_table; /* MVCC table */
GLOBAL_UNIQUE_STATS_TABLE unique_stats_table; /* global unique statistics */
// *INDENT-OFF*
log_global ();
~log_global ();
// *INDENT-ON*
};
/* logging statistics */
typedef struct log_logging_stat
{
/* logpb_next_append_page() call count */
unsigned long total_append_page_count;
/* last created page id for logging */
LOG_PAGEID last_append_pageid;
/* time taken to use a page for logging */
double use_append_page_sec;
/* log buffer full count */
unsigned long log_buffer_full_count;
/* log buffer flush count by replacement */
unsigned long log_buffer_flush_count_by_replacement;
/* normal flush */
/* logpb_flush_all_append_pages() call count */
unsigned long flushall_append_pages_call_count;
/* pages count to flush in logpb_flush_all_append_pages() */
unsigned long last_flush_count_by_trans;
/* total pages count to flush in logpb_flush_all_append_pages() */
unsigned long total_flush_count_by_trans;
/* time taken to flush in logpb_flush_all_append_pages() */
double last_flush_sec_by_trans;
/* total time taken to flush in logpb_flush_all_append_pages() */
double total_flush_sec_by_trans;
/* logpb_flush_pages_direct() count */
unsigned long direct_flush_count;
/* logpb_flush_header() call count */
unsigned long flush_hdr_call_count;
/* page count to flush in logpb_flush_header() */
double last_flush_hdr_sec_by_LFT;
/* total page count to flush in logpb_flush_header() */
double total_flush_hdr_sec_by_LFT;
/* total sync count */
unsigned long total_sync_count;
/* commit count */
unsigned long commit_count;
/* group commit count */
unsigned long last_group_commit_count;
/* total group commit count */
unsigned long total_group_commit_count;
/* commit count while using a log page */
unsigned long last_commit_count_while_using_a_page;
/* total commit count while using a log page */
unsigned long total_commit_count_while_using_a_page;
/* commit count included logpb_flush_all_append_pages */
unsigned long last_commit_count_in_flush_pages;
/* total commit count included logpb_flush_all_append_pages */
unsigned long total_commit_count_in_flush_pages;
/* group commit request count */
unsigned long gc_commit_request_count;
/* wait time for group commit */
double gc_total_wait_time;
/* flush count in group commit mode by LFT */
unsigned long gc_flush_count;
/* async commit request count */
unsigned long async_commit_request_count;
} LOG_LOGGING_STAT;
/* For CDC interface */
typedef enum cdc_producer_state
{
CDC_PRODUCER_STATE_WAIT,
CDC_PRODUCER_STATE_RUN,
CDC_PRODUCER_STATE_DEAD
} CDC_PRODUCER_STATE;
typedef enum cdc_consumer_request
{
CDC_REQUEST_CONSUMER_TO_WAIT,
CDC_REQUEST_CONSUMER_TO_RUN,
CDC_REQUEST_CONSUMER_NONE
} CDC_CONSUMER_REQUEST;
typedef enum cdc_producer_request
{
CDC_REQUEST_PRODUCER_TO_WAIT,
CDC_REQUEST_PRODUCER_TO_BE_DEAD,
CDC_REQUEST_PRODUCER_NONE
} CDC_PRODUCER_REQUEST;
typedef struct cdc_loginfo_entry
{
LOG_LSA next_lsa;
int length;
char *log_info;
} CDC_LOGINFO_ENTRY;
typedef struct cdc_temp_logbuf
{
LOG_PAGE *log_page_p;
char log_page[IO_MAX_PAGE_SIZE + MAX_ALIGNMENT];
} CDC_TEMP_LOGBUF;
typedef struct cdc_producer
{
LOG_LSA next_extraction_lsa;
/* configuration */
int all_in_cond;
int num_extraction_user;
char **extraction_user;
int num_extraction_class;
UINT64 *extraction_classoids;
volatile CDC_PRODUCER_STATE state;
volatile CDC_PRODUCER_REQUEST request;
int produced_queue_size;
pthread_mutex_t lock;
pthread_cond_t wait_cond;
CDC_TEMP_LOGBUF temp_logbuf[2];
/* *INDENT-OFF* */
std::unordered_map <TRANID, char *> tran_user; /*to clear when log producer ends suddenly */
std::unordered_map<TRANID, int > tran_ignore;
/* *INDENT-ON* */
} CDC_PRODUCER;
typedef struct cdc_consumer
{
int extraction_timeout;
int max_log_item;
char *log_info; /* log info list. it is used as buffer to send to client */
int log_info_size; /* total length of data in log_info */
int log_info_buf_size; /* size of buffer for log_info */
int num_log_info; /* how many log info is stored in log_infos (log info list) */
int consumed_queue_size;
volatile CDC_CONSUMER_REQUEST request;
LOG_LSA start_lsa; /* first LSA of log info that should be sent */
LOG_LSA next_lsa; /* next LSA to be sent to client */
} CDC_CONSUMER;
typedef struct cdc_global
{
css_conn_entry conn;
CDC_PRODUCER producer;
CDC_CONSUMER consumer;
/* *INDENT-OFF* */
lockfree::circular_queue<CDC_LOGINFO_ENTRY *> *loginfo_queue;
/* *INDENT-ON* */
LOG_LSA first_loginfo_queue_lsa;
LOG_LSA last_loginfo_queue_lsa;
bool is_queue_reinitialized;
} CDC_GLOBAL;
/* will be moved to new file for CDC */
typedef struct ovf_page_list
{
char *rec_type;
char *data;
int length;
struct ovf_page_list *next;
} OVF_PAGE_LIST;
typedef enum cdc_dataitem_type
{
CDC_DDL = 0,
CDC_DML,
CDC_DCL,
CDC_TIMER
} CDC_DATAITEM_TYPE;
typedef enum cdc_dcl_type
{
CDC_COMMIT = 0,
CDC_ABORT
} CDC_DCL_TYPE;
typedef enum cdc_dml_type
{
CDC_INSERT = 0,
CDC_UPDATE,
CDC_DELETE,
CDC_TRIGGER_INSERT,
CDC_TRIGGER_UPDATE,
CDC_TRIGGER_DELETE
} CDC_DML_TYPE;
/*Data structure for CDC interface end */
// todo - move to manager
enum log_cs_access_mode
{ LOG_CS_FORCE_USE, LOG_CS_SAFE_READER };
typedef enum log_cs_access_mode LOG_CS_ACCESS_MODE;
#if !defined(SERVER_MODE)
#if !defined(LOG_TRAN_INDEX)
#define LOG_TRAN_INDEX
extern int log_Tran_index; /* Index onto transaction table for current thread of execution (client) */
#endif /* !LOG_TRAN_INDEX */
#endif /* !SERVER_MODE */
extern LOG_GLOBAL log_Gl;
extern LOG_LOGGING_STAT log_Stat;
/* Name of the database and logs */
extern char log_Path[];
extern char log_Archive_path[];
extern char log_Prefix[];
extern const char *log_Db_fullname;
extern char log_Name_active[];
extern char log_Name_info[];
extern char log_Name_bkupinfo[];
extern char log_Name_volinfo[];
extern char log_Name_bg_archive[];
extern char log_Name_removed_archive[];
/*CDC global variables */
extern CDC_GLOBAL cdc_Gl;
extern bool cdc_Logging;
#if defined (SERVER_MODE)
// *INDENT-OFF*
extern cubthread::worker_pool_type *g_backup_read_worker_pool;
// *INDENT-ON*
#endif
/* logging */
#if defined (SA_MODE)
#define LOG_THREAD_TRAN_MSG "%s"
#define LOG_THREAD_TRAN_ARGS(thread_p) "(SA_MODE)"
#else /* !SA_MODE */ /* SERVER_MODE */
#define LOG_THREAD_TRAN_MSG "(thr=%d, trid=%d)"
#define LOG_THREAD_TRAN_ARGS(thread_p) thread_get_current_entry_index (), LOG_FIND_CURRENT_TDES (thread_p)
#endif /* SERVER_MODE */
extern int logpb_initialize_pool (THREAD_ENTRY * thread_p);
extern void logpb_finalize_pool (THREAD_ENTRY * thread_p);
extern bool logpb_is_pool_initialized (void);
extern void logpb_invalidate_pool (THREAD_ENTRY * thread_p);
extern LOG_PAGE *logpb_create_page (THREAD_ENTRY * thread_p, LOG_PAGEID pageid);
extern void logpb_set_dirty (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr);
extern int logpb_flush_page (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr);
extern LOG_PAGEID logpb_get_page_id (LOG_PAGE * log_pgptr);
extern int logpb_initialize_header (THREAD_ENTRY * thread_p, LOG_HEADER * loghdr, const char *prefix_logname,
DKNPAGES npages, INT64 * db_creation);
extern LOG_PAGE *logpb_create_header_page (THREAD_ENTRY * thread_p);
extern void logpb_fetch_header (THREAD_ENTRY * thread_p, LOG_HEADER * hdr);
extern void logpb_fetch_header_with_buffer (THREAD_ENTRY * thread_p, LOG_HEADER * hdr, LOG_PAGE * log_pgptr);
extern void logpb_flush_header (THREAD_ENTRY * thread_p);
extern int logpb_fetch_page (THREAD_ENTRY * thread_p, const LOG_LSA * req_lsa, LOG_CS_ACCESS_MODE access_mode,
LOG_PAGE * log_pgptr);
extern int logpb_copy_page_from_log_buffer (THREAD_ENTRY * thread_p, LOG_PAGEID pageid, LOG_PAGE * log_pgptr);
extern int logpb_copy_page_from_file (THREAD_ENTRY * thread_p, LOG_PAGEID pageid, LOG_PAGE * log_pgptr);
extern int logpb_read_page_from_file (THREAD_ENTRY * thread_p, LOG_PAGEID pageid, LOG_CS_ACCESS_MODE access_mode,
LOG_PAGE * log_pgptr);
extern int logpb_read_page_from_active_log (THREAD_ENTRY * thread_p, LOG_PAGEID pageid, int num_pages,
bool decrypt_needed, LOG_PAGE * log_pgptr);
extern int logpb_write_page_to_disk (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr, LOG_PAGEID logical_pageid);
extern int logpb_fetch_header_from_active_log (THREAD_ENTRY * thread_p, const char *db_fullname,
const char *logpath, const char *prefix_logname, LOG_HEADER * hdr,
LOG_PAGE * log_pgptr);
extern PGLENGTH logpb_find_header_parameters (THREAD_ENTRY * thread_p, const bool force_read_log_header,
const char *db_fullname, const char *logpath,
const char *prefix_logname, PGLENGTH * io_page_size,
PGLENGTH * log_page_size, INT64 * db_creation, float *db_compatibility,
int *db_charset);
extern int logpb_fetch_start_append_page (THREAD_ENTRY * thread_p);
extern LOG_PAGE *logpb_fetch_start_append_page_new (THREAD_ENTRY * thread_p);
extern void logpb_flush_pages_direct (THREAD_ENTRY * thread_p);
extern void logpb_flush_pages (THREAD_ENTRY * thread_p, LOG_LSA * flush_lsa);
extern void logpb_force_flush_pages (THREAD_ENTRY * thread_p);
extern void logpb_force_flush_header_and_pages (THREAD_ENTRY * thread_p);
extern void logpb_invalid_all_append_pages (THREAD_ENTRY * thread_p);
extern void logpb_flush_log_for_wal (THREAD_ENTRY * thread_p, const LOG_LSA * lsa_ptr);
#if defined (ENABLE_UNUSED_FUNCTION)
extern void logpb_remove_append (LOG_TDES * tdes);
#endif
extern void logpb_create_log_info (const char *logname_info, const char *db_fullname);
extern bool logpb_find_volume_info_exist (void);
extern int logpb_create_volume_info (const char *db_fullname);
extern int logpb_recreate_volume_info (THREAD_ENTRY * thread_p);
extern VOLID logpb_add_volume (const char *db_fullname, VOLID new_volid, const char *new_volfullname,
DISK_VOLPURPOSE new_volpurpose);
extern int logpb_scan_volume_info (THREAD_ENTRY * thread_p, const char *db_fullname, VOLID ignore_volid,
VOLID start_volid, int (*fun) (THREAD_ENTRY * thread_p, VOLID xvolid,
const char *vlabel, void *args), void *args);
extern LOG_PHY_PAGEID logpb_to_physical_pageid (LOG_PAGEID logical_pageid);
extern bool logpb_is_page_in_archive (LOG_PAGEID pageid);
extern bool logpb_is_smallest_lsa_in_archive (THREAD_ENTRY * thread_p);
extern int logpb_get_archive_number (THREAD_ENTRY * thread_p, LOG_PAGEID pageid);
extern void logpb_decache_archive_info (THREAD_ENTRY * thread_p);
extern LOG_PAGE *logpb_fetch_from_archive (THREAD_ENTRY * thread_p, LOG_PAGEID pageid, LOG_PAGE * log_pgptr,
int *ret_arv_num, LOG_ARV_HEADER * arv_hdr, bool is_fatal);
extern void logpb_remove_archive_logs (THREAD_ENTRY * thread_p, const char *info_reason);
extern int logpb_remove_archive_logs_exceed_limit (THREAD_ENTRY * thread_p, int max_count);
extern void logpb_copy_from_log (THREAD_ENTRY * thread_p, char *area, int length, LOG_LSA * log_lsa,
LOG_PAGE * log_pgptr);
extern int logpb_initialize_log_names (THREAD_ENTRY * thread_p, const char *db_fullname, const char *logpath,
const char *prefix_logname);
extern bool logpb_exist_log (THREAD_ENTRY * thread_p, const char *db_fullname, const char *logpath,
const char *prefix_logname);
extern LOG_PAGEID logpb_checkpoint (THREAD_ENTRY * thread_p);
extern void logpb_dump_checkpoint_trans (FILE * out_fp, int length, void *data);
extern int logpb_backup (THREAD_ENTRY * thread_p, int num_perm_vols, const char *allbackup_path,
FILEIO_BACKUP_LEVEL backup_level, bool delete_unneeded_logarchives,
const char *backup_verbose_file_path, int num_threads, FILEIO_ZIP_METHOD zip_method,
FILEIO_ZIP_LEVEL zip_level, int skip_activelog, int sleep_msecs, bool separate_keys);
extern void logpb_create_backup_read_worker_pool (size_t thread_count);
extern void logpb_push_backup_read_task (cubthread::entry_task * task);
extern void logpb_destroy_backup_read_worker_pool ();
extern int logpb_restore (THREAD_ENTRY * thread_p, const char *db_fullname, const char *logpath,
const char *prefix_logname, bo_restart_arg * r_args);
extern int logpb_copy_database (THREAD_ENTRY * thread_p, VOLID num_perm_vols, const char *to_db_fullname,
const char *to_logpath, const char *to_prefix_logname, const char *toext_path,
const char *fileof_vols_and_copypaths);
extern int logpb_rename_all_volumes_files (THREAD_ENTRY * thread_p, VOLID num_perm_vols, const char *to_db_fullname,
const char *to_logpath, const char *to_prefix_logname,
const char *toext_path, const char *fileof_vols_and_renamepaths,
bool extern_rename, bool force_delete);
extern int logpb_delete (THREAD_ENTRY * thread_p, VOLID num_perm_vols, const char *db_fullname, const char *logpath,
const char *prefix_logname, bool force_delete);
extern int logpb_check_exist_any_volumes (THREAD_ENTRY * thread_p, const char *db_fullname, const char *logpath,
const char *prefix_logname, char *first_vol, bool * is_exist);
extern void logpb_fatal_error (THREAD_ENTRY * thread_p, bool logexit, const char *file_name, const int lineno,
const char *fmt, ...);
extern void logpb_fatal_error_exit_immediately_wo_flush (THREAD_ENTRY * thread_p, const char *file_name,
const int lineno, const char *fmt, ...);
extern int logpb_check_and_reset_temp_lsa (THREAD_ENTRY * thread_p, VOLID volid);
extern void logpb_initialize_arv_page_info_table (void);
extern void logpb_initialize_logging_statistics (void);
extern int logpb_background_archiving (THREAD_ENTRY * thread_p);
extern void xlogpb_dump_stat (FILE * outfp);
extern void logpb_dump (THREAD_ENTRY * thread_p, FILE * out_fp);
extern int logpb_remove_all_in_log_path (THREAD_ENTRY * thread_p, const char *db_fullname, const char *logpath,
const char *prefix_logname);
extern TDE_ALGORITHM logpb_get_tde_algorithm (const LOG_PAGE * log_pgptr);
extern void logpb_set_tde_algorithm (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr, const TDE_ALGORITHM tde_algo);
extern void *logtb_realloc_topops_stack (LOG_TDES * tdes, int num_elms);
extern void logtb_define_trantable (THREAD_ENTRY * thread_p, int num_expected_tran_indices, int num_expected_locks);
extern int logtb_define_trantable_log_latch (THREAD_ENTRY * thread_p, int num_expected_tran_indices);
extern void logtb_undefine_trantable (THREAD_ENTRY * thread_p);
extern int logtb_get_number_assigned_tran_indices (void);
extern int logtb_get_number_of_total_tran_indices (void);
#if defined(ENABLE_UNUSED_FUNCTION)
extern bool logtb_am_i_sole_tran (THREAD_ENTRY * thread_p);
extern void logtb_i_am_not_sole_tran (THREAD_ENTRY * thread_p);
#endif
extern bool logtb_am_i_dba_client (THREAD_ENTRY * thread_p);
extern int logtb_assign_tran_index (THREAD_ENTRY * thread_p, TRANID trid, TRAN_STATE state,
const BOOT_CLIENT_CREDENTIAL * client_credential, TRAN_STATE * current_state,
int wait_msecs, TRAN_ISOLATION isolation);
extern LOG_TDES *logtb_rv_find_allocate_tran_index (THREAD_ENTRY * thread_p, TRANID trid, const LOG_LSA * log_lsa);
extern void logtb_rv_assign_mvccid_for_undo_recovery (THREAD_ENTRY * thread_p, MVCCID mvccid);
extern void logtb_release_tran_index (THREAD_ENTRY * thread_p, int tran_index);
extern void logtb_free_tran_index (THREAD_ENTRY * thread_p, int tran_index);
extern void logtb_free_tran_index_with_undo_lsa (THREAD_ENTRY * thread_p, const LOG_LSA * undo_lsa);
extern void logtb_initialize_tdes (LOG_TDES * tdes, int tran_index);
extern void logtb_clear_tdes (THREAD_ENTRY * thread_p, LOG_TDES * tdes);
extern void logtb_finalize_tdes (THREAD_ENTRY * thread_p, LOG_TDES * tdes);
extern int logtb_get_new_tran_id (THREAD_ENTRY * thread_p, LOG_TDES * tdes);
extern int logtb_find_tran_index (THREAD_ENTRY * thread_p, TRANID trid);
#if defined (ENABLE_UNUSED_FUNCTION)
extern int logtb_find_tran_index_host_pid (THREAD_ENTRY * thread_p, const char *host_name, int process_id);
#endif
extern TRANID logtb_find_tranid (int tran_index);
extern TRANID logtb_find_current_tranid (THREAD_ENTRY * thread_p);
#if defined (ENABLE_UNUSED_FUNCTION)
extern int logtb_count_clients_with_type (THREAD_ENTRY * thread_p, int client_type);
#endif
extern int logtb_count_clients (THREAD_ENTRY * thread_p);
extern int logtb_count_not_allowed_clients_in_maintenance_mode (THREAD_ENTRY * thread_p);
extern int logtb_find_client_type (int tran_index);
extern const char *logtb_find_client_name (int tran_index);
extern void logtb_set_user_name (int tran_index, const char *client_name);
extern void logtb_set_current_user_name (THREAD_ENTRY * thread_p, const char *client_name);
extern const char *logtb_find_client_hostname (int tran_index);
extern void logtb_set_current_user_active (THREAD_ENTRY * thread_p, bool is_user_active);
extern int logtb_find_client_name_host_pid (int tran_index, const char **client_prog_name,
const char **client_user_name, const char **client_host_name,
int *client_pid);
#if !defined(NDEBUG)
extern void logpb_debug_check_log_page (THREAD_ENTRY * thread_p, void *log_pgptr_ptr);
#endif
#if defined (SERVER_MODE)
extern int logtb_find_client_tran_name_host_pid (int &tran_index, const char **client_prog_name,
const char **client_user_name, const char **client_host_name,
int *client_pid);
#endif // SERVER_MODE
extern int logtb_get_client_ids (int tran_index, CLIENTIDS * client_info);
extern int logtb_find_current_client_type (THREAD_ENTRY * thread_p);
extern const char *logtb_find_current_client_name (THREAD_ENTRY * thread_p);
extern const char *logtb_find_current_client_hostname (THREAD_ENTRY * thread_p);
extern LOG_LSA *logtb_find_current_tran_lsa (THREAD_ENTRY * thread_p);
extern TRAN_STATE logtb_find_state (int tran_index);
extern int logtb_find_wait_msecs (int tran_index);
extern int logtb_find_interrupt (int tran_index, bool * interrupt);
extern TRAN_ISOLATION logtb_find_isolation (int tran_index);
extern TRAN_ISOLATION logtb_find_current_isolation (THREAD_ENTRY * thread_p);
extern bool logtb_set_tran_index_interrupt (THREAD_ENTRY * thread_p, int tran_index, bool set);
extern bool logtb_set_suppress_repl_on_transaction (THREAD_ENTRY * thread_p, int tran_index, int set);
extern bool logtb_is_interrupted (THREAD_ENTRY * thread_p, bool clear, bool * continue_checking);
extern bool logtb_is_interrupted_tran (THREAD_ENTRY * thread_p, bool clear, bool * continue_checking, int tran_index);
extern bool logtb_is_active (THREAD_ENTRY * thread_p, TRANID trid);
extern bool logtb_is_current_active (THREAD_ENTRY * thread_p);
extern bool logtb_istran_finished (THREAD_ENTRY * thread_p, TRANID trid);
extern void logtb_disable_update (THREAD_ENTRY * thread_p);
extern void logtb_enable_update (THREAD_ENTRY * thread_p);
extern void logtb_set_to_system_tran_index (THREAD_ENTRY * thread_p);
#if defined (ENABLE_UNUSED_FUNCTION)
extern LOG_LSA *logtb_find_largest_lsa (THREAD_ENTRY * thread_p);
#endif
extern int logtb_set_num_loose_end_trans (THREAD_ENTRY * thread_p);
extern void logtb_rv_read_only_map_undo_tdes (THREAD_ENTRY * thread_p,
const std::function < void (const log_tdes &) > map_func);
extern void logtb_find_smallest_lsa (THREAD_ENTRY * thread_p, LOG_LSA * lsa);
extern void logtb_find_smallest_and_largest_active_pages (THREAD_ENTRY * thread_p, LOG_PAGEID * smallest,
LOG_PAGEID * largest);
extern int logtb_is_tran_modification_disabled (THREAD_ENTRY * thread_p);
extern bool logtb_has_deadlock_priority (int tran_index);
/* For Debugging */
extern void xlogtb_dump_trantable (THREAD_ENTRY * thread_p, FILE * out_fp);
extern bool logpb_need_wal (const LOG_LSA * lsa);
extern char *logpb_backup_level_info_to_string (char *buf, int buf_size, const LOG_HDR_BKUP_LEVEL_INFO * info);
extern const char *tran_abort_reason_to_string (TRAN_ABORT_REASON val);
extern int logtb_descriptors_start_scan (THREAD_ENTRY * thread_p, int type, DB_VALUE ** arg_values, int arg_cnt,
void **ctx);
extern LOG_PAGEID logpb_find_oldest_available_page_id (THREAD_ENTRY * thread_p);
extern int logpb_find_oldest_available_arv_num (THREAD_ENTRY * thread_p);
extern void logtb_get_new_subtransaction_mvccid (THREAD_ENTRY * thread_p, MVCC_INFO * curr_mvcc_info);
extern MVCCID logtb_find_current_mvccid (THREAD_ENTRY * thread_p);
extern MVCCID logtb_get_current_mvccid (THREAD_ENTRY * thread_p);
extern int logtb_invalidate_snapshot_data (THREAD_ENTRY * thread_p);
extern int xlogtb_get_mvcc_snapshot (THREAD_ENTRY * thread_p);
extern bool logtb_is_current_mvccid (THREAD_ENTRY * thread_p, MVCCID mvccid);
extern bool logtb_is_mvccid_committed (THREAD_ENTRY * thread_p, MVCCID mvccid);
extern MVCC_SNAPSHOT *logtb_get_mvcc_snapshot (THREAD_ENTRY * thread_p);
extern void logtb_complete_mvcc (THREAD_ENTRY * thread_p, LOG_TDES * tdes, bool committed);
extern void logtb_complete_sub_mvcc (THREAD_ENTRY * thread_p, LOG_TDES * tdes);
extern LOG_TRAN_CLASS_COS *logtb_tran_find_class_cos (THREAD_ENTRY * thread_p, const OID * class_oid, bool create);
extern int logtb_tran_update_unique_stats (THREAD_ENTRY * thread_p, const BTID * btid, long long n_keys,
long long n_oids, long long n_nulls, bool write_to_log);
// *INDENT-OFF*
extern int logtb_tran_update_unique_stats (THREAD_ENTRY * thread_p, const BTID &btid, const btree_unique_stats &ustats,
bool write_to_log);
extern int logtb_tran_update_unique_stats (THREAD_ENTRY * thread_p, const multi_index_unique_stats &multi_stats,
bool write_to_log);
// *INDENT-ON*
extern int logtb_tran_update_btid_unique_stats (THREAD_ENTRY * thread_p, const BTID * btid, long long n_keys,
long long n_oids, long long n_nulls);
extern LOG_TRAN_BTID_UNIQUE_STATS *logtb_tran_find_btid_stats (THREAD_ENTRY * thread_p, const BTID * btid, bool create);
extern int logtb_tran_prepare_count_optim_classes (THREAD_ENTRY * thread_p, const char **classes,
LC_PREFETCH_FLAGS * flags, int n_classes);
extern void logtb_tran_reset_count_optim_state (THREAD_ENTRY * thread_p);
extern int logtb_find_log_records_count (int tran_index);
extern int logtb_initialize_global_unique_stats_table (THREAD_ENTRY * thread_p);
extern void logtb_finalize_global_unique_stats_table (THREAD_ENTRY * thread_p);
extern int logtb_get_global_unique_stats (THREAD_ENTRY * thread_p, BTID * btid, long long *num_oids,
long long *num_nulls, long long *num_keys);
extern int logtb_rv_update_global_unique_stats_by_abs (THREAD_ENTRY * thread_p, BTID * btid, long long num_oids,
long long num_nulls, long long num_keys);
extern int logtb_update_global_unique_stats_by_delta (THREAD_ENTRY * thread_p, BTID * btid, long long oid_delta,
long long null_delta, long long key_delta, bool log);
extern int logtb_delete_global_unique_stats (THREAD_ENTRY * thread_p, BTID * btid);
extern int logtb_reflect_global_unique_stats_to_btree (THREAD_ENTRY * thread_p);
extern int logtb_tran_update_all_global_unique_stats (THREAD_ENTRY * thread_p);
extern void log_set_ha_promotion_time (THREAD_ENTRY * thread_p, INT64 ha_promotion_time);
extern void log_set_db_restore_time (THREAD_ENTRY * thread_p, INT64 db_restore_time);
extern int logpb_prior_lsa_append_all_list (THREAD_ENTRY * thread_p);
extern bool logtb_check_class_for_rr_isolation_err (const OID * class_oid);
extern void logpb_vacuum_reset_log_header_cache (THREAD_ENTRY * thread_p, LOG_HEADER * loghdr);
extern VACUUM_LOG_BLOCKID logpb_last_complete_blockid (void);
extern int logpb_page_check_corruption (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr, bool * is_page_corrupted);
extern void logpb_dump_log_page_area (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr, int offset, int length);
extern void logpb_page_get_first_null_block_lsa (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr,
LOG_LSA * first_null_block_lsa);
extern void logtb_slam_transaction (THREAD_ENTRY * thread_p, int tran_index);
extern int xlogtb_kill_tran_index (THREAD_ENTRY * thread_p, int kill_tran_index, char *kill_user, char *kill_host,
int kill_pid);
extern int xlogtb_kill_or_interrupt_tran (THREAD_ENTRY * thread_p, int tran_id, bool is_dba_group_member,
bool interrupt_only);
extern THREAD_ENTRY *logtb_find_thread_by_tran_index (int tran_index);
extern THREAD_ENTRY *logtb_find_thread_by_tran_index_except_me (int tran_index);
extern int logtb_get_current_tran_index (void);
extern void logtb_set_current_tran_index (THREAD_ENTRY * thread_p, int tran_index);
#if defined (SERVER_MODE)
extern void logtb_wakeup_thread_with_tran_index (int tran_index, thread_resume_suspend_status resume_reason);
#endif // SERVER_MODE
extern bool logtb_set_check_interrupt (THREAD_ENTRY * thread_p, bool flag);
extern bool logtb_get_check_interrupt (THREAD_ENTRY * thread_p);
extern int logpb_set_page_checksum (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr);
extern LOG_TDES *logtb_get_system_tdes (THREAD_ENTRY * thread_p = NULL);
extern int logtb_load_global_statistics_to_tran (THREAD_ENTRY * thread_p);
// inline/template implementation
inline LOG_TDES *
LOG_FIND_TDES (int tran_index)
{
if (tran_index >= LOG_SYSTEM_TRAN_INDEX && tran_index < log_Gl.trantable.num_total_indices)
{
if (tran_index == LOG_SYSTEM_TRAN_INDEX)
{
return logtb_get_system_tdes ();
}
else
{
return log_Gl.trantable.all_tdes[tran_index];
}
}
else
{
return NULL;
}
}
inline LOG_TDES *
LOG_FIND_CURRENT_TDES (THREAD_ENTRY * thread_p = NULL)
{
return LOG_FIND_TDES (LOG_FIND_THREAD_TRAN_INDEX (thread_p));
}
inline bool
logtb_is_system_worker_tranid (TRANID trid)
{
return trid < NULL_TRANID;
}
#endif /* _LOG_IMPL_H_ */