1
/*****************************************************************************
3
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2009, Sun Microsystems, Inc.
6
Portions of this file contain modifications contributed and copyrighted by
7
Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
8
are described briefly in the InnoDB documentation. The contributions by
9
Sun Microsystems are incorporated with their permission, and subject to the
10
conditions contained in the file COPYING.Sun_Microsystems.
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
St, Fifth Floor, Boston, MA 02110-1301 USA
24
*****************************************************************************/
26
/***************************************************************//**
28
Various utilities for Innobase.
30
Created 5/11/1994 Heikki Tuuri
31
********************************************************************/
43
#ifndef UNIV_HOTBACKUP
45
# if defined(BUILD_DRIZZLE)
46
# include "drizzled/common.h"
47
# if TIME_WITH_SYS_TIME
48
# include <sys/time.h>
52
# include <sys/time.h>
58
# include "ha_prototypes.h"
59
# include "mysql_com.h" /* NAME_LEN */
61
#endif /* UNIV_HOTBACKUP */
65
/** A constant to prevent the compiler from optimizing ut_delay() away. */
66
UNIV_INTERN ibool ut_always_false = FALSE;
69
/*****************************************************************//**
70
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
71
epoch starts from 1970/1/1. For selection of constant see:
72
http://support.microsoft.com/kb/167296/ */
73
#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
76
/*****************************************************************//**
77
This is the Windows version of gettimeofday(2).
78
@return 0 if all OK else -1 */
83
struct timeval* tv, /*!< out: Values are relative to Unix epoch */
84
void* tz) /*!< in: not used */
94
GetSystemTimeAsFileTime(&ft);
96
tm = (ib_int64_t) ft.dwHighDateTime << 32;
97
tm |= ft.dwLowDateTime;
99
ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
102
tm /= 10; /* Convert from 100 nsec periods to usec */
104
/* If we don't convert to the Unix epoch the value for
105
struct timeval::tv_sec will overflow.*/
106
tm -= WIN_TO_UNIX_DELTA_USEC;
108
tv->tv_sec = (long) (tm / 1000000L);
109
tv->tv_usec = (long) (tm % 1000000L);
114
/** An alias for gettimeofday(2). On Microsoft Windows, we have to
115
reimplement this function. */
116
#define ut_gettimeofday gettimeofday
119
/********************************************************//**
120
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
121
but since there seem to be compiler bugs in both gcc and Visual C++,
122
we do this by a special conversion.
128
ulint a) /*!< in: ulint */
139
/**********************************************************//**
140
Returns system time. We do not specify the format of the time returned:
141
the only way to manipulate it is to use the function ut_difftime.
142
@return system time */
151
#ifndef UNIV_HOTBACKUP
152
/**********************************************************//**
154
Upon successful completion, the value 0 is returned; otherwise the
155
value -1 is returned and the global variable errno is set to indicate the
157
@return 0 on success, -1 otherwise */
162
ulint* sec, /*!< out: seconds since the Epoch */
163
ulint* ms) /*!< out: microseconds since the Epoch+*sec */
167
int errno_gettimeofday;
170
for (i = 0; i < 10; i++) {
172
ret = ut_gettimeofday(&tv, NULL);
175
errno_gettimeofday = errno;
176
ut_print_timestamp(stderr);
177
fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
178
strerror(errno_gettimeofday));
179
os_thread_sleep(100000); /* 0.1 sec */
180
errno = errno_gettimeofday;
187
*sec = (ulint) tv.tv_sec;
188
*ms = (ulint) tv.tv_usec;
194
/**********************************************************//**
195
Returns the number of microseconds since epoch. Similar to
196
time(3), the return value is also stored in *tloc, provided
197
that tloc is non-NULL.
198
@return us since epoch */
203
ullint* tloc) /*!< out: us since epoch, if non-NULL */
208
ut_gettimeofday(&tv, NULL);
210
us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
219
/**********************************************************//**
220
Returns the number of milliseconds since some epoch. The
221
value may wrap around. It should only be used for heuristic
223
@return ms since epoch */
231
ut_gettimeofday(&tv, NULL);
233
return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
235
#endif /* !UNIV_HOTBACKUP */
237
/**********************************************************//**
238
Returns the difference of two times in seconds.
239
@return time2 - time1 expressed in seconds */
244
ib_time_t time2, /*!< in: time */
245
ib_time_t time1) /*!< in: time */
247
return(difftime(time2, time1));
250
/**********************************************************//**
251
Prints a timestamp to a file. */
256
FILE* file) /*!< in: file where to print */
261
GetLocalTime(&cal_tm);
263
fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
264
(int)cal_tm.wYear % 100,
269
(int)cal_tm.wSecond);
272
struct tm* cal_tm_ptr;
277
#ifdef HAVE_LOCALTIME_R
278
localtime_r(&tm, &cal_tm);
279
cal_tm_ptr = &cal_tm;
281
cal_tm_ptr = localtime(&tm);
283
fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
284
cal_tm_ptr->tm_year % 100,
285
cal_tm_ptr->tm_mon + 1,
293
/**********************************************************//**
294
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
297
ut_sprintf_timestamp(
298
/*=================*/
299
char* buf) /*!< in: buffer where to sprintf */
304
GetLocalTime(&cal_tm);
306
sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
307
(int)cal_tm.wYear % 100,
312
(int)cal_tm.wSecond);
315
struct tm* cal_tm_ptr;
320
#ifdef HAVE_LOCALTIME_R
321
localtime_r(&tm, &cal_tm);
322
cal_tm_ptr = &cal_tm;
324
cal_tm_ptr = localtime(&tm);
326
sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
327
cal_tm_ptr->tm_year % 100,
328
cal_tm_ptr->tm_mon + 1,
336
#ifdef UNIV_HOTBACKUP
337
/**********************************************************//**
338
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
342
ut_sprintf_timestamp_without_extra_chars(
343
/*=====================================*/
344
char* buf) /*!< in: buffer where to sprintf */
349
GetLocalTime(&cal_tm);
351
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
352
(int)cal_tm.wYear % 100,
357
(int)cal_tm.wSecond);
360
struct tm* cal_tm_ptr;
365
#ifdef HAVE_LOCALTIME_R
366
localtime_r(&tm, &cal_tm);
367
cal_tm_ptr = &cal_tm;
369
cal_tm_ptr = localtime(&tm);
371
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
372
cal_tm_ptr->tm_year % 100,
373
cal_tm_ptr->tm_mon + 1,
381
/**********************************************************//**
382
Returns current year, month, day. */
385
ut_get_year_month_day(
386
/*==================*/
387
ulint* year, /*!< out: current year */
388
ulint* month, /*!< out: month */
389
ulint* day) /*!< out: day */
394
GetLocalTime(&cal_tm);
396
*year = (ulint)cal_tm.wYear;
397
*month = (ulint)cal_tm.wMonth;
398
*day = (ulint)cal_tm.wDay;
401
struct tm* cal_tm_ptr;
406
#ifdef HAVE_LOCALTIME_R
407
localtime_r(&tm, &cal_tm);
408
cal_tm_ptr = &cal_tm;
410
cal_tm_ptr = localtime(&tm);
412
*year = (ulint)cal_tm_ptr->tm_year + 1900;
413
*month = (ulint)cal_tm_ptr->tm_mon + 1;
414
*day = (ulint)cal_tm_ptr->tm_mday;
417
#endif /* UNIV_HOTBACKUP */
419
#ifndef UNIV_HOTBACKUP
420
/*************************************************************//**
421
Runs an idle loop on CPU. The argument gives the desired delay
422
in microseconds on 100 MHz Pentium + Visual C++.
423
@return dummy value */
428
ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
434
for (i = 0; i < delay * 50; i++) {
439
if (ut_always_false) {
440
ut_always_false = (ibool) j;
445
#endif /* !UNIV_HOTBACKUP */
447
/*************************************************************//**
448
Prints the contents of a memory buffer in hex and ascii. */
453
FILE* file, /*!< in: file where to print */
454
const void* buf, /*!< in: memory buffer */
455
ulint len) /*!< in: length of the buffer */
460
UNIV_MEM_ASSERT_RW(buf, len);
462
fprintf(file, " len %lu; hex ", len);
464
for (data = (const byte*)buf, i = 0; i < len; i++) {
465
fprintf(file, "%02lx", (ulong)*data++);
468
fputs("; asc ", file);
470
data = (const byte*)buf;
472
for (i = 0; i < len; i++) {
473
int c = (int) *data++;
474
putc(isprint(c) ? c : ' ', file);
480
/*************************************************************//**
481
Calculates fast the number rounded up to the nearest power of 2.
482
@return first power of 2 which is >= n */
487
ulint n) /*!< in: number != 0 */
502
/**********************************************************************//**
503
Outputs a NUL-terminated file name, quoted with apostrophes. */
508
FILE* f, /*!< in: output stream */
509
const char* name) /*!< in: name to print */
527
#ifndef UNIV_HOTBACKUP
528
/**********************************************************************//**
529
Outputs a fixed-length string, quoted as an SQL identifier.
530
If the string contains a slash '/', the string will be
531
output as two identifiers separated by a period (.),
532
as in SQL database_name.identifier. */
537
FILE* f, /*!< in: output stream */
538
trx_t* trx, /*!< in: transaction */
539
ibool table_id,/*!< in: TRUE=print a table name,
540
FALSE=print other identifier */
541
const char* name) /*!< in: name to print */
543
ut_print_namel(f, trx, table_id, name, strlen(name));
546
/**********************************************************************//**
547
Outputs a fixed-length string, quoted as an SQL identifier.
548
If the string contains a slash '/', the string will be
549
output as two identifiers separated by a period (.),
550
as in SQL database_name.identifier. */
555
FILE* f, /*!< in: output stream */
556
trx_t* trx, /*!< in: transaction (NULL=no quotes) */
557
ibool table_id,/*!< in: TRUE=print a table name,
558
FALSE=print other identifier */
559
const char* name, /*!< in: name to print */
560
ulint namelen)/*!< in: length of name */
562
/* 2 * NAME_LEN for database and table name,
563
and some slack for the #mysql50# prefix and quotes */
564
char buf[3 * NAME_LEN];
567
bufend = innobase_convert_name(buf, sizeof buf,
569
trx ? trx->mysql_thd : NULL,
572
ssize_t ret= fwrite(buf, 1, bufend - buf, f);
573
assert(ret==bufend-buf);
576
/**********************************************************************//**
582
FILE* dest, /*!< in: output file */
583
FILE* src) /*!< in: input file to be appended to output */
585
long len = ftell(src);
590
size_t maxs = len < (long) sizeof buf
593
size_t size = fread(buf, 1, maxs, src);
594
size_t ret= fwrite(buf, 1, size, dest);
602
#endif /* !UNIV_HOTBACKUP */
606
/**********************************************************************//**
607
A substitute for snprintf(3), formatted output conversion into
609
@return number of characters that would have been printed if the size
610
were unlimited, not including the terminating '\0'. */
615
char* str, /*!< out: string */
616
size_t size, /*!< in: str size */
617
const char* fmt, /*!< in: format */
618
...) /*!< in: format values */
627
res = _vscprintf(fmt, ap1);
631
_vsnprintf(str, size, fmt, ap2);
633
if ((size_t) res >= size) {
634
str[size - 1] = '\0';
645
/*************************************************************//**
646
Convert an error number to a human readable text message. The
647
returned string is static and should not be freed or modified.
648
@return string, describing the error */
653
enum db_err num) /*!< in: error number */
658
case DB_SUCCESS_LOCKED_REC:
659
return("Success, record lock created");
661
return("Generic error");
663
return("Operation interrupted");
664
case DB_OUT_OF_MEMORY:
665
return("Cannot allocate memory");
666
case DB_OUT_OF_FILE_SPACE:
667
return("Out of disk space");
674
case DB_DUPLICATE_KEY:
675
return("Duplicate key");
676
case DB_QUE_THR_SUSPENDED:
677
return("The queue thread has been suspended");
678
case DB_MISSING_HISTORY:
679
return("Required history data has been deleted");
680
case DB_CLUSTER_NOT_FOUND:
681
return("Cluster not found");
682
case DB_TABLE_NOT_FOUND:
683
return("Table not found");
684
case DB_MUST_GET_MORE_FILE_SPACE:
685
return("More file space needed");
686
case DB_TABLE_IS_BEING_USED:
687
return("Table is being used");
688
case DB_TOO_BIG_RECORD:
689
return("Record too big");
690
case DB_LOCK_WAIT_TIMEOUT:
691
return("Lock wait timeout");
692
case DB_NO_REFERENCED_ROW:
693
return("Referenced key value not found");
694
case DB_ROW_IS_REFERENCED:
695
return("Row is referenced");
696
case DB_CANNOT_ADD_CONSTRAINT:
697
return("Cannot add constraint");
699
return("Data structure corruption");
700
case DB_COL_APPEARS_TWICE_IN_INDEX:
701
return("Column appears twice in index");
702
case DB_CANNOT_DROP_CONSTRAINT:
703
return("Cannot drop constraint");
704
case DB_NO_SAVEPOINT:
705
return("No such savepoint");
706
case DB_TABLESPACE_ALREADY_EXISTS:
707
return("Tablespace already exists");
708
case DB_TABLESPACE_DELETED:
709
return("No such tablespace");
710
case DB_LOCK_TABLE_FULL:
711
return("Lock structs have exhausted the buffer pool");
712
case DB_FOREIGN_DUPLICATE_KEY:
713
return("Foreign key activated with duplicate keys");
714
case DB_FOREIGN_EXCEED_MAX_CASCADE:
715
return("Foreign key cascade delete/update exceeds max depth");
716
case DB_TOO_MANY_CONCURRENT_TRXS:
717
return("Too many concurrent transactions");
719
return("Unsupported");
720
case DB_PRIMARY_KEY_IS_NULL:
721
return("Primary key is NULL");
722
case DB_STATS_DO_NOT_EXIST:
723
return("Persistent statistics do not exist");
725
return("Failed, retry may succeed");
731
return("Failed, retry will not succeed");
732
case DB_ZIP_OVERFLOW:
733
return("Zip overflow");
734
case DB_RECORD_NOT_FOUND:
735
return("Record not found");
736
case DB_END_OF_INDEX:
737
return("End of index");
738
/* do not add default: in order to produce a warning if new code
739
is added to the enum but not added here */
742
/* we abort here because if unknown error code is given, this could
743
mean that memory corruption has happened and someone's error-code
744
variable has been overwritten with bogus data */
748
return("Unknown error");