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(
ulint old_checksum;
ulint checksum_field;
ulint old_checksum_field;
#ifndef UNIV_HOTBACKUP
dulint current_lsn;
#endif
if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
!= mach_read_from_4(read_buf + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
......
......@@ -301,9 +301,12 @@ dict_build_table_def_step(
- page 2 is the first inode page,
- page 3 will contain the root of the clustered index of the
table we create here. */
table->space = 0; /* reset to zero for the call below */
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) {
return(error);
......@@ -311,7 +314,7 @@ dict_build_table_def_step(
mtr_start(&mtr);
fsp_header_init(table->space, 4, &mtr);
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
}
......
......@@ -2580,7 +2580,7 @@ dict_create_foreign_constraints_low(
sprintf(buf + strlen(buf),
" Error in foreign key constraint of table %.500s.\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);
mutex_exit(&dict_foreign_err_mutex);
......
This diff is collapsed.
......@@ -27,6 +27,10 @@ Created 11/29/1995 Heikki Tuuri
#include "dict0mem.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 */
typedef byte fsp_header_t;
typedef byte xdes_t;
......@@ -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
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_NOT_USED 4 /* this field contained a value up to
......@@ -90,7 +92,6 @@ descriptor page, but used only in the first. */
#define FSP_FREE_ADD 4 /* this many free extents are added
to the free list from above
FSP_FREE_LIMIT at a time */
/* FILE SEGMENT INODE
==================
......@@ -298,6 +299,19 @@ fseg_alloc_free_page_low(
FSP_UP, FSP_NO_DIR */
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. */
UNIV_INLINE
......@@ -1034,8 +1048,9 @@ fsp_try_extend_data_file_with_pages(
fsp_header_t* header, /* in: space header */
mtr_t* mtr) /* in: mtr */
{
ulint size;
ibool success;
ulint actual_size;
ulint size;
ut_a(space != 0);
......@@ -1043,12 +1058,12 @@ fsp_try_extend_data_file_with_pages(
ut_a(page_no >= size);
success = fil_extend_data_file_with_pages(space, size, page_no + 1);
if (success) {
mlog_write_ulint(header + FSP_SIZE, page_no + 1, MLOG_4BYTES,
mtr);
}
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 */
mlog_write_ulint(header + FSP_SIZE, actual_size, MLOG_4BYTES, mtr);
return(success);
}
......@@ -1060,13 +1075,20 @@ ibool
fsp_try_extend_data_file(
/*=====================*/
/* 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 */
fsp_header_t* header, /* in: space header */
mtr_t* mtr) /* in: mtr */
{
ulint size;
ulint new_size;
ulint old_size;
ulint size_increase;
ulint actual_size;
ibool success;
*actual_increase = 0;
......@@ -1078,6 +1100,8 @@ fsp_try_extend_data_file(
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
old_size = size;
if (space == 0 && srv_last_file_size_max != 0) {
if (srv_last_file_size_max
< srv_data_file_sizes[srv_n_data_files - 1]) {
......@@ -1107,8 +1131,12 @@ fsp_try_extend_data_file(
success = fsp_try_extend_data_file_with_pages(
space, FSP_EXTENT_SIZE - 1,
header, mtr);
if (!success) {
new_size = mtr_read_ulint(
header + FSP_SIZE, MLOG_4BYTES, mtr);
*actual_increase = new_size - old_size;
return(FALSE);
}
......@@ -1118,7 +1146,10 @@ fsp_try_extend_data_file(
if (size < 32 * FSP_EXTENT_SIZE) {
size_increase = FSP_EXTENT_SIZE;
} 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(
return(TRUE);
}
/* Extend the data file. If we are not able to extend the full
requested length, the function tells how many pages we were able to
extend so that the size of the tablespace would be divisible by 1 MB
(we possibly managed to extend more, but we only take into account
full megabytes). */
success = fil_extend_last_data_file(actual_increase, space, size,
size_increase);
if (success) {
mlog_write_ulint(header + FSP_SIZE, size + *actual_increase,
success = fil_extend_space_to_desired_size(&actual_size, space,
size + size_increase);
/* We ignore any fragments of a full megabyte when storing the size
to the space header */
mlog_write_ulint(header + FSP_SIZE,
ut_calc_align_down(actual_size, (1024 * 1024) / UNIV_PAGE_SIZE),
MLOG_4BYTES, mtr);
}
new_size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
*actual_increase = new_size - old_size;
return(TRUE);
}
......@@ -1186,8 +1216,10 @@ fsp_fill_free_list(
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
}
if (space != 0 && !init_space) {
/* Try to increase the data file size */
if (space != 0 && !init_space
&& 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);
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
}
......@@ -1222,7 +1254,7 @@ fsp_fill_free_list(
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
order, and we must be able to release its latch
before returning from the fsp routine */
......@@ -1797,7 +1829,7 @@ fsp_free_seg_inode(
flst_remove(space_header + FSP_SEG_INODES_FREE,
page + FSEG_INODE_PAGE_NODE, mtr);
fsp_free_page(space, buf_frame_get_page_no(page), mtr);
fsp_free_page(space, buf_frame_get_page_no(page), mtr);
}
}
......@@ -3157,7 +3189,7 @@ fseg_free_step(
freed yet */
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);
inode = fseg_inode_get(header, mtr);
......
......@@ -16,6 +16,14 @@ Created 10/25/1995 Heikki Tuuri
#include "ut0byte.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 */
#define FIL_NULL ULINT32_UNDEFINED
......@@ -261,6 +269,35 @@ fil_decr_pending_ibuf_merges(
/*========================*/
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
memory cache. */
......@@ -306,16 +343,18 @@ ulint
fil_create_new_single_table_tablespace(
/*===================================*/
/* 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
databasename/tablename format of InnoDB */
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
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
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. */
ibool
......@@ -410,39 +449,32 @@ fil_space_for_table_exists_in_mem(
the .err log if a matching tablespace is
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
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
fil_extend_data_file_with_pages(
/*============================*/
fil_extend_space_to_desired_size(
/*=============================*/
/* 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 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
extension, should be less than 4 GB (this
function is primarily intended for increasing
the data file size from < 64 pages to up to
64 pages) */
extension; if the current space size is bigger
than this already, the function does nothing */
#ifdef UNIV_HOTBACKUP
/************************************************************************
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. */
......
......@@ -67,6 +67,14 @@ fsp_header_get_tablespace_size(
/* out: size in pages */
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. */
ulint
......
......@@ -51,8 +51,6 @@ ha_chain_get_next(
/* out: next node, NULL if none */
ha_node_t* node) /* in: hash chain node */
{
ut_ad(table);
return(node->next);
}
......@@ -144,8 +142,6 @@ ha_next(
fold = node->fold;
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
node = ha_chain_get_next(node);
while (node) {
......
......@@ -175,17 +175,14 @@ recv_apply_hashed_log_recs(
disk and invalidated in buffer pool: this
alternative means that no new log records
can be generated during the application */
#ifdef UNIV_HOTBACKUP
/***********************************************************************
Applies log records in the hash table to a backup. */
void
recv_apply_log_recs_for_backup(
/*===========================*/
ulint n_data_files, /* in: number of data files */
char** data_files, /* in: array containing the paths to the
data files */
ulint* file_sizes); /* in: sizes of the data files in database
pages */
recv_apply_log_recs_for_backup(void);
/*================================*/
#endif
/************************************************************
Recovers from archived log files, and also from log files, if they exist. */
......
......@@ -58,6 +58,19 @@ mlog_write_initial_log_record(
byte type, /* in: log item type: MLOG_1BYTE, ... */
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. */
UNIV_INLINE
void
......
......@@ -185,3 +185,31 @@ mlog_write_initial_log_record_fast(
#endif
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! */
sequence of these records */
#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
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) */
/*******************************************************************
......
......@@ -63,6 +63,7 @@ log. */
#define OS_FILE_READ_ONLY 333
#define OS_FILE_READ_WRITE 444
#define OS_FILE_READ_ALLOW_DELETE 555 /* for ibbackup */
/* Options for file_create */
#define OS_FILE_AIO 61
......@@ -199,6 +200,21 @@ os_file_readdir_next_file(
char* dirname,/* in: directory name or path */
os_file_dir_t dir, /* in: directory stream */
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. */
......@@ -206,7 +222,8 @@ os_file_t
os_file_create_simple(
/*==================*/
/* 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
string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
......@@ -221,13 +238,16 @@ os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
/* 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
string */
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
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 */
/********************************************************************
Opens an existing file or creates a new. */
......@@ -236,7 +256,8 @@ os_file_t
os_file_create(
/*===========*/
/* 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
string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
......
......@@ -30,39 +30,8 @@ extern ulint* ut_dbg_null_ptr;
" 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,\
"InnoDB: Failing assertion: " #EXPR);\
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__);\
fputs(\
"InnoDB: Failing assertion: " #EXPR, stderr);\
fprintf(stderr,\
"\nInnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\
......
......@@ -139,7 +139,7 @@ void
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
ut_clock(void);
......@@ -174,6 +174,14 @@ ut_sprintf_timestamp(
/*=================*/
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. */
void
......
......@@ -95,14 +95,6 @@ static
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,
......@@ -407,7 +399,7 @@ log_pad_current_log_block(void)
log_close();
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);
}
......@@ -745,7 +737,8 @@ log_init(void)
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->next_archived_lsn = ut_dulint_zero;
......@@ -754,13 +747,15 @@ log_init(void)
rw_lock_create(&(log_sys->archive_lock));
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
+ OS_FILE_LOG_BLOCK_SIZE),
OS_FILE_LOG_BLOCK_SIZE);
log_sys->archive_buf_size = LOG_ARCHIVE_BUF_SIZE;
OS_FILE_LOG_BLOCK_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);
......@@ -1107,8 +1102,8 @@ log_group_write_buf(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
ut_anp(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(len % 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) {
write_header = TRUE;
......@@ -2080,6 +2075,8 @@ log_archived_file_name_gen(
ulint id, /* in: group id */
ulint file_no)/* in: file number */
{
ut_a(0);
UT_NOT_USED(id); /* Currently we only archive the first group */
sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, file_no);
......@@ -2101,6 +2098,8 @@ log_group_archive_file_header_write(
byte* buf;
ulint dest_offset;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
ut_a(nth_file < group->n_files);
......@@ -2138,6 +2137,8 @@ log_group_archive_completed_header_write(
byte* buf;
ulint dest_offset;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
ut_a(nth_file < group->n_files);
......@@ -2177,15 +2178,17 @@ log_group_archive(
ulint n_files;
ulint open_mode;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
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;
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;
......@@ -2289,7 +2292,7 @@ log_group_archive(
group->next_archived_file_no = group->archived_file_no + n_files;
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)
{
log_group_t* group;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
......@@ -2325,6 +2330,8 @@ log_archive_write_complete_groups(void)
dulint end_lsn;
ulint i;
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
......@@ -2387,6 +2394,8 @@ void
log_archive_check_completion_low(void)
/*==================================*/
{
ut_a(0);
ut_ad(mutex_own(&(log_sys->mutex)));
if (log_sys->n_pending_archive_ios == 0
......@@ -2423,6 +2432,8 @@ log_io_complete_archive(void)
{
log_group_t* group;
ut_a(0);
mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
......@@ -2458,6 +2469,8 @@ log_archive_do(
dulint start_lsn;
dulint limit_lsn;
ut_a(0);
calc_new_limit = TRUE;
loop:
mutex_enter(&(log_sys->mutex));
......@@ -2484,7 +2497,7 @@ log_archive_do(
start_lsn = log_sys->archived_lsn;
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);
limit_lsn = ut_dulint_add(start_lsn,
log_sys->archive_buf_size);
......@@ -2584,6 +2597,8 @@ log_archive_all(void)
return;
}
ut_a(0);
present_lsn = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
......@@ -2621,11 +2636,17 @@ log_archive_close_groups(
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);
trunc_len = UNIV_PAGE_SIZE
* fil_space_get_size(group->archive_space_id);
if (trunc_len > 0) {
ut_a(trunc_len == group->file_size);
......@@ -2653,17 +2674,18 @@ log_archive_close_groups(
/********************************************************************
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
log file numbers start from 2 higher, so that the archiving will
not write again to the archived log files which exist when this function
returns. */
log file numbers start from 2 higher, so that the archiving will not write
again to the archived log files which exist when this function returns. */
ulint
log_archive_stop(void)
/*==================*/
/* out: DB_SUCCESS or DB_ERROR */
/* out: DB_SUCCESS or DB_ERROR */
{
ibool success;
ut_a(0);
mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state != LOG_ARCH_ON) {
......@@ -2676,7 +2698,7 @@ log_archive_stop(void)
log_sys->archiving_state = LOG_ARCH_STOPPING;
mutex_exit(&(log_sys->mutex));
log_archive_all();
mutex_enter(&(log_sys->mutex));
......@@ -2697,7 +2719,7 @@ log_archive_stop(void)
if appropriate */
log_archive_close_groups(TRUE);
mutex_exit(&(log_sys->mutex));
/* Make a checkpoint, so that if recovery is needed, the file numbers
......@@ -2726,6 +2748,8 @@ log_archive_start(void)
/*===================*/
/* out: DB_SUCCESS or DB_ERROR */
{
ut_a(0);
mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state != LOG_ARCH_STOPPED) {
......@@ -2752,6 +2776,7 @@ log_archive_noarchivelog(void)
/*==========================*/
/* out: DB_SUCCESS or DB_ERROR */
{
ut_a(0);
loop:
mutex_enter(&(log_sys->mutex));
......@@ -2784,6 +2809,7 @@ log_archive_archivelog(void)
/*========================*/
/* out: DB_SUCCESS or DB_ERROR */
{
ut_a(0);
mutex_enter(&(log_sys->mutex));
if (log_sys->archiving_state == LOG_ARCH_OFF) {
......@@ -2791,7 +2817,7 @@ log_archive_archivelog(void)
log_sys->archiving_state = LOG_ARCH_ON;
log_sys->archived_lsn = ut_dulint_align_down(log_sys->lsn,
OS_FILE_LOG_BLOCK_SIZE);
OS_FILE_LOG_BLOCK_SIZE);
mutex_exit(&(log_sys->mutex));
return(DB_SUCCESS);
......@@ -2802,6 +2828,7 @@ log_archive_archivelog(void)
return(DB_ERROR);
}
#ifdef notdefined
/********************************************************************
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
......@@ -2855,6 +2882,7 @@ log_archive_margin(void)
goto loop;
}
}
#endif
/************************************************************************
Checks that there is enough free space in the log to start a new query step.
......@@ -2871,7 +2899,7 @@ log_check_margins(void)
log_checkpoint_margin();
log_archive_margin();
/* log_archive_margin(); */
mutex_enter(&(log_sys->mutex));
......@@ -3009,7 +3037,7 @@ logs_empty_and_mark_files_at_shutdown(void)
goto loop;
}
log_archive_all();
/* log_archive_all(); */
log_make_checkpoint_at(ut_dulint_max, TRUE);
mutex_enter(&(log_sys->mutex));
......@@ -3027,15 +3055,16 @@ logs_empty_and_mark_files_at_shutdown(void)
goto loop;
}
arch_log_no =
arch_log_no = 0;
/*
UT_LIST_GET_FIRST(log_sys->log_groups)->archived_file_no;
if (0 == UT_LIST_GET_FIRST(log_sys->log_groups)->archived_offset) {
arch_log_no--;
}
log_archive_close_groups(TRUE);
*/
/* log_archive_close_groups(TRUE); */
mutex_exit(&(log_sys->mutex));
......
This diff is collapsed.
......@@ -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));
......
......@@ -595,6 +595,51 @@ dbname.sym can redirect a database directory:
#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. */
......@@ -602,7 +647,8 @@ os_file_t
os_file_create_simple(
/*==================*/
/* 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
string */
ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
......@@ -714,13 +760,16 @@ os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
/* 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
string */
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
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 */
{
#ifdef __WIN__
......@@ -728,6 +777,7 @@ os_file_create_simple_no_error_handling(
DWORD create_flag;
DWORD access;
DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ;
ut_a(name);
......@@ -744,6 +794,13 @@ os_file_create_simple_no_error_handling(
access = GENERIC_READ;
} else if (access_type == OS_FILE_READ_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 {
access = 0;
ut_error;
......@@ -751,8 +808,7 @@ os_file_create_simple_no_error_handling(
file = CreateFile(name,
access,
FILE_SHARE_READ,/* file can be read also by other
processes */
share_mode,
NULL, /* default security attributes */
create_flag,
attributes,
......@@ -808,7 +864,8 @@ os_file_t
os_file_create(
/*===========*/
/* 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
string */
ulint create_mode, /* in: OS_FILE_OPEN if an existing file is opened
......@@ -896,7 +953,7 @@ os_file_create(
start 2 instances of mysqld on the
SAME files, that could cause severe
database corruption! When opening
raw disk partitions Microsoft manuals
raw disk partitions, Microsoft manuals
say that we must give also the write
permission. */
NULL, /* default security attributes */
......@@ -1017,6 +1074,10 @@ os_file_delete(
{
#ifdef __WIN__
BOOL ret;
ulint count = 0;
loop:
/* In Windows, deleting an .ibd file may fail if ibbackup is copying
it */
ret = DeleteFile((LPCTSTR)name);
......@@ -1024,9 +1085,31 @@ os_file_delete(
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
int ret;
......@@ -1103,6 +1186,7 @@ os_file_close(
}
os_file_handle_error(file, NULL, "close");
return(FALSE);
#else
int ret;
......@@ -1111,6 +1195,7 @@ os_file_close(
if (ret == -1) {
os_file_handle_error(file, NULL, "close");
return(FALSE);
}
......
/* A lexical scanner generated by flex */
/* 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
......
......@@ -2346,8 +2346,13 @@ row_drop_table_for_mysql(
/* Do not drop possible .ibd tablespace if something went
wrong: we do not want to delete valuable data of the user */
if (err == DB_SUCCESS && space_id != 0
&& fil_tablespace_exists_in_mem(space_id)) {
if (err == DB_SUCCESS && space_id > 0) {
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);
......
......@@ -3288,7 +3288,13 @@ row_search_for_mysql(
} 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)) {
err = row_sel_build_prev_vers_for_mysql(
......
......@@ -102,7 +102,7 @@ char** srv_log_group_home_dirs = NULL;
ulint srv_n_log_groups = ULINT_MAX;
ulint srv_n_log_files = ULINT_MAX;
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_flush_log_at_trx_commit = 1;
......@@ -3209,11 +3209,13 @@ srv_master_thread(
goto loop;
}
mutex_exit(&kernel_mutex);
/*
srv_main_thread_op_info =
(char*)"archiving log (if log archive is on)";
log_archive_do(FALSE, &n_bytes_archived);
*/
n_bytes_archived = 0;
/* Keep looping in the background loop if still work to do */
......
......@@ -553,7 +553,6 @@ open_or_create_log_file(
ulint i) /* in: log file number in group */
{
ibool ret;
ulint arch_space_id;
ulint size;
ulint size_high;
char name[10000];
......@@ -649,9 +648,10 @@ open_or_create_log_file(
fil_node_create(name, srv_log_file_size,
2 * k + SRV_LOG_SPACE_FIRST_ID, FALSE);
#ifdef notdefined
/* 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) {
arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
......@@ -661,12 +661,13 @@ open_or_create_log_file(
} else {
arch_space_id = ULINT_UNDEFINED;
}
#endif
if (i == 0) {
log_group_init(k, srv_n_log_files,
srv_log_file_size * UNIV_PAGE_SIZE,
2 * k + SRV_LOG_SPACE_FIRST_ID,
arch_space_id);
SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch
space id */
}
return(DB_SUCCESS);
......@@ -1000,7 +1001,6 @@ innobase_start_or_create_for_mysql(void)
dulint max_flushed_lsn;
ulint min_arch_log_no;
ulint max_arch_log_no;
ibool start_archive;
ulint sum_of_new_sizes;
ulint sum_of_data_file_sizes;
ulint tablespace_size_in_header;
......@@ -1156,7 +1156,7 @@ NetWare. */
assume fewer threads. */
srv_max_n_threads = 10000;
} else {
srv_max_n_threads = 1000; /* saves several MB of memory,
srv_max_n_threads = 1000; /* saves several MB of memory,
especially in 64-bit
computers */
}
......@@ -1341,7 +1341,9 @@ NetWare. */
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));
}
......@@ -1430,6 +1432,8 @@ NetWare. */
log_make_checkpoint_at(ut_dulint_max, TRUE);
#ifdef notdefined
/* Archiving is always off under MySQL */
if (!srv_log_archive_on) {
ut_a(DB_SUCCESS == log_archive_noarchivelog());
} else {
......@@ -1447,7 +1451,7 @@ NetWare. */
ut_a(DB_SUCCESS == log_archive_archivelog());
}
}
#endif
if (!create_new_db && srv_force_recovery == 0) {
/* After a crash recovery we only check that the info in data
dictionary is consistent with what we already know about space
......
......@@ -71,9 +71,8 @@ ut_find_prime(
/* Found a prime */
break;
next_n: ;
next_n: ;
}
return(n);
}
......@@ -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
ut_clock(void)
......@@ -181,6 +181,50 @@ ut_sprintf_timestamp(
#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. */
......
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