MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ut0ut.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /***************************************************************/
26 #include "ut0ut.h"
27 
28 #ifndef UNIV_INNOCHECKSUM
29 
30 #include "ut0sort.h"
31 #include "os0thread.h" /* thread-ID */
32 
33 #ifdef UNIV_NONINL
34 #include "ut0ut.ic"
35 #endif
36 
37 #include <stdarg.h>
38 #include <string.h>
39 #include <ctype.h>
40 
41 #ifndef UNIV_HOTBACKUP
42 # include "trx0trx.h"
43 # include "ha_prototypes.h"
44 # include "mysql_com.h" /* NAME_LEN */
45 #endif /* UNIV_HOTBACKUP */
46 
48 UNIV_INTERN ibool ut_always_false = FALSE;
49 
50 #ifdef __WIN__
51 /*****************************************************************/
55 #define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
56 
57 
58 /*****************************************************************/
61 static
62 int
64 /*============*/
65  struct timeval* tv,
66  void* tz)
67 {
68  FILETIME ft;
69  ib_int64_t tm;
70 
71  if (!tv) {
72  errno = EINVAL;
73  return(-1);
74  }
75 
76  GetSystemTimeAsFileTime(&ft);
77 
78  tm = (ib_int64_t) ft.dwHighDateTime << 32;
79  tm |= ft.dwLowDateTime;
80 
81  ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
82  does not work */
83 
84  tm /= 10; /* Convert from 100 nsec periods to usec */
85 
86  /* If we don't convert to the Unix epoch the value for
87  struct timeval::tv_sec will overflow.*/
88  tm -= WIN_TO_UNIX_DELTA_USEC;
89 
90  tv->tv_sec = (long) (tm / 1000000L);
91  tv->tv_usec = (long) (tm % 1000000L);
92 
93  return(0);
94 }
95 #else
96 
98 #define ut_gettimeofday gettimeofday
99 #endif
100 
101 /**********************************************************/
105 UNIV_INTERN
106 ib_time_t
107 ut_time(void)
108 /*=========*/
109 {
110  return(time(NULL));
111 }
112 
113 #ifndef UNIV_HOTBACKUP
114 /**********************************************************/
120 UNIV_INTERN
121 int
123 /*========*/
124  ulint* sec,
125  ulint* ms)
126 {
127  struct timeval tv;
128  int ret;
129  int errno_gettimeofday;
130  int i;
131 
132  for (i = 0; i < 10; i++) {
133 
134  ret = ut_gettimeofday(&tv, NULL);
135 
136  if (ret == -1) {
137  errno_gettimeofday = errno;
138  ut_print_timestamp(stderr);
139  fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
140  strerror(errno_gettimeofday));
141  os_thread_sleep(100000); /* 0.1 sec */
142  errno = errno_gettimeofday;
143  } else {
144  break;
145  }
146  }
147 
148  if (ret != -1) {
149  *sec = (ulint) tv.tv_sec;
150  *ms = (ulint) tv.tv_usec;
151  }
152 
153  return(ret);
154 }
155 
156 /**********************************************************/
161 UNIV_INTERN
162 ullint
164 /*=======*/
165  ullint* tloc)
166 {
167  struct timeval tv;
168  ullint us;
169 
170  ut_gettimeofday(&tv, NULL);
171 
172  us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
173 
174  if (tloc != NULL) {
175  *tloc = us;
176  }
177 
178  return(us);
179 }
180 
181 /**********************************************************/
186 UNIV_INTERN
187 ulint
189 /*============*/
190 {
191  struct timeval tv;
192 
193  ut_gettimeofday(&tv, NULL);
194 
195  return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
196 }
197 #endif /* !UNIV_HOTBACKUP */
198 
199 /**********************************************************/
202 UNIV_INTERN
203 double
205 /*========*/
206  ib_time_t time2,
207  ib_time_t time1)
208 {
209  return(difftime(time2, time1));
210 }
211 
212 #endif /* !UNIV_INNOCHECKSUM */
213 
214 /**********************************************************/
216 UNIV_INTERN
217 void
219 /*===============*/
220  FILE* file)
221 {
222  ulint thread_id = 0;
223 
224 #ifndef UNIV_INNOCHECKSUM
225  thread_id = os_thread_pf(os_thread_get_curr_id());
226 #endif
227 
228 #ifdef __WIN__
229  SYSTEMTIME cal_tm;
230 
231  GetLocalTime(&cal_tm);
232 
233  fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lx",
234  (int) cal_tm.wYear,
235  (int) cal_tm.wMonth,
236  (int) cal_tm.wDay,
237  (int) cal_tm.wHour,
238  (int) cal_tm.wMinute,
239  (int) cal_tm.wSecond,
240  thread_id);
241 #else
242  struct tm* cal_tm_ptr;
243  time_t tm;
244 
245 #ifdef HAVE_LOCALTIME_R
246  struct tm cal_tm;
247  time(&tm);
248  localtime_r(&tm, &cal_tm);
249  cal_tm_ptr = &cal_tm;
250 #else
251  time(&tm);
252  cal_tm_ptr = localtime(&tm);
253 #endif
254  fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lx",
255  cal_tm_ptr->tm_year + 1900,
256  cal_tm_ptr->tm_mon + 1,
257  cal_tm_ptr->tm_mday,
258  cal_tm_ptr->tm_hour,
259  cal_tm_ptr->tm_min,
260  cal_tm_ptr->tm_sec,
261  thread_id);
262 #endif
263 }
264 
265 #ifndef UNIV_INNOCHECKSUM
266 
267 /**********************************************************/
269 UNIV_INTERN
270 void
272 /*=================*/
273  char* buf)
274 {
275 #ifdef __WIN__
276  SYSTEMTIME cal_tm;
277 
278  GetLocalTime(&cal_tm);
279 
280  sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
281  (int) cal_tm.wYear % 100,
282  (int) cal_tm.wMonth,
283  (int) cal_tm.wDay,
284  (int) cal_tm.wHour,
285  (int) cal_tm.wMinute,
286  (int) cal_tm.wSecond);
287 #else
288  struct tm* cal_tm_ptr;
289  time_t tm;
290 
291 #ifdef HAVE_LOCALTIME_R
292  struct tm cal_tm;
293  time(&tm);
294  localtime_r(&tm, &cal_tm);
295  cal_tm_ptr = &cal_tm;
296 #else
297  time(&tm);
298  cal_tm_ptr = localtime(&tm);
299 #endif
300  sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
301  cal_tm_ptr->tm_year % 100,
302  cal_tm_ptr->tm_mon + 1,
303  cal_tm_ptr->tm_mday,
304  cal_tm_ptr->tm_hour,
305  cal_tm_ptr->tm_min,
306  cal_tm_ptr->tm_sec);
307 #endif
308 }
309 
310 #ifdef UNIV_HOTBACKUP
311 /**********************************************************/
314 UNIV_INTERN
315 void
316 ut_sprintf_timestamp_without_extra_chars(
317 /*=====================================*/
318  char* buf)
319 {
320 #ifdef __WIN__
321  SYSTEMTIME cal_tm;
322 
323  GetLocalTime(&cal_tm);
324 
325  sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
326  (int) cal_tm.wYear % 100,
327  (int) cal_tm.wMonth,
328  (int) cal_tm.wDay,
329  (int) cal_tm.wHour,
330  (int) cal_tm.wMinute,
331  (int) cal_tm.wSecond);
332 #else
333  struct tm* cal_tm_ptr;
334  time_t tm;
335 
336 #ifdef HAVE_LOCALTIME_R
337  struct tm cal_tm;
338  time(&tm);
339  localtime_r(&tm, &cal_tm);
340  cal_tm_ptr = &cal_tm;
341 #else
342  time(&tm);
343  cal_tm_ptr = localtime(&tm);
344 #endif
345  sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
346  cal_tm_ptr->tm_year % 100,
347  cal_tm_ptr->tm_mon + 1,
348  cal_tm_ptr->tm_mday,
349  cal_tm_ptr->tm_hour,
350  cal_tm_ptr->tm_min,
351  cal_tm_ptr->tm_sec);
352 #endif
353 }
354 
355 /**********************************************************/
357 UNIV_INTERN
358 void
359 ut_get_year_month_day(
360 /*==================*/
361  ulint* year,
362  ulint* month,
363  ulint* day)
364 {
365 #ifdef __WIN__
366  SYSTEMTIME cal_tm;
367 
368  GetLocalTime(&cal_tm);
369 
370  *year = (ulint) cal_tm.wYear;
371  *month = (ulint) cal_tm.wMonth;
372  *day = (ulint) cal_tm.wDay;
373 #else
374  struct tm* cal_tm_ptr;
375  time_t tm;
376 
377 #ifdef HAVE_LOCALTIME_R
378  struct tm cal_tm;
379  time(&tm);
380  localtime_r(&tm, &cal_tm);
381  cal_tm_ptr = &cal_tm;
382 #else
383  time(&tm);
384  cal_tm_ptr = localtime(&tm);
385 #endif
386  *year = (ulint) cal_tm_ptr->tm_year + 1900;
387  *month = (ulint) cal_tm_ptr->tm_mon + 1;
388  *day = (ulint) cal_tm_ptr->tm_mday;
389 #endif
390 }
391 #endif /* UNIV_HOTBACKUP */
392 
393 #ifndef UNIV_HOTBACKUP
394 /*************************************************************/
398 UNIV_INTERN
399 ulint
401 /*=====*/
402  ulint delay)
403 {
404  ulint i, j;
405 
406  j = 0;
407 
408  for (i = 0; i < delay * 50; i++) {
409  j += i;
410  UT_RELAX_CPU();
411  }
412 
413  if (ut_always_false) {
414  ut_always_false = (ibool) j;
415  }
416 
417  return(j);
418 }
419 #endif /* !UNIV_HOTBACKUP */
420 
421 /*************************************************************/
423 UNIV_INTERN
424 void
426 /*=========*/
427  FILE* file,
428  const void* buf,
429  ulint len)
430 {
431  const byte* data;
432  ulint i;
433 
434  UNIV_MEM_ASSERT_RW(buf, len);
435 
436  fprintf(file, " len %lu; hex ", len);
437 
438  for (data = (const byte*) buf, i = 0; i < len; i++) {
439  fprintf(file, "%02lx", (ulong)*data++);
440  }
441 
442  fputs("; asc ", file);
443 
444  data = (const byte*) buf;
445 
446  for (i = 0; i < len; i++) {
447  int c = (int) *data++;
448  putc(isprint(c) ? c : ' ', file);
449  }
450 
451  putc(';', file);
452 }
453 
454 /**********************************************************************/
456 UNIV_INTERN
457 void
459 /*==========*/
460  ulint* arr,
461  ulint* aux_arr,
462  ulint low,
463  ulint high)
464 {
465  UT_SORT_FUNCTION_BODY(ut_ulint_sort, arr, aux_arr, low, high,
466  ut_ulint_cmp);
467 }
468 
469 /*************************************************************/
472 UNIV_INTERN
473 ulint
475 /*==========*/
476  ulint n)
477 {
478  ulint res;
479 
480  res = 1;
481 
482  ut_ad(n > 0);
483 
484  while (res < n) {
485  res = res * 2;
486  }
487 
488  return(res);
489 }
490 
491 /**********************************************************************/
493 UNIV_INTERN
494 void
496 /*==============*/
497  FILE* f,
498  const char* name)
499 {
500  putc('\'', f);
501  for (;;) {
502  int c = *name++;
503  switch (c) {
504  case 0:
505  goto done;
506  case '\'':
507  putc(c, f);
508  /* fall through */
509  default:
510  putc(c, f);
511  }
512  }
513 done:
514  putc('\'', f);
515 }
516 #ifndef UNIV_HOTBACKUP
517 /**********************************************************************/
522 UNIV_INTERN
523 void
525 /*==========*/
526  FILE* f,
527  const trx_t* trx,
528  ibool table_id,
530  const char* name)
531 {
532  ut_print_namel(f, trx, table_id, name, strlen(name));
533 }
534 
535 /**********************************************************************/
540 UNIV_INTERN
541 void
543 /*===========*/
544  FILE* f,
545  const trx_t* trx,
546  ibool table_id,
548  const char* name,
549  ulint namelen)
550 {
551  /* 2 * NAME_LEN for database and table name,
552  and some slack for the #mysql50# prefix and quotes */
553  char buf[3 * NAME_LEN];
554  const char* bufend;
555 
556  bufend = innobase_convert_name(buf, sizeof buf,
557  name, namelen,
558  trx ? trx->mysql_thd : NULL,
559  table_id);
560 
561  fwrite(buf, 1, bufend - buf, f);
562 }
563 
564 /**********************************************************************/
569 UNIV_INTERN
570 char*
572 /*===========*/
573  const char* name,
575  ibool is_table,
577  char* formatted,
579  ulint formatted_size)
581 {
582  switch (formatted_size) {
583  case 1:
584  formatted[0] = '\0';
585  /* FALL-THROUGH */
586  case 0:
587  return(formatted);
588  }
589 
590  char* end;
591 
592  end = innobase_convert_name(formatted, formatted_size,
593  name, strlen(name), NULL, is_table);
594 
595  /* If the space in 'formatted' was completely used, then sacrifice
596  the last character in order to write '\0' at the end. */
597  if ((ulint) (end - formatted) == formatted_size) {
598  end--;
599  }
600 
601  ut_a((ulint) (end - formatted) < formatted_size);
602 
603  *end = '\0';
604 
605  return(formatted);
606 }
607 
608 /**********************************************************************/
610 UNIV_INTERN
611 void
613 /*=========*/
614  FILE* dest,
615  FILE* src)
616 {
617  long len = ftell(src);
618  char buf[4096];
619 
620  rewind(src);
621  do {
622  size_t maxs = len < (long) sizeof buf
623  ? (size_t) len
624  : sizeof buf;
625  size_t size = fread(buf, 1, maxs, src);
626  fwrite(buf, 1, size, dest);
627  len -= (long) size;
628  if (size < maxs) {
629  break;
630  }
631  } while (len > 0);
632 }
633 #endif /* !UNIV_HOTBACKUP */
634 
635 #ifdef __WIN__
636 # include <stdarg.h>
637 /**********************************************************************/
644 UNIV_INTERN
645 void
647 /*=========*/
648  char* str,
649  size_t size,
650  const char* fmt,
651  va_list ap)
652 {
653  _vsnprintf(str, size, fmt, ap);
654  str[size - 1] = '\0';
655 }
656 
657 /**********************************************************************/
662 UNIV_INTERN
663 int
665 /*========*/
666  char* str,
667  size_t size,
668  const char* fmt,
669  ...)
670 {
671  int res;
672  va_list ap1;
673  va_list ap2;
674 
675  va_start(ap1, fmt);
676  va_start(ap2, fmt);
677 
678  res = _vscprintf(fmt, ap1);
679  ut_a(res != -1);
680 
681  if (size > 0) {
682  _vsnprintf(str, size, fmt, ap2);
683 
684  if ((size_t) res >= size) {
685  str[size - 1] = '\0';
686  }
687  }
688 
689  va_end(ap1);
690  va_end(ap2);
691 
692  return(res);
693 }
694 #endif /* __WIN__ */
695 
696 /*************************************************************/
700 UNIV_INTERN
701 const char*
703 /*======*/
704  dberr_t num)
705 {
706  switch (num) {
707  case DB_SUCCESS:
708  return("Success");
710  return("Success, record lock created");
711  case DB_ERROR:
712  return("Generic error");
713  case DB_READ_ONLY:
714  return("Read only transaction");
715  case DB_INTERRUPTED:
716  return("Operation interrupted");
717  case DB_OUT_OF_MEMORY:
718  return("Cannot allocate memory");
719  case DB_OUT_OF_FILE_SPACE:
720  return("Out of disk space");
721  case DB_LOCK_WAIT:
722  return("Lock wait");
723  case DB_DEADLOCK:
724  return("Deadlock");
725  case DB_ROLLBACK:
726  return("Rollback");
727  case DB_DUPLICATE_KEY:
728  return("Duplicate key");
729  case DB_QUE_THR_SUSPENDED:
730  return("The queue thread has been suspended");
731  case DB_MISSING_HISTORY:
732  return("Required history data has been deleted");
733  case DB_CLUSTER_NOT_FOUND:
734  return("Cluster not found");
735  case DB_TABLE_NOT_FOUND:
736  return("Table not found");
738  return("More file space needed");
739  case DB_TABLE_IS_BEING_USED:
740  return("Table is being used");
741  case DB_TOO_BIG_RECORD:
742  return("Record too big");
744  return("Index columns size too big");
746  return("Lock wait timeout");
748  return("Referenced key value not found");
750  return("Row is referenced");
752  return("Cannot add constraint");
753  case DB_CORRUPTION:
754  return("Data structure corruption");
756  return("Cannot drop constraint");
757  case DB_NO_SAVEPOINT:
758  return("No such savepoint");
760  return("Tablespace already exists");
762  return("Tablespace deleted or being deleted");
763  case DB_TABLESPACE_NOT_FOUND:
764  return("Tablespace not found");
765  case DB_LOCK_TABLE_FULL:
766  return("Lock structs have exhausted the buffer pool");
768  return("Foreign key activated with duplicate keys");
770  return("Foreign key cascade delete/update exceeds max depth");
772  return("Too many concurrent transactions");
773  case DB_UNSUPPORTED:
774  return("Unsupported");
775  case DB_INVALID_NULL:
776  return("NULL value encountered in NOT NULL column");
778  return("Persistent statistics do not exist");
779  case DB_FAIL:
780  return("Failed, retry may succeed");
781  case DB_OVERFLOW:
782  return("Overflow");
783  case DB_UNDERFLOW:
784  return("Underflow");
785  case DB_STRONG_FAIL:
786  return("Failed, retry will not succeed");
787  case DB_ZIP_OVERFLOW:
788  return("Zip overflow");
789  case DB_RECORD_NOT_FOUND:
790  return("Record not found");
791  case DB_CHILD_NO_INDEX:
792  return("No index on referencing keys in referencing table");
793  case DB_PARENT_NO_INDEX:
794  return("No index on referenced keys in referenced table");
795  case DB_FTS_INVALID_DOCID:
796  return("FTS Doc ID cannot be zero");
797  case DB_INDEX_CORRUPT:
798  return("Index corrupted");
800  return("Undo record too big");
801  case DB_END_OF_INDEX:
802  return("End of index");
803  case DB_IO_ERROR:
804  return("I/O error");
805  case DB_TABLE_IN_FK_CHECK:
806  return("Table is being used in foreign key check");
807  case DB_DATA_MISMATCH:
808  return("data mismatch");
810  return("schema not locked");
811  case DB_NOT_FOUND:
812  return("not found");
814  return("Log size exceeded during online index creation");
815  case DB_DICT_CHANGED:
816  return("Table dictionary has changed");
818  return("Identifier name is too long");
820  return("FTS query exceeds result cache limit");
821 
822  /* do not add default: in order to produce a warning if new code
823  is added to the enum but not added here */
824  }
825 
826  /* we abort here because if unknown error code is given, this could
827  mean that memory corruption has happened and someone's error-code
828  variable has been overwritten with bogus data */
829  ut_error;
830 
831  /* NOT REACHED */
832  return("Unknown error");
833 }
834 #endif /* !UNIV_INNOCHECKSUM */