Commit 69dbdde1 authored by unknown's avatar unknown

Many files:

  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation


innobase/buf/buf0buf.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/dict/dict0crea.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/dict/dict0dict.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/fil/fil0fil.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/fsp/fsp0fsp.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/fil0fil.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/fsp0fsp.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/log0recv.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/mtr0log.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/mtr0mtr.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/os0file.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/ut0dbg.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/ut0ut.h:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/ha0ha.ic:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/include/mtr0log.ic:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/log/log0log.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/log/log0recv.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/mem/mem0pool.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/os/os0file.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/pars/lexyy.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/row/row0mysql.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/row/row0sel.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/srv/srv0srv.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/srv/srv0start.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/ut/ut0rnd.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
innobase/ut/ut0ut.c:
  Merge with ibbackup; bug fix: .ibd files were extended 2 x the required amount; InnoDB does not create the small file inno_arch_log... any more at database creation
parent 32c22ce2
...@@ -297,8 +297,9 @@ buf_page_is_corrupted( ...@@ -297,8 +297,9 @@ buf_page_is_corrupted(
ulint old_checksum; ulint old_checksum;
ulint checksum_field; ulint checksum_field;
ulint old_checksum_field; ulint old_checksum_field;
#ifndef UNIV_HOTBACKUP
dulint current_lsn; dulint current_lsn;
#endif
if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
!= mach_read_from_4(read_buf + UNIV_PAGE_SIZE != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
......
...@@ -302,8 +302,11 @@ dict_build_table_def_step( ...@@ -302,8 +302,11 @@ dict_build_table_def_step(
- page 3 will contain the root of the clustered index of the - page 3 will contain the root of the clustered index of the
table we create here. */ table we create here. */
table->space = 0; /* reset to zero for the call below */
error = fil_create_new_single_table_tablespace( error = fil_create_new_single_table_tablespace(
&(table->space), table->name, 4); &(table->space), table->name,
FIL_IBD_FILE_INITIAL_SIZE);
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
return(error); return(error);
...@@ -311,7 +314,7 @@ dict_build_table_def_step( ...@@ -311,7 +314,7 @@ dict_build_table_def_step(
mtr_start(&mtr); mtr_start(&mtr);
fsp_header_init(table->space, 4, &mtr); fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
} }
......
...@@ -2580,7 +2580,7 @@ dict_create_foreign_constraints_low( ...@@ -2580,7 +2580,7 @@ dict_create_foreign_constraints_low(
sprintf(buf + strlen(buf), sprintf(buf + strlen(buf),
" Error in foreign key constraint of table %.500s.\n" " Error in foreign key constraint of table %.500s.\n"
"Cannot find the table from the internal data dictionary of InnoDB.\n" "Cannot find the table from the internal data dictionary of InnoDB.\n"
"Create table statement:\n%.2000\n", name, sql_string); "Create table statement:\n%.2000s\n", name, sql_string);
ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN); ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
......
This diff is collapsed.
...@@ -27,6 +27,10 @@ Created 11/29/1995 Heikki Tuuri ...@@ -27,6 +27,10 @@ Created 11/29/1995 Heikki Tuuri
#include "dict0mem.h" #include "dict0mem.h"
#include "log0log.h" #include "log0log.h"
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
within a file page */
/* The data structures in files are defined just as byte strings in C */ /* The data structures in files are defined just as byte strings in C */
typedef byte fsp_header_t; typedef byte fsp_header_t;
typedef byte xdes_t; typedef byte xdes_t;
...@@ -38,8 +42,6 @@ File space header data structure: this data structure is contained in the ...@@ -38,8 +42,6 @@ File space header data structure: this data structure is contained in the
first page of a space. The space for this header is reserved in every extent first page of a space. The space for this header is reserved in every extent
descriptor page, but used only in the first. */ descriptor page, but used only in the first. */
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
within a file page */
/*-------------------------------------*/ /*-------------------------------------*/
#define FSP_SPACE_ID 0 /* space id */ #define FSP_SPACE_ID 0 /* space id */
#define FSP_NOT_USED 4 /* this field contained a value up to #define FSP_NOT_USED 4 /* this field contained a value up to
...@@ -91,7 +93,6 @@ descriptor page, but used only in the first. */ ...@@ -91,7 +93,6 @@ descriptor page, but used only in the first. */
to the free list from above to the free list from above
FSP_FREE_LIMIT at a time */ FSP_FREE_LIMIT at a time */
/* FILE SEGMENT INODE /* FILE SEGMENT INODE
================== ==================
...@@ -298,6 +299,19 @@ fseg_alloc_free_page_low( ...@@ -298,6 +299,19 @@ fseg_alloc_free_page_low(
FSP_UP, FSP_NO_DIR */ FSP_UP, FSP_NO_DIR */
mtr_t* mtr); /* in: mtr handle */ mtr_t* mtr); /* in: mtr handle */
/**************************************************************************
Reads the file space size stored in the header page. */
ulint
fsp_get_size_low(
/*=============*/
/* out: tablespace size stored in the space header */
page_t* page) /* in: header page (page 0 in the tablespace) */
{
return(mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SIZE));
}
/************************************************************************** /**************************************************************************
Gets a pointer to the space header and x-locks its page. */ Gets a pointer to the space header and x-locks its page. */
UNIV_INLINE UNIV_INLINE
...@@ -1034,8 +1048,9 @@ fsp_try_extend_data_file_with_pages( ...@@ -1034,8 +1048,9 @@ fsp_try_extend_data_file_with_pages(
fsp_header_t* header, /* in: space header */ fsp_header_t* header, /* in: space header */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
ulint size;
ibool success; ibool success;
ulint actual_size;
ulint size;
ut_a(space != 0); ut_a(space != 0);
...@@ -1043,12 +1058,12 @@ fsp_try_extend_data_file_with_pages( ...@@ -1043,12 +1058,12 @@ fsp_try_extend_data_file_with_pages(
ut_a(page_no >= size); ut_a(page_no >= size);
success = fil_extend_data_file_with_pages(space, size, page_no + 1); success = fil_extend_space_to_desired_size(&actual_size, space,
page_no + 1);
/* actual_size now has the space size in pages; it may be less than
we wanted if we ran out of disk space */
if (success) { mlog_write_ulint(header + FSP_SIZE, actual_size, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_SIZE, page_no + 1, MLOG_4BYTES,
mtr);
}
return(success); return(success);
} }
...@@ -1060,13 +1075,20 @@ ibool ...@@ -1060,13 +1075,20 @@ ibool
fsp_try_extend_data_file( fsp_try_extend_data_file(
/*=====================*/ /*=====================*/
/* out: FALSE if not auto-extending */ /* out: FALSE if not auto-extending */
ulint* actual_increase,/* out: actual increase in pages */ ulint* actual_increase,/* out: actual increase in pages, where
we measure the tablespace size from
what the header field says; it may be
the actual file size rounded down to
megabyte */
ulint space, /* in: space */ ulint space, /* in: space */
fsp_header_t* header, /* in: space header */ fsp_header_t* header, /* in: space header */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
ulint size; ulint size;
ulint new_size;
ulint old_size;
ulint size_increase; ulint size_increase;
ulint actual_size;
ibool success; ibool success;
*actual_increase = 0; *actual_increase = 0;
...@@ -1078,6 +1100,8 @@ fsp_try_extend_data_file( ...@@ -1078,6 +1100,8 @@ fsp_try_extend_data_file(
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
old_size = size;
if (space == 0 && srv_last_file_size_max != 0) { if (space == 0 && srv_last_file_size_max != 0) {
if (srv_last_file_size_max if (srv_last_file_size_max
< srv_data_file_sizes[srv_n_data_files - 1]) { < srv_data_file_sizes[srv_n_data_files - 1]) {
...@@ -1107,8 +1131,12 @@ fsp_try_extend_data_file( ...@@ -1107,8 +1131,12 @@ fsp_try_extend_data_file(
success = fsp_try_extend_data_file_with_pages( success = fsp_try_extend_data_file_with_pages(
space, FSP_EXTENT_SIZE - 1, space, FSP_EXTENT_SIZE - 1,
header, mtr); header, mtr);
if (!success) { if (!success) {
new_size = mtr_read_ulint(
header + FSP_SIZE, MLOG_4BYTES, mtr);
*actual_increase = new_size - old_size;
return(FALSE); return(FALSE);
} }
...@@ -1118,7 +1146,10 @@ fsp_try_extend_data_file( ...@@ -1118,7 +1146,10 @@ fsp_try_extend_data_file(
if (size < 32 * FSP_EXTENT_SIZE) { if (size < 32 * FSP_EXTENT_SIZE) {
size_increase = FSP_EXTENT_SIZE; size_increase = FSP_EXTENT_SIZE;
} else { } else {
size_increase = 8 * FSP_EXTENT_SIZE; /* Below in fsp_fill_free_list() we assume
that we add at most FSP_FREE_ADD extents at
a time */
size_increase = FSP_FREE_ADD * FSP_EXTENT_SIZE;
} }
} }
} }
...@@ -1128,18 +1159,17 @@ fsp_try_extend_data_file( ...@@ -1128,18 +1159,17 @@ fsp_try_extend_data_file(
return(TRUE); return(TRUE);
} }
/* Extend the data file. If we are not able to extend the full success = fil_extend_space_to_desired_size(&actual_size, space,
requested length, the function tells how many pages we were able to size + size_increase);
extend so that the size of the tablespace would be divisible by 1 MB /* We ignore any fragments of a full megabyte when storing the size
(we possibly managed to extend more, but we only take into account to the space header */
full megabytes). */
success = fil_extend_last_data_file(actual_increase, space, size, mlog_write_ulint(header + FSP_SIZE,
size_increase); ut_calc_align_down(actual_size, (1024 * 1024) / UNIV_PAGE_SIZE),
if (success) {
mlog_write_ulint(header + FSP_SIZE, size + *actual_increase,
MLOG_4BYTES, mtr); MLOG_4BYTES, mtr);
} new_size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
*actual_increase = new_size - old_size;
return(TRUE); return(TRUE);
} }
...@@ -1186,8 +1216,10 @@ fsp_fill_free_list( ...@@ -1186,8 +1216,10 @@ fsp_fill_free_list(
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
} }
if (space != 0 && !init_space) { if (space != 0 && !init_space
/* Try to increase the data file size */ && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
/* Try to increase the .ibd file size */
fsp_try_extend_data_file(&actual_increase, space, header, mtr); fsp_try_extend_data_file(&actual_increase, space, header, mtr);
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
} }
...@@ -1222,7 +1254,7 @@ fsp_fill_free_list( ...@@ -1222,7 +1254,7 @@ fsp_fill_free_list(
fsp_init_file_page(descr_page, mtr); fsp_init_file_page(descr_page, mtr);
} }
/* Initialize the ibuf page in a separate /* Initialize the ibuf bitmap page in a separate
mini-transaction because it is low in the latching mini-transaction because it is low in the latching
order, and we must be able to release its latch order, and we must be able to release its latch
before returning from the fsp routine */ before returning from the fsp routine */
...@@ -3157,7 +3189,7 @@ fseg_free_step( ...@@ -3157,7 +3189,7 @@ fseg_free_step(
freed yet */ freed yet */
ut_a(descr); ut_a(descr);
ut_anp(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header) ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
% FSP_EXTENT_SIZE, mtr) == FALSE); % FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_get(header, mtr); inode = fseg_inode_get(header, mtr);
......
...@@ -16,6 +16,14 @@ Created 10/25/1995 Heikki Tuuri ...@@ -16,6 +16,14 @@ Created 10/25/1995 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include "os0file.h" #include "os0file.h"
/* When mysqld is run, the default directory "." is the mysqld datadir, but in
ibbackup we must set it explicitly; the patgh must NOT contain the trailing
'/' or '\' */
extern char* fil_path_to_mysql_datadir;
/* Initial size of a single-table tablespace in pages */
#define FIL_IBD_FILE_INITIAL_SIZE 4
/* 'null' (undefined) page offset in the context of file spaces */ /* 'null' (undefined) page offset in the context of file spaces */
#define FIL_NULL ULINT32_UNDEFINED #define FIL_NULL ULINT32_UNDEFINED
...@@ -261,6 +269,35 @@ fil_decr_pending_ibuf_merges( ...@@ -261,6 +269,35 @@ fil_decr_pending_ibuf_merges(
/*========================*/ /*========================*/
ulint id); /* in: space id */ ulint id); /* in: space id */
/*********************************************************************** /***********************************************************************
Parses the body of a log record written about an .ibd file operation. That is,
the log record part after the standard (type, space id, page no) header of the
log record.
If desired, also replays the delete or rename operation if the .ibd file
exists and the space id in it matches. Replays the create operation if a file
at that path does not exist yet. If the database directory for the file to be
created does not exist, then we create the directory, too.
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
datadir that we should use in replaying the file operations. */
byte*
fil_op_log_parse_or_replay(
/*=======================*/
/* out: end of log record, or NULL if the
record was not completely contained between
ptr and end_ptr */
byte* ptr, /* in: buffer containing the log record body,
or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
ibool do_replay, /* in: TRUE if we want to replay the
operation, and not just parse the log record */
ulint space_id); /* in: if do_replay is TRUE, the space id of
the tablespace in question; otherwise
ignored */
/***********************************************************************
Deletes a single-table tablespace. The tablespace must be cached in the Deletes a single-table tablespace. The tablespace must be cached in the
memory cache. */ memory cache. */
...@@ -306,16 +343,18 @@ ulint ...@@ -306,16 +343,18 @@ ulint
fil_create_new_single_table_tablespace( fil_create_new_single_table_tablespace(
/*===================================*/ /*===================================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
ulint* space_id, /* out: space id */ ulint* space_id, /* in/out: space id; if this is != 0, then
this is an input parameter, otherwise
output */
char* tablename, /* in: the table name in the usual char* tablename, /* in: the table name in the usual
databasename/tablename format of InnoDB */ databasename/tablename format of InnoDB */
ulint size); /* in: the initial size of the tablespace file ulint size); /* in: the initial size of the tablespace file
in pages */ in pages, must be > 0 */
/************************************************************************ /************************************************************************
Tries to open a single-table tablespace and checks the space id is right in Tries to open a single-table tablespace and checks the space id is right in
it. If does not succeed, prints an error message to the .err log. This it. If does not succeed, prints an error message to the .err log. This
function is used to open the tablespace when we load a table definition function is used to open the tablespace when we load a table definition
to the dictionarky cache. NOTE that we assume this operation is used under the to the dictionary cache. NOTE that we assume this operation is used under the
protection of the dictionary mutex, so that two users cannot race here. */ protection of the dictionary mutex, so that two users cannot race here. */
ibool ibool
...@@ -410,39 +449,32 @@ fil_space_for_table_exists_in_mem( ...@@ -410,39 +449,32 @@ fil_space_for_table_exists_in_mem(
the .err log if a matching tablespace is the .err log if a matching tablespace is
not found from memory */ not found from memory */
/************************************************************************** /**************************************************************************
Tries to extend a data file by the number of pages given. Fractions of 1 MB
are ignored. The tablespace must be cached in the memory cache. */
ibool
fil_extend_last_data_file(
/*======================*/
/* out: TRUE if success, also if we run
out of disk space we may return TRUE */
ulint* actual_increase,/* out: number of pages we were able to
extend, here the original size of the file and
the resulting size of the file are rounded
downwards to a full megabyte, and the
difference expressed in pages is returned */
ulint space_id, /* in: space id */
ulint size, /* in: current size of the space in pages, as
stored in the fsp header */
ulint size_increase); /* in: try to extend this many pages */
/**************************************************************************
Tries to extend a data file so that it would accommodate the number of pages Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. */ given. The tablespace must be cached in the memory cache. If the space is big
enough already, does nothing. */
ibool ibool
fil_extend_data_file_with_pages( fil_extend_space_to_desired_size(
/*============================*/ /*=============================*/
/* out: TRUE if success */ /* out: TRUE if success */
ulint* actual_size, /* out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
ulint space_id, /* in: space id, must be != 0 */ ulint space_id, /* in: space id, must be != 0 */
ulint size, /* in: current size of the space in pages, as
stored in the fsp header */
ulint size_after_extend);/* in: desired size in pages after the ulint size_after_extend);/* in: desired size in pages after the
extension, should be less than 4 GB (this extension; if the current space size is bigger
function is primarily intended for increasing than this already, the function does nothing */
the data file size from < 64 pages to up to #ifdef UNIV_HOTBACKUP
64 pages) */ /************************************************************************
Extends all tablespaces to the size stored in the space header. During the
ibbackup --apply-log phase we extended the spaces on-demand so that log records
could be appllied, but that may have left spaces still too small compared to
the size stored in the space header. */
void
fil_extend_tablespaces_to_stored_len(void);
/*======================================*/
#endif
/*********************************************************************** /***********************************************************************
Tries to reserve free extents in a file space. */ Tries to reserve free extents in a file space. */
......
...@@ -67,6 +67,14 @@ fsp_header_get_tablespace_size( ...@@ -67,6 +67,14 @@ fsp_header_get_tablespace_size(
/* out: size in pages */ /* out: size in pages */
ulint space); /* in: space id, must be 0 */ ulint space); /* in: space id, must be 0 */
/************************************************************************** /**************************************************************************
Reads the file space size stored in the header page. */
ulint
fsp_get_size_low(
/*=============*/
/* out: tablespace size stored in the space header */
page_t* page); /* in: header page (page 0 in the tablespace) */
/**************************************************************************
Reads the space id from the first page of a tablespace. */ Reads the space id from the first page of a tablespace. */
ulint ulint
......
...@@ -51,8 +51,6 @@ ha_chain_get_next( ...@@ -51,8 +51,6 @@ ha_chain_get_next(
/* out: next node, NULL if none */ /* out: next node, NULL if none */
ha_node_t* node) /* in: hash chain node */ ha_node_t* node) /* in: hash chain node */
{ {
ut_ad(table);
return(node->next); return(node->next);
} }
...@@ -144,8 +142,6 @@ ha_next( ...@@ -144,8 +142,6 @@ ha_next(
fold = node->fold; fold = node->fold;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_chain_get_next(node); node = ha_chain_get_next(node);
while (node) { while (node) {
......
...@@ -175,17 +175,14 @@ recv_apply_hashed_log_recs( ...@@ -175,17 +175,14 @@ recv_apply_hashed_log_recs(
disk and invalidated in buffer pool: this disk and invalidated in buffer pool: this
alternative means that no new log records alternative means that no new log records
can be generated during the application */ can be generated during the application */
#ifdef UNIV_HOTBACKUP
/*********************************************************************** /***********************************************************************
Applies log records in the hash table to a backup. */ Applies log records in the hash table to a backup. */
void void
recv_apply_log_recs_for_backup( recv_apply_log_recs_for_backup(void);
/*===========================*/ /*================================*/
ulint n_data_files, /* in: number of data files */ #endif
char** data_files, /* in: array containing the paths to the
data files */
ulint* file_sizes); /* in: sizes of the data files in database
pages */
/************************************************************ /************************************************************
Recovers from archived log files, and also from log files, if they exist. */ Recovers from archived log files, and also from log files, if they exist. */
......
...@@ -58,6 +58,19 @@ mlog_write_initial_log_record( ...@@ -58,6 +58,19 @@ mlog_write_initial_log_record(
byte type, /* in: log item type: MLOG_1BYTE, ... */ byte type, /* in: log item type: MLOG_1BYTE, ... */
mtr_t* mtr); /* in: mini-transaction handle */ mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************ /************************************************************
Writes a log record about an .ibd file create/delete/rename. */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
/* out: new value of log_ptr */
ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
ulint space_id,/* in: space id, if applicable */
ulint page_no,/* in: page number (not relevant currently) */
byte* log_ptr,/* in: pointer to mtr log which has been opened */
mtr_t* mtr); /* in: mtr */
/************************************************************
Catenates 1 - 4 bytes to the mtr log. */ Catenates 1 - 4 bytes to the mtr log. */
UNIV_INLINE UNIV_INLINE
void void
......
...@@ -185,3 +185,31 @@ mlog_write_initial_log_record_fast( ...@@ -185,3 +185,31 @@ mlog_write_initial_log_record_fast(
#endif #endif
return(log_ptr); return(log_ptr);
} }
/************************************************************
Writes a log record about an .ibd file create/delete/rename. */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
/* out: new value of log_ptr */
ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
ulint space_id,/* in: space id, if applicable */
ulint page_no,/* in: page number (not relevant currently) */
byte* log_ptr,/* in: pointer to mtr log which has been opened */
mtr_t* mtr) /* in: mtr */
{
ut_ad(log_ptr);
mach_write_to_1(log_ptr, type);
log_ptr++;
/* We write dummy space id and page number */
log_ptr += mach_write_compressed(log_ptr, space_id);
log_ptr += mach_write_compressed(log_ptr, page_no);
mtr->n_log_recs++;
return(log_ptr);
}
...@@ -96,7 +96,13 @@ flag value must give the length also! */ ...@@ -96,7 +96,13 @@ flag value must give the length also! */
sequence of these records */ sequence of these records */
#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to #define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
pad a log block full */ pad a log block full */
#define MLOG_BIGGEST_TYPE ((byte)32) /* biggest value (used in #define MLOG_FILE_CREATE ((byte)33) /* log record about an .ibd
file creation */
#define MLOG_FILE_RENAME ((byte)34) /* log record about an .ibd
file rename */
#define MLOG_FILE_DELETE ((byte)35) /* log record about an .ibd
file deletion */
#define MLOG_BIGGEST_TYPE ((byte)35) /* biggest value (used in
asserts) */ asserts) */
/******************************************************************* /*******************************************************************
......
...@@ -63,6 +63,7 @@ log. */ ...@@ -63,6 +63,7 @@ log. */
#define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_ONLY 333
#define OS_FILE_READ_WRITE 444 #define OS_FILE_READ_WRITE 444
#define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */
/* Options for file_create */ /* Options for file_create */
#define OS_FILE_AIO 61 #define OS_FILE_AIO 61
...@@ -199,6 +200,21 @@ os_file_readdir_next_file( ...@@ -199,6 +200,21 @@ os_file_readdir_next_file(
char* dirname,/* in: directory name or path */ char* dirname,/* in: directory name or path */
os_file_dir_t dir, /* in: directory stream */ os_file_dir_t dir, /* in: directory stream */
os_file_stat_t* info); /* in/out: buffer where the info is returned */ os_file_stat_t* info); /* in/out: buffer where the info is returned */
/*********************************************************************
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
fail_if_exists arguments is true. */
ibool
os_file_create_directory(
/*=====================*/
/* out: TRUE if call succeeds, FALSE on
error */
char* pathname, /* in: directory name as null-terminated
string */
ibool fail_if_exists);/* in: if TRUE, pre-existing directory is
treated as an error. */
/******************************************************************** /********************************************************************
A simple function to open or create a file. */ A simple function to open or create a file. */
...@@ -206,7 +222,8 @@ os_file_t ...@@ -206,7 +222,8 @@ os_file_t
os_file_create_simple( os_file_create_simple(
/*==================*/ /*==================*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
...@@ -221,13 +238,16 @@ os_file_t ...@@ -221,13 +238,16 @@ os_file_t
os_file_create_simple_no_error_handling( os_file_create_simple_no_error_handling(
/*====================================*/ /*====================================*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
(if does not exist, error), or OS_FILE_CREATE if a new (if does not exist, error), or OS_FILE_CREATE if a new
file is created (if exists, error) */ file is created (if exists, error) */
ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is used by
a backup program reading the file */
ibool* success);/* out: TRUE if succeed, FALSE if error */ ibool* success);/* out: TRUE if succeed, FALSE if error */
/******************************************************************** /********************************************************************
Opens an existing file or creates a new. */ Opens an existing file or creates a new. */
...@@ -236,7 +256,8 @@ os_file_t ...@@ -236,7 +256,8 @@ os_file_t
os_file_create( os_file_create(
/*===========*/ /*===========*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
......
...@@ -30,39 +30,8 @@ extern ulint* ut_dbg_null_ptr; ...@@ -30,39 +30,8 @@ extern ulint* ut_dbg_null_ptr;
" InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\ " InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\ os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\
(ulint)__LINE__);\ (ulint)__LINE__);\
fprintf(stderr,\ fputs(\
"InnoDB: Failing assertion: " #EXPR);\ "InnoDB: Failing assertion: " #EXPR, stderr);\
fprintf(stderr,\
"\nInnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\
"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");\
ut_dbg_stop_threads = TRUE;\
dbg_i = *(ut_dbg_null_ptr);\
if (dbg_i) {\
ut_dbg_null_ptr = NULL;\
}\
}\
if (ut_dbg_stop_threads) {\
fprintf(stderr,\
"InnoDB: Thread %lu stopped in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\
os_thread_sleep(1000000000);\
}\
}
/* This can be used if there are % characters in the assertion formula:
if we try to printf the formula gcc would complain of illegal print
format characters */
#define ut_anp(EXPR)\
{\
ulint dbg_i;\
\
if (!((ulint)(EXPR) + ut_dbg_zero)) {\
ut_print_timestamp(stderr);\
fprintf(stderr,\
" InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\
(ulint)__LINE__);\
fprintf(stderr,\ fprintf(stderr,\
"\nInnoDB: We intentionally generate a memory trap.\n");\ "\nInnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\ fprintf(stderr,\
......
...@@ -139,7 +139,7 @@ void ...@@ -139,7 +139,7 @@ void
ut_ulint_sort(ulint* arr, ulint* aux_arr, ulint low, ulint high); ut_ulint_sort(ulint* arr, ulint* aux_arr, ulint low, ulint high);
/*============================================================*/ /*============================================================*/
/************************************************************ /************************************************************
The following function returns a clock time in milliseconds. */ The following function returns elapsed CPU time in milliseconds. */
ulint ulint
ut_clock(void); ut_clock(void);
...@@ -174,6 +174,14 @@ ut_sprintf_timestamp( ...@@ -174,6 +174,14 @@ ut_sprintf_timestamp(
/*=================*/ /*=================*/
char* buf); /* in: buffer where to sprintf */ char* buf); /* in: buffer where to sprintf */
/************************************************************** /**************************************************************
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
char* buf); /* in: buffer where to sprintf */
/**************************************************************
Returns current year, month, day. */ Returns current year, month, day. */
void void
......
...@@ -95,14 +95,6 @@ static ...@@ -95,14 +95,6 @@ static
void void
log_io_complete_archive(void); log_io_complete_archive(void);
/*=========================*/ /*=========================*/
/********************************************************************
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for a
archiving. */
static
void
log_archive_margin(void);
/*====================*/
/******************************************************************** /********************************************************************
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint, Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
...@@ -407,7 +399,7 @@ log_pad_current_log_block(void) ...@@ -407,7 +399,7 @@ log_pad_current_log_block(void)
log_close(); log_close();
log_release(); log_release();
ut_anp((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE) ut_a((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
== LOG_BLOCK_HDR_SIZE); == LOG_BLOCK_HDR_SIZE);
} }
...@@ -745,7 +737,8 @@ log_init(void) ...@@ -745,7 +737,8 @@ log_init(void)
memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE); memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);
/*----------------------------*/ /*----------------------------*/
log_sys->archiving_state = LOG_ARCH_ON; /* Under MySQL, log archiving is always off */
log_sys->archiving_state = LOG_ARCH_OFF;
log_sys->archived_lsn = log_sys->lsn; log_sys->archived_lsn = log_sys->lsn;
log_sys->next_archived_lsn = ut_dulint_zero; log_sys->next_archived_lsn = ut_dulint_zero;
...@@ -754,13 +747,15 @@ log_init(void) ...@@ -754,13 +747,15 @@ log_init(void)
rw_lock_create(&(log_sys->archive_lock)); rw_lock_create(&(log_sys->archive_lock));
rw_lock_set_level(&(log_sys->archive_lock), SYNC_NO_ORDER_CHECK); rw_lock_set_level(&(log_sys->archive_lock), SYNC_NO_ORDER_CHECK);
log_sys->archive_buf = ut_align( log_sys->archive_buf = NULL;
/* ut_align(
ut_malloc(LOG_ARCHIVE_BUF_SIZE ut_malloc(LOG_ARCHIVE_BUF_SIZE
+ OS_FILE_LOG_BLOCK_SIZE), + OS_FILE_LOG_BLOCK_SIZE),
OS_FILE_LOG_BLOCK_SIZE); OS_FILE_LOG_BLOCK_SIZE); */
log_sys->archive_buf_size = LOG_ARCHIVE_BUF_SIZE; log_sys->archive_buf_size = 0;
memset(log_sys->archive_buf, '\0', LOG_ARCHIVE_BUF_SIZE); /* memset(log_sys->archive_buf, '\0', LOG_ARCHIVE_BUF_SIZE); */
log_sys->archiving_on = os_event_create(NULL); log_sys->archiving_on = os_event_create(NULL);
...@@ -1107,8 +1102,8 @@ log_group_write_buf( ...@@ -1107,8 +1102,8 @@ log_group_write_buf(
ulint i; ulint i;
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
ut_anp(len % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
if (new_data_offset == 0) { if (new_data_offset == 0) {
write_header = TRUE; write_header = TRUE;
...@@ -2080,6 +2075,8 @@ log_archived_file_name_gen( ...@@ -2080,6 +2075,8 @@ log_archived_file_name_gen(
ulint id, /* in: group id */ ulint id, /* in: group id */
ulint file_no)/* in: file number */ ulint file_no)/* in: file number */
{ {
ut_a(0);
UT_NOT_USED(id); /* Currently we only archive the first group */ UT_NOT_USED(id); /* Currently we only archive the first group */
sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, file_no); sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, file_no);
...@@ -2101,6 +2098,8 @@ log_group_archive_file_header_write( ...@@ -2101,6 +2098,8 @@ log_group_archive_file_header_write(
byte* buf; byte* buf;
ulint dest_offset; ulint dest_offset;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
ut_a(nth_file < group->n_files); ut_a(nth_file < group->n_files);
...@@ -2138,6 +2137,8 @@ log_group_archive_completed_header_write( ...@@ -2138,6 +2137,8 @@ log_group_archive_completed_header_write(
byte* buf; byte* buf;
ulint dest_offset; ulint dest_offset;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
ut_a(nth_file < group->n_files); ut_a(nth_file < group->n_files);
...@@ -2177,15 +2178,17 @@ log_group_archive( ...@@ -2177,15 +2178,17 @@ log_group_archive(
ulint n_files; ulint n_files;
ulint open_mode; ulint open_mode;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
start_lsn = log_sys->archived_lsn; start_lsn = log_sys->archived_lsn;
ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
end_lsn = log_sys->next_archived_lsn; end_lsn = log_sys->next_archived_lsn;
ut_anp(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
buf = log_sys->archive_buf; buf = log_sys->archive_buf;
...@@ -2289,7 +2292,7 @@ log_group_archive( ...@@ -2289,7 +2292,7 @@ log_group_archive(
group->next_archived_file_no = group->archived_file_no + n_files; group->next_archived_file_no = group->archived_file_no + n_files;
group->next_archived_offset = next_offset % group->file_size; group->next_archived_offset = next_offset % group->file_size;
ut_anp(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0); ut_a(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
} }
/********************************************************* /*********************************************************
...@@ -2302,6 +2305,8 @@ log_archive_groups(void) ...@@ -2302,6 +2305,8 @@ log_archive_groups(void)
{ {
log_group_t* group; log_group_t* group;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
group = UT_LIST_GET_FIRST(log_sys->log_groups); group = UT_LIST_GET_FIRST(log_sys->log_groups);
...@@ -2325,6 +2330,8 @@ log_archive_write_complete_groups(void) ...@@ -2325,6 +2330,8 @@ log_archive_write_complete_groups(void)
dulint end_lsn; dulint end_lsn;
ulint i; ulint i;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
group = UT_LIST_GET_FIRST(log_sys->log_groups); group = UT_LIST_GET_FIRST(log_sys->log_groups);
...@@ -2387,6 +2394,8 @@ void ...@@ -2387,6 +2394,8 @@ void
log_archive_check_completion_low(void) log_archive_check_completion_low(void)
/*==================================*/ /*==================================*/
{ {
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
if (log_sys->n_pending_archive_ios == 0 if (log_sys->n_pending_archive_ios == 0
...@@ -2423,6 +2432,8 @@ log_io_complete_archive(void) ...@@ -2423,6 +2432,8 @@ log_io_complete_archive(void)
{ {
log_group_t* group; log_group_t* group;
ut_a(0);
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups); group = UT_LIST_GET_FIRST(log_sys->log_groups);
...@@ -2458,6 +2469,8 @@ log_archive_do( ...@@ -2458,6 +2469,8 @@ log_archive_do(
dulint start_lsn; dulint start_lsn;
dulint limit_lsn; dulint limit_lsn;
ut_a(0);
calc_new_limit = TRUE; calc_new_limit = TRUE;
loop: loop:
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
...@@ -2484,7 +2497,7 @@ log_archive_do( ...@@ -2484,7 +2497,7 @@ log_archive_do(
start_lsn = log_sys->archived_lsn; start_lsn = log_sys->archived_lsn;
if (calc_new_limit) { if (calc_new_limit) {
ut_anp(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE ut_a(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE
== 0); == 0);
limit_lsn = ut_dulint_add(start_lsn, limit_lsn = ut_dulint_add(start_lsn,
log_sys->archive_buf_size); log_sys->archive_buf_size);
...@@ -2584,6 +2597,8 @@ log_archive_all(void) ...@@ -2584,6 +2597,8 @@ log_archive_all(void)
return; return;
} }
ut_a(0);
present_lsn = log_sys->lsn; present_lsn = log_sys->lsn;
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
...@@ -2621,11 +2636,17 @@ log_archive_close_groups( ...@@ -2621,11 +2636,17 @@ log_archive_close_groups(
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
if (log_sys->archiving_state == LOG_ARCH_OFF) {
return;
}
ut_a(0);
group = UT_LIST_GET_FIRST(log_sys->log_groups); group = UT_LIST_GET_FIRST(log_sys->log_groups);
trunc_len = UNIV_PAGE_SIZE trunc_len = UNIV_PAGE_SIZE
* fil_space_get_size(group->archive_space_id); * fil_space_get_size(group->archive_space_id);
if (trunc_len > 0) { if (trunc_len > 0) {
ut_a(trunc_len == group->file_size); ut_a(trunc_len == group->file_size);
...@@ -2653,9 +2674,8 @@ log_archive_close_groups( ...@@ -2653,9 +2674,8 @@ log_archive_close_groups(
/******************************************************************** /********************************************************************
Writes the log contents to the archive up to the lsn when this function was Writes the log contents to the archive up to the lsn when this function was
called, and stops the archiving. When archiving is started again, the archived called, and stops the archiving. When archiving is started again, the archived
log file numbers start from 2 higher, so that the archiving will log file numbers start from 2 higher, so that the archiving will not write
not write again to the archived log files which exist when this function again to the archived log files which exist when this function returns. */
returns. */
ulint ulint
log_archive_stop(void) log_archive_stop(void)
...@@ -2664,6 +2684,8 @@ log_archive_stop(void) ...@@ -2664,6 +2684,8 @@ log_archive_stop(void)
{ {
ibool success; ibool success;
ut_a(0);
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state != LOG_ARCH_ON) { if (log_sys->archiving_state != LOG_ARCH_ON) {
...@@ -2726,6 +2748,8 @@ log_archive_start(void) ...@@ -2726,6 +2748,8 @@ log_archive_start(void)
/*===================*/ /*===================*/
/* out: DB_SUCCESS or DB_ERROR */ /* out: DB_SUCCESS or DB_ERROR */
{ {
ut_a(0);
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state != LOG_ARCH_STOPPED) { if (log_sys->archiving_state != LOG_ARCH_STOPPED) {
...@@ -2752,6 +2776,7 @@ log_archive_noarchivelog(void) ...@@ -2752,6 +2776,7 @@ log_archive_noarchivelog(void)
/*==========================*/ /*==========================*/
/* out: DB_SUCCESS or DB_ERROR */ /* out: DB_SUCCESS or DB_ERROR */
{ {
ut_a(0);
loop: loop:
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
...@@ -2784,6 +2809,7 @@ log_archive_archivelog(void) ...@@ -2784,6 +2809,7 @@ log_archive_archivelog(void)
/*========================*/ /*========================*/
/* out: DB_SUCCESS or DB_ERROR */ /* out: DB_SUCCESS or DB_ERROR */
{ {
ut_a(0);
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state == LOG_ARCH_OFF) { if (log_sys->archiving_state == LOG_ARCH_OFF) {
...@@ -2802,6 +2828,7 @@ log_archive_archivelog(void) ...@@ -2802,6 +2828,7 @@ log_archive_archivelog(void)
return(DB_ERROR); return(DB_ERROR);
} }
#ifdef notdefined
/******************************************************************** /********************************************************************
Tries to establish a big enough margin of free space in the log groups, such Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for that a new log entry can be catenated without an immediate need for
...@@ -2855,6 +2882,7 @@ log_archive_margin(void) ...@@ -2855,6 +2882,7 @@ log_archive_margin(void)
goto loop; goto loop;
} }
} }
#endif
/************************************************************************ /************************************************************************
Checks that there is enough free space in the log to start a new query step. Checks that there is enough free space in the log to start a new query step.
...@@ -2871,7 +2899,7 @@ log_check_margins(void) ...@@ -2871,7 +2899,7 @@ log_check_margins(void)
log_checkpoint_margin(); log_checkpoint_margin();
log_archive_margin(); /* log_archive_margin(); */
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
...@@ -3009,7 +3037,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3009,7 +3037,7 @@ logs_empty_and_mark_files_at_shutdown(void)
goto loop; goto loop;
} }
log_archive_all(); /* log_archive_all(); */
log_make_checkpoint_at(ut_dulint_max, TRUE); log_make_checkpoint_at(ut_dulint_max, TRUE);
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
...@@ -3027,15 +3055,16 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3027,15 +3055,16 @@ logs_empty_and_mark_files_at_shutdown(void)
goto loop; goto loop;
} }
arch_log_no = arch_log_no = 0;
/*
UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no; UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no;
if (0 == UT_LIST_GET_FIRST(log_sys->log_groups)->archived_offset) { if (0 == UT_LIST_GET_FIRST(log_sys->log_groups)->archived_offset) {
arch_log_no--; arch_log_no--;
} }
*/
log_archive_close_groups(TRUE); /* log_archive_close_groups(TRUE); */
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
......
This diff is collapsed.
...@@ -603,7 +603,7 @@ mem_pool_validate( ...@@ -603,7 +603,7 @@ mem_pool_validate(
} }
} }
ut_anp(free + pool->reserved == pool->size); ut_a(free + pool->reserved == pool->size);
mutex_exit(&(pool->mutex)); mutex_exit(&(pool->mutex));
......
...@@ -595,6 +595,51 @@ dbname.sym can redirect a database directory: ...@@ -595,6 +595,51 @@ dbname.sym can redirect a database directory:
#endif #endif
} }
/*********************************************************************
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
fail_if_exists arguments is true. */
ibool
os_file_create_directory(
/*=====================*/
/* out: TRUE if call succeeds, FALSE on
error */
char* pathname, /* in: directory name as null-terminated
string */
ibool fail_if_exists) /* in: if TRUE, pre-existing directory is
treated as an error. */
{
#ifdef __WIN__
BOOL rcode;
rcode = CreateDirectory(pathname, NULL);
if (!(rcode != 0 ||
(GetLastError() == ERROR_FILE_EXISTS && !fail_if_exists))) {
/* failure */
os_file_handle_error(NULL, pathname, "CreateDirectory");
return(FALSE);
}
return (TRUE);
#else
int rcode;
rcode = mkdir(pathname, 0770);
if (!(rcode == 0 || (errno == EEXIST && !fail_if_exists))) {
/* failure */
os_file_handle_error(0, pathname, "mkdir");
return(FALSE);
}
return (TRUE);
#endif
}
/******************************************************************** /********************************************************************
A simple function to open or create a file. */ A simple function to open or create a file. */
...@@ -602,7 +647,8 @@ os_file_t ...@@ -602,7 +647,8 @@ os_file_t
os_file_create_simple( os_file_create_simple(
/*==================*/ /*==================*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
...@@ -714,13 +760,16 @@ os_file_t ...@@ -714,13 +760,16 @@ os_file_t
os_file_create_simple_no_error_handling( os_file_create_simple_no_error_handling(
/*====================================*/ /*====================================*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
(if does not exist, error), or OS_FILE_CREATE if a new (if does not exist, error), or OS_FILE_CREATE if a new
file is created (if exists, error) */ file is created (if exists, error) */
ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is used by
a backup program reading the file */
ibool* success)/* out: TRUE if succeed, FALSE if error */ ibool* success)/* out: TRUE if succeed, FALSE if error */
{ {
#ifdef __WIN__ #ifdef __WIN__
...@@ -728,6 +777,7 @@ os_file_create_simple_no_error_handling( ...@@ -728,6 +777,7 @@ os_file_create_simple_no_error_handling(
DWORD create_flag; DWORD create_flag;
DWORD access; DWORD access;
DWORD attributes = 0; DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ;
ut_a(name); ut_a(name);
...@@ -744,6 +794,13 @@ os_file_create_simple_no_error_handling( ...@@ -744,6 +794,13 @@ os_file_create_simple_no_error_handling(
access = GENERIC_READ; access = GENERIC_READ;
} else if (access_type == OS_FILE_READ_WRITE) { } else if (access_type == OS_FILE_READ_WRITE) {
access = GENERIC_READ | GENERIC_WRITE; access = GENERIC_READ | GENERIC_WRITE;
} else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
access = GENERIC_READ;
share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
| FILE_SHARE_WRITE; /* A backup program has to give
mysqld the maximum freedom to
do what it likes with the
file */
} else { } else {
access = 0; access = 0;
ut_error; ut_error;
...@@ -751,8 +808,7 @@ os_file_create_simple_no_error_handling( ...@@ -751,8 +808,7 @@ os_file_create_simple_no_error_handling(
file = CreateFile(name, file = CreateFile(name,
access, access,
FILE_SHARE_READ,/* file can be read also by other share_mode,
processes */
NULL, /* default security attributes */ NULL, /* default security attributes */
create_flag, create_flag,
attributes, attributes,
...@@ -808,7 +864,8 @@ os_file_t ...@@ -808,7 +864,8 @@ os_file_t
os_file_create( os_file_create(
/*===========*/ /*===========*/
/* out, own: handle to the file, not defined if error, /* out, own: handle to the file, not defined if error,
error number can be retrieved with os_get_last_error */ error number can be retrieved with
os_file_get_last_error */
char* name, /* in: name of the file or path as a null-terminated char* name, /* in: name of the file or path as a null-terminated
string */ string */
ulint create_mode, /* in: OS_FILE_OPEN if an existing file is opened ulint create_mode, /* in: OS_FILE_OPEN if an existing file is opened
...@@ -896,7 +953,7 @@ os_file_create( ...@@ -896,7 +953,7 @@ os_file_create(
start 2 instances of mysqld on the start 2 instances of mysqld on the
SAME files, that could cause severe SAME files, that could cause severe
database corruption! When opening database corruption! When opening
raw disk partitions Microsoft manuals raw disk partitions, Microsoft manuals
say that we must give also the write say that we must give also the write
permission. */ permission. */
NULL, /* default security attributes */ NULL, /* default security attributes */
...@@ -1017,6 +1074,10 @@ os_file_delete( ...@@ -1017,6 +1074,10 @@ os_file_delete(
{ {
#ifdef __WIN__ #ifdef __WIN__
BOOL ret; BOOL ret;
ulint count = 0;
loop:
/* In Windows, deleting an .ibd file may fail if ibbackup is copying
it */
ret = DeleteFile((LPCTSTR)name); ret = DeleteFile((LPCTSTR)name);
...@@ -1024,9 +1085,31 @@ os_file_delete( ...@@ -1024,9 +1085,31 @@ os_file_delete(
return(TRUE); return(TRUE);
} }
os_file_handle_error(NULL, name, "delete"); if (GetLastError() == ERROR_PATH_NOT_FOUND) {
/* If the file does not exist, we classify this as a 'mild'
error and return */
return(FALSE); return(FALSE);
}
count++;
if (count > 100 && 0 == (count % 10)) {
fprintf(stderr,
"InnoDB: Warning: cannot delete file %s\n"
"InnoDB: Are you running ibbackup to back up the file?\n", name);
os_file_get_last_error(TRUE); /* print error information */
}
os_thread_sleep(1000000); /* sleep for a second */
if (count > 2000) {
return(FALSE);
}
goto loop;
#else #else
int ret; int ret;
...@@ -1103,6 +1186,7 @@ os_file_close( ...@@ -1103,6 +1186,7 @@ os_file_close(
} }
os_file_handle_error(file, NULL, "close"); os_file_handle_error(file, NULL, "close");
return(FALSE); return(FALSE);
#else #else
int ret; int ret;
...@@ -1111,6 +1195,7 @@ os_file_close( ...@@ -1111,6 +1195,7 @@ os_file_close(
if (ret == -1) { if (ret == -1) {
os_file_handle_error(file, NULL, "close"); os_file_handle_error(file, NULL, "close");
return(FALSE); return(FALSE);
} }
......
/* A lexical scanner generated by flex */ /* A lexical scanner generated by flex */
/* Scanner skeleton version: /* Scanner skeleton version:
* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ * $Header: /home/heikki/cvsroot/ib/pars/lexyy.c,v 1.2 2003/10/30 20:27:19 heikki Exp $
*/ */
#define FLEX_SCANNER #define FLEX_SCANNER
......
...@@ -2346,8 +2346,13 @@ row_drop_table_for_mysql( ...@@ -2346,8 +2346,13 @@ row_drop_table_for_mysql(
/* Do not drop possible .ibd tablespace if something went /* Do not drop possible .ibd tablespace if something went
wrong: we do not want to delete valuable data of the user */ wrong: we do not want to delete valuable data of the user */
if (err == DB_SUCCESS && space_id != 0 if (err == DB_SUCCESS && space_id > 0) {
&& fil_tablespace_exists_in_mem(space_id)) { if (!fil_space_for_table_exists_in_mem(space_id, name,
FALSE, TRUE)) {
err = DB_ERROR;
goto funct_exit;
}
success = fil_delete_tablespace(space_id); success = fil_delete_tablespace(space_id);
......
...@@ -3288,7 +3288,13 @@ row_search_for_mysql( ...@@ -3288,7 +3288,13 @@ row_search_for_mysql(
} else if (index == clust_index) { } else if (index == clust_index) {
if (!lock_clust_rec_cons_read_sees(rec, index, /* Fetch a previous version of the row if the current
one is not visible in the snapshot; if we have a very
high force recovery level set, we try to avoid crashes
by skipping this lookup */
if (srv_force_recovery < 5
&& !lock_clust_rec_cons_read_sees(rec, index,
trx->read_view)) { trx->read_view)) {
err = row_sel_build_prev_vers_for_mysql( err = row_sel_build_prev_vers_for_mysql(
......
...@@ -102,7 +102,7 @@ char** srv_log_group_home_dirs = NULL; ...@@ -102,7 +102,7 @@ char** srv_log_group_home_dirs = NULL;
ulint srv_n_log_groups = ULINT_MAX; ulint srv_n_log_groups = ULINT_MAX;
ulint srv_n_log_files = ULINT_MAX; ulint srv_n_log_files = ULINT_MAX;
ulint srv_log_file_size = ULINT_MAX; /* size in database pages */ ulint srv_log_file_size = ULINT_MAX; /* size in database pages */
ibool srv_log_archive_on = TRUE; ibool srv_log_archive_on = FALSE;
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */ ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
ulint srv_flush_log_at_trx_commit = 1; ulint srv_flush_log_at_trx_commit = 1;
...@@ -3209,11 +3209,13 @@ srv_master_thread( ...@@ -3209,11 +3209,13 @@ srv_master_thread(
goto loop; goto loop;
} }
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
/*
srv_main_thread_op_info = srv_main_thread_op_info =
(char*)"archiving log (if log archive is on)"; (char*)"archiving log (if log archive is on)";
log_archive_do(FALSE, &n_bytes_archived); log_archive_do(FALSE, &n_bytes_archived);
*/
n_bytes_archived = 0;
/* Keep looping in the background loop if still work to do */ /* Keep looping in the background loop if still work to do */
......
...@@ -553,7 +553,6 @@ open_or_create_log_file( ...@@ -553,7 +553,6 @@ open_or_create_log_file(
ulint i) /* in: log file number in group */ ulint i) /* in: log file number in group */
{ {
ibool ret; ibool ret;
ulint arch_space_id;
ulint size; ulint size;
ulint size_high; ulint size_high;
char name[10000]; char name[10000];
...@@ -649,9 +648,10 @@ open_or_create_log_file( ...@@ -649,9 +648,10 @@ open_or_create_log_file(
fil_node_create(name, srv_log_file_size, fil_node_create(name, srv_log_file_size,
2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE); 2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE);
#ifdef notdefined
/* If this is the first log group, create the file space object /* If this is the first log group, create the file space object
for archived logs */ for archived logs.
Under MySQL, no archiving ever done. */
if (k == 0 && i == 0) { if (k == 0 && i == 0) {
arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID; arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
...@@ -661,12 +661,13 @@ open_or_create_log_file( ...@@ -661,12 +661,13 @@ open_or_create_log_file(
} else { } else {
arch_space_id = ULINT_UNDEFINED; arch_space_id = ULINT_UNDEFINED;
} }
#endif
if (i == 0) { if (i == 0) {
log_group_init(k, srv_n_log_files, log_group_init(k, srv_n_log_files,
srv_log_file_size * UNIV_PAGE_SIZE, srv_log_file_size * UNIV_PAGE_SIZE,
2 * k + SRV_LOG_SPACE_FIRST_ID, 2 * k + SRV_LOG_SPACE_FIRST_ID,
arch_space_id); SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch
space id */
} }
return(DB_SUCCESS); return(DB_SUCCESS);
...@@ -1000,7 +1001,6 @@ innobase_start_or_create_for_mysql(void) ...@@ -1000,7 +1001,6 @@ innobase_start_or_create_for_mysql(void)
dulint max_flushed_lsn; dulint max_flushed_lsn;
ulint min_arch_log_no; ulint min_arch_log_no;
ulint max_arch_log_no; ulint max_arch_log_no;
ibool start_archive;
ulint sum_of_new_sizes; ulint sum_of_new_sizes;
ulint sum_of_data_file_sizes; ulint sum_of_data_file_sizes;
ulint tablespace_size_in_header; ulint tablespace_size_in_header;
...@@ -1341,7 +1341,9 @@ NetWare. */ ...@@ -1341,7 +1341,9 @@ NetWare. */
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
recv_reset_logs(max_flushed_lsn, max_arch_log_no + 1, TRUE); /* Do not + 1 arch_log_no because we do not use log
archiving */
recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
} }
...@@ -1430,6 +1432,8 @@ NetWare. */ ...@@ -1430,6 +1432,8 @@ NetWare. */
log_make_checkpoint_at(ut_dulint_max, TRUE); log_make_checkpoint_at(ut_dulint_max, TRUE);
#ifdef notdefined
/* Archiving is always off under MySQL */
if (!srv_log_archive_on) { if (!srv_log_archive_on) {
ut_a(DB_SUCCESS == log_archive_noarchivelog()); ut_a(DB_SUCCESS == log_archive_noarchivelog());
} else { } else {
...@@ -1447,7 +1451,7 @@ NetWare. */ ...@@ -1447,7 +1451,7 @@ NetWare. */
ut_a(DB_SUCCESS == log_archive_archivelog()); ut_a(DB_SUCCESS == log_archive_archivelog());
} }
} }
#endif
if (!create_new_db && srv_force_recovery == 0) { if (!create_new_db && srv_force_recovery == 0) {
/* After a crash recovery we only check that the info in data /* After a crash recovery we only check that the info in data
dictionary is consistent with what we already know about space dictionary is consistent with what we already know about space
......
...@@ -71,9 +71,8 @@ ut_find_prime( ...@@ -71,9 +71,8 @@ ut_find_prime(
/* Found a prime */ /* Found a prime */
break; break;
next_n: ; next_n: ;
} }
return(n); return(n);
} }
...@@ -63,7 +63,7 @@ ut_get_high32( ...@@ -63,7 +63,7 @@ ut_get_high32(
} }
/************************************************************ /************************************************************
The following function returns a clock time in milliseconds. */ The following function returns elapsed CPU time in milliseconds. */
ulint ulint
ut_clock(void) ut_clock(void)
...@@ -181,6 +181,50 @@ ut_sprintf_timestamp( ...@@ -181,6 +181,50 @@ ut_sprintf_timestamp(
#endif #endif
} }
/**************************************************************
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
char* buf) /* in: buffer where to sprintf */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
GetLocalTime(&cal_tm);
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
(int)cal_tm.wYear % 100,
(int)cal_tm.wMonth,
(int)cal_tm.wDay,
(int)cal_tm.wHour,
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
struct tm cal_tm;
struct tm* cal_tm_ptr;
time_t tm;
time(&tm);
#ifdef HAVE_LOCALTIME_R
localtime_r(&tm, &cal_tm);
cal_tm_ptr = &cal_tm;
#else
cal_tm_ptr = localtime(&tm);
#endif
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
cal_tm_ptr->tm_year % 100,
cal_tm_ptr->tm_mon + 1,
cal_tm_ptr->tm_mday,
cal_tm_ptr->tm_hour,
cal_tm_ptr->tm_min,
cal_tm_ptr->tm_sec);
#endif
}
/************************************************************** /**************************************************************
Returns current year, month, day. */ Returns current year, month, day. */
......
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