summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <tsmith@ramayana.hindu.god>2007-08-15 17:20:54 -0600
committerunknown <tsmith@ramayana.hindu.god>2007-08-15 17:20:54 -0600
commit05dd9e4987bd2ad93a40f14ace4351291308bd5a (patch)
treecec562a0c69f21f9a3f99e535eddafc7c5dfd1fd /innobase
parent0739c70ecd779373b98920341802abc8db86d893 (diff)
downloadmariadb-git-05dd9e4987bd2ad93a40f14ace4351291308bd5a.tar.gz
NULL MERGE this ChangeSet to 5.1
Apply innodb-5.0-ss1696 snapshot Fixes: - Bug#20090: InnoDB: Error: trying to declare trx to enter InnoDB - Bug#23710: crash_commit_before fails if innodb_file_per_table=1 At InnoDB startup consider the case where log scan went beyond checkpoint_lsn as a crash and initiate crash recovery code path. - Bug#28781: InnoDB increments auto-increment value incorrectly with ON DUPLICATE KEY UPDATE We need to do some special AUTOINC handling for the following case: INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ... We need to use the AUTOINC counter that was actually used by MySQL in the UPDATE statement, which can be different from the value used in the INSERT statement. - Bug#29097: fsp_get_available_space_in_free_extents() is capped at 4TB Fix by typecasting the variables before multiplying them, so that the result of the multiplication is of type "unsigned long long". - Bug#29155: Innodb "Parallel recovery" is not prevented Fix by enabling file locking on FreeBSD. It has been disabled because InnoDB has refused to start on FreeBSD & LinuxThreads, but now it starts just fine. innobase/fsp/fsp0fsp.c: Apply innodb-5.0-ss1696 snapshot Revision r1614: branches/5.0: Merge r1605 from trunk: Fix Bug#29097 "fsp_get_available_space_in_free_extents() is capped at 4TB" by typecasting the variables before multiplying them, so that the result of the multiplication is of type "unsigned long long". I verified this fix by creating a sparse file of 6TB and forcing InnoDB to use it without overwriting it with zeroes (by commenting the code that overwrites :newraw files). New type ullint is introduced with the sole purpose of shortening "unsigned long long", please do not define it to something else than "unsigned long long". Approved by: Heikki innobase/include/fsp0fsp.h: Apply innodb-5.0-ss1696 snapshot Revision r1614: branches/5.0: Merge r1605 from trunk: Fix Bug#29097 "fsp_get_available_space_in_free_extents() is capped at 4TB" by typecasting the variables before multiplying them, so that the result of the multiplication is of type "unsigned long long". I verified this fix by creating a sparse file of 6TB and forcing InnoDB to use it without overwriting it with zeroes (by commenting the code that overwrites :newraw files). New type ullint is introduced with the sole purpose of shortening "unsigned long long", please do not define it to something else than "unsigned long long". Approved by: Heikki innobase/include/univ.i: Apply innodb-5.0-ss1696 snapshot Revision r1614: branches/5.0: Merge r1605 from trunk: Fix Bug#29097 "fsp_get_available_space_in_free_extents() is capped at 4TB" by typecasting the variables before multiplying them, so that the result of the multiplication is of type "unsigned long long". I verified this fix by creating a sparse file of 6TB and forcing InnoDB to use it without overwriting it with zeroes (by commenting the code that overwrites :newraw files). New type ullint is introduced with the sole purpose of shortening "unsigned long long", please do not define it to something else than "unsigned long long". Approved by: Heikki innobase/log/log0recv.c: Apply innodb-5.0-ss1696 snapshot Revision r1608: branches/5.0: Bug#23710 Back port of r1607 from trunk At InnoDB startup consider the case where log scan went beyond checkpoint_lsn as a crash and initiate crash recovery code path. reviewed by: Heikki innobase/os/os0file.c: Apply innodb-5.0-ss1696 snapshot Revision r1615: branches/5.0: Merge r1613 from trunk: Fix Bug#29155 by enabling file locking on FreeBSD. It has been disabled because InnoDB has refused to start on FreeBSD & LinuxThreads, but now it starts just fine. Approved by: Heikki innobase/srv/srv0srv.c: Apply innodb-5.0-ss1696 snapshot Revision r1552: branches/5.0: Fix Bug#20090 as suggested in the bug followup by Heikki. Approved by: Heikki innobase/trx/trx0trx.c: Apply innodb-5.0-ss1696 snapshot Revision r1596: branches/5.0: Merge r1595 from trunk: trx_commit_for_mysql(): Avoid acquiring and releasing kernel_mutex when trx->sess or trx_dummy_sess is non-NULL. sql/ha_innodb.cc: Apply innodb-5.0-ss1696 snapshot Revision r1614: branches/5.0: Merge r1605 from trunk: Fix Bug#29097 "fsp_get_available_space_in_free_extents() is capped at 4TB" by typecasting the variables before multiplying them, so that the result of the multiplication is of type "unsigned long long". I verified this fix by creating a sparse file of 6TB and forcing InnoDB to use it without overwriting it with zeroes (by commenting the code that overwrites :newraw files). New type ullint is introduced with the sole purpose of shortening "unsigned long long", please do not define it to something else than "unsigned long long". Approved by: Heikki Revision r1695: branches/5.0: Merge a change from MySQL AB: ChangeSet@1.2463.166.1 2007-06-20 19:22:27+03:00 monty@mysql.fi Allow multiple calls to mysql_server_end() (Part of fix for Bug 25621 Error in my_thread_global_end(): 1 threads didn't exit) Give correct error message if InnoDB table is not found (This allows us to drop a an innodb table that is not in the InnoDB registery) ha_innodb.cc: Give correct error message if InnoDB table is not found. (This allows us to drop a an innodb table that is not in the InnoDB registery) Revision r1606: branches/5.0: Formatting corrections. spotted by: Vasil Revision r1691: branches/5.0: Merge a change from MySQL AB: ChangeSet@1.2463.261.1 2007-07-20 14:17:15+03:00 gkodinov@magare.gmz Bug 29644: alter table hangs if records locked in share mode by long running transaction On Windows opened files can't be deleted. There was a special upgraded lock mode (TL_WRITE instead of TL_WRITE_ALLOW_READ) in ALTER TABLE to make sure nobody has the table opened when deleting the old table in ALTER TABLE. This special mode was causing ALTER TABLE to hang waiting on a lock inside InnoDB. This special lock is no longer necessary as the server is closing the tables it needs to delete in ALTER TABLE. Fixed by removing the special lock. Note that this also reverses the fix for bug 17264 that deals with another consequence of this special lock mode being used. sql/ha_innodb.cc: Bug 29644: reverse the (now excessive) fix for bug 17264 (but leave the test case). Revision r1601: branches/5.0: Fix for bug#28781 We need to do some special AUTOINC handling for the following case: INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ... We need to use the AUTOINC counter that was actually used by MySQL in the UPDATE statement, which can be different from the value used in the INSERT statement. approved by: Sunny Revision r1692: branches/5.0: Merge a change from MySQL AB: ChangeSet@1.2463.267.1 2007-07-30 17:14:34+04:00 evgen@local Bug 24989: The DEADLOCK error is improperly handled by InnoDB. When innodb detects a deadlock it calls ha_rollback_trans() to rollback the main transaction. But such action isn't allowed from inside of triggers and functions. When it happen the 'Explicit or implicit commit' error is thrown even if there is no commit/rollback statements in the trigger/function. This leads to the user confusion. Now the convert_error_code_to_mysql() function doesn't call the ha_rollback_trans() function directly but rather calls the mark_transaction_to_rollback function and returns an error. The sp_rcontext::find_handler() now doesn't allow errors to be caught by the trigger/function error handlers when the thd->is_fatal_sub_stmt_error flag is set. Procedures are still allowed to catch such errors. The sp_rcontext::find_handler function now accepts a THD handle as a parameter. The transaction_rollback_request and the is_fatal_sub_stmt_error flags are added to the THD class. The are initialized by the THD class constructor. Now the ha_autocommit_or_rollback function rolls back main transaction when not in a sub statement and the thd->transaction_rollback_request is set. The THD::restore_sub_statement_state function now resets the thd->is_fatal_sub_stmt_error flag on exit from a sub-statement. innodb-big.test, innodb-big.result: Added a test case for the bug 24989: The DEADLOCK error is improperly handled by InnoDB. sql/ha_innodb.cc: Bug 24989: The DEADLOCK error is improperly handled by InnoDB. Now the convert_error_code_to_mysql() function doesn't call the ha_rollback_trans() function directly but rather calls the mark_transaction_to_rollback function and returns an error. Revision r1693: branches/5.0: Merge a change from MySQL AB: ChangeSet@1.2489.5.1 2007-07-31 17:42:48+04:00 evgen@local ha_innodb.cc: Warning fixed.
Diffstat (limited to 'innobase')
-rw-r--r--innobase/fsp/fsp0fsp.c7
-rw-r--r--innobase/include/fsp0fsp.h2
-rw-r--r--innobase/include/univ.i2
-rw-r--r--innobase/log/log0recv.c225
-rw-r--r--innobase/os/os0file.c3
-rw-r--r--innobase/srv/srv0srv.c2
-rw-r--r--innobase/trx/trx0trx.c12
7 files changed, 164 insertions, 89 deletions
diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c
index 333894d2312..c71bb6ed827 100644
--- a/innobase/fsp/fsp0fsp.c
+++ b/innobase/fsp/fsp0fsp.c
@@ -2806,7 +2806,7 @@ will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
the safety margin required by the above function fsp_reserve_free_extents. */
-ulint
+ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
/* out: available space in kB */
@@ -2872,8 +2872,9 @@ fsp_get_available_space_in_free_extents(
return(0);
}
- return(((n_free - reserve) * FSP_EXTENT_SIZE)
- * (UNIV_PAGE_SIZE / 1024));
+ return((ullint)(n_free - reserve)
+ * FSP_EXTENT_SIZE
+ * (UNIV_PAGE_SIZE / 1024));
}
/************************************************************************
diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h
index 2fcde882df7..57f0ae6f65b 100644
--- a/innobase/include/fsp0fsp.h
+++ b/innobase/include/fsp0fsp.h
@@ -245,7 +245,7 @@ will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
the safety margin required by the above function fsp_reserve_free_extents. */
-ulint
+ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
/* out: available space in kB */
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index 64a240ae8a7..88cef65afeb 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -195,6 +195,8 @@ typedef __int64 ib_longlong;
typedef longlong ib_longlong;
#endif
+typedef unsigned long long int ullint;
+
#ifndef __WIN__
#if SIZEOF_LONG != SIZEOF_VOIDP
#error "Error: InnoDB's ulint must be of the same size as void*"
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index c1ceb9791f2..5fd5ab863df 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -57,6 +57,16 @@ ibool recv_needed_recovery = FALSE;
ibool recv_lsn_checks_on = FALSE;
+/* There are two conditions under which we scan the logs, the first
+is normal startup and the second is when we do a recovery from an
+archive.
+This flag is set if we are doing a scan from the last checkpoint during
+startup. If we find log entries that were written after the last checkpoint
+we know that the server was not cleanly shutdown. We must then initialize
+the crash recovery environment before attempting to store these entries in
+the log hash table. */
+ibool recv_log_scan_is_startup_type = FALSE;
+
/* If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
the log record hash table becomes too full, and log records must be merged
@@ -99,6 +109,16 @@ the recovery failed and the database may be corrupt. */
dulint recv_max_page_lsn;
+/* prototypes */
+
+/***********************************************************
+Initialize crash recovery environment. Can be called iff
+recv_needed_recovery == FALSE. */
+static
+void
+recv_init_crash_recovery(void);
+/*===========================*/
+
/************************************************************
Creates the recovery system. */
@@ -2438,6 +2458,23 @@ recv_scan_log_recs(
if (ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) > 0) {
+ /* We have found more entries. If this scan is
+ of startup type, we must initiate crash recovery
+ environment before parsing these log records. */
+
+ if (recv_log_scan_is_startup_type
+ && !recv_needed_recovery) {
+
+ fprintf(stderr,
+ "InnoDB: Log scan progressed"
+ " past the checkpoint lsn %lu %lu\n",
+ (ulong) ut_dulint_get_high(
+ recv_sys->scanned_lsn),
+ (ulong) ut_dulint_get_low(
+ recv_sys->scanned_lsn));
+ recv_init_crash_recovery();
+ }
+
/* We were able to find more log data: add it to the
parsing buffer if parse_start_lsn is already
non-zero */
@@ -2557,6 +2594,48 @@ recv_group_scan_log_recs(
#endif /* UNIV_DEBUG */
}
+/***********************************************************
+Initialize crash recovery environment. Can be called iff
+recv_needed_recovery == FALSE. */
+static
+void
+recv_init_crash_recovery(void)
+/*==========================*/
+{
+ ut_a(!recv_needed_recovery);
+
+ recv_needed_recovery = TRUE;
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+ " InnoDB: Database was not"
+ " shut down normally!\n"
+ "InnoDB: Starting crash recovery.\n");
+
+ fprintf(stderr,
+ "InnoDB: Reading tablespace information"
+ " from the .ibd files...\n");
+
+ fil_load_single_table_tablespaces();
+
+ /* If we are using the doublewrite method, we will
+ check if there are half-written pages in data files,
+ and restore them from the doublewrite buffer if
+ possible */
+
+ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
+
+ fprintf(stderr,
+ "InnoDB: Restoring possible"
+ " half-written data pages from"
+ " the doublewrite\n"
+ "InnoDB: buffer...\n");
+ trx_sys_doublewrite_init_or_restore_pages(TRUE);
+ }
+
+}
+
/************************************************************
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
@@ -2681,72 +2760,6 @@ recv_recovery_from_checkpoint_start(
recv_sys->recovered_lsn = checkpoint_lsn;
srv_start_lsn = checkpoint_lsn;
-
- /* NOTE: we always do a 'recovery' at startup, but only if
- there is something wrong we will print a message to the
- user about recovery: */
-
- if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0
- || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) {
-
- if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn)
- < 0) {
- fprintf(stderr,
-"InnoDB: ##########################################################\n"
-"InnoDB: WARNING!\n"
-"InnoDB: The log sequence number in ibdata files is higher\n"
-"InnoDB: than the log sequence number in the ib_logfiles! Are you sure\n"
-"InnoDB: you are using the right ib_logfiles to start up the database?\n"
-"InnoDB: Log sequence number in ib_logfiles is %lu %lu, log\n"
-"InnoDB: sequence numbers stamped to ibdata file headers are between\n"
-"InnoDB: %lu %lu and %lu %lu.\n"
-"InnoDB: ##########################################################\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn),
- (ulong) ut_dulint_get_high(min_flushed_lsn),
- (ulong) ut_dulint_get_low(min_flushed_lsn),
- (ulong) ut_dulint_get_high(max_flushed_lsn),
- (ulong) ut_dulint_get_low(max_flushed_lsn));
- }
-
- recv_needed_recovery = TRUE;
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
-" InnoDB: Database was not shut down normally!\n"
-"InnoDB: Starting crash recovery.\n");
-
- fprintf(stderr,
-"InnoDB: Reading tablespace information from the .ibd files...\n");
-
- fil_load_single_table_tablespaces();
-
- /* If we are using the doublewrite method, we will
- check if there are half-written pages in data files,
- and restore them from the doublewrite buffer if
- possible */
-
- if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
-
- fprintf(stderr,
-"InnoDB: Restoring possible half-written data pages from the doublewrite\n"
-"InnoDB: buffer...\n");
- trx_sys_doublewrite_init_or_restore_pages(
- TRUE);
- }
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
-" InnoDB: Starting log scan based on checkpoint at\n"
-"InnoDB: log sequence number %lu %lu.\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn));
- } else {
- /* Init the doublewrite buffer memory structure */
- trx_sys_doublewrite_init_or_restore_pages(FALSE);
- }
}
contiguous_lsn = ut_dulint_align_down(recv_sys->scanned_lsn,
@@ -2798,7 +2811,9 @@ recv_recovery_from_checkpoint_start(
group = UT_LIST_GET_NEXT(log_groups, group);
}
- while (group) {
+ /* Set the flag to publish that we are doing startup scan. */
+ recv_log_scan_is_startup_type = (type == LOG_CHECKPOINT);
+ while (group) {
old_scanned_lsn = recv_sys->scanned_lsn;
recv_group_scan_log_recs(group, &contiguous_lsn,
@@ -2819,6 +2834,69 @@ recv_recovery_from_checkpoint_start(
group = UT_LIST_GET_NEXT(log_groups, group);
}
+ /* Done with startup scan. Clear the flag. */
+ recv_log_scan_is_startup_type = FALSE;
+ if (type == LOG_CHECKPOINT) {
+ /* NOTE: we always do a 'recovery' at startup, but only if
+ there is something wrong we will print a message to the
+ user about recovery: */
+
+ if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0
+ || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) {
+
+ if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn)
+ < 0) {
+ fprintf(stderr,
+ "InnoDB: #########################"
+ "#################################\n"
+ "InnoDB: "
+ "WARNING!\n"
+ "InnoDB: The log sequence number"
+ " in ibdata files is higher\n"
+ "InnoDB: than the log sequence number"
+ " in the ib_logfiles! Are you sure\n"
+ "InnoDB: you are using the right"
+ " ib_logfiles to start up"
+ " the database?\n"
+ "InnoDB: Log sequence number in"
+ " ib_logfiles is %lu %lu, log\n"
+ "InnoDB: sequence numbers stamped"
+ " to ibdata file headers are between\n"
+ "InnoDB: %lu %lu and %lu %lu.\n"
+ "InnoDB: #########################"
+ "#################################\n",
+ (ulong) ut_dulint_get_high(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_low(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_high(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_high(
+ max_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ max_flushed_lsn));
+
+
+ }
+
+ if (!recv_needed_recovery) {
+ fprintf(stderr,
+ "InnoDB: The log sequence number"
+ " in ibdata files does not match\n"
+ "InnoDB: the log sequence number"
+ " in the ib_logfiles!\n");
+ recv_init_crash_recovery();
+ }
+
+ }
+ if (!recv_needed_recovery) {
+ /* Init the doublewrite buffer memory structure */
+ trx_sys_doublewrite_init_or_restore_pages(FALSE);
+ }
+ }
+
/* We currently have only one log group */
if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) {
ut_print_timestamp(stderr);
@@ -2871,16 +2949,9 @@ recv_recovery_from_checkpoint_start(
recv_synchronize_groups(up_to_date_group);
if (!recv_needed_recovery) {
- if (ut_dulint_cmp(checkpoint_lsn, recv_sys->recovered_lsn)
- != 0) {
- fprintf(stderr,
-"InnoDB: Warning: we did not need to do crash recovery, but log scan\n"
-"InnoDB: progressed past the checkpoint lsn %lu %lu up to lsn %lu %lu\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn),
- (ulong) ut_dulint_get_high(recv_sys->recovered_lsn),
- (ulong) ut_dulint_get_low(recv_sys->recovered_lsn));
- }
+ ut_a(ut_dulint_cmp(checkpoint_lsn,
+ recv_sys->recovered_lsn) == 0);
+
} else {
srv_start_lsn = recv_sys->recovered_lsn;
}
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 3030b20a685..8b1fbd742d5 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -436,10 +436,9 @@ os_file_handle_error_no_exit(
#undef USE_FILE_LOCK
#define USE_FILE_LOCK
-#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__) || defined(__NETWARE__)
+#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__NETWARE__)
/* InnoDB Hot Backup does not lock the data files.
* On Windows, mandatory locking is used.
- * On FreeBSD with LinuxThreads, advisory locking does not work properly.
*/
# undef USE_FILE_LOCK
#endif
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index e4ce29f445c..31cd202e4d2 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -1151,7 +1151,7 @@ srv_conc_force_enter_innodb(
srv_conc_n_threads++;
trx->declared_to_be_inside_innodb = TRUE;
- trx->n_tickets_to_enter_innodb = 0;
+ trx->n_tickets_to_enter_innodb = 1;
os_fast_mutex_unlock(&srv_conc_mutex);
}
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 4dc826e5947..d865c709bf6 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -1606,19 +1606,21 @@ trx_commit_for_mysql(
the transaction object does not have an InnoDB session object, and we
set the dummy session that we use for all MySQL transactions. */
- mutex_enter(&kernel_mutex);
-
if (trx->sess == NULL) {
/* Open a dummy session */
if (!trx_dummy_sess) {
- trx_dummy_sess = sess_open();
+ mutex_enter(&kernel_mutex);
+
+ if (!trx_dummy_sess) {
+ trx_dummy_sess = sess_open();
+ }
+
+ mutex_exit(&kernel_mutex);
}
trx->sess = trx_dummy_sess;
}
-
- mutex_exit(&kernel_mutex);
trx_start_if_not_started(trx);