#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
-diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
---- a/storage/innobase/buf/buf0buf.c 2010-12-03 17:49:11.574962867 +0900
-+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:35:58.624514033 +0900
-@@ -4248,7 +4248,8 @@
+--- a/storage/innobase/buf/buf0buf.c
++++ b/storage/innobase/buf/buf0buf.c
+@@ -3807,7 +3807,8 @@
read_space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
&& trx_doublewrite_page_inside(bpage->offset)) {
ut_print_timestamp(stderr);
-diff -ruN a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
---- a/storage/innobase/buf/buf0flu.c 2010-12-03 15:49:59.179956111 +0900
-+++ b/storage/innobase/buf/buf0flu.c 2010-12-04 15:35:58.624514033 +0900
-@@ -791,7 +791,8 @@
+--- a/storage/innobase/buf/buf0flu.c
++++ b/storage/innobase/buf/buf0flu.c
+@@ -793,7 +793,8 @@
write_buf = trx_doublewrite->write_buf;
i = 0;
trx_doublewrite->block1, 0, len,
(void*) write_buf, NULL);
-@@ -828,7 +829,8 @@
+@@ -830,7 +831,8 @@
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
ut_ad(i == TRX_SYS_DOUBLEWRITE_BLOCK_SIZE);
trx_doublewrite->block2, 0, len,
(void*) write_buf, NULL);
-@@ -858,7 +860,7 @@
+@@ -860,7 +862,7 @@
flush:
/* Now flush the doublewrite buffer data to disk */
-- fil_flush(TRX_SYS_SPACE);
-+ fil_flush(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE);
+- fil_flush(TRX_SYS_SPACE, FALSE);
++ fil_flush(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE, FALSE);
/* We know that the writes have been flushed to disk now
and in recovery we will find them in the doublewrite buffer
-diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
---- a/storage/innobase/buf/buf0rea.c 2010-12-04 15:35:29.138514157 +0900
-+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:35:58.626486771 +0900
-@@ -88,7 +88,9 @@
+--- a/storage/innobase/buf/buf0rea.c
++++ b/storage/innobase/buf/buf0rea.c
+@@ -90,7 +90,9 @@
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
&& ( (offset >= trx_doublewrite->block1
&& offset < trx_doublewrite->block1
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
-diff -ruN a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
---- a/storage/innobase/dict/dict0load.c 2010-12-03 17:30:16.252956569 +0900
-+++ b/storage/innobase/dict/dict0load.c 2010-12-04 15:35:58.627482825 +0900
+--- a/storage/innobase/dict/dict0load.c
++++ b/storage/innobase/dict/dict0load.c
@@ -41,6 +41,7 @@
#include "srv0start.h"
#include "srv0srv.h"
/** Following are six InnoDB system tables */
-@@ -797,7 +798,7 @@
+@@ -816,7 +817,7 @@
mtr_commit(&mtr);
/* The system tablespace always exists. */
} else if (in_crash_recovery) {
/* Check that the tablespace (the .ibd file) really
-@@ -1594,7 +1595,7 @@
+@@ -1727,7 +1728,7 @@
space = mach_read_from_4(field);
/* Check if the tablespace exists and has the right name */
flags = dict_sys_tables_get_flags(rec);
if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) {
-@@ -1744,7 +1745,7 @@
+@@ -1880,7 +1881,7 @@
goto err_exit;
}
/* The system tablespace is always available. */
} else if (!fil_space_for_table_exists_in_mem(
table->space, name,
-diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
---- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:35:29.143813775 +0900
-+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:35:58.628498870 +0900
-@@ -655,7 +655,7 @@
+--- a/storage/innobase/fil/fil0fil.c
++++ b/storage/innobase/fil/fil0fil.c
+@@ -657,7 +657,7 @@
UT_LIST_ADD_LAST(chain, space->chain, node);
fil_system->max_assigned_id = id;
}
-@@ -719,14 +719,14 @@
+@@ -721,14 +721,14 @@
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr,
-@@ -772,7 +772,7 @@
+@@ -774,7 +774,7 @@
}
if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
fprintf(stderr,
"InnoDB: Error: tablespace id %lu"
" in file %s is not sensible\n",
-@@ -840,7 +840,7 @@
+@@ -842,7 +842,7 @@
system->n_open++;
/* Put the node to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
-@@ -873,7 +873,7 @@
+@@ -876,7 +876,7 @@
ut_a(system->n_open > 0);
system->n_open--;
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
/* The node is in the LRU list, remove it */
-@@ -959,7 +959,7 @@
+@@ -962,7 +962,7 @@
retry:
mutex_enter(&fil_system->mutex);
/* We keep log files and system tablespace files always open;
this is important in preventing deadlocks in this module, as
a page read completion often performs another read from the
-@@ -1190,7 +1190,7 @@
+@@ -1193,7 +1193,7 @@
" tablespace memory cache!\n",
(ulong) space->id);
mutex_exit(&fil_system->mutex);
-@@ -1252,6 +1252,7 @@
+@@ -1255,6 +1255,7 @@
space->mark = FALSE;
if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
&& UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
if (!fil_system->space_id_reuse_warned) {
fil_system->space_id_reuse_warned = TRUE;
-@@ -1335,7 +1336,7 @@
+@@ -1338,7 +1339,7 @@
(ulong) SRV_LOG_SPACE_FIRST_ID);
}
if (success) {
*space_id = fil_system->max_assigned_id = id;
-@@ -1598,6 +1599,8 @@
+@@ -1601,6 +1602,8 @@
UT_LIST_INIT(fil_system->LRU);
fil_system->max_n_open = max_n_open;
}
/*******************************************************************//**
-@@ -1619,7 +1622,7 @@
+@@ -1622,7 +1625,7 @@
space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
-@@ -1709,6 +1712,10 @@
+@@ -1712,6 +1715,10 @@
ut_error;
}
mutex_enter(&fil_system->mutex);
if (fil_system->max_assigned_id < max_id) {
-@@ -1727,6 +1734,7 @@
+@@ -1730,6 +1737,7 @@
ulint
fil_write_lsn_and_arch_no_to_file(
/*==============================*/
ulint sum_of_sizes, /*!< in: combined size of previous files
in space, in database pages */
ib_uint64_t lsn, /*!< in: lsn to write */
-@@ -1736,14 +1744,16 @@
+@@ -1739,14 +1747,16 @@
byte* buf1;
byte* buf;
mem_free(buf1);
-@@ -1779,7 +1789,7 @@
+@@ -1782,7 +1792,7 @@
always open. */
if (space->purpose == FIL_TABLESPACE
sum_of_sizes = 0;
node = UT_LIST_GET_FIRST(space->chain);
-@@ -1787,7 +1797,7 @@
+@@ -1790,7 +1800,7 @@
mutex_exit(&fil_system->mutex);
err = fil_write_lsn_and_arch_no_to_file(
if (err != DB_SUCCESS) {
return(err);
-@@ -3834,7 +3844,7 @@
+@@ -4176,7 +4186,7 @@
}
#ifndef UNIV_HOTBACKUP
fprintf(stderr,
"InnoDB: Error: tablespace id %lu in file %s"
" is not sensible\n",
-@@ -3843,7 +3853,7 @@
+@@ -4185,7 +4195,7 @@
goto func_exit;
}
#else
char* new_path;
fprintf(stderr,
-@@ -4664,7 +4674,7 @@
+@@ -5006,7 +5016,7 @@
}
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
/* The node is in the LRU list, remove it */
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-@@ -4710,7 +4720,7 @@
+@@ -5052,7 +5062,7 @@
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
/* The node must be put back to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
-@@ -5318,7 +5328,7 @@
+@@ -5663,7 +5673,7 @@
ut_a(fil_node->n_pending == 0);
ut_a(fil_node->open);
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
}
-diff -ruN a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
---- a/storage/innobase/fsp/fsp0fsp.c 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:35:58.632513243 +0900
+--- a/storage/innobase/fsp/fsp0fsp.c
++++ b/storage/innobase/fsp/fsp0fsp.c
@@ -48,7 +48,7 @@
# include "log0log.h"
#endif /* UNIV_HOTBACKUP */
-
+#include "trx0sys.h"
- #define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
- within a file page */
-@@ -999,10 +999,10 @@
+ /* FILE SEGMENT INODE
+ ==================
+@@ -938,10 +938,10 @@
flst_init(header + FSP_SEG_INODES_FREE, mtr);
mlog_write_ull(header + FSP_SEG_ID, 1, mtr);
dict_ind_redundant, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
-diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:35:29.153514047 +0900
-+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:35:58.636549909 +0900
+--- a/storage/innobase/handler/ha_innodb.cc
++++ b/storage/innobase/handler/ha_innodb.cc
@@ -163,6 +163,7 @@
static char* innobase_log_group_home_dir = NULL;
static char* innobase_file_format_name = NULL;
/* The highest file format being used in the database. The value can be
set by user, however, it will be adjusted to the newer file format if
-@@ -2445,6 +2446,8 @@
+@@ -2508,6 +2509,8 @@
goto error;
}
srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
/* -------------- Log files ---------------------------*/
-@@ -11610,6 +11613,11 @@
+@@ -11771,6 +11774,11 @@
"Path to individual files and their sizes.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The AUTOINC lock modes supported by InnoDB: "
-@@ -11782,6 +11790,7 @@
+@@ -11990,6 +11998,7 @@
MYSQL_SYSVAR(commit_concurrency),
MYSQL_SYSVAR(concurrency_tickets),
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
MYSQL_SYSVAR(recovery_stats),
-diff -ruN a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic
---- a/storage/innobase/include/mtr0log.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/mtr0log.ic 2010-12-04 15:35:58.644607059 +0900
+--- a/storage/innobase/include/mtr0log.ic
++++ b/storage/innobase/include/mtr0log.ic
@@ -27,8 +27,8 @@
#include "ut0lst.h"
#include "buf0buf.h"
&& offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
if (trx_doublewrite_buf_is_being_created) {
/* Do nothing: we only come to this branch in an
-diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
---- a/storage/innobase/include/srv0srv.h 2010-12-04 15:35:29.177480351 +0900
-+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:35:58.646556250 +0900
-@@ -132,6 +132,8 @@
+--- a/storage/innobase/include/srv0srv.h
++++ b/storage/innobase/include/srv0srv.h
+@@ -129,6 +129,8 @@
extern ulint* srv_data_file_sizes;
extern ulint* srv_data_file_is_raw_partition;
extern ibool srv_recovery_stats;
extern ibool srv_auto_extend_last_data_file;
-diff -ruN a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
---- a/storage/innobase/include/srv0start.h 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/srv0start.h 2010-12-08 17:15:07.602605797 +0900
+--- a/storage/innobase/include/srv0start.h
++++ b/storage/innobase/include/srv0start.h
@@ -127,4 +127,7 @@
/** Log 'spaces' have id's >= this */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
+#define SRV_EXTRA_SYS_SPACE_FIRST_ID 0xFFFFFFE0UL
+
#endif
-diff -ruN a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
---- a/storage/innobase/include/trx0sys.h 2010-12-03 15:41:52.047049291 +0900
-+++ b/storage/innobase/include/trx0sys.h 2010-12-04 15:35:58.647551222 +0900
-@@ -124,6 +124,22 @@
+--- a/storage/innobase/include/trx0sys.h
++++ b/storage/innobase/include/trx0sys.h
+@@ -125,6 +125,22 @@
/*=============*/
ulint space, /*!< in: space */
ulint page_no);/*!< in: page number */
/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
-@@ -137,6 +153,13 @@
+@@ -138,6 +154,13 @@
void
trx_sys_create(void);
/*================*/
/****************************************************************//**
Looks for a free slot for a rollback segment in the trx system file copy.
@return slot index or ULINT_UNDEFINED if not found */
-@@ -448,6 +471,8 @@
+@@ -453,6 +476,8 @@
/* Space id and page no where the trx system file copy resides */
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
#include "fsp0fsp.h"
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
-diff -ruN a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
---- a/storage/innobase/include/trx0sys.ic 2010-11-03 07:01:13.000000000 +0900
-+++ b/storage/innobase/include/trx0sys.ic 2010-12-04 15:35:58.649473284 +0900
+--- a/storage/innobase/include/trx0sys.ic
++++ b/storage/innobase/include/trx0sys.ic
@@ -71,6 +71,40 @@
}
Gets the pointer in the nth slot of the rseg array.
@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
-diff -ruN a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
---- a/storage/innobase/row/row0mysql.c 2010-12-03 17:30:16.334989510 +0900
-+++ b/storage/innobase/row/row0mysql.c 2010-12-04 15:35:58.652496484 +0900
-@@ -3423,7 +3423,7 @@
+--- a/storage/innobase/row/row0mysql.c
++++ b/storage/innobase/row/row0mysql.c
+@@ -3436,7 +3436,7 @@
/* Do not drop possible .ibd tablespace if something went
wrong: we do not want to delete valuable data of the user */
if (!fil_space_for_table_exists_in_mem(space_id,
name_or_path,
is_temp, FALSE,
-diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
---- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:35:29.180483212 +0900
-+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:35:58.656550107 +0900
-@@ -170,6 +170,8 @@
+--- a/storage/innobase/srv/srv0srv.c
++++ b/storage/innobase/srv/srv0srv.c
+@@ -163,6 +163,8 @@
/* size in database pages */
UNIV_INTERN ulint* srv_data_file_sizes = NULL;
UNIV_INTERN ibool srv_recovery_stats = FALSE;
/* if TRUE, then we auto-extend the last data file */
-diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
---- a/storage/innobase/srv/srv0start.c 2010-12-04 15:35:29.183481330 +0900
-+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:35:58.661550545 +0900
+--- a/storage/innobase/srv/srv0start.c
++++ b/storage/innobase/srv/srv0start.c
@@ -715,6 +715,7 @@
/*======================*/
ibool* create_new_db, /*!< out: TRUE if new database should be
#ifdef UNIV_LOG_ARCHIVE
ulint* min_arch_log_no,/*!< out: min of archived log
numbers in data files */
-@@ -747,6 +748,7 @@
+@@ -748,6 +749,7 @@
*sum_of_new_sizes = 0;
*create_new_db = FALSE;
srv_normalize_path_for_win(srv_data_home);
-@@ -984,6 +986,142 @@
+@@ -1004,6 +1006,142 @@
srv_data_file_is_raw_partition[i] != 0);
}
+ (ulong) TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9);
+ }
+
-+ fil_read_flushed_lsn_and_arch_log_no(
-+ files[i], one_opened,
++ fil_read_first_page(
++ files[i], one_opened, &flags,
+#ifdef UNIV_LOG_ARCHIVE
+ min_arch_log_no, max_arch_log_no,
+#endif /* UNIV_LOG_ARCHIVE */
return(DB_SUCCESS);
}
-@@ -997,6 +1135,7 @@
+@@ -1017,6 +1155,7 @@
/*====================================*/
{
ibool create_new_db;
ibool log_file_created;
ibool log_created = FALSE;
ibool log_opened = FALSE;
-@@ -1456,6 +1595,7 @@
+@@ -1482,6 +1621,7 @@
}
err = open_or_create_data_files(&create_new_db,
#ifdef UNIV_LOG_ARCHIVE
&min_arch_log_no, &max_arch_log_no,
#endif /* UNIV_LOG_ARCHIVE */
-@@ -1623,6 +1763,14 @@
+@@ -1649,6 +1789,14 @@
after the double write buffer has been created. */
trx_sys_create();
dict_create();
srv_startup_is_before_trx_rollback_phase = FALSE;
-@@ -1656,6 +1804,13 @@
+@@ -1682,6 +1830,13 @@
recv_recovery_from_archive_finish();
#endif /* UNIV_LOG_ARCHIVE */
} else {
/* Check if we support the max format that is stamped
on the system tablespace.
-@@ -1742,6 +1897,17 @@
+@@ -1768,6 +1923,17 @@
we have finished the recovery process so that the
image of TRX_SYS_PAGE_NO is not stale. */
trx_sys_file_format_tag_init();
}
if (!create_new_db && sum_of_new_sizes > 0) {
-diff -ruN a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
---- a/storage/innobase/trx/trx0sys.c 2010-12-03 17:32:15.651024019 +0900
-+++ b/storage/innobase/trx/trx0sys.c 2010-12-04 15:35:58.664550291 +0900
-@@ -414,6 +414,152 @@
+--- a/storage/innobase/trx/trx0sys.c
++++ b/storage/innobase/trx/trx0sys.c
+@@ -415,6 +415,152 @@
goto start_again;
}
}
/****************************************************************//**
-@@ -437,10 +583,19 @@
+@@ -438,10 +584,19 @@
ulint source_page_no;
byte* page;
byte* doublewrite;
/* We do the file i/o past the buffer pool */
unaligned_read_buf = ut_malloc(2 * UNIV_PAGE_SIZE);
-@@ -449,7 +604,7 @@
+@@ -450,7 +605,7 @@
/* Read the trx sys header to check if we are using the doublewrite
buffer */
UNIV_PAGE_SIZE, read_buf, NULL);
doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
-@@ -487,10 +642,10 @@
+@@ -488,10 +643,10 @@
/* Read the pages from the doublewrite buffer to memory */
TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
NULL);
-@@ -546,7 +701,8 @@
+@@ -547,7 +702,8 @@
" doublewrite buf.\n",
(ulong) space_id, (ulong) page_no, (ulong) i);
&& ((page_no >= block1
&& page_no
< block1 + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
-@@ -990,6 +1146,83 @@
+@@ -1016,6 +1172,83 @@
}
/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
UNIV_INTERN
-@@ -1351,6 +1584,26 @@
+@@ -1387,6 +1620,26 @@
/* Does nothing at the moment */
}
/*********************************************************************
Creates the rollback segments */
UNIV_INTERN
+--- /dev/null
++++ b/mysql-test/r/percona_innodb_doublewrite_file.result
+@@ -0,0 +1,4 @@
++show variables like 'innodb_doublewrite%';
++Variable_name Value
++innodb_doublewrite ON
++innodb_doublewrite_file ib_doublewrite
+--- /dev/null
++++ b/mysql-test/t/percona_innodb_doublewrite_file-master.opt
+@@ -0,0 +1 @@
++--innodb_doublewrite_file=ib_doublewrite
+--- /dev/null
++++ b/mysql-test/t/percona_innodb_doublewrite_file.test
+@@ -0,0 +1,2 @@
++--source include/have_innodb.inc
++show variables like 'innodb_doublewrite%';