mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Remove unnecessary files and functions
innobase/srv/srv0srv.c: Removed unused code BitKeeper/deleted/.del-FSP0FSP.C~f1c7e596cadd429: Delete: innobase/fsp/trash/FSP0FSP.C BitKeeper/deleted/.del-log0trsh.c~ebdd6ce463d8bf0: Delete: innobase/log/trash/log0trsh.c BitKeeper/deleted/.del-os0fileold.c~7be518438162e2f: Delete: innobase/os/os0fileold.c innobase/include/usr0sess.h: Remove unused functions innobase/lock/lock0lock.c: Remove commented-out call to deleted function sess_raise_error_low() innobase/trx/trx0trx.c: Remove commented-out or unreachable calls to deleted function sess_raise_error_low() innobase/usr/usr0sess.c: Remove unused functions
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -66,28 +66,6 @@ sess_open(
|
|||||||
byte* addr_buf, /* in: client address */
|
byte* addr_buf, /* in: client address */
|
||||||
ulint addr_len); /* in: client address length */
|
ulint addr_len); /* in: client address length */
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Closes a session, freeing the memory occupied by it. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_close(
|
|
||||||
/*=======*/
|
|
||||||
sess_t* sess); /* in, own: session object */
|
|
||||||
/*************************************************************************
|
|
||||||
Raises an SQL error. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_raise_error_low(
|
|
||||||
/*=================*/
|
|
||||||
trx_t* trx, /* in: transaction */
|
|
||||||
ulint err_no, /* in: error number */
|
|
||||||
ulint type, /* in: more info of the error, or 0 */
|
|
||||||
dict_table_t* table, /* in: dictionary table or NULL */
|
|
||||||
dict_index_t* index, /* in: table index or NULL */
|
|
||||||
dtuple_t* tuple, /* in: tuple to insert or NULL */
|
|
||||||
rec_t* rec, /* in: record or NULL */
|
|
||||||
char* err_str);/* in: arbitrary null-terminated error string,
|
|
||||||
or NULL */
|
|
||||||
/*************************************************************************
|
|
||||||
Closes a session, freeing the memory occupied by it, if it is in a state
|
Closes a session, freeing the memory occupied by it, if it is in a state
|
||||||
where it should be closed. */
|
where it should be closed. */
|
||||||
|
|
||||||
@ -117,16 +95,6 @@ sess_srv_msg_send_simple(
|
|||||||
ulint rel_kernel); /* in: SESS_RELEASE_KERNEL or
|
ulint rel_kernel); /* in: SESS_RELEASE_KERNEL or
|
||||||
SESS_NOT_RELEASE_KERNEL */
|
SESS_NOT_RELEASE_KERNEL */
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Processes a message from a client. NOTE: May release the kernel mutex
|
|
||||||
temporarily. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_receive_msg_rel_kernel(
|
|
||||||
/*========================*/
|
|
||||||
sess_t* sess, /* in: session */
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len); /* in: message length */
|
|
||||||
/***************************************************************************
|
|
||||||
When a command has been completed, this function sends the message about it
|
When a command has been completed, this function sends the message about it
|
||||||
to the client. */
|
to the client. */
|
||||||
|
|
||||||
@ -136,17 +104,6 @@ sess_command_completed_message(
|
|||||||
sess_t* sess, /* in: session */
|
sess_t* sess, /* in: session */
|
||||||
byte* msg, /* in: message buffer */
|
byte* msg, /* in: message buffer */
|
||||||
ulint len); /* in: message data length */
|
ulint len); /* in: message data length */
|
||||||
/***********************************************************************
|
|
||||||
Starts a new connection and a session, or starts a query based on a client
|
|
||||||
message. This is called by a SRV_COM thread. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_process_cli_msg(
|
|
||||||
/*=================*/
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len, /* in: string length */
|
|
||||||
byte* addr, /* in: address string */
|
|
||||||
ulint alen); /* in: address length */
|
|
||||||
|
|
||||||
|
|
||||||
/* The session handle. All fields are protected by the kernel mutex */
|
/* The session handle. All fields are protected by the kernel mutex */
|
||||||
|
@ -3063,11 +3063,6 @@ retry:
|
|||||||
|
|
||||||
ut_a(strlen(lock_latest_err_buf) < 4100);
|
ut_a(strlen(lock_latest_err_buf) < 4100);
|
||||||
|
|
||||||
/*
|
|
||||||
sess_raise_error_low(trx, DB_DEADLOCK, lock->type_mode, table,
|
|
||||||
index, NULL, NULL, NULL);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,648 +0,0 @@
|
|||||||
/******************************************************
|
|
||||||
Recovery
|
|
||||||
|
|
||||||
(c) 1997 Innobase Oy
|
|
||||||
|
|
||||||
Created 9/20/1997 Heikki Tuuri
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
#include "log0recv.h"
|
|
||||||
|
|
||||||
#ifdef UNIV_NONINL
|
|
||||||
#include "log0recv.ic"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mem0mem.h"
|
|
||||||
#include "buf0buf.h"
|
|
||||||
#include "buf0flu.h"
|
|
||||||
#include "srv0srv.h"
|
|
||||||
|
|
||||||
/* Size of block reads when the log groups are scanned forward to do
|
|
||||||
roll-forward */
|
|
||||||
#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
|
|
||||||
|
|
||||||
/* Size of block reads when the log groups are scanned backwards to synchronize
|
|
||||||
them */
|
|
||||||
#define RECV_BACK_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
|
|
||||||
|
|
||||||
recv_sys_t* recv_sys = NULL;
|
|
||||||
|
|
||||||
recv_recover_page(block->frame, block->space, block->offset);
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Creates the recovery system. */
|
|
||||||
|
|
||||||
void
|
|
||||||
recv_sys_create(void)
|
|
||||||
/*=================*/
|
|
||||||
{
|
|
||||||
ut_a(recv_sys == NULL);
|
|
||||||
|
|
||||||
recv_sys = mem_alloc(sizeof(recv_t));
|
|
||||||
|
|
||||||
mutex_create(&(recv_sys->mutex));
|
|
||||||
|
|
||||||
recv_sys->hash = NULL;
|
|
||||||
recv_sys->heap = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Inits the recovery system for a recovery operation. */
|
|
||||||
|
|
||||||
void
|
|
||||||
recv_sys_init(void)
|
|
||||||
/*===============*/
|
|
||||||
{
|
|
||||||
recv_sys->hash = hash_create(buf_pool_get_curr_size() / 64);
|
|
||||||
recv_sys->heap = mem_heap_create_in_buffer(256);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Empties the recovery system. */
|
|
||||||
|
|
||||||
void
|
|
||||||
recv_sys_empty(void)
|
|
||||||
/*================*/
|
|
||||||
{
|
|
||||||
mutex_enter(&(recv_sys->mutex));
|
|
||||||
|
|
||||||
hash_free(recv_sys->hash);
|
|
||||||
mem_heap_free(recv_sys->heap);
|
|
||||||
|
|
||||||
recv_sys->hash = NULL;
|
|
||||||
recv_sys->heap = NULL;
|
|
||||||
|
|
||||||
mutex_exit(&(recv_sys->mutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
For recovery purposes copies the log buffer to a group to synchronize log
|
|
||||||
data. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
recv_log_buf_flush(
|
|
||||||
/*===============*/
|
|
||||||
log_group_t* group, /* in: log group */
|
|
||||||
dulint start_lsn, /* in: start lsn of the log data in
|
|
||||||
the log buffer; must be divisible by
|
|
||||||
OS_FILE_LOG_BLOCK_SIZE */
|
|
||||||
dulint end_lsn) /* in: end lsn of the log data in the
|
|
||||||
log buffer; must be divisible by
|
|
||||||
OS_FILE_LOG_BLOCK_SIZE */
|
|
||||||
{
|
|
||||||
ulint len;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
|
||||||
|
|
||||||
len = ut_dulint_minus(end_lsn, start_lsn);
|
|
||||||
|
|
||||||
log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, start_lsn,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
Compares two buffers containing log segments and determines the highest lsn
|
|
||||||
where they match, if any. */
|
|
||||||
static
|
|
||||||
dulint
|
|
||||||
recv_log_bufs_cmp(
|
|
||||||
/*==============*/
|
|
||||||
/* out: if no match found, ut_dulint_zero or
|
|
||||||
if start_lsn == LOG_START_LSN, returns
|
|
||||||
LOG_START_LSN; otherwise the highest matching
|
|
||||||
lsn */
|
|
||||||
byte* recv_buf, /* in: buffer containing valid log data */
|
|
||||||
byte* buf, /* in: buffer of data from a possibly
|
|
||||||
incompletely written log group */
|
|
||||||
dulint start_lsn, /* in: buffer start lsn, must be divisible
|
|
||||||
by OS_FILE_LOG_BLOCK_SIZE and must be >=
|
|
||||||
LOG_START_LSN */
|
|
||||||
dulint end_lsn, /* in: buffer end lsn, must be divisible
|
|
||||||
by OS_FILE_LOG_BLOCK_SIZE */
|
|
||||||
dulint recovered_lsn) /* in: recovery succeeded up to this lsn */
|
|
||||||
{
|
|
||||||
ulint len;
|
|
||||||
ulint offset;
|
|
||||||
byte* log_block1;
|
|
||||||
byte* log_block2;
|
|
||||||
ulint no;
|
|
||||||
ulint data_len;
|
|
||||||
|
|
||||||
ut_ad(ut_dulint_cmp(start_lsn, LOG_START_LSN) >= 0);
|
|
||||||
|
|
||||||
if (ut_dulint_cmp(end_lsn, recovered_lsn) > 0) {
|
|
||||||
end_lsn = ut_dulint_align_up(recovered_lsn,
|
|
||||||
OS_FILE_LOG_BLOCK_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = ut_dulint_minus(end_lsn, start_lsn);
|
|
||||||
|
|
||||||
if (len == 0) {
|
|
||||||
|
|
||||||
goto no_match;
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
|
|
||||||
|
|
||||||
log_block1 = recv_buf + len;
|
|
||||||
log_block2 = buf + len;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
log_block1 -= OS_FILE_LOG_BLOCK_SIZE;
|
|
||||||
log_block2 -= OS_FILE_LOG_BLOCK_SIZE;
|
|
||||||
|
|
||||||
no = log_block_get_hdr_no(log_block1);
|
|
||||||
ut_a(no == log_block_get_trl_no(log_block1));
|
|
||||||
|
|
||||||
if ((no == log_block_get_hdr_no(log_block2))
|
|
||||||
&& (no == log_block_get_trl_no(log_block2))) {
|
|
||||||
|
|
||||||
/* Match found if the block is not corrupted */
|
|
||||||
|
|
||||||
data_len = log_block_get_data_len(log_block2);
|
|
||||||
|
|
||||||
if (0 == ut_memcmp(log_block1 + LOG_BLOCK_DATA,
|
|
||||||
log_block2 + LOG_BLOCK_DATA,
|
|
||||||
data_len - LOG_BLOCK_DATA)) {
|
|
||||||
|
|
||||||
/* Match found */
|
|
||||||
|
|
||||||
return(ut_dulint_add(start_lsn,
|
|
||||||
log_block2 - buf + data_len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_block1 == recv_buf) {
|
|
||||||
|
|
||||||
/* No match found */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
no_match:
|
|
||||||
if (ut_dulint_cmp(start_lsn, LOG_START_LSN) == 0) {
|
|
||||||
|
|
||||||
return(LOG_START_LSN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ut_dulint_zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Copies a log segment from the most up-to-date log group to the other log
|
|
||||||
group, so that it contains the latest log data. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
recv_copy_group(
|
|
||||||
/*============*/
|
|
||||||
log_group_t* up_to_date_group, /* in: the most up-to-date
|
|
||||||
log group */
|
|
||||||
log_group_t* group, /* in: copy to this log group */
|
|
||||||
dulint_lsn recovered_lsn) /* in: recovery succeeded up
|
|
||||||
to this lsn */
|
|
||||||
{
|
|
||||||
dulint start_lsn;
|
|
||||||
dulint end_lsn;
|
|
||||||
dulint match;
|
|
||||||
byte* buf;
|
|
||||||
byte* buf1;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
|
||||||
|
|
||||||
if (0 == ut_dulint_cmp(LOG_START_LSN, recovered_lsn)) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(RECV_BACK_SCAN_SIZE <= log_sys->buf_size);
|
|
||||||
|
|
||||||
buf1 = mem_alloc(2 * RECV_BACK_SCAN_SIZE);
|
|
||||||
buf = ut_align(buf, RECV_BACK_SCAN_SIZE););
|
|
||||||
|
|
||||||
end_lsn = ut_dulint_align_up(recovered_lsn, RECV_BACK_SCAN_SIZE);
|
|
||||||
|
|
||||||
match = ut_dulint_zero;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (ut_dulint_cmp(ut_dulint_add(LOG_START_LSN,
|
|
||||||
RECV_BACK_SCAN_SIZE), end_lsn) >= 0) {
|
|
||||||
start_lsn = LOG_START_LSN;
|
|
||||||
} else {
|
|
||||||
start_lsn = ut_dulint_subtract(end_lsn,
|
|
||||||
RECV_BACK_SCAN_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_group_read_log_seg(LOG_RECOVER, buf, group, start_lsn,
|
|
||||||
end_lsn);
|
|
||||||
log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
|
|
||||||
up_to_date_group, start_lsn, end_lsn);
|
|
||||||
|
|
||||||
match = recv_log_bufs_cmp(log_sys->buf, buf, start_lsn,
|
|
||||||
end_lsn, recovered_lsn);
|
|
||||||
|
|
||||||
if (ut_dulint_cmp(match, recovered_lsn) != 0) {
|
|
||||||
recv_log_buf_flush(group, start_lsn, end_lsn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ut_dulint_zero(match)) {
|
|
||||||
|
|
||||||
mem_free(buf1);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
end_lsn = start_lsn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Copies a log segment from the most up-to-date log group to the other log
|
|
||||||
groups, so that they all contain the latest log data. Also writes the info
|
|
||||||
about the latest checkpoint to the groups, and inits the fields in the group
|
|
||||||
memory structs to up-to-date values. */
|
|
||||||
|
|
||||||
void
|
|
||||||
recv_synchronize_groups(
|
|
||||||
/*====================*/
|
|
||||||
log_group_t* up_to_date_group, /* in: the most up-to-date
|
|
||||||
log group */
|
|
||||||
dulint_lsn recovered_lsn, /* in: recovery succeeded up
|
|
||||||
to this lsn */
|
|
||||||
log_group_t* max_checkpoint_group) /* in: the group with the most
|
|
||||||
recent checkpoint info */
|
|
||||||
{
|
|
||||||
log_group_t* group;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
|
||||||
|
|
||||||
group = UT_LIST_GET_FIRST(log_sys->log_groups);
|
|
||||||
|
|
||||||
while (group) {
|
|
||||||
if (group != up_to_date_group) {
|
|
||||||
|
|
||||||
/* Copy log data */
|
|
||||||
|
|
||||||
recv_copy_group(group, up_to_date_group,
|
|
||||||
recovered_lsn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group != max_checkpoint_group) {
|
|
||||||
|
|
||||||
/* Copy the checkpoint info to the group */
|
|
||||||
|
|
||||||
log_group_checkpoint(group);
|
|
||||||
|
|
||||||
mutex_exit(&(log_sys->mutex));
|
|
||||||
|
|
||||||
/* Wait for the checkpoint write to complete */
|
|
||||||
rw_lock_s_lock(&(log_sys->checkpoint_lock));
|
|
||||||
rw_lock_s_unlock(&(log_sys->checkpoint_lock));
|
|
||||||
|
|
||||||
mutex_enter(&(log_sys->mutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the fields in the group struct to correspond to
|
|
||||||
recovered_lsn */
|
|
||||||
|
|
||||||
log_group_set_fields(group, recovered_lsn);
|
|
||||||
|
|
||||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Looks for the maximum consistent checkpoint from the log groups. */
|
|
||||||
static
|
|
||||||
ulint
|
|
||||||
recv_find_max_checkpoint(
|
|
||||||
/*=====================*/
|
|
||||||
/* out: error code or DB_SUCCESS */
|
|
||||||
log_group_t** max_group, /* out: max group */
|
|
||||||
ulint* max_field) /* out: LOG_CHECKPOINT_1 or
|
|
||||||
LOG_CHECKPOINT_2 */
|
|
||||||
{
|
|
||||||
log_group_t* group;
|
|
||||||
dulint max_no;
|
|
||||||
dulint cp_no;
|
|
||||||
ulint field;
|
|
||||||
ulint fold;
|
|
||||||
byte* buf;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
|
||||||
|
|
||||||
/* Look for the latest checkpoint from the log groups */
|
|
||||||
group = UT_LIST_GET_FIRST(log_sys->log_groups);
|
|
||||||
|
|
||||||
checkpoint_no = ut_dulint_zero;
|
|
||||||
checkpoint_lsn = ut_dulint_zero;
|
|
||||||
*max_group = NULL;
|
|
||||||
|
|
||||||
buf = log_sys->checkpoint_buf;
|
|
||||||
|
|
||||||
while (group) {
|
|
||||||
group->state = LOG_GROUP_CORRUPTED;
|
|
||||||
|
|
||||||
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
|
|
||||||
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
|
|
||||||
|
|
||||||
log_group_read_checkpoint_info(group, field);
|
|
||||||
|
|
||||||
/* Check the consistency of the checkpoint info */
|
|
||||||
fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);
|
|
||||||
|
|
||||||
if (fold != mach_read_from_4(buf
|
|
||||||
+ LOG_CHECKPOINT_CHECKSUM_1)) {
|
|
||||||
goto not_consistent;
|
|
||||||
}
|
|
||||||
|
|
||||||
fold = ut_fold_binary(buf + LOG_CHECKPOINT_LSN,
|
|
||||||
LOG_CHECKPOINT_CHECKSUM_2
|
|
||||||
- LOG_CHECKPOINT_LSN);
|
|
||||||
if (fold != mach_read_from_4(buf
|
|
||||||
+ LOG_CHECKPOINT_CHECKSUM_2)) {
|
|
||||||
goto not_consistent;
|
|
||||||
}
|
|
||||||
|
|
||||||
group->state = LOG_GROUP_OK;
|
|
||||||
|
|
||||||
group->lsn = mach_read_from_8(buf
|
|
||||||
+ LOG_CHECKPOINT_LSN);
|
|
||||||
group->lsn_offset = mach_read_from_4(buf
|
|
||||||
+ LOG_CHECKPOINT_OFFSET);
|
|
||||||
group->lsn_file_count = mach_read_from_4(
|
|
||||||
buf + LOG_CHECKPOINT_FILE_COUNT);
|
|
||||||
|
|
||||||
cp_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
|
|
||||||
|
|
||||||
if (ut_dulint_cmp(cp_no, max_no) >= 0) {
|
|
||||||
*max_group = group;
|
|
||||||
*max_field = field;
|
|
||||||
max_no = cp_no;
|
|
||||||
}
|
|
||||||
|
|
||||||
not_consistent:
|
|
||||||
}
|
|
||||||
|
|
||||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*max_group == NULL) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************
|
|
||||||
Parses log records from a buffer and stores them to a hash table to wait
|
|
||||||
merging to file pages. If the hash table becomes too big, merges automatically
|
|
||||||
it to file pages. */
|
|
||||||
static
|
|
||||||
bool
|
|
||||||
recv_parse_and_hash_log_recs(
|
|
||||||
/*=========================*/
|
|
||||||
/* out: TRUE if limit_lsn has been reached */
|
|
||||||
byte* buf, /* in: buffer containing a log segment or
|
|
||||||
garbage */
|
|
||||||
ulint len, /* in: buffer length */
|
|
||||||
dulint start_lsn, /* in: buffer start lsn */
|
|
||||||
dulint limit_lsn, /* in: recover at least to this lsn */
|
|
||||||
dulint* recovered_lsn) /* out: was able to parse up to this lsn */
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Recovers from a checkpoint. When this function returns, the database is able
|
|
||||||
to start processing new user transactions, but the function
|
|
||||||
recv_recovery_from_checkpoint_finish should be called later to complete
|
|
||||||
the recovery and free the resources used in it. */
|
|
||||||
|
|
||||||
ulint
|
|
||||||
recv_recovery_from_checkpoint_start(
|
|
||||||
/*================================*/
|
|
||||||
/* out: error code or DB_SUCCESS */
|
|
||||||
dulint limit_lsn) /* in: recover up to this lsn if possible */
|
|
||||||
{
|
|
||||||
log_group_t* max_cp_group;
|
|
||||||
log_group_t* up_to_date_group;
|
|
||||||
ulint max_cp_field;
|
|
||||||
byte* buf;
|
|
||||||
ulint err;
|
|
||||||
dulint checkpoint_lsn;
|
|
||||||
dulint checkpoint_no;
|
|
||||||
dulint recovered_lsn;
|
|
||||||
dulint old_lsn;
|
|
||||||
dulint end_lsn;
|
|
||||||
dulint start_lsn;
|
|
||||||
bool finished;
|
|
||||||
dulint flush_start_lsn;
|
|
||||||
|
|
||||||
mutex_enter(&(log_sys->mutex));
|
|
||||||
|
|
||||||
/* Look for the latest checkpoint from any of the log groups */
|
|
||||||
|
|
||||||
err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
|
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
|
||||||
mutex_exit(&(log_sys->mutex));
|
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_group_read_checkpoint_info(max_cp_group, max_cp_field);
|
|
||||||
|
|
||||||
buf = log_sys->checkpoint_buf;
|
|
||||||
|
|
||||||
checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
|
|
||||||
checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
|
|
||||||
|
|
||||||
if (ut_dulint_cmp(limit_lsn, checkpoint_lsn) < 0) {
|
|
||||||
mutex_exit(&(log_sys->mutex));
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start reading the log groups from the checkpoint lsn up. The
|
|
||||||
variable flush_start_lsn tells a lsn up to which the log is known
|
|
||||||
to be contiguously written in all log groups. */
|
|
||||||
|
|
||||||
recovered_lsn = checkpoint_lsn;
|
|
||||||
flush_start_lsn = ut_dulint_align_down(checkpoint_lsn,
|
|
||||||
OS_FILE_LOG_BLOCK_SIZE);
|
|
||||||
up_to_date_group = max_cp_group;
|
|
||||||
|
|
||||||
ut_ad(RECV_SCAN_SIZE <= log_sys->buf_size);
|
|
||||||
|
|
||||||
group = UT_LIST_GET_FIRST(log_sys->log_groups);
|
|
||||||
|
|
||||||
while (group) {
|
|
||||||
finished = FALSE;
|
|
||||||
|
|
||||||
if (group->state == LOG_GROUP_CORRUPTED) {
|
|
||||||
finished = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
start_lsn = flush_start_lsn;
|
|
||||||
|
|
||||||
while (!finished) {
|
|
||||||
end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
|
|
||||||
|
|
||||||
log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
|
|
||||||
group, start_lsn, end_lsn);
|
|
||||||
old_lsn = recovered_lsn;
|
|
||||||
|
|
||||||
finished = recv_parse_and_hash_log_recs(log_sys->buf,
|
|
||||||
RECV_SCAN_SIZE, start_lsn,
|
|
||||||
limit_lsn, &flush_start_lsn,
|
|
||||||
&recovered_lsn);
|
|
||||||
|
|
||||||
if (ut_dulint_cmp(recovered_lsn, old_lsn) > 0) {
|
|
||||||
|
|
||||||
/* We found a more up-to-date group */
|
|
||||||
up_to_date_group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
start_lsn = end_lsn;
|
|
||||||
}
|
|
||||||
|
|
||||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete possible corrupted or extra log records from all log
|
|
||||||
groups */
|
|
||||||
|
|
||||||
recv_truncate_groups(recovered_lsn);
|
|
||||||
|
|
||||||
/* Synchronize the uncorrupted log groups to the most up-to-date log
|
|
||||||
group; we may also have to copy checkpoint info to groups */
|
|
||||||
|
|
||||||
log_sys->next_checkpoint_lsn = checkpoint_lsn;
|
|
||||||
log_sys->next_checkpoint_no = checkpoint_no;
|
|
||||||
|
|
||||||
recv_synchronize_groups(up_to_date_group, _lsn, max_cp_group);
|
|
||||||
|
|
||||||
log_sys->next_checkpoint_no = ut_dulint_add(checkpoint_no, 1);
|
|
||||||
|
|
||||||
/* The database is now ready to start almost normal processing of user
|
|
||||||
transactions */
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
|
||||||
Completes recovery from a checkpoint. */
|
|
||||||
|
|
||||||
void
|
|
||||||
recv_recovery_from_checkpoint_finish(void)
|
|
||||||
/*======================================*/
|
|
||||||
{
|
|
||||||
/* Rollback the uncommitted transactions which have no user session */
|
|
||||||
|
|
||||||
trx_rollback_all_without_sess();
|
|
||||||
|
|
||||||
/* Merge the hashed log records */
|
|
||||||
|
|
||||||
recv_merge_hashed_log_recs();
|
|
||||||
|
|
||||||
/* Free the resources of the recovery system */
|
|
||||||
|
|
||||||
recv_sys_empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Writes to the log a record about incrementing the row id counter. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
log_write_row_id_incr_rec(void)
|
|
||||||
/*===========================*/
|
|
||||||
{
|
|
||||||
log_t* log = log_sys;
|
|
||||||
ulint data_len;
|
|
||||||
|
|
||||||
mutex_enter(&(log->mutex));
|
|
||||||
|
|
||||||
data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + 1;
|
|
||||||
|
|
||||||
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
|
|
||||||
|
|
||||||
/* The string does not fit within the current log block
|
|
||||||
or the the block would become full */
|
|
||||||
|
|
||||||
mutex_exit(&(log->mutex));
|
|
||||||
|
|
||||||
log_write_row_id_incr_rec_slow();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(log->buf + log->buf_free) = MLOG_INCR_ROW_ID | MLOG_SINGLE_REC_FLAG;
|
|
||||||
|
|
||||||
log_block_set_data_len(ut_align_down(log->buf + log->buf_free,
|
|
||||||
OS_FILE_LOG_BLOCK_SIZE),
|
|
||||||
data_len);
|
|
||||||
#ifdef UNIV_LOG_DEBUG
|
|
||||||
log->old_buf_free = log->buf_free;
|
|
||||||
log->old_lsn = log->lsn;
|
|
||||||
log_check_log_recs(log->buf + log->buf_free, 1, log->lsn);
|
|
||||||
#endif
|
|
||||||
log->buf_free++;
|
|
||||||
|
|
||||||
ut_ad(log->buf_free <= log->buf_size);
|
|
||||||
|
|
||||||
UT_DULINT_INC(log->lsn);
|
|
||||||
|
|
||||||
mutex_exit(&(log->mutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
Writes to the log a record about incrementing the row id counter. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
log_write_row_id_incr_rec_slow(void)
|
|
||||||
/*================================*/
|
|
||||||
{
|
|
||||||
byte type;
|
|
||||||
|
|
||||||
log_reserve_and_open(1);
|
|
||||||
|
|
||||||
type = MLOG_INCR_ROW_ID | MLOG_SINGLE_REC_FLAG;
|
|
||||||
|
|
||||||
log_write_low(&type, 1);
|
|
||||||
|
|
||||||
log_close();
|
|
||||||
|
|
||||||
log_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
Parses and applies a log record MLOG_SET_ROW_ID. */
|
|
||||||
|
|
||||||
byte*
|
|
||||||
dict_hdr_parse_set_row_id(
|
|
||||||
/*======================*/
|
|
||||||
/* out: end of log record or NULL */
|
|
||||||
byte* ptr, /* in: buffer */
|
|
||||||
byte* end_ptr,/* in: buffer end */
|
|
||||||
page_t* page) /* in: page or NULL */
|
|
||||||
{
|
|
||||||
dulint dval;
|
|
||||||
|
|
||||||
ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval);
|
|
||||||
|
|
||||||
if (ptr == NULL) {
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
|
|
||||||
return(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
mach_write_to_8(page + DICT_HDR + DICT_HDR_ROW_ID, dval);
|
|
||||||
|
|
||||||
return(ptr);
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -863,123 +863,6 @@ srv_release_max_if_no_queries(void)
|
|||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdefined
|
|
||||||
/***********************************************************************
|
|
||||||
Releases one utility thread if no queries are active and
|
|
||||||
the high-water mark 2 for the utility is exceeded. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
srv_release_one_if_no_queries(void)
|
|
||||||
/*===============================*/
|
|
||||||
{
|
|
||||||
ulint m;
|
|
||||||
ulint type;
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
if (srv_n_threads_active[SRV_COM] > 0) {
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = SRV_RECOVERY;
|
|
||||||
|
|
||||||
m = 1;
|
|
||||||
|
|
||||||
if ((srv_meter[type] > srv_meter_high_water2[type])
|
|
||||||
&& (srv_n_threads_active[type] < m)) {
|
|
||||||
|
|
||||||
srv_release_threads(type, m - srv_n_threads_active[type]);
|
|
||||||
|
|
||||||
printf("Releasing one background\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
Decrements the utility meter by the value given and suspends the calling
|
|
||||||
thread, which must be an utility thread of the type given, if necessary. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
srv_decrement_meter(
|
|
||||||
/*================*/
|
|
||||||
ulint type, /* in: utility type */
|
|
||||||
ulint n) /* in: value to subtract from meter */
|
|
||||||
{
|
|
||||||
ulint opt;
|
|
||||||
os_event_t event;
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
if (srv_meter[type] < n) {
|
|
||||||
srv_meter[type] = 0;
|
|
||||||
} else {
|
|
||||||
srv_meter[type] -= n;
|
|
||||||
}
|
|
||||||
|
|
||||||
opt = srv_max_n_utilities(type);
|
|
||||||
|
|
||||||
if (opt < srv_n_threads_active[type]) {
|
|
||||||
|
|
||||||
event = srv_suspend_thread();
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
os_event_wait(event);
|
|
||||||
} else {
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Implements the server console. */
|
|
||||||
|
|
||||||
ulint
|
|
||||||
srv_console(
|
|
||||||
/*========*/
|
|
||||||
/* out: return code, not used */
|
|
||||||
void* arg) /* in: argument, not used */
|
|
||||||
{
|
|
||||||
char command[256];
|
|
||||||
|
|
||||||
UT_NOT_USED(arg);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
srv_table_reserve_slot(SRV_CONSOLE);
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
os_event_wait(srv_sys->operational);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
scanf("%s", command);
|
|
||||||
|
|
||||||
srv_inc_thread_count(SRV_CONSOLE);
|
|
||||||
|
|
||||||
if (command[0] == 'c') {
|
|
||||||
printf("Making checkpoint\n");
|
|
||||||
|
|
||||||
log_make_checkpoint_at(ut_dulint_max, TRUE);
|
|
||||||
|
|
||||||
printf("Checkpoint completed\n");
|
|
||||||
|
|
||||||
} else if (command[0] == 'd') {
|
|
||||||
srv_sim_disk_wait_pct = atoi(command + 1);
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Starting disk access simulation with pct %lu\n",
|
|
||||||
srv_sim_disk_wait_pct);
|
|
||||||
} else {
|
|
||||||
printf("\nNot supported!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_dec_thread_count(SRV_CONSOLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates the first communication endpoint for the server. This
|
Creates the first communication endpoint for the server. This
|
||||||
first call also initializes the com0com.* module. */
|
first call also initializes the com0com.* module. */
|
||||||
@ -1008,69 +891,6 @@ srv_communication_init(
|
|||||||
ut_a(ret == 0);
|
ut_a(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdefined
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Implements the recovery utility. */
|
|
||||||
static
|
|
||||||
ulint
|
|
||||||
srv_recovery_thread(
|
|
||||||
/*================*/
|
|
||||||
/* out: return code, not used */
|
|
||||||
void* arg) /* in: not used */
|
|
||||||
{
|
|
||||||
ulint slot_no;
|
|
||||||
os_event_t event;
|
|
||||||
|
|
||||||
UT_NOT_USED(arg);
|
|
||||||
|
|
||||||
slot_no = srv_table_reserve_slot(SRV_RECOVERY);
|
|
||||||
|
|
||||||
os_event_wait(srv_sys->operational);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
/* Finish a possible recovery */
|
|
||||||
|
|
||||||
srv_inc_thread_count(SRV_RECOVERY);
|
|
||||||
|
|
||||||
/* recv_recovery_from_checkpoint_finish(); */
|
|
||||||
|
|
||||||
srv_dec_thread_count(SRV_RECOVERY);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
event = srv_suspend_thread();
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
/* Wait for somebody to release this thread; (currently, this
|
|
||||||
should never be released) */
|
|
||||||
|
|
||||||
os_event_wait(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Implements the purge utility. */
|
|
||||||
|
|
||||||
ulint
|
|
||||||
srv_purge_thread(
|
|
||||||
/*=============*/
|
|
||||||
/* out: return code, not used */
|
|
||||||
void* arg) /* in: not used */
|
|
||||||
{
|
|
||||||
UT_NOT_USED(arg);
|
|
||||||
|
|
||||||
os_event_wait(srv_sys->operational);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
trx_purge();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
#endif /* notdefined */
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates the utility threads. */
|
Creates the utility threads. */
|
||||||
|
|
||||||
@ -1100,58 +920,6 @@ srv_create_utility_threads(void)
|
|||||||
ut_a(thread); */
|
ut_a(thread); */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdefined
|
|
||||||
/*************************************************************************
|
|
||||||
Implements the communication threads. */
|
|
||||||
static
|
|
||||||
ulint
|
|
||||||
srv_com_thread(
|
|
||||||
/*===========*/
|
|
||||||
/* out: return code; not used */
|
|
||||||
void* arg) /* in: not used */
|
|
||||||
{
|
|
||||||
byte* msg_buf;
|
|
||||||
byte* addr_buf;
|
|
||||||
ulint msg_len;
|
|
||||||
ulint addr_len;
|
|
||||||
ulint ret;
|
|
||||||
|
|
||||||
UT_NOT_USED(arg);
|
|
||||||
|
|
||||||
srv_table_reserve_slot(SRV_COM);
|
|
||||||
|
|
||||||
os_event_wait(srv_sys->operational);
|
|
||||||
|
|
||||||
msg_buf = mem_alloc(com_endpoint_get_max_size(srv_sys->endpoint));
|
|
||||||
addr_buf = mem_alloc(COM_MAX_ADDR_LEN);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
ret = com_recvfrom(srv_sys->endpoint, msg_buf,
|
|
||||||
com_endpoint_get_max_size(srv_sys->endpoint),
|
|
||||||
&msg_len, (char*)addr_buf, COM_MAX_ADDR_LEN,
|
|
||||||
&addr_len);
|
|
||||||
ut_a(ret == 0);
|
|
||||||
|
|
||||||
srv_inc_thread_count(SRV_COM);
|
|
||||||
|
|
||||||
sess_process_cli_msg(msg_buf, msg_len, addr_buf, addr_len);
|
|
||||||
|
|
||||||
/* srv_increment_meter(SRV_RECOVERY, 1); */
|
|
||||||
|
|
||||||
srv_dec_thread_count(SRV_COM);
|
|
||||||
|
|
||||||
/* Release one utility thread for each utility if
|
|
||||||
high water mark 2 is exceeded and there are no
|
|
||||||
active queries. This is done to utilize possible
|
|
||||||
quiet time in the server. */
|
|
||||||
|
|
||||||
srv_release_one_if_no_queries();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates the communication threads. */
|
Creates the communication threads. */
|
||||||
|
|
||||||
@ -1171,53 +939,6 @@ srv_create_com_threads(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdefined
|
|
||||||
/*************************************************************************
|
|
||||||
Implements the worker threads. */
|
|
||||||
static
|
|
||||||
ulint
|
|
||||||
srv_worker_thread(
|
|
||||||
/*==============*/
|
|
||||||
/* out: return code, not used */
|
|
||||||
void* arg) /* in: not used */
|
|
||||||
{
|
|
||||||
os_event_t event;
|
|
||||||
|
|
||||||
UT_NOT_USED(arg);
|
|
||||||
|
|
||||||
srv_table_reserve_slot(SRV_WORKER);
|
|
||||||
|
|
||||||
os_event_wait(srv_sys->operational);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
event = srv_suspend_thread();
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
/* Wait for somebody to release this thread */
|
|
||||||
os_event_wait(event);
|
|
||||||
|
|
||||||
srv_inc_thread_count(SRV_WORKER);
|
|
||||||
|
|
||||||
/* Check in the server task queue if there is work for this
|
|
||||||
thread, and do the work */
|
|
||||||
|
|
||||||
srv_que_task_queue_check();
|
|
||||||
|
|
||||||
srv_dec_thread_count(SRV_WORKER);
|
|
||||||
|
|
||||||
/* Release one utility thread for each utility if
|
|
||||||
high water mark 2 is exceeded and there are no
|
|
||||||
active queries. This is done to utilize possible
|
|
||||||
quiet time in the server. */
|
|
||||||
|
|
||||||
srv_release_one_if_no_queries();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates the worker threads. */
|
Creates the worker threads. */
|
||||||
|
|
||||||
@ -1238,404 +959,6 @@ srv_create_worker_threads(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdefined
|
|
||||||
/*************************************************************************
|
|
||||||
Reads a keyword and a value from a file. */
|
|
||||||
|
|
||||||
ulint
|
|
||||||
srv_read_init_val(
|
|
||||||
/*==============*/
|
|
||||||
/* out: DB_SUCCESS or error code */
|
|
||||||
FILE* initfile, /* in: file pointer */
|
|
||||||
char* keyword, /* in: keyword before value(s), or NULL if
|
|
||||||
no keyword read */
|
|
||||||
char* str_buf, /* in/out: buffer for a string value to read,
|
|
||||||
buffer size must be 10000 bytes, if NULL
|
|
||||||
then not read */
|
|
||||||
ulint* num_val, /* out: numerical value to read, if NULL
|
|
||||||
then not read */
|
|
||||||
ibool print_not_err) /* in: if TRUE, then we will not print
|
|
||||||
error messages to console */
|
|
||||||
{
|
|
||||||
ulint ret;
|
|
||||||
char scan_buf[10000];
|
|
||||||
|
|
||||||
if (keyword == NULL) {
|
|
||||||
|
|
||||||
goto skip_keyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fscanf(initfile, "%9999s", scan_buf);
|
|
||||||
|
|
||||||
if (ret == 0 || ret == EOF || 0 != ut_strcmp(scan_buf, keyword)) {
|
|
||||||
if (print_not_err) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Error in InnoDB booting: keyword %s not found\n",
|
|
||||||
keyword);
|
|
||||||
printf("from the initfile!\n");
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
skip_keyword:
|
|
||||||
if (num_val == NULL && str_buf == NULL) {
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fscanf(initfile, "%9999s", scan_buf);
|
|
||||||
|
|
||||||
if (ret == EOF || ret == 0) {
|
|
||||||
if (print_not_err) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Error in InnoDB booting: could not read first value after %s\n",
|
|
||||||
keyword);
|
|
||||||
printf("from the initfile!\n");
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_buf) {
|
|
||||||
ut_memcpy(str_buf, scan_buf, 10000);
|
|
||||||
|
|
||||||
printf("init keyword %s value %s read\n", keyword, str_buf);
|
|
||||||
|
|
||||||
if (!num_val) {
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fscanf(initfile, "%9999s", scan_buf);
|
|
||||||
|
|
||||||
if (ret == EOF || ret == 0) {
|
|
||||||
|
|
||||||
if (print_not_err) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Error in InnoDB booting: could not read second value after %s\n",
|
|
||||||
keyword);
|
|
||||||
printf("from the initfile!\n");
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ut_strlen(scan_buf) > 9) {
|
|
||||||
|
|
||||||
if (print_not_err) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Error in InnoDB booting: numerical value too big after %s\n",
|
|
||||||
keyword);
|
|
||||||
printf("in the initfile!\n");
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
*num_val = (ulint)atoi(scan_buf);
|
|
||||||
|
|
||||||
if (*num_val >= 1000000000) {
|
|
||||||
|
|
||||||
if (print_not_err) {
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"Error in InnoDB booting: numerical value too big after %s\n",
|
|
||||||
keyword);
|
|
||||||
printf("in the initfile!\n");
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("init keyword %s value %lu read\n", keyword, *num_val);
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Reads keywords and values from an initfile. */
|
|
||||||
|
|
||||||
ulint
|
|
||||||
srv_read_initfile(
|
|
||||||
/*==============*/
|
|
||||||
/* out: DB_SUCCESS or error code */
|
|
||||||
FILE* initfile) /* in: file pointer */
|
|
||||||
{
|
|
||||||
char str_buf[10000];
|
|
||||||
ulint n;
|
|
||||||
ulint i;
|
|
||||||
ulint ulint_val;
|
|
||||||
ulint val1;
|
|
||||||
ulint val2;
|
|
||||||
ulint err;
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "INNOBASE_DATA_HOME_DIR",
|
|
||||||
str_buf, NULL, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_data_home = ut_malloc(ut_strlen(str_buf) + 1);
|
|
||||||
ut_memcpy(srv_data_home, str_buf, ut_strlen(str_buf) + 1);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile,"TABLESPACE_NUMBER_OF_DATA_FILES",
|
|
||||||
NULL, &n, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_n_data_files = n;
|
|
||||||
|
|
||||||
srv_data_file_names = ut_malloc(n * sizeof(char*));
|
|
||||||
srv_data_file_sizes = ut_malloc(n * sizeof(ulint));
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
err = srv_read_init_val(initfile,
|
|
||||||
"DATA_FILE_PATH_AND_SIZE_MB",
|
|
||||||
str_buf, &ulint_val, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_data_file_names[i] = ut_malloc(ut_strlen(str_buf) + 1);
|
|
||||||
ut_memcpy(srv_data_file_names[i], str_buf,
|
|
||||||
ut_strlen(str_buf) + 1);
|
|
||||||
srv_data_file_sizes[i] = ulint_val
|
|
||||||
* ((1024 * 1024) / UNIV_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile,
|
|
||||||
"NUMBER_OF_MIRRORED_LOG_GROUPS", NULL,
|
|
||||||
&srv_n_log_groups, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile,
|
|
||||||
"NUMBER_OF_LOG_FILES_IN_GROUP", NULL,
|
|
||||||
&srv_n_log_files, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "LOG_FILE_SIZE_KB", NULL,
|
|
||||||
&srv_log_file_size, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_log_file_size = srv_log_file_size / (UNIV_PAGE_SIZE / 1024);
|
|
||||||
|
|
||||||
srv_log_group_home_dirs = ut_malloc(srv_n_log_files * sizeof(char*));
|
|
||||||
|
|
||||||
for (i = 0; i < srv_n_log_groups; i++) {
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile,
|
|
||||||
"INNOBASE_LOG_GROUP_HOME_DIR",
|
|
||||||
str_buf, NULL, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_log_group_home_dirs[i] = ut_malloc(ut_strlen(str_buf) + 1);
|
|
||||||
ut_memcpy(srv_log_group_home_dirs[i], str_buf,
|
|
||||||
ut_strlen(str_buf) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "INNOBASE_LOG_ARCH_DIR",
|
|
||||||
str_buf, NULL, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_arch_dir = ut_malloc(ut_strlen(str_buf) + 1);
|
|
||||||
ut_memcpy(srv_arch_dir, str_buf, ut_strlen(str_buf) + 1);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "LOG_ARCHIVE_ON(1/0)", NULL,
|
|
||||||
&srv_log_archive_on, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "LOG_BUFFER_SIZE_KB", NULL,
|
|
||||||
&srv_log_buffer_size, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_log_buffer_size = srv_log_buffer_size / (UNIV_PAGE_SIZE / 1024);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "FLUSH_LOG_AT_TRX_COMMIT(1/0)", NULL,
|
|
||||||
&srv_flush_log_at_trx_commit, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "BUFFER_POOL_SIZE_MB", NULL,
|
|
||||||
&srv_pool_size, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_pool_size = srv_pool_size * ((1024 * 1024) / UNIV_PAGE_SIZE);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "ADDITIONAL_MEM_POOL_SIZE_MB", NULL,
|
|
||||||
&srv_mem_pool_size, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
srv_mem_pool_size = srv_mem_pool_size * 1024 * 1024;
|
|
||||||
|
|
||||||
srv_lock_table_size = 20 * srv_pool_size;
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "NUMBER_OF_FILE_IO_THREADS", NULL,
|
|
||||||
&srv_n_file_io_threads, FALSE);
|
|
||||||
if (err != DB_SUCCESS) return(err);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "SRV_RECOVER_FROM_BACKUP",
|
|
||||||
NULL, NULL, TRUE);
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
srv_archive_recovery = TRUE;
|
|
||||||
srv_archive_recovery_limit_lsn = ut_dulint_max;
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, NULL, NULL, &val1, TRUE);
|
|
||||||
err = srv_read_init_val(initfile, NULL, NULL, &val2, TRUE);
|
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
srv_archive_recovery_limit_lsn =
|
|
||||||
ut_dulint_create(val1, val2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* err = srv_read_init_val(initfile,
|
|
||||||
"SYNC_NUMBER_OF_SPIN_WAIT_ROUNDS", NULL,
|
|
||||||
&srv_n_spin_wait_rounds);
|
|
||||||
|
|
||||||
err = srv_read_init_val(initfile, "SYNC_SPIN_WAIT_DELAY", NULL,
|
|
||||||
&srv_spin_wait_delay); */
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Reads keywords and a values from an initfile. In case of an error, exits
|
|
||||||
from the process. */
|
|
||||||
|
|
||||||
void
|
|
||||||
srv_read_initfile(
|
|
||||||
/*==============*/
|
|
||||||
FILE* initfile) /* in: file pointer */
|
|
||||||
{
|
|
||||||
char str_buf[10000];
|
|
||||||
ulint ulint_val;
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, FALSE, "SRV_ENDPOINT_NAME", str_buf,
|
|
||||||
&ulint_val);
|
|
||||||
ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN);
|
|
||||||
|
|
||||||
ut_memcpy(srv_endpoint_name, str_buf, COM_MAX_ADDR_LEN);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SRV_N_COM_THREADS", str_buf,
|
|
||||||
&srv_n_com_threads);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SRV_N_WORKER_THREADS", str_buf,
|
|
||||||
&srv_n_worker_threads);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SYNC_N_SPIN_WAIT_ROUNDS", str_buf,
|
|
||||||
&srv_n_spin_wait_rounds);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SYNC_SPIN_WAIT_DELAY", str_buf,
|
|
||||||
&srv_spin_wait_delay);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "THREAD_PRIORITY_BOOST", str_buf,
|
|
||||||
&srv_priority_boost);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "N_SPACES", str_buf, &srv_n_spaces);
|
|
||||||
srv_read_init_val(initfile, TRUE, "N_FILES", str_buf, &srv_n_files);
|
|
||||||
srv_read_init_val(initfile, TRUE, "FILE_SIZE", str_buf,
|
|
||||||
&srv_file_size);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "N_LOG_GROUPS", str_buf,
|
|
||||||
&srv_n_log_groups);
|
|
||||||
srv_read_init_val(initfile, TRUE, "N_LOG_FILES", str_buf,
|
|
||||||
&srv_n_log_files);
|
|
||||||
srv_read_init_val(initfile, TRUE, "LOG_FILE_SIZE", str_buf,
|
|
||||||
&srv_log_file_size);
|
|
||||||
srv_read_init_val(initfile, TRUE, "LOG_ARCHIVE_ON", str_buf,
|
|
||||||
&srv_log_archive_on);
|
|
||||||
srv_read_init_val(initfile, TRUE, "LOG_BUFFER_SIZE", str_buf,
|
|
||||||
&srv_log_buffer_size);
|
|
||||||
srv_read_init_val(initfile, TRUE, "FLUSH_LOG_AT_TRX_COMMIT", str_buf,
|
|
||||||
&srv_flush_log_at_trx_commit);
|
|
||||||
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "POOL_SIZE", str_buf,
|
|
||||||
&srv_pool_size);
|
|
||||||
srv_read_init_val(initfile, TRUE, "MEM_POOL_SIZE", str_buf,
|
|
||||||
&srv_mem_pool_size);
|
|
||||||
srv_read_init_val(initfile, TRUE, "LOCK_TABLE_SIZE", str_buf,
|
|
||||||
&srv_lock_table_size);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SIM_DISK_WAIT_PCT", str_buf,
|
|
||||||
&srv_sim_disk_wait_pct);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SIM_DISK_WAIT_LEN", str_buf,
|
|
||||||
&srv_sim_disk_wait_len);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SIM_DISK_WAIT_BY_YIELD", str_buf,
|
|
||||||
&srv_sim_disk_wait_by_yield);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "SIM_DISK_WAIT_BY_WAIT", str_buf,
|
|
||||||
&srv_sim_disk_wait_by_wait);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "MEASURE_CONTENTION", str_buf,
|
|
||||||
&srv_measure_contention);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "MEASURE_BY_SPIN", str_buf,
|
|
||||||
&srv_measure_by_spin);
|
|
||||||
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_THREAD_RELEASES", str_buf,
|
|
||||||
&srv_print_thread_releases);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_LOCK_WAITS", str_buf,
|
|
||||||
&srv_print_lock_waits);
|
|
||||||
if (srv_print_lock_waits) {
|
|
||||||
lock_print_waits = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_BUF_IO", str_buf,
|
|
||||||
&srv_print_buf_io);
|
|
||||||
if (srv_print_buf_io) {
|
|
||||||
buf_debug_prints = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_LOG_IO", str_buf,
|
|
||||||
&srv_print_log_io);
|
|
||||||
if (srv_print_log_io) {
|
|
||||||
log_debug_writes = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_PARSED_SQL", str_buf,
|
|
||||||
&srv_print_parsed_sql);
|
|
||||||
if (srv_print_parsed_sql) {
|
|
||||||
pars_print_lexed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "PRINT_LATCH_WAITS", str_buf,
|
|
||||||
&srv_print_latch_waits);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_EXTRA_MUTEXES", str_buf,
|
|
||||||
&srv_test_extra_mutexes);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_NOCACHE", str_buf,
|
|
||||||
&srv_test_nocache);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_CACHE_EVICT", str_buf,
|
|
||||||
&srv_test_cache_evict);
|
|
||||||
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_SYNC", str_buf,
|
|
||||||
&srv_test_sync);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_N_THREADS", str_buf,
|
|
||||||
&srv_test_n_threads);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_N_LOOPS", str_buf,
|
|
||||||
&srv_test_n_loops);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_N_FREE_RNDS", str_buf,
|
|
||||||
&srv_test_n_free_rnds);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_N_RESERVED_RNDS", str_buf,
|
|
||||||
&srv_test_n_reserved_rnds);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_N_MUTEXES", str_buf,
|
|
||||||
&srv_test_n_mutexes);
|
|
||||||
srv_read_init_val(initfile, TRUE, "TEST_ARRAY_SIZE", str_buf,
|
|
||||||
&srv_test_array_size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Initializes the server. */
|
Initializes the server. */
|
||||||
|
|
||||||
|
@ -1147,8 +1147,6 @@ trx_sig_send(
|
|||||||
|
|
||||||
ut_a(0);
|
ut_a(0);
|
||||||
|
|
||||||
/* sess_raise_error_low(trx, 0, 0, NULL, NULL, NULL, NULL,
|
|
||||||
"Incompatible signal"); */
|
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,9 +1195,6 @@ trx_sig_send(
|
|||||||
in the error state: */
|
in the error state: */
|
||||||
|
|
||||||
ut_a(0);
|
ut_a(0);
|
||||||
|
|
||||||
sess_raise_error_low(trx, 0, 0, NULL, NULL, NULL, NULL,
|
|
||||||
(char *) "Signal from another session, or a break execution signal");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there were no other signals ahead in the queue, try to start
|
/* If there were no other signals ahead in the queue, try to start
|
||||||
|
@ -28,6 +28,13 @@ Created 6/25/1996 Heikki Tuuri
|
|||||||
/* The session system global data structure */
|
/* The session system global data structure */
|
||||||
sess_sys_t* sess_sys = NULL;
|
sess_sys_t* sess_sys = NULL;
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Closes a session, freeing the memory occupied by it. */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
sess_close(
|
||||||
|
/*=======*/
|
||||||
|
sess_t* sess); /* in, own: session object */
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Communicates an error message to the client. If sess->client_waits is not
|
Communicates an error message to the client. If sess->client_waits is not
|
||||||
TRUE, puts the session to error state and does not try to send the error
|
TRUE, puts the session to error state and does not try to send the error
|
||||||
@ -85,42 +92,6 @@ sess_cli_msg_set_sess(
|
|||||||
mach_write_to_4(str + SESS_CLI_MSG_SESS_ID_CHECK, fold);
|
mach_write_to_4(str + SESS_CLI_MSG_SESS_ID_CHECK, fold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Returns the session to which a message from a client is addressed.
|
|
||||||
NOTE: this function does not assume that the message is uncorrupted. */
|
|
||||||
static
|
|
||||||
sess_t*
|
|
||||||
sess_cli_msg_get_sess(
|
|
||||||
/*==================*/
|
|
||||||
/* out: session, NULL if not found */
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len) /* in: message string length */
|
|
||||||
{
|
|
||||||
sess_t* sess;
|
|
||||||
ulint fold;
|
|
||||||
dulint id;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
|
|
||||||
if (len < SESS_CLI_MSG_SESS_ID_CHECK + 4) {
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = mach_read_from_8(str + SESS_CLI_MSG_SESS_ID);
|
|
||||||
|
|
||||||
fold = sess_id_fold(id);
|
|
||||||
|
|
||||||
if (fold != mach_read_from_4(str + SESS_CLI_MSG_SESS_ID_CHECK)) {
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
HASH_SEARCH(hash, sess_sys->hash, fold, sess,
|
|
||||||
UT_DULINT_EQ(id, sess->id));
|
|
||||||
return(sess);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Decrements the reference count of a session and closes it, if desired. */
|
Decrements the reference count of a session and closes it, if desired. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -311,6 +282,7 @@ sess_open(
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Closes a session, freeing the memory occupied by it. */
|
Closes a session, freeing the memory occupied by it. */
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
sess_close(
|
sess_close(
|
||||||
/*=======*/
|
/*=======*/
|
||||||
@ -595,330 +567,6 @@ sess_error_low(
|
|||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
Raises an SQL error. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_raise_error_low(
|
|
||||||
/*=================*/
|
|
||||||
trx_t* trx, /* in: transaction */
|
|
||||||
ulint err_no, /* in: error number */
|
|
||||||
ulint type, /* in: more info of the error, or 0 */
|
|
||||||
dict_table_t* table, /* in: dictionary table or NULL */
|
|
||||||
dict_index_t* index, /* in: table index or NULL */
|
|
||||||
dtuple_t* tuple, /* in: tuple to insert or NULL */
|
|
||||||
rec_t* rec, /* in: record or NULL */
|
|
||||||
char* err_str)/* in: arbitrary null-terminated error string,
|
|
||||||
or NULL */
|
|
||||||
{
|
|
||||||
char* str;
|
|
||||||
ulint len;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
|
|
||||||
str = mem_alloc(64000);
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
len += sprintf(str + len, "Error number: %lu", err_no);
|
|
||||||
|
|
||||||
if (type) {
|
|
||||||
len += sprintf(str + len, ", type: %lu", type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table) {
|
|
||||||
len += sprintf(str + len, ", table: %s", table->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index) {
|
|
||||||
len += sprintf(str + len, ", index: %s", index->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tuple) {
|
|
||||||
len += sprintf(str + len, ", tuple:");
|
|
||||||
len += dtuple_sprintf(str + len, 8192, tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec) {
|
|
||||||
len += sprintf(str + len, ", record:");
|
|
||||||
len += rec_sprintf(str + len, 8192, rec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err_str) {
|
|
||||||
len += sprintf(str + len, ", %s", err_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
str[len] = '\0';
|
|
||||||
|
|
||||||
ut_a(len < 64000);
|
|
||||||
|
|
||||||
if (trx->sess) {
|
|
||||||
sess_error_low(trx->sess, err_no, str);
|
|
||||||
} else {
|
|
||||||
mem_free(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Processes a client message which is part of a bigger message. */
|
|
||||||
static
|
|
||||||
ibool
|
|
||||||
sess_receive_msg_part(
|
|
||||||
/*==================*/
|
|
||||||
/* TRUE if message completed */
|
|
||||||
sess_t* sess, /* in: session */
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len) /* in: message length */
|
|
||||||
{
|
|
||||||
ulint cont;
|
|
||||||
|
|
||||||
cont = sess_cli_msg_get_continue(str);
|
|
||||||
|
|
||||||
ut_ad(cont != SESS_MSG_SINGLE_PART);
|
|
||||||
|
|
||||||
if (cont == SESS_MSG_FIRST_PART) {
|
|
||||||
if (sess->big_msg) {
|
|
||||||
sess_error_low(sess, SESS_ERR_MSG_LOST, NULL);
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
sess->big_msg_size = 1024 * sess_cli_msg_get_cont_size(str);
|
|
||||||
sess->big_msg = mem_alloc(sess->big_msg_size);
|
|
||||||
|
|
||||||
if (sess->big_msg == NULL) {
|
|
||||||
sess_error_low(sess, SESS_ERR_OUT_OF_MEMORY, NULL);
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_memcpy(sess->big_msg, str, len);
|
|
||||||
sess->big_msg_len = len;
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
} else {
|
|
||||||
if (sess->big_msg == NULL) {
|
|
||||||
sess_error_low(sess, SESS_ERR_MSG_LOST, NULL);
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_memcpy(sess->big_msg + sess->big_msg_len,
|
|
||||||
str + SESS_CLI_MSG_DATA, len - SESS_CLI_MSG_DATA);
|
|
||||||
|
|
||||||
sess->big_msg_len += len - SESS_CLI_MSG_DATA;
|
|
||||||
|
|
||||||
if (cont == SESS_MSG_MIDDLE_PART) {
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Processes a client message which requires SQL parsing. This function decodes
|
|
||||||
the client message built in SQLPrepare. NOTE: The kernel mutex is temporarily
|
|
||||||
released within this function. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
sess_receive_prepare(
|
|
||||||
/*=================*/
|
|
||||||
sess_t* sess, /* in: session */
|
|
||||||
byte* cli_msg,/* in: client message */
|
|
||||||
ulint len) /* in: message length */
|
|
||||||
{
|
|
||||||
dulint error_count;
|
|
||||||
que_t* graph;
|
|
||||||
byte msg[ODBC_DATAGRAM_SIZE];
|
|
||||||
|
|
||||||
UT_NOT_USED(len);
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
|
|
||||||
error_count = sess->error_count;
|
|
||||||
|
|
||||||
/* Make sure the session object is not freed during the parsing */
|
|
||||||
|
|
||||||
sess_refer_count_inc(sess);
|
|
||||||
|
|
||||||
/* We release the kernel mutex before parsing the command: this is
|
|
||||||
to reduce contention on the kernel mutex */
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
/* printf("To parse query %s\n", (char*)(cli_msg + SESS_CLI_MSG_DATA)); */
|
|
||||||
|
|
||||||
graph = pars_sql((char*)(cli_msg + SESS_CLI_MSG_DATA));
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
if (graph == NULL) {
|
|
||||||
/* Error in parsing */
|
|
||||||
sess_error_low(sess, SESS_ERR_SQL_ERROR, NULL);
|
|
||||||
|
|
||||||
sess_refer_count_dec(sess);
|
|
||||||
|
|
||||||
ut_error;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UT_DULINT_EQ(error_count, sess->error_count)) {
|
|
||||||
|
|
||||||
/* An error, or an asyncronous signal on the session happened
|
|
||||||
when the kernel mutex was not reserved: discard graph */
|
|
||||||
|
|
||||||
graph->state = QUE_FORK_INVALID;
|
|
||||||
|
|
||||||
que_graph_try_free(graph);
|
|
||||||
|
|
||||||
sess_refer_count_dec(sess);
|
|
||||||
|
|
||||||
ut_error;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UT_LIST_ADD_LAST(graphs, sess->graphs, graph);
|
|
||||||
|
|
||||||
graph->id = sess->next_graph_id;
|
|
||||||
sess->next_graph_id++;
|
|
||||||
|
|
||||||
/* Tell the client that the preparation succeeded and communicate info
|
|
||||||
about the possible query parameters: the message will be decoded in
|
|
||||||
SQLPrepare */
|
|
||||||
|
|
||||||
ut_ad(sess->client_waits);
|
|
||||||
|
|
||||||
sess_srv_msg_init(sess, msg, SESS_SRV_SUCCESS);
|
|
||||||
|
|
||||||
mach_write_to_4(msg + SESS_SRV_MSG_DATA, graph->id);
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
len = pars_write_query_param_info(msg + SESS_SRV_MSG_DATA + 4, graph);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
sess_srv_msg_send(sess, msg, SESS_SRV_MSG_DATA + 4 + len,
|
|
||||||
SESS_RELEASE_KERNEL);
|
|
||||||
sess_refer_count_dec(sess);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Processes a client message which does not require SQL parsing. This function
|
|
||||||
decodes the client message built in SQLExecute. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
sess_receive_command(
|
|
||||||
/*=================*/
|
|
||||||
sess_t* sess, /* in: session */
|
|
||||||
byte* cli_msg,/* in: client message */
|
|
||||||
ulint len, /* in: message length */
|
|
||||||
ulint type) /* in: message type */
|
|
||||||
{
|
|
||||||
proc_node_t* proc_node;
|
|
||||||
call_node_t* call_node;
|
|
||||||
dict_proc_t* dict_proc;
|
|
||||||
que_thr_t* thr;
|
|
||||||
que_t* graph;
|
|
||||||
ulint stat_id;
|
|
||||||
|
|
||||||
UT_NOT_USED(len);
|
|
||||||
UT_NOT_USED(type);
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
|
|
||||||
sess->client_waits = TRUE;
|
|
||||||
|
|
||||||
stat_id = mach_read_from_4(cli_msg + SESS_CLI_MSG_DATA);
|
|
||||||
|
|
||||||
/* Look for the statement from the list of query graphs */
|
|
||||||
|
|
||||||
graph = UT_LIST_GET_FIRST(sess->graphs);
|
|
||||||
|
|
||||||
while (graph != NULL) {
|
|
||||||
|
|
||||||
if (graph->id == stat_id) {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
graph = UT_LIST_GET_NEXT(graphs, graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (graph == NULL) {
|
|
||||||
/* Could not find the right graph: error */
|
|
||||||
sess_error_low(sess, SESS_ERR_STMT_NOT_FOUND, NULL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (graph->state != QUE_FORK_COMMAND_WAIT) {
|
|
||||||
sess_error_low(sess, SESS_ERR_STMT_NOT_READY, NULL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* printf("To execute stat %lu\n", stat_id); */
|
|
||||||
|
|
||||||
if (graph->fork_type == QUE_FORK_PROCEDURE_CALL) {
|
|
||||||
/* It is a stored procedure call: retrieve a parsed copy of
|
|
||||||
the procedure from the dictionary cache */
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
call_node = que_fork_get_child(graph);
|
|
||||||
|
|
||||||
graph = dict_procedure_reserve_parsed_copy(
|
|
||||||
call_node->procedure_def);
|
|
||||||
graph->trx = sess->trx;
|
|
||||||
|
|
||||||
/* Retrieve the procedure input parameters from the message */
|
|
||||||
|
|
||||||
pars_proc_read_input_params_from_buf(graph,
|
|
||||||
cli_msg + SESS_CLI_MSG_DATA + 4);
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
} else {
|
|
||||||
/* It is a create procedure command: add the procedure to the
|
|
||||||
dictionary cache */
|
|
||||||
ut_ad(graph->fork_type == QUE_FORK_PROCEDURE);
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
proc_node = que_fork_get_child(graph);
|
|
||||||
|
|
||||||
dict_proc = dict_mem_procedure_create(proc_node->proc_id->name,
|
|
||||||
proc_node->sym_tab->sql_string,
|
|
||||||
graph);
|
|
||||||
|
|
||||||
dict_procedure_add_to_cache(dict_proc);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
sess_srv_msg_send_simple(sess, SESS_SRV_SUCCESS,
|
|
||||||
SESS_RELEASE_KERNEL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Choose a query thread for execution */
|
|
||||||
thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0);
|
|
||||||
|
|
||||||
ut_ad(thr);
|
|
||||||
|
|
||||||
sess->trx->graph = graph;
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
/* Run query threads with the kernel mutex released */
|
|
||||||
|
|
||||||
que_run_threads(thr);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
When a command has been completed, this function sends the message about it
|
When a command has been completed, this function sends the message about it
|
||||||
to the client. */
|
to the client. */
|
||||||
@ -936,239 +584,3 @@ sess_command_completed_message(
|
|||||||
SESS_RELEASE_KERNEL);
|
SESS_RELEASE_KERNEL);
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Processes a break message from the client. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
sess_receive_break(
|
|
||||||
/*===============*/
|
|
||||||
sess_t* sess) /* in: session */
|
|
||||||
{
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
|
|
||||||
/* Rollback the latest incomplete SQL statement */
|
|
||||||
|
|
||||||
sess_error_low(sess, SESS_ERR_BREAK_BY_CLIENT, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Processes a message from a client. NOTE: Releases the kernel mutex temporarily
|
|
||||||
when parsing an SQL string. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_receive_msg_rel_kernel(
|
|
||||||
/*========================*/
|
|
||||||
sess_t* sess, /* in: session */
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len) /* in: message length */
|
|
||||||
{
|
|
||||||
dulint msg_no;
|
|
||||||
ulint msg_type;
|
|
||||||
ulint cont;
|
|
||||||
ibool is_big_msg = FALSE;
|
|
||||||
ibool client_waited;
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
|
||||||
ut_ad(!sess->disconnecting);
|
|
||||||
|
|
||||||
client_waited = sess->client_waits;
|
|
||||||
|
|
||||||
sess->client_waits = TRUE;
|
|
||||||
|
|
||||||
if (sess->state == SESS_ERROR) {
|
|
||||||
|
|
||||||
/* Send a buffered error message */
|
|
||||||
sess_srv_msg_send_error(sess);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FALSE == sess_cli_msg_check_consistency(str, len)) {
|
|
||||||
/* Message from the client was corrupted */
|
|
||||||
|
|
||||||
sess_error_low(sess, SESS_ERR_MSG_CORRUPTED, NULL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_no = sess_cli_msg_get_msg_no(str);
|
|
||||||
|
|
||||||
UT_DULINT_INC(sess->msgs_recv);
|
|
||||||
|
|
||||||
if (!UT_DULINT_EQ(msg_no, sess->msgs_recv)) {
|
|
||||||
|
|
||||||
sess_error_low(sess, SESS_ERR_MSG_LOST, NULL);
|
|
||||||
|
|
||||||
sess->msgs_recv = msg_no;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_type = sess_cli_msg_get_type(str);
|
|
||||||
|
|
||||||
if (msg_type == SESS_CLI_BREAK_EXECUTION) {
|
|
||||||
|
|
||||||
sess_receive_break(sess);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client_waited) {
|
|
||||||
/* Client sent an extraneous message which is not a break
|
|
||||||
command: an error */
|
|
||||||
|
|
||||||
sess_error_low(sess, SESS_ERR_EXTRANEOUS_MSG, NULL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
/* Handle big messages */
|
|
||||||
|
|
||||||
cont = sess_cli_msg_get_continue(str);
|
|
||||||
|
|
||||||
if (cont == SESS_MSG_SINGLE_PART) {
|
|
||||||
if (sess->big_msg) {
|
|
||||||
|
|
||||||
sess_error_low(sess, SESS_ERR_MSG_LOST, NULL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ut_error; /* Not in use */
|
|
||||||
|
|
||||||
is_big_msg = sess_receive_msg_part(sess, str, len);
|
|
||||||
|
|
||||||
if (is_big_msg) {
|
|
||||||
str = sess->big_msg;
|
|
||||||
len = sess->big_msg_len;
|
|
||||||
sess->big_msg = NULL;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
/* The session has received a complete message from the client */
|
|
||||||
|
|
||||||
ut_ad(!UT_LIST_GET_FIRST((sess->trx)->signals));
|
|
||||||
|
|
||||||
if (msg_type == SESS_CLI_PREPARE) {
|
|
||||||
/* Note that the kernel mutex is temporarily released when
|
|
||||||
the SQL string is parsed */
|
|
||||||
|
|
||||||
sess_receive_prepare(sess, str, len);
|
|
||||||
} else {
|
|
||||||
/* Note that the kernel mutex is temporarily released when the
|
|
||||||
command is executed */
|
|
||||||
|
|
||||||
sess_receive_command(sess, str, len, msg_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_big_msg) {
|
|
||||||
mem_free(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
Opens a new connection and creates a session. */
|
|
||||||
static
|
|
||||||
ibool
|
|
||||||
sess_open_connection(
|
|
||||||
/*=================*/
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len, /* in: string length */
|
|
||||||
byte* addr, /* in: user address string */
|
|
||||||
ulint alen) /* in: user address length */
|
|
||||||
{
|
|
||||||
dulint sess_id;
|
|
||||||
sess_t* sess;
|
|
||||||
|
|
||||||
sess_id = mach_read_from_8(str + SESS_CLI_MSG_SESS_ID);
|
|
||||||
|
|
||||||
if (!(UT_DULINT_EQ(sess_id, ut_dulint_zero))
|
|
||||||
|| !(sess_cli_msg_get_type(str) == SESS_CLI_CONNECT)) {
|
|
||||||
|
|
||||||
/* It is not a valid connect message */
|
|
||||||
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_a(len == SESS_CLI_MSG_DATA);
|
|
||||||
|
|
||||||
sess = sess_open(srv_sys->endpoint, addr, alen);
|
|
||||||
|
|
||||||
sess_srv_msg_send_simple(sess, SESS_SRV_ACCEPT_CONNECT,
|
|
||||||
SESS_NOT_RELEASE_KERNEL);
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
Starts a new connection and a session, or starts a query based on a client
|
|
||||||
message. This is called by a SRV_COM thread. */
|
|
||||||
|
|
||||||
void
|
|
||||||
sess_process_cli_msg(
|
|
||||||
/*=================*/
|
|
||||||
byte* str, /* in: message string */
|
|
||||||
ulint len, /* in: string length */
|
|
||||||
byte* addr, /* in: address string */
|
|
||||||
ulint alen) /* in: address length */
|
|
||||||
{
|
|
||||||
sess_t* sess;
|
|
||||||
ibool success;
|
|
||||||
|
|
||||||
UT_NOT_USED(addr);
|
|
||||||
UT_NOT_USED(alen);
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
sess = sess_cli_msg_get_sess(str, len);
|
|
||||||
|
|
||||||
if (sess == NULL) {
|
|
||||||
/* There was no matching session */
|
|
||||||
|
|
||||||
if (sess_cli_msg_check_consistency(str, len)) {
|
|
||||||
|
|
||||||
/* As the message is consistent, it may be a connect
|
|
||||||
message */
|
|
||||||
|
|
||||||
/* printf("%s\n", addr); */
|
|
||||||
|
|
||||||
success = sess_open_connection(str, len, addr, alen);
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Could not make sense of the message: write an error entry
|
|
||||||
to the system error log */
|
|
||||||
|
|
||||||
/* srv_err_log_insert(
|
|
||||||
"MESSAGE SENT TO AN UNKNOWN SESSION");*/
|
|
||||||
ut_error;
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sess->disconnecting) {
|
|
||||||
|
|
||||||
/* srv_err_log_insert(
|
|
||||||
"MESSAGE SENT TO A DISCONNECTING SESSION");*/
|
|
||||||
ut_error;
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sess_receive_msg_rel_kernel(sess, str, len);
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user