1
0
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:
unknown
2004-02-19 14:37:39 +02:00
parent f509ce23d6
commit 731fd9c5e0
8 changed files with 8 additions and 7030 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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);
} }

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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);
}