Commit 388b78c9 authored by marko's avatar marko

branches/innodb+: Merge revisions 2322:2340 from branches/zip

parent 95c241b5
......@@ -25,7 +25,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/extra/yassl/include)
SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
data/data0data.c data/data0type.c
dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
dyn/dyn0dyn.c
......@@ -33,26 +33,28 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
fil/fil0fil.c
fsp/fsp0fsp.c
fut/fut0fut.c fut/fut0lst.c
ha/ha0ha.c ha/hash0hash.c
ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c
ibuf/ibuf0ibuf.c
pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
lock/lock0lock.c
lock/lock0lock.c lock/lock0iter.c
log/log0log.c log/log0recv.c
mach/mach0data.c
mem/mem0mem.c mem/mem0pool.c
mtr/mtr0log.c mtr/mtr0mtr.c
os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
page/page0cur.c page/page0page.c
page/page0cur.c page/page0page.c page/page0zip.c
que/que0que.c
handler/ha_innodb.cc
handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
read/read0read.c
rem/rem0cmp.c rem/rem0rec.c
row/row0ins.c row/row0mysql.c row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c
row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c
row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c
row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
srv/srv0que.c srv/srv0srv.c srv/srv0start.c
sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
thr/thr0loc.c
trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
......
......@@ -3733,7 +3733,7 @@ btr_push_update_extern_fields(
InnoDB writes a longer prefix of externally
stored columns, so that column prefixes
in secondary indexes can be reconstructed. */
dfield_set_data(field, dfield_get_data(field)
dfield_set_data(field, (byte*) dfield_get_data(field)
+ dfield_get_len(field)
- BTR_EXTERN_FIELD_REF_SIZE,
BTR_EXTERN_FIELD_REF_SIZE);
......@@ -4551,13 +4551,13 @@ btr_copy_zblob_prefix(
ulint page_no,/* in: page number of the first BLOB page */
ulint offset) /* in: offset on the first BLOB page */
{
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
ut_ad(ut_is_2pow(zip_size));
ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE);
ut_ad(zip_size <= UNIV_PAGE_SIZE);
ut_ad(space_id);
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
for (;;) {
buf_page_t* bpage;
int err;
......
......@@ -28,6 +28,9 @@ UNIV_INTERN ulint buf_buddy_used[BUF_BUDDY_SIZES + 1];
/** Counts of blocks relocated by the buddy system.
Protected by buf_pool_mutex. */
UNIV_INTERN ib_uint64_t buf_buddy_relocated[BUF_BUDDY_SIZES + 1];
/** Durations of block relocations.
Protected by buf_pool_mutex. */
UNIV_INTERN ullint buf_buddy_relocated_duration[BUF_BUDDY_SIZES + 1];
/** Preferred minimum number of frames allocated from the buffer pool
to the buddy system. Unless this number is exceeded or the buffer
......@@ -268,135 +271,6 @@ buf_buddy_alloc_from(
return(buf);
}
/**************************************************************************
Try to allocate a block by freeing an unmodified page. */
static
void*
buf_buddy_alloc_clean(
/*==================*/
/* out: allocated block, or NULL */
ulint i, /* in: index of buf_pool->zip_free[] */
ibool* lru) /* in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released */
{
ulint count;
buf_page_t* bpage;
ut_ad(buf_pool_mutex_own());
ut_ad(!mutex_own(&buf_pool_zip_mutex));
if (buf_buddy_n_frames >= buf_buddy_max_n_frames
&& ((BUF_BUDDY_LOW << i) >= PAGE_ZIP_MIN_SIZE
&& i < BUF_BUDDY_SIZES)) {
/* Try to find a clean compressed-only page
of the same size. */
ulint j;
page_zip_des_t dummy_zip;
page_zip_set_size(&dummy_zip, BUF_BUDDY_LOW << i);
j = ut_min(UT_LIST_GET_LEN(buf_pool->zip_clean), 100);
bpage = UT_LIST_GET_FIRST(buf_pool->zip_clean);
mutex_enter(&buf_pool_zip_mutex);
for (; j--; bpage = UT_LIST_GET_NEXT(list, bpage)) {
if (bpage->zip.ssize != dummy_zip.ssize
|| !buf_LRU_free_block(bpage, FALSE, lru)) {
continue;
}
/* Reuse the block. */
mutex_exit(&buf_pool_zip_mutex);
bpage = buf_buddy_alloc_zip(i);
/* bpage may be NULL if buf_buddy_free()
[invoked by buf_LRU_free_block() via
buf_LRU_block_remove_hashed_page()]
recombines blocks and invokes
buf_buddy_block_free(). Because
buf_pool_mutex will not be released
after buf_buddy_block_free(), there will
be at least one block available in the
buffer pool, and thus it does not make sense
to deallocate any further compressed blocks. */
return(bpage);
}
mutex_exit(&buf_pool_zip_mutex);
}
/* Free blocks from the end of the LRU list until enough space
is available. */
count = 0;
free_LRU:
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
bpage;
bpage = UT_LIST_GET_PREV(LRU, bpage), ++count) {
void* ret;
mutex_t* block_mutex = buf_page_get_mutex(bpage);
if (UNIV_UNLIKELY(!buf_page_in_file(bpage))) {
/* This is most likely BUF_BLOCK_REMOVE_HASH,
that is, the block is already being freed. */
continue;
}
mutex_enter(block_mutex);
/* Keep the compressed pages of uncompressed blocks. */
if (!buf_LRU_free_block(bpage, FALSE, lru)) {
mutex_exit(block_mutex);
continue;
}
mutex_exit(block_mutex);
/* The block was successfully freed.
Attempt to allocate memory. */
if (i < BUF_BUDDY_SIZES) {
ret = buf_buddy_alloc_zip(i);
if (ret) {
return(ret);
}
} else {
buf_block_t* block = buf_LRU_get_free_only();
if (block) {
buf_buddy_block_register(block);
return(block->frame);
}
}
/* A successful buf_LRU_free_block() may release and
reacquire buf_pool_mutex, and thus bpage->LRU of
an uncompressed page may point to garbage. Furthermore,
if bpage were a compressed page descriptor, it would
have been deallocated by buf_LRU_free_block().
Thus, we must restart the traversal of the LRU list. */
goto free_LRU;
}
return(NULL);
}
/**************************************************************************
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
......@@ -442,13 +316,6 @@ buf_buddy_alloc_low(
return(NULL);
}
/* Try replacing a clean page in the buffer pool. */
block = buf_buddy_alloc_clean(i, lru);
if (block) {
goto func_exit;
}
/* Try replacing an uncompressed page in the buffer pool. */
buf_pool_mutex_exit();
block = buf_LRU_get_free_block(0);
......@@ -533,6 +400,7 @@ buf_buddy_relocate(
{
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
ullint usec = ut_time_us(NULL);
ut_ad(buf_pool_mutex_own());
ut_ad(!mutex_own(&buf_pool_zip_mutex));
......@@ -605,6 +473,8 @@ buf_buddy_relocate(
success:
UNIV_MEM_INVALID(src, size);
buf_buddy_relocated[i]++;
buf_buddy_relocated_duration[i]
+= ut_time_us(NULL) - usec;
return(TRUE);
}
......
......@@ -989,13 +989,16 @@ buf_pool_free(void)
/************************************************************************
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list. */
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
UNIV_INTERN
void
buf_relocate(
/*=========*/
buf_page_t* bpage, /* control block being relocated */
buf_page_t* dpage) /* destination control block */
buf_page_t* bpage, /* in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
buf_page_t* dpage) /* in/out: destination control block */
{
buf_page_t* b;
ulint fold;
......@@ -1004,11 +1007,24 @@ buf_relocate(
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
ut_a(bpage->buf_fix_count == 0);
ut_a(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
ut_ad(!bpage->in_zip_hash);
ut_ad(bpage->in_page_hash);
ut_ad(bpage == buf_page_hash_get(bpage->space, bpage->offset));
#ifdef UNIV_DEBUG
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_FILE_PAGE:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
ut_error;
case BUF_BLOCK_ZIP_DIRTY:
case BUF_BLOCK_ZIP_PAGE:
break;
}
#endif /* UNIV_DEBUG */
memcpy(dpage, bpage, sizeof *dpage);
......
......@@ -29,6 +29,7 @@ Created 1/8/1996 Heikki Tuuri
#include "row0merge.h"
#ifndef UNIV_HOTBACKUP
# include "m_ctype.h" /* my_isspace() */
# include "ha_prototypes.h" /* innobase_strcasecmp() */
#endif /* !UNIV_HOTBACKUP */
#include <ctype.h>
......@@ -82,19 +83,6 @@ innobase_convert_from_id(
ulint len); /* in: length of 'to', in bytes;
should be at least 3 * strlen(to) + 1 */
/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
this function, you MUST change also the prototype here! */
UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
const char* a, /* in: first string to compare */
const char* b); /* in: second string to compare */
/**********************************************************************
Makes all characters in a NUL-terminated UTF-8 string lower case.
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
......
......@@ -64,6 +64,7 @@ extern "C" {
#include "../storage/innobase/include/thr0loc.h"
#include "../storage/innobase/include/dict0boot.h"
#include "../storage/innobase/include/ha_prototypes.h"
#include "../storage/innobase/include/ut0mem.h"
}
#include "ha_innodb.h"
......@@ -813,10 +814,7 @@ innobase_convert_from_id(
}
/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE that the exact prototype of this function has to be in
/innobase/dict/dict0dict.c! */
Compares NUL-terminated UTF-8 strings case insensitively. */
extern "C" UNIV_INTERN
int
innobase_strcasecmp(
......@@ -909,6 +907,45 @@ innobase_convert_string(
errors));
}
/***********************************************************************
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
terminating '\0'). */
extern "C" UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
/* out: number of bytes
that were written */
const char* data, /* in: raw data */
ulint data_len, /* in: raw data length
in bytes */
ulint charset_coll, /* in: charset collation */
char* buf, /* out: output buffer */
ulint buf_size) /* in: output buffer size
in bytes */
{
/* XXX we use a hard limit instead of allocating
but_size bytes from the heap */
CHARSET_INFO* data_cs;
char buf_tmp[8192];
ulint buf_tmp_used;
uint num_errors;
data_cs = all_charsets[charset_coll];
buf_tmp_used = innobase_convert_string(buf_tmp, sizeof(buf_tmp),
system_charset_info,
data, data_len, data_cs,
&num_errors);
return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size));
}
/*************************************************************************
Gets the InnoDB transaction handle for a MySQL handler object, creates
an InnoDB transaction struct if the corresponding MySQL thread struct still
......
......@@ -653,6 +653,7 @@ ha_innobase::add_index(
mem_heap_free(heap);
trx_general_rollback_for_mysql(trx, FALSE, NULL);
trx_free_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
DBUG_RETURN(error);
}
......
......@@ -6,7 +6,6 @@ InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
*******************************************************/
#include <strings.h>
#include <mysql_priv.h>
#include <mysqld_error.h>
......@@ -931,7 +930,7 @@ trx_i_s_common_fill_table(
trx_i_s_cache_start_read(cache);
if (strcasecmp(table_name, "innodb_trx") == 0) {
if (innobase_strcasecmp(table_name, "innodb_trx") == 0) {
if (fill_innodb_trx_from_cache(
cache, thd, tables->table) != 0) {
......@@ -939,7 +938,7 @@ trx_i_s_common_fill_table(
ret = 1;
}
} else if (strcasecmp(table_name, "innodb_locks") == 0) {
} else if (innobase_strcasecmp(table_name, "innodb_locks") == 0) {
if (fill_innodb_locks_from_cache(
cache, thd, tables->table) != 0) {
......@@ -947,7 +946,7 @@ trx_i_s_common_fill_table(
ret = 1;
}
} else if (strcasecmp(table_name, "innodb_lock_waits") == 0) {
} else if (innobase_strcasecmp(table_name, "innodb_lock_waits") == 0) {
if (fill_innodb_lock_waits_from_cache(
cache, thd, tables->table) != 0) {
......@@ -992,6 +991,22 @@ static ST_FIELD_INFO i_s_zip_fields_info[] =
STRUCT_FLD(old_name, "Block Size"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "used"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Currently in Use"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "free"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Currently Available"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "relocated"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
......@@ -1000,6 +1015,14 @@ static ST_FIELD_INFO i_s_zip_fields_info[] =
STRUCT_FLD(old_name, "Total Number of Relocations"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "relocated_usec"),
STRUCT_FLD(field_length, 42),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Total Duration of Relocations"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "compressed"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
......@@ -1017,28 +1040,28 @@ static ST_FIELD_INFO i_s_zip_fields_info[] =
" Successful Compressions"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "decompressed"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
{STRUCT_FLD(field_name, "compressed_usec"),
STRUCT_FLD(field_length, 42),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Total Number of Decompressions"),
STRUCT_FLD(old_name, "Total Duration of Compressions"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "used"),
{STRUCT_FLD(field_name, "decompressed"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Currently in Use"),
STRUCT_FLD(old_name, "Total Number of Decompressions"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
{STRUCT_FLD(field_name, "free"),
STRUCT_FLD(field_length, 21),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
{STRUCT_FLD(field_name, "decompressed_usec"),
STRUCT_FLD(field_length, 42),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, "Currently Available"),
STRUCT_FLD(old_name, "Total Duration of Decompressions"),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
......@@ -1076,10 +1099,17 @@ i_s_zip_fill_low(
for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
table->field[0]->store(BUF_BUDDY_LOW << x);
table->field[1]->store(buf_buddy_relocated[x]);
table->field[1]->store(buf_buddy_used[x]);
table->field[2]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES)
? UT_LIST_GET_LEN(buf_pool->zip_free[x])
: 0);
table->field[3]->store(buf_buddy_relocated[x]);
table->field[4]->store(buf_buddy_relocated_duration[x]);
if (reset) {
/* This is protected by buf_pool_mutex. */
buf_buddy_relocated[x] = 0;
buf_buddy_relocated_duration[x] = 0;
}
if (x > y) {
......@@ -1090,23 +1120,25 @@ i_s_zip_fill_low(
mutex protection, but it could cause a
measureable performance hit in page0zip.c. */
const uint i = x - y;
table->field[2]->store(page_zip_compress_count[i]);
table->field[3]->store(page_zip_compress_ok[i]);
table->field[4]->store(page_zip_decompress_count[i]);
table->field[5]->store(page_zip_compress_count[i]);
table->field[6]->store(page_zip_compress_ok[i]);
table->field[7]->store(page_zip_compress_duration[i]);
table->field[8]->store(page_zip_decompress_count[i]);
table->field[9]->store(page_zip_decompress_duration[i]);
if (reset) {
page_zip_compress_count[i] = 0;
page_zip_compress_ok[i] = 0;
page_zip_decompress_count[i] = 0;
page_zip_compress_duration[i] = 0;
page_zip_decompress_duration[i] = 0;
}
} else {
table->field[2]->store(0);
table->field[3]->store(0);
table->field[4]->store(0);
table->field[5]->store(0);
table->field[6]->store(0);
table->field[7]->store(0);
table->field[8]->store(0);
table->field[9]->store(0);
}
table->field[5]->store(buf_buddy_used[x]);
table->field[6]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES)
? UT_LIST_GET_LEN(buf_pool->zip_free[x])
: 0);
if (schema_table_store_record(thd, table)) {
status = 1;
......
......@@ -21,10 +21,10 @@ Created December 2006 by Marko Makela
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
if lru == BUF_BUDDY_USE_LRU. This function should only be used for
allocating compressed page frames or control blocks (buf_page_t).
Allocated control blocks must be properly initialized immediately
after buf_buddy_alloc() has returned the memory, before releasing
if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool_mutex. */
UNIV_INLINE
void*
......@@ -69,6 +69,9 @@ extern ulint buf_buddy_used[BUF_BUDDY_SIZES + 1];
/** Counts of blocks relocated by the buddy system.
Protected by buf_pool_mutex. */
extern ib_uint64_t buf_buddy_relocated[BUF_BUDDY_SIZES + 1];
/** Durations of block relocations.
Protected by buf_pool_mutex. */
extern ullint buf_buddy_relocated_duration[BUF_BUDDY_SIZES + 1];
#ifndef UNIV_NONINL
# include "buf0buddy.ic"
......
......@@ -19,8 +19,7 @@ Created December 2006 by Marko Makela
/**************************************************************************
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
The buf_pool_mutex may only be released and reacquired if
lru == BUF_BUDDY_USE_LRU. */
The buf_pool_mutex may only be released and reacquired if lru != NULL. */
UNIV_INTERN
void*
buf_buddy_alloc_low(
......@@ -70,10 +69,10 @@ buf_buddy_get_slot(
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
if lru == BUF_BUDDY_USE_LRU. This function should only be used for
allocating compressed page frames or control blocks (buf_page_t).
Allocated control blocks must be properly initialized immediately
after buf_buddy_alloc() has returned the memory, before releasing
if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
buf_pool_mutex. */
UNIV_INLINE
void*
......
......@@ -100,13 +100,16 @@ buf_pool_free(void);
/************************************************************************
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list. */
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
UNIV_INTERN
void
buf_relocate(
/*=========*/
buf_page_t* bpage, /* control block being relocated */
buf_page_t* dpage) /* destination control block */
buf_page_t* bpage, /* in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
buf_page_t* dpage) /* in/out: destination control block */
__attribute__((nonnull));
/************************************************************************
Resizes the buffer pool. */
......@@ -805,7 +808,7 @@ buf_page_get_space(
/*===============*/
/* out: space id */
const buf_page_t* bpage) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the space id of a block. */
UNIV_INLINE
......@@ -814,7 +817,7 @@ buf_block_get_space(
/*================*/
/* out: space id */
const buf_block_t* block) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the page number of a block. */
UNIV_INLINE
......@@ -823,7 +826,7 @@ buf_page_get_page_no(
/*=================*/
/* out: page number */
const buf_page_t* bpage) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the page number of a block. */
UNIV_INLINE
......@@ -832,7 +835,7 @@ buf_block_get_page_no(
/*==================*/
/* out: page number */
const buf_block_t* block) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the compressed page size of a block. */
UNIV_INLINE
......@@ -841,7 +844,7 @@ buf_page_get_zip_size(
/*==================*/
/* out: compressed page size, or 0 */
const buf_page_t* bpage) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the compressed page size of a block. */
UNIV_INLINE
......@@ -850,7 +853,7 @@ buf_block_get_zip_size(
/*===================*/
/* out: compressed page size, or 0 */
const buf_block_t* block) /* in: pointer to the control block */
__attribute((pure));
__attribute__((pure));
/*************************************************************************
Gets the compressed page descriptor corresponding to an uncompressed page
if applicable. */
......
......@@ -24,6 +24,28 @@ innobase_convert_string(
CHARSET_INFO* from_cs,
uint* errors);
/***********************************************************************
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
terminating '\0'). */
UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
/* out: number of bytes
that were written */
const char* data, /* in: raw data */
ulint data_len, /* in: raw data length
in bytes */
ulint charset_coll, /* in: charset collation */
char* buf, /* out: output buffer */
ulint buf_size); /* in: output buffer size
in bytes */
/*********************************************************************
Convert a table or index name to the MySQL system_charset_info (UTF-8)
and quote it if needed. */
......@@ -126,5 +148,15 @@ innobase_get_cset_width(
ulint cset, /* in: MySQL charset-collation code */
ulint* mbminlen, /* out: minimum length of a char (in bytes) */
ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively. */
UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
const char* a, /* in: first string to compare */
const char* b); /* in: second string to compare */
#endif
#endif
......@@ -290,6 +290,17 @@ os_file_create_simple_no_error_handling(
used by a backup program reading the file */
ibool* success);/* out: TRUE if succeed, FALSE if error */
/********************************************************************
Tries to disable OS caching on an opened file descriptor. */
UNIV_INTERN
void
os_file_set_nocache(
/*================*/
int fd, /* in: file descriptor to alter */
const char* file_name, /* in: file name, used in the
diagnostic message */
const char* operation_name);/* in: "open" or "create"; used in the
diagnostic message */
/********************************************************************
Opens an existing file or creates a new. */
UNIV_INTERN
os_file_t
......
......@@ -54,6 +54,10 @@ extern ulint page_zip_compress_count[8];
extern ulint page_zip_compress_ok[8];
/** Number of page decompressions, indexed by page_zip_des_t::ssize */
extern ulint page_zip_decompress_count[8];
/** Duration of page compressions, indexed by page_zip_des_t::ssize */
extern ullint page_zip_compress_duration[8];
/** Duration of page decompressions, indexed by page_zip_des_t::ssize */
extern ullint page_zip_decompress_duration[8];
/**************************************************************************
Write data to the compressed page. The data must already be written to
......
......@@ -45,7 +45,7 @@ if we are compiling on Windows. */
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
# include <sys/stat.h>
# ifndef __NETWARE__
# if !defined(__NETWARE__) && !defined(__WIN__)
# include <sys/mman.h> /* mmap() for os0proc.c */
# endif
......
......@@ -1109,12 +1109,10 @@ void
os_file_set_nocache(
/*================*/
int fd, /* in: file descriptor to alter */
const char* file_name, /* in: used in the diagnostic message */
const char* operation_name) /* in: used in the diagnostic message,
we call os_file_set_nocache()
immediately after opening or creating
a file, so this is either "open" or
"create" */
const char* file_name, /* in: file name, used in the
diagnostic message */
const char* operation_name) /* in: "open" or "create"; used in the
diagnostic message */
{
/* some versions of Solaris may not have DIRECTIO_ON */
#if defined(UNIV_SOLARIS) && defined(DIRECTIO_ON)
......
......@@ -129,7 +129,7 @@ os_mem_alloc_large(
size = *n = ut_2pow_round(*n + system_info.dwPageSize - 1,
system_info.dwPageSize);
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE | PAGE_WRITECOMBINE);
PAGE_READWRITE);
if (!ptr) {
fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
" Windows error %lu\n",
......
......@@ -30,6 +30,10 @@ UNIV_INTERN ulint page_zip_compress_count[8];
UNIV_INTERN ulint page_zip_compress_ok[8];
/** Number of page decompressions, indexed by page_zip_des_t::ssize */
UNIV_INTERN ulint page_zip_decompress_count[8];
/** Duration of page compressions, indexed by page_zip_des_t::ssize */
UNIV_INTERN ullint page_zip_compress_duration[8];
/** Duration of page decompressions, indexed by page_zip_des_t::ssize */
UNIV_INTERN ullint page_zip_decompress_duration[8];
/* Please refer to ../include/page0zip.ic for a description of the
compressed page format. */
......@@ -1104,6 +1108,7 @@ page_zip_compress(
ulint* offsets = NULL;
ulint n_blobs = 0;
byte* storage;/* storage of uncompressed columns */
ullint usec = ut_time_us(NULL);
#ifdef PAGE_ZIP_COMPRESS_DBG
FILE* logfile = NULL;
#endif
......@@ -1169,12 +1174,8 @@ page_zip_compress(
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
>= page_zip_get_size(page_zip))) {
#ifdef PAGE_ZIP_COMPRESS_DBG
if (logfile) {
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
return(FALSE);
goto err_exit;
}
heap = mem_heap_create(page_zip_get_size(page_zip)
......@@ -1300,11 +1301,14 @@ page_zip_compress(
zlib_error:
deflateEnd(&c_stream);
mem_heap_free(heap);
err_exit:
#ifdef PAGE_ZIP_COMPRESS_DBG
if (logfile) {
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
page_zip_compress_duration[page_zip->ssize]
+= ut_time_us(NULL) - usec;
return(FALSE);
}
......@@ -1362,6 +1366,8 @@ page_zip_compress(
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
page_zip_compress_duration[page_zip->ssize]
+= ut_time_us(NULL) - usec;
return(TRUE);
}
......@@ -2779,6 +2785,7 @@ page_zip_decompress(
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
ulint* offsets;
ullint usec = ut_time_us(NULL);
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
......@@ -2935,6 +2942,8 @@ page_zip_decompress(
page_zip_fields_free(index);
mem_heap_free(heap);
page_zip_decompress_count[page_zip->ssize]++;
page_zip_decompress_duration[page_zip->ssize]
+= ut_time_us(NULL) - usec;
return(TRUE);
}
......
......@@ -1725,7 +1725,7 @@ row_create_table_for_mysql(
" by the user.\n"
"InnoDB: Shut down mysqld and edit my.cnf so that newraw"
" is replaced with raw.\n", stderr);
err_exit:
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
......@@ -1742,11 +1742,7 @@ row_create_table_for_mysql(
"InnoDB: MySQL system tables must be"
" of the MyISAM type!\n",
table->name);
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
goto err_exit;
}
/* Check that no reserved column names are used. */
......@@ -1754,10 +1750,7 @@ row_create_table_for_mysql(
if (dict_col_name_is_reserved(
dict_table_get_col_name(table, i))) {
dict_mem_table_free(table);
trx_commit_for_mysql(trx);
return(DB_ERROR);
goto err_exit;
}
}
......@@ -1833,10 +1826,13 @@ row_create_table_for_mysql(
err = trx->error_state;
switch (err) {
case DB_OUT_OF_FILE_SPACE:
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, FALSE, NULL);
}
switch (err) {
case DB_OUT_OF_FILE_SPACE:
ut_print_timestamp(stderr);
fputs(" InnoDB: Warning: cannot create table ",
stderr);
......@@ -1850,8 +1846,6 @@ row_create_table_for_mysql(
break;
case DB_DUPLICATE_KEY:
trx_general_rollback_for_mysql(trx, FALSE, NULL);
ut_print_timestamp(stderr);
fputs(" InnoDB: Error: table ", stderr);
ut_print_name(stderr, trx, TRUE, table->name);
......
......@@ -905,47 +905,6 @@ row_raw_format_int(
return(ut_min(ret, buf_size));
}
extern CHARSET_INFO* system_charset_info;
/***********************************************************************
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
terminating '\0'). */
static
ulint
row_raw_format_str_convert(
/*=======================*/
/* out: number of bytes
that were written */
const char* data, /* in: raw data */
ulint data_len, /* in: raw data length
in bytes */
ulint charset_coll, /* in: charset collation */
char* buf, /* out: output buffer */
ulint buf_size) /* in: output buffer size
in bytes */
{
/* XXX we use a hard limit instead of allocating
but_size bytes from the heap */
CHARSET_INFO* data_cs;
char buf_tmp[8192];
ulint buf_tmp_used;
uint num_errors;
data_cs = all_charsets[charset_coll];
buf_tmp_used = innobase_convert_string(buf_tmp, sizeof(buf_tmp),
system_charset_info,
data, data_len, data_cs,
&num_errors);
return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size));
}
/***********************************************************************
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
......@@ -997,7 +956,7 @@ row_raw_format_str(
}
/* else */
return(row_raw_format_str_convert(data, data_len, charset_coll,
return(innobase_raw_format(data, data_len, charset_coll,
buf, buf_size));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment