Commit 2018ce35 authored by marko's avatar marko

branches/zip: Implement resizeable buffer pool.

mysql.patch: Patch to change or add variables to MySQL

innodb.patch: Patch to make the master thread poll requests to resize
the buffer pool.

Replace srv_pool_size and innobase_buffer_pool_size
with srv_buf_pool_size, srv_buf_pool_old_size,
and srv_buf_pool_curr_size.

Add buf_chunk_t, a collection of buf_block_t.
parent 8e8719da
This diff is collapsed.
...@@ -157,7 +157,7 @@ long innobase_mirrored_log_groups, innobase_log_files_in_group, ...@@ -157,7 +157,7 @@ long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_lock_wait_timeout, innobase_force_recovery, innobase_lock_wait_timeout, innobase_force_recovery,
innobase_open_files; innobase_open_files;
longlong innobase_buffer_pool_size, innobase_log_file_size; longlong innobase_log_file_size;
/* The default values for the following char* start-up parameters /* The default values for the following char* start-up parameters
are determined in innobase_init below: */ are determined in innobase_init below: */
...@@ -1404,7 +1404,7 @@ innobase_init(void *p) ...@@ -1404,7 +1404,7 @@ innobase_init(void *p)
/* Check that values don't overflow on 32-bit systems. */ /* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) { if (sizeof(ulint) == 4) {
if (innobase_buffer_pool_size > UINT_MAX32) { if (srv_buf_pool_size > UINT_MAX32) {
sql_print_error( sql_print_error(
"innobase_buffer_pool_size can't be over 4GB" "innobase_buffer_pool_size can't be over 4GB"
" on 32-bit systems"); " on 32-bit systems");
...@@ -1533,14 +1533,6 @@ innobase_init(void *p) ...@@ -1533,14 +1533,6 @@ innobase_init(void *p)
#endif /* UNIV_LOG_ARCHIVE */ #endif /* UNIV_LOG_ARCHIVE */
srv_log_buffer_size = (ulint) innobase_log_buffer_size; srv_log_buffer_size = (ulint) innobase_log_buffer_size;
/* We set srv_pool_size here in units of 1 kB. InnoDB internally
changes the value so that it becomes the number of database pages. */
/* Careful here: we first convert the signed long int to ulint
and only after that divide */
srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024;
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size; srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_n_file_io_threads = (ulint) innobase_file_io_threads; srv_n_file_io_threads = (ulint) innobase_file_io_threads;
......
...@@ -207,7 +207,7 @@ extern SHOW_VAR innodb_status_variables[]; ...@@ -207,7 +207,7 @@ extern SHOW_VAR innodb_status_variables[];
extern ulong innobase_fast_shutdown; extern ulong innobase_fast_shutdown;
extern ulong innobase_large_page_size; extern ulong innobase_large_page_size;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group; extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_buffer_pool_size, innobase_log_file_size; extern longlong innobase_log_file_size;
extern long innobase_log_buffer_size; extern long innobase_log_buffer_size;
extern long innobase_additional_mem_pool_size; extern long innobase_additional_mem_pool_size;
extern long innobase_file_io_threads, innobase_lock_wait_timeout; extern long innobase_file_io_threads, innobase_lock_wait_timeout;
...@@ -225,6 +225,8 @@ extern my_bool innobase_log_archive, ...@@ -225,6 +225,8 @@ extern my_bool innobase_log_archive,
innobase_file_per_table, innobase_locks_unsafe_for_binlog, innobase_file_per_table, innobase_locks_unsafe_for_binlog,
innobase_create_status_file; innobase_create_status_file;
extern "C" { extern "C" {
extern ulong srv_buf_pool_curr_size;
extern ulong srv_buf_pool_size;
extern ulong srv_max_buf_pool_modified_pct; extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag; extern ulong srv_max_purge_lag;
extern ulong srv_auto_extend_increment; extern ulong srv_auto_extend_increment;
......
...@@ -69,11 +69,16 @@ extern ulint srv_buf_pool_write_requests; /* variable to count write request ...@@ -69,11 +69,16 @@ extern ulint srv_buf_pool_write_requests; /* variable to count write request
Creates the buffer pool. */ Creates the buffer pool. */
buf_pool_t* buf_pool_t*
buf_pool_init( buf_pool_init(void);
/*==========*/ /*===============*/
/* out, own: buf_pool object, NULL if not /* out, own: buf_pool object, NULL if not
enough memory or error */ enough memory or error */
ulint curr_size); /* in: current size to use */ /************************************************************************
Resizes the buffer pool. */
void
buf_pool_resize(void);
/*=================*/
/************************************************************************* /*************************************************************************
Gets the current size of buffer buf_pool in bytes. */ Gets the current size of buffer buf_pool in bytes. */
UNIV_INLINE UNIV_INLINE
...@@ -833,11 +838,8 @@ struct buf_pool_struct{ ...@@ -833,11 +838,8 @@ struct buf_pool_struct{
mutex_t mutex; /* mutex protecting the buffer pool mutex_t mutex; /* mutex protecting the buffer pool
struct and control blocks, except the struct and control blocks, except the
read-write lock in them */ read-write lock in them */
byte* frame_mem; /* pointer to the memory area which ulint n_chunks; /* number of buffer pool chunks */
was allocated for the frames */ buf_chunk_t* chunks; /* buffer pool chunks */
ulint frame_mem_size; /* allocated length of frame_mem
in bytes */
buf_block_t* blocks; /* array of buffer control blocks */
ulint curr_size; /* current pool size in pages */ ulint curr_size; /* current pool size in pages */
hash_table_t* page_hash; /* hash table of the file pages */ hash_table_t* page_hash; /* hash table of the file pages */
......
...@@ -42,22 +42,6 @@ buf_pool_get_curr_size(void) ...@@ -42,22 +42,6 @@ buf_pool_get_curr_size(void)
return(buf_pool->curr_size * UNIV_PAGE_SIZE); return(buf_pool->curr_size * UNIV_PAGE_SIZE);
} }
/***********************************************************************
Accessor function for block array. */
UNIV_INLINE
buf_block_t*
buf_pool_get_nth_block(
/*===================*/
/* out: pointer to block */
buf_pool_t* buf_pool,/* in: buf_pool */
ulint i) /* in: index of the block */
{
ut_ad(buf_pool);
ut_ad(i < buf_pool->curr_size);
return(i + buf_pool->blocks);
}
/************************************************************************ /************************************************************************
Gets the smallest oldest_modification lsn for any page in the pool. Returns Gets the smallest oldest_modification lsn for any page in the pool. Returns
ut_dulint_zero if all modified pages have been flushed to disk. */ ut_dulint_zero if all modified pages have been flushed to disk. */
...@@ -114,8 +98,6 @@ buf_block_get_frame( ...@@ -114,8 +98,6 @@ buf_block_get_frame(
buf_block_t* block) /* in: pointer to the control block */ buf_block_t* block) /* in: pointer to the control block */
{ {
ut_ad(block); ut_ad(block);
ut_ad(block >= buf_pool->blocks);
ut_ad(block < buf_pool->blocks + buf_pool->curr_size);
ut_ad(block->state != BUF_BLOCK_NOT_USED); ut_ad(block->state != BUF_BLOCK_NOT_USED);
ut_ad((block->state != BUF_BLOCK_FILE_PAGE) ut_ad((block->state != BUF_BLOCK_FILE_PAGE)
|| (block->buf_fix_count > 0)); || (block->buf_fix_count > 0));
...@@ -133,8 +115,6 @@ buf_block_get_space( ...@@ -133,8 +115,6 @@ buf_block_get_space(
const buf_block_t* block) /* in: pointer to the control block */ const buf_block_t* block) /* in: pointer to the control block */
{ {
ut_ad(block); ut_ad(block);
ut_ad(block >= buf_pool->blocks);
ut_ad(block < buf_pool->blocks + buf_pool->curr_size);
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
...@@ -151,8 +131,6 @@ buf_block_get_page_no( ...@@ -151,8 +131,6 @@ buf_block_get_page_no(
const buf_block_t* block) /* in: pointer to the control block */ const buf_block_t* block) /* in: pointer to the control block */
{ {
ut_ad(block); ut_ad(block);
ut_ad(block >= buf_pool->blocks);
ut_ad(block < buf_pool->blocks + buf_pool->curr_size);
ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->state == BUF_BLOCK_FILE_PAGE);
ut_ad(block->buf_fix_count > 0); ut_ad(block->buf_fix_count > 0);
......
...@@ -94,8 +94,9 @@ ibool ...@@ -94,8 +94,9 @@ ibool
buf_flush_ready_for_replace( buf_flush_ready_for_replace(
/*========================*/ /*========================*/
/* out: TRUE if can replace immediately */ /* out: TRUE if can replace immediately */
buf_block_t* block); /* in: buffer control block, must be in state buf_block_t* block); /* in: buffer control block, must
BUF_BLOCK_FILE_PAGE and in the LRU list */ be in state BUF_BLOCK_FILE_PAGE
and in the LRU list */
/********************************************************************** /**********************************************************************
Validates the flush list. */ Validates the flush list. */
......
...@@ -10,6 +10,7 @@ Created 11/17/1995 Heikki Tuuri ...@@ -10,6 +10,7 @@ Created 11/17/1995 Heikki Tuuri
#define buf0types_h #define buf0types_h
typedef struct buf_block_struct buf_block_t; typedef struct buf_block_struct buf_block_t;
typedef struct buf_chunk_struct buf_chunk_t;
typedef struct buf_pool_struct buf_pool_t; typedef struct buf_pool_struct buf_pool_t;
/* The 'type' used of a buffer frame */ /* The 'type' used of a buffer frame */
......
...@@ -84,7 +84,9 @@ extern ulong srv_flush_log_at_trx_commit; ...@@ -84,7 +84,9 @@ extern ulong srv_flush_log_at_trx_commit;
extern byte srv_latin1_ordering[256];/* The sort order table of the latin1 extern byte srv_latin1_ordering[256];/* The sort order table of the latin1
character set */ character set */
extern ulint srv_pool_size; extern ulong srv_buf_pool_size; /* requested size in kilobytes */
extern ulong srv_buf_pool_old_size; /* previously requested size */
extern ulong srv_buf_pool_curr_size; /* current size in kilobytes */
extern ulint srv_mem_pool_size; extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size; extern ulint srv_lock_table_size;
...@@ -153,7 +155,6 @@ extern ulong srv_thread_sleep_delay; ...@@ -153,7 +155,6 @@ extern ulong srv_thread_sleep_delay;
extern ulint srv_spin_wait_delay; extern ulint srv_spin_wait_delay;
extern ibool srv_priority_boost; extern ibool srv_priority_boost;
extern ulint srv_pool_size;
extern ulint srv_mem_pool_size; extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size; extern ulint srv_lock_table_size;
......
Index: srv/srv0srv.c
===================================================================
--- srv/srv0srv.c (revision 1010)
+++ srv/srv0srv.c (working copy)
@@ -2183,6 +2182,12 @@ loop:
/* ---- When there is database activity by users, we cycle in this
loop */
+ if (UNIV_UNLIKELY(srv_buf_pool_size != srv_buf_pool_old_size)) {
+ srv_main_thread_op_info = "resizing buffer pool";
+
+ buf_pool_resize();
+ }
+
srv_main_thread_op_info = "reserving kernel mutex";
n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
@@ -2543,6 +2548,12 @@ flush_loop:
master thread to wait for more server activity */
suspend_thread:
+ if (UNIV_UNLIKELY(srv_buf_pool_size != srv_buf_pool_old_size)) {
+ srv_main_thread_op_info = "resizing buffer pool";
+
+ buf_pool_resize();
+ }
+
srv_main_thread_op_info = "suspending";
mutex_enter(&kernel_mutex);
@@ -2553,7 +2564,9 @@ suspend_thread:
goto loop;
}
+#if 0
event = srv_suspend_thread();
+#endif
mutex_exit(&kernel_mutex);
@@ -2563,7 +2576,11 @@ suspend_thread:
manual also mentions this string in several places. */
srv_main_thread_op_info = "waiting for server activity";
+#if 0
os_event_wait(event);
+#else
+ os_thread_sleep(1000000);
+#endif
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
/* This is only extra safety, the thread should exit
diff -pu mysql-5.1-bk/sql/mysqld.cc mysql-5.1-zip/sql/mysqld.cc
--- mysql-5.1-bk/sql/mysqld.cc 2006-11-09 16:01:19.000000000 +0200
+++ mysql-5.1-zip/sql/mysqld.cc 2006-11-13 12:54:04.000000000 +0200
@@ -370,7 +370,6 @@ extern long innobase_lock_scan_time;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_log_file_size;
extern long innobase_log_buffer_size;
-extern longlong innobase_buffer_pool_size;
extern long innobase_additional_mem_pool_size;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
extern long innobase_force_recovery;
@@ -390,6 +389,8 @@ extern "C" {
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
extern ulong srv_auto_extend_increment;
+extern ulong srv_buf_pool_curr_size;
+extern ulong srv_buf_pool_size;
extern ulong srv_n_spin_wait_rounds;
extern ulong srv_n_free_tickets_to_enter;
extern ulong srv_thread_sleep_delay;
@@ -5801,9 +5802,9 @@ log and this option does nothing anymore
(gptr*) &srv_auto_extend_increment,
0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
{"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
- "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
- (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
- GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0,
+ "The requested size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
+ (gptr*) &srv_buf_pool_size, (gptr*) &srv_buf_pool_size, 0,
+ GET_LL, REQUIRED_ARG, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 0,
1024*1024L, 0},
{"innodb_commit_concurrency", OPT_INNODB_COMMIT_CONCURRENCY,
"Helps in performance tuning in heavily concurrent environments.",
diff -pu mysql-5.1-bk/sql/set_var.cc mysql-5.1-zip/sql/set_var.cc
--- mysql-5.1-bk/sql/set_var.cc 2006-11-09 16:01:19.000000000 +0200
+++ mysql-5.1-zip/sql/set_var.cc 2006-11-13 12:54:05.000000000 +0200
@@ -65,7 +65,6 @@ extern ulong innobase_fast_shutdown;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_log_file_size;
extern long innobase_log_buffer_size;
-extern longlong innobase_buffer_pool_size;
extern long innobase_additional_mem_pool_size;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
extern long innobase_force_recovery;
@@ -81,6 +80,8 @@ extern my_bool innobase_log_archive,
innobase_locks_unsafe_for_binlog;
extern "C" {
+extern ulong srv_buf_pool_curr_size;
+extern ulong srv_buf_pool_size;
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
extern ulong srv_auto_extend_increment;
@@ -499,6 +500,8 @@ sys_var_thd_bool sys_innodb_support_xa("
&SV::innodb_support_xa);
sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment",
&srv_auto_extend_increment);
+sys_var_long_ptr sys_innodb_buffer_pool_size("innodb_buffer_pool_size",
+ &srv_buf_pool_size);
sys_var_long_ptr sys_innodb_sync_spin_loops("innodb_sync_spin_loops",
&srv_n_spin_wait_rounds);
sys_var_long_ptr sys_innodb_concurrency_tickets("innodb_concurrency_tickets",
@@ -818,7 +821,8 @@ SHOW_VAR init_vars[]= {
#ifdef WITH_INNOBASE_STORAGE_ENGINE
{"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
{sys_innodb_autoextend_increment.name, (char*) &sys_innodb_autoextend_increment, SHOW_SYS},
- {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONGLONG },
+ {sys_innodb_buffer_pool_size.name, (char*) &sys_innodb_buffer_pool_size, SHOW_SYS },
+ {"innodb_buffer_pool_curr_size", (char*) &srv_buf_pool_curr_size, SHOW_LONGLONG },
{"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL},
{sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS},
{sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS},
...@@ -159,10 +159,11 @@ byte srv_latin1_ordering[256] /* The sort order table of the latin1 ...@@ -159,10 +159,11 @@ byte srv_latin1_ordering[256] /* The sort order table of the latin1
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF , 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
}; };
ulint srv_pool_size = ULINT_MAX; /* size in pages; MySQL inits ulong srv_buf_pool_size = ULINT_MAX; /* requested size
this to size in kilobytes but in kilobytes */
we normalize this to pages in ulong srv_buf_pool_old_size; /* previously requested size */
srv_boot() */ ulong srv_buf_pool_curr_size = 0; /* current size
in kilobytes */
ulint srv_mem_pool_size = ULINT_MAX; /* size in bytes */ ulint srv_mem_pool_size = ULINT_MAX; /* size in bytes */
ulint srv_lock_table_size = ULINT_MAX; ulint srv_lock_table_size = ULINT_MAX;
...@@ -1233,9 +1234,7 @@ srv_normalize_init_values(void) ...@@ -1233,9 +1234,7 @@ srv_normalize_init_values(void)
srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE; srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
srv_pool_size = srv_pool_size / (UNIV_PAGE_SIZE / 1024); srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
srv_lock_table_size = 5 * srv_pool_size;
return(DB_SUCCESS); return(DB_SUCCESS);
} }
......
...@@ -1132,7 +1132,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -1132,7 +1132,7 @@ innobase_start_or_create_for_mysql(void)
} }
/* Note that the call srv_boot() also changes the values of /* Note that the call srv_boot() also changes the values of
srv_pool_size etc. to the units used by InnoDB internally */ some variables to the units used by InnoDB internally */
/* Set the maximum number of threads which can wait for a semaphore /* Set the maximum number of threads which can wait for a semaphore
inside InnoDB: this is the 'sync wait array' size, as well as the inside InnoDB: this is the 'sync wait array' size, as well as the
...@@ -1147,15 +1147,12 @@ innobase_start_or_create_for_mysql(void) ...@@ -1147,15 +1147,12 @@ innobase_start_or_create_for_mysql(void)
NetWare. */ NetWare. */
srv_max_n_threads = 1000; srv_max_n_threads = 1000;
#else #else
if (srv_pool_size >= 1000 * 1024) { if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
/* Here we still have srv_pool_size counted /* If buffer pool is less than 1000 MB,
in kilobytes (in 4.0 this was in bytes)
srv_boot() converts the value to
pages; if buffer pool is less than 1000 MB,
assume fewer threads. */ assume fewer threads. */
srv_max_n_threads = 50000; srv_max_n_threads = 50000;
} else if (srv_pool_size >= 8 * 1024) { } else if (srv_buf_pool_size >= 8 * 1024 * 1024) {
srv_max_n_threads = 10000; srv_max_n_threads = 10000;
} else { } else {
...@@ -1164,7 +1161,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -1164,7 +1161,7 @@ innobase_start_or_create_for_mysql(void)
computers */ computers */
} }
#endif #endif
err = srv_boot(); /* This changes srv_pool_size to units of a page */ err = srv_boot();
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
...@@ -1230,7 +1227,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -1230,7 +1227,7 @@ innobase_start_or_create_for_mysql(void)
fil_init(srv_max_n_open_files); fil_init(srv_max_n_open_files);
ret = buf_pool_init(srv_pool_size); ret = buf_pool_init();
if (ret == NULL) { if (ret == NULL) {
fprintf(stderr, fprintf(stderr,
......
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