diff options
Diffstat (limited to 'innobase/include')
29 files changed, 460 insertions, 65 deletions
diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index bea85565125..d22f9d79c1c 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -49,6 +49,12 @@ inserted to the index, at the searched position */ /* This flag ORed to latch mode says that we do the search in query optimization */ #define BTR_ESTIMATE 1024 + +/* This flag ORed to latch mode says that we can ignore possible +UNIQUE definition on secondary indexes when we decide if we can use the +insert buffer to speed up inserts */ +#define BTR_IGNORE_SEC_UNIQUE 2048 + /****************************************************************** Gets a buffer page and declares its latching order level. */ UNIV_INLINE diff --git a/innobase/include/buf0flu.h b/innobase/include/buf0flu.h index cb1c0965a65..1b40acaa269 100644 --- a/innobase/include/buf0flu.h +++ b/innobase/include/buf0flu.h @@ -28,6 +28,16 @@ a margin of replaceable pages there. */ void buf_flush_free_margin(void); /*=======================*/ +/************************************************************************ +Initializes a page for writing to the tablespace. */ + +void +buf_flush_init_for_writing( +/*=======================*/ + byte* page, /* in: page */ + dulint newest_lsn, /* in: newest modification lsn to the page */ + ulint space, /* in: space id */ + ulint page_no); /* in: page number */ /*********************************************************************** This utility flushes dirty blocks from the end of the LRU list or flush_list. NOTE 1: in the case of an LRU flush the calling thread may own latches to diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 0f6f516c2cb..fd79e17090a 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -105,7 +105,8 @@ dict_table_autoinc_initialize( dict_table_t* table, /* in: table */ ib_longlong value); /* in: value which was assigned to a row */ /************************************************************************ -Gets the next autoinc value, 0 if not yet initialized. */ +Gets the next autoinc value, 0 if not yet initialized. If initialized, +increments the counter by 1. */ ib_longlong dict_table_autoinc_get( @@ -113,6 +114,15 @@ dict_table_autoinc_get( /* out: value for a new row, or 0 */ dict_table_t* table); /* in: table */ /************************************************************************ +Reads the autoinc counter value, 0 if not yet initialized. Does not +increment the counter. */ + +ib_longlong +dict_table_autoinc_read( +/*====================*/ + /* out: value of the counter */ + dict_table_t* table); /* in: table */ +/************************************************************************ Updates the autoinc counter if the value supplied is bigger than the current value. If not inited, does nothing. */ @@ -143,7 +153,10 @@ dict_table_rename_in_cache( /*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ - char* new_name); /* in: new name */ + char* new_name, /* in: new name */ + ibool rename_also_foreigns);/* in: in ALTER TABLE we want + to preserve the original table name + in constraints which reference it */ /************************************************************************** Adds a foreign key constraint object to the dictionary cache. May free the object if there already is an object with the same identifier in. @@ -284,6 +297,10 @@ Sprintfs to a string info on foreign keys of a table. */ void dict_print_info_on_foreign_keys( /*============================*/ + ibool create_table_format, /* in: if TRUE then print in + a format suitable to be inserted into + a CREATE TABLE, otherwise in the format + of SHOW TABLE STATUS */ char* str, /* in/out: pointer to a string */ ulint len, /* in: space in str available for info */ dict_table_t* table); /* in: table */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 5ef0103087a..ef15c99fdba 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -249,6 +249,8 @@ struct dict_foreign_struct{ this memory heap */ char* id; /* id of the constraint as a null-terminated string */ + ulint type; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE + or DICT_FOREIGN_ON_DELETE_SET_NULL */ char* foreign_table_name;/* foreign table name */ dict_table_t* foreign_table; /* table where the foreign key is */ char** foreign_col_names;/* names of the columns in the @@ -278,6 +280,9 @@ struct dict_foreign_struct{ table */ }; +#define DICT_FOREIGN_ON_DELETE_CASCADE 1 +#define DICT_FOREIGN_ON_DELETE_SET_NULL 2 + #define DICT_INDEX_MAGIC_N 76789786 /* Data structure for a database table */ @@ -313,6 +318,12 @@ struct dict_table_struct{ NOT allowed until this count gets to zero; MySQL does NOT itself check the number of open handles at drop */ + ulint n_foreign_key_checks_running; + /* count of how many foreign key check + operations are currently being performed + on the table: we cannot drop the table while + there are foreign key checks running on + it! */ ibool cached; /* TRUE if the table object has been added to the dictionary cache */ lock_t* auto_inc_lock;/* a buffer for an auto-inc lock @@ -359,17 +370,16 @@ struct dict_table_struct{ after database startup or table creation */ ulint stat_modified_counter; /* when a row is inserted, updated, or deleted, - we add the row length to this number; we - calculate new estimates for the stat_... - values for the table and the indexes at an - interval of 2 GB or when about 1 / 16 of table - has been modified; also - when the estimate operation is called - for MySQL SHOW TABLE STATUS; the counter is - reset to zero at statistics calculation; - this counter - is not protected by any latch, because this - is only used for heuristics */ + we add 1 to this number; we calculate new + estimates for the stat_... values for the + table and the indexes at an interval of 2 GB + or when about 1 / 16 of table has been + modified; also when the estimate operation is + called for MySQL SHOW TABLE STATUS; the + counter is reset to zero at statistics + calculation; this counter is not protected by + any latch, because this is only used for + heuristics */ /*----------------------*/ mutex_t autoinc_mutex; /* mutex protecting the autoincrement diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index ca74ea4cb2c..63e20221c16 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -64,8 +64,10 @@ extern fil_addr_t fil_addr_null; #define FIL_PAGE_DATA 38 /* start of the data on the page */ /* File page trailer */ -#define FIL_PAGE_END_LSN 8 /* this should be same as - FIL_PAGE_LSN */ +#define FIL_PAGE_END_LSN 8 /* the low 4 bytes of this are used + to store the page checksum, the + last 4 bytes should be identical + to the last 4 bytes of FIL_PAGE_LSN */ #define FIL_PAGE_DATA_END 8 /* File page types */ @@ -134,6 +136,21 @@ fil_space_truncate_start( ulint trunc_len); /* in: truncate by this much; it is an error if this does not equal to the combined size of some initial files in the space */ +/************************************************************************** +Tries to extend a data file by the number of pages given. Any fractions of a +megabyte are ignored. */ + +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 orginal 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 size_increase); /* in: try to extend this many pages */ /*********************************************************************** Frees a space object from a file system. Closes the files in the chain but does not delete them. */ diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h index e7f9eab330b..a0197ec2d97 100644 --- a/innobase/include/fsp0fsp.h +++ b/innobase/include/fsp0fsp.h @@ -46,6 +46,17 @@ void fsp_init(void); /*==========*/ /************************************************************************** +Gets the current free limit of a tablespace. The free limit means the +place of the first page which has never been put to the the free list +for allocation. The space above that address is initialized to zero. +Sets also the global variable log_fsp_current_free_limit. */ + +ulint +fsp_header_get_free_limit( +/*======================*/ + /* out: free limit in megabytes */ + ulint space); /* in: space id */ +/************************************************************************** Initializes the space header of a new created space. */ void diff --git a/innobase/include/ibuf0ibuf.h b/innobase/include/ibuf0ibuf.h index 99fb1595f49..fac28461be4 100644 --- a/innobase/include/ibuf0ibuf.h +++ b/innobase/include/ibuf0ibuf.h @@ -127,7 +127,11 @@ UNIV_INLINE ibool ibuf_should_try( /*============*/ - dict_index_t* index); /* in: index where to insert */ + dict_index_t* index, /* in: index where to insert */ + ulint ignore_sec_unique); /* in: if != 0, we should + ignore UNIQUE constraint on + a secondary index when we + decide */ /********************************************************************** Returns TRUE if the current OS thread is performing an insert buffer routine. */ diff --git a/innobase/include/ibuf0ibuf.ic b/innobase/include/ibuf0ibuf.ic index e969a0550da..0886c8c02cc 100644 --- a/innobase/include/ibuf0ibuf.ic +++ b/innobase/include/ibuf0ibuf.ic @@ -81,10 +81,16 @@ UNIV_INLINE ibool ibuf_should_try( /*============*/ - dict_index_t* index) /* in: index where to insert */ + dict_index_t* index, /* in: index where to insert */ + ulint ignore_sec_unique) /* in: if != 0, we should + ignore UNIQUE constraint on + a secondary index when we + decide */ { - if (!(index->type & (DICT_CLUSTERED | DICT_UNIQUE)) - && ibuf->meter > IBUF_THRESHOLD) { + if (!(index->type & DICT_CLUSTERED) + && (ignore_sec_unique || !(index->type & DICT_UNIQUE)) + && ibuf->meter > IBUF_THRESHOLD) { + ibuf_flush_count++; if (ibuf_flush_count % 8 == 0) { diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index adff9fae544..eeb4f2e45f1 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -26,6 +26,32 @@ extern ibool log_debug_writes; #define LOG_WAIT_ALL_GROUPS 93 #define LOG_MAX_N_GROUPS 32 +/******************************************************************** +Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint, +so that we know that the limit has been written to a log checkpoint field +on disk. */ + +void +log_fsp_current_free_limit_set_and_checkpoint( +/*==========================================*/ + ulint limit); /* in: limit to set */ +/*********************************************************************** +Calculates where in log files we find a specified lsn. */ + +ulint +log_calc_where_lsn_is( +/*==================*/ + /* out: log file number */ + ib_longlong* log_file_offset, /* out: offset in that file + (including the header) */ + dulint first_header_lsn, /* in: first log file start + lsn */ + dulint lsn, /* in: lsn whose position to + determine */ + ulint n_log_files, /* in: total number of log + files */ + ib_longlong log_file_size); /* in: log file size + (including the header) */ /**************************************************************** Writes to the log the string given. The log must be released with log_release. */ @@ -225,6 +251,16 @@ Writes checkpoint info to groups. */ void log_groups_write_checkpoint_info(void); /*==================================*/ +/********************************************************** +Writes info to a buffer of a log group when log files are created in +backup restoration. */ + +void +log_reset_first_header_and_checkpoint( +/*==================================*/ + byte* hdr_buf,/* in: buffer which will be written to the start + of the first log file */ + dulint lsn); /* in: lsn of the start of the first log file */ /************************************************************************ Starts an archiving operation. */ @@ -507,7 +543,16 @@ extern log_t* log_sys; + LOG_MAX_N_GROUPS * 8) #define LOG_CHECKPOINT_CHECKSUM_1 LOG_CHECKPOINT_ARRAY_END #define LOG_CHECKPOINT_CHECKSUM_2 (4 + LOG_CHECKPOINT_ARRAY_END) -#define LOG_CHECKPOINT_SIZE (8 + LOG_CHECKPOINT_ARRAY_END) +#define LOG_CHECKPOINT_FSP_FREE_LIMIT (8 + LOG_CHECKPOINT_ARRAY_END) + /* current fsp free limit in the + tablespace, in units of one megabyte */ +#define LOG_CHECKPOINT_FSP_MAGIC_N (12 + LOG_CHECKPOINT_ARRAY_END) + /* this magic number tells if the + checkpoint contains the above field: + the field was added to InnoDB-3.23.50 */ +#define LOG_CHECKPOINT_SIZE (16 + LOG_CHECKPOINT_ARRAY_END) + +#define LOG_CHECKPOINT_FSP_MAGIC_N_VAL 1441231243 /* Offsets of a log file header */ #define LOG_GROUP_ID 0 /* log group number */ diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h index 8f896756db9..0825325965d 100644 --- a/innobase/include/log0recv.h +++ b/innobase/include/log0recv.h @@ -16,6 +16,39 @@ Created 9/20/1997 Heikki Tuuri #include "log0log.h" /*********************************************************************** +Reads the checkpoint info needed in hot backup. */ + +ibool +recv_read_cp_info_for_backup( +/*=========================*/ + /* out: TRUE if success */ + byte* hdr, /* in: buffer containing the log group header */ + dulint* lsn, /* out: checkpoint lsn */ + ulint* offset, /* out: checkpoint offset in the log group */ + ulint* fsp_limit,/* out: fsp limit, 1000000000 if the database + is running with < version 3.23.50 of InnoDB */ + dulint* cp_no, /* out: checkpoint number */ + dulint* first_header_lsn); + /* out: lsn of of the start of the first log file */ +/*********************************************************************** +Scans the log segment and n_bytes_scanned is set to the length of valid +log scanned. */ + +void +recv_scan_log_seg_for_backup( +/*=========================*/ + byte* buf, /* in: buffer containing log data */ + ulint buf_len, /* in: data length in that buffer */ + dulint* scanned_lsn, /* in/out: lsn of buffer start, + we return scanned lsn */ + ulint* scanned_checkpoint_no, + /* in/out: 4 lowest bytes of the + highest scanned checkpoint number so + far */ + ulint* n_bytes_scanned);/* out: how much we were able to + scan, smaller than buf_len if log + data ended here */ +/*********************************************************************** Returns TRUE if recovery is currently running. */ UNIV_INLINE ibool @@ -35,6 +68,10 @@ read in, or also for a page already in the buffer pool. */ void recv_recover_page( /*==============*/ + ibool recover_backup, /* in: TRUE if we are recovering a backup + page: then we do not acquire any latches + since the page was read in outside the + buffer pool */ ibool just_read_in, /* in: TRUE if the i/o-handler calls this for a freshly read page */ page_t* page, /* in: buffer page */ @@ -69,8 +106,15 @@ recv_scan_log_recs( /*===============*/ /* out: TRUE if limit_lsn has been reached, or not able to scan any more in this log group */ + ibool apply_automatically,/* in: TRUE if we want this function to + apply log records automatically when the + hash table becomes full; in the hot backup tool + the tool does the applying, not this + function */ + ulint available_memory,/* in: we let the hash table of recs to grow + to this size, at the maximum */ ibool store_to_hash, /* in: TRUE if the records should be stored - to the hash table; this is set FALSE if just + to the hash table; this is set to FALSE if just debug checking is needed */ byte* buf, /* in: buffer containing a log segment or garbage */ @@ -92,6 +136,16 @@ recv_reset_logs( ibool new_logs_created);/* in: TRUE if resetting logs is done at the log creation; FALSE if it is done after archive recovery */ +/********************************************************** +Creates new log files after a backup has been restored. */ + +void +recv_reset_log_files_for_backup( +/*============================*/ + char* log_dir, /* in: log file directory path */ + ulint n_log_files, /* in: number of log files */ + ulint log_file_size, /* in: log file size */ + dulint lsn); /* in: new start lsn */ /************************************************************ Creates the recovery system. */ @@ -102,8 +156,11 @@ recv_sys_create(void); Inits the recovery system for a recovery operation. */ void -recv_sys_init(void); -/*===============*/ +recv_sys_init( +/*==========*/ + ibool recover_from_backup, /* in: TRUE if this is called + to recover from a hot backup */ + ulint available_memory); /* in: available memory in bytes */ /*********************************************************************** Empties the hash table of stored log records, applying them to appropriate pages. */ @@ -118,6 +175,17 @@ 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 */ +/*********************************************************************** +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 */ /************************************************************ Recovers from archived log files, and also from log files, if they exist. */ @@ -260,6 +328,14 @@ extern ibool recv_recovery_on; extern ibool recv_no_ibuf_operations; extern ibool recv_needed_recovery; +/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many +times! */ +#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024) + +/* Size of block reads when the log groups are scanned forward to do a +roll-forward */ +#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE) + /* States of recv_addr_struct */ #define RECV_NOT_PROCESSED 71 #define RECV_BEING_READ 72 diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 89c5428f054..bfd25f5bdbe 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -41,11 +41,11 @@ page buffer pool; the latter method is used for very big heaps */ /* The following start size is used for the first block in the memory heap if the size is not specified, i.e., 0 is given as the parameter in the call of -create. The standard size is the maximum size of the blocks used for +create. The standard size is the maximum (payload) size of the blocks used for allocations of small buffers. */ #define MEM_BLOCK_START_SIZE 64 -#define MEM_BLOCK_STANDARD_SIZE 8192 +#define MEM_BLOCK_STANDARD_SIZE 8000 /* If a memory heap is allowed to grow into the buffer pool, the following is the maximum size for a single allocated buffer: */ diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 411a9fb2c21..01fa12955ff 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -11,6 +11,12 @@ Created 10/21/1995 Heikki Tuuri #include "univ.i" + +/* If the following is set to TRUE, we do not call os_file_flush in every +os_file_write */ +extern ibool os_do_not_call_flush_at_each_write; +extern ibool os_has_said_disk_full; + #ifdef __WIN__ /* We define always WIN_ASYNC_IO, and check at run-time whether @@ -19,12 +25,6 @@ Created 10/21/1995 Heikki Tuuri #define UNIV_NON_BUFFERED_IO -#else - -#if defined(HAVE_AIO_H) && defined(HAVE_LIBRT) -#define POSIX_ASYNC_IO -#endif - #endif #ifdef __WIN__ @@ -55,6 +55,9 @@ log. */ #define OS_FILE_CREATE 52 #define OS_FILE_OVERWRITE 53 +#define OS_FILE_READ_ONLY 333 +#define OS_FILE_READ_WRITE 444 + /* Options for file_create */ #define OS_FILE_AIO 61 #define OS_FILE_NORMAL 62 @@ -118,6 +121,27 @@ os_get_os_version(void); /*===================*/ /* out: OS_WIN95, OS_WIN31, OS_WINNT (2000 == NT) */ /******************************************************************** +Creates the seek mutexes used in positioned reads and writes. */ + +void +os_io_init_simple(void); +/*===================*/ +/******************************************************************** +A simple function to open or create a file. */ + +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 */ + 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 */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ +/******************************************************************** Opens an existing file or creates a new. */ os_file_t @@ -317,6 +341,8 @@ os_aio_windows_handle( void** message2, ulint* type); /* out: OS_FILE_WRITE or ..._READ */ #endif + +/* Currently we do not use Posix async i/o */ #ifdef POSIX_ASYNC_IO /************************************************************************** This function is only used in Posix asynchronous i/o. Waits for an aio diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index 617f6b036fe..b2d613c4619 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -149,9 +149,9 @@ void os_mutex_free( /*==========*/ os_mutex_t mutex); /* in: mutex to free */ -#ifndef _WIN32 /************************************************************** -Acquires ownership of a fast mutex. */ +Acquires ownership of a fast mutex. Currently in Windows this is the same +as os_fast_mutex_lock! */ UNIV_INLINE ulint os_fast_mutex_trylock( @@ -160,7 +160,6 @@ os_fast_mutex_trylock( was reserved by another thread */ os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */ -#endif /************************************************************** Releases ownership of a fast mutex. */ diff --git a/innobase/include/os0sync.ic b/innobase/include/os0sync.ic index aa00300dec5..6bff75d8ec6 100644 --- a/innobase/include/os0sync.ic +++ b/innobase/include/os0sync.ic @@ -10,9 +10,9 @@ Created 9/6/1995 Heikki Tuuri #include <winbase.h> #endif -#ifndef _WIN32 /************************************************************** -Acquires ownership of a fast mutex. */ +Acquires ownership of a fast mutex. Currently in Windows this is the same +as os_fast_mutex_lock! */ UNIV_INLINE ulint os_fast_mutex_trylock( @@ -23,20 +23,11 @@ os_fast_mutex_trylock( os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */ { #ifdef __WIN__ - int ret; + EnterCriticalSection(fast_mutex); - /* TODO: TryEnterCriticalSection is probably not found from - NT versions < 4! */ - ret = TryEnterCriticalSection(fast_mutex); - - if (ret) { - return(0); - } - - return(1); + return(0); #else return((ulint) pthread_mutex_trylock(fast_mutex)); #endif } -#endif diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 48b6ba8a715..13b3dffd874 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -209,6 +209,27 @@ row_update_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL handle */ /************************************************************************* +Creates an query graph node of 'update' type to be used in the MySQL +interface. */ + +upd_node_t* +row_create_update_node_for_mysql( +/*=============================*/ + /* out, own: update node */ + dict_table_t* table, /* in: table to update */ + mem_heap_t* heap); /* in: mem heap from which allocated */ +/************************************************************************** +Does a cascaded delete or set null in a foreign key operation. */ + +ulint +row_update_cascade_for_mysql( +/*=========================*/ + /* out: error code or DB_SUCCESS */ + que_thr_t* thr, /* in: query thread */ + upd_node_t* node, /* in: update node used in the cascade + or set null operation */ + dict_table_t* table); /* in: table where we do the operation */ +/************************************************************************* Does a table creation operation for MySQL. If the name of the created table ends to characters INNODB_MONITOR, then this also starts printing of monitor output by the master thread. */ @@ -402,13 +423,13 @@ struct row_prebuilt_struct { byte* ins_upd_rec_buff;/* buffer for storing data converted to the Innobase format from the MySQL format */ - ibool in_update_remember_pos; - /* if an update is processed, then if - this flag is set to TRUE, it means - that the stored cursor position in - SELECT is the right position also - for the update: we can just restore - the cursor and save CPU time */ + ibool hint_no_need_to_fetch_extra_cols; + /* normally this is TRUE, but + MySQL will set this to FALSE + if we might be required to fetch also + other columns than mentioned in the + query: the clustered index column(s), + or an auto-increment column*/ upd_node_t* upd_node; /* Innobase SQL update node used to perform updates and deletes */ que_fork_t* ins_graph; /* Innobase SQL query graph used diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 106d3866b25..9a3e2463267 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -312,6 +312,11 @@ struct upd_node_struct{ ibool in_mysql_interface; /* TRUE if the update node was created for the MySQL interface */ + upd_node_t* cascade_node;/* NULL or an update node template which + is used to implement ON DELETE CASCADE + or ... SET NULL for foreign keys */ + mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade + node is created */ sel_node_t* select; /* query graph subtree implementing a base table cursor: the rows returned will be updated */ @@ -322,6 +327,11 @@ struct upd_node_struct{ of the MySQL interface */ dict_table_t* table; /* table where updated */ upd_t* update; /* update vector for the row */ + ulint update_n_fields; + /* when this struct is used to implement + a cascade operation for foreign keys, we store + here the size of the buffer allocated for use + as the update vector */ sym_node_list_t columns;/* symbol table nodes for the columns to retrieve from the table */ ibool has_clust_rec_x_lock; diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 2b40852fe67..6777a24e7db 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -24,10 +24,13 @@ extern char srv_fatal_errbuf[]; thread starts running */ extern os_event_t srv_lock_timeout_thread_event; +/* If the last data file is auto-extended, we add this many pages to it +at a time */ +#define SRV_AUTO_EXTEND_INCREMENT (8 * ((1024 * 1024) / UNIV_PAGE_SIZE)) + /* Server parameters which are read from the initfile */ extern char* srv_data_home; -extern char* srv_logs_home; extern char* srv_arch_dir; extern ulint srv_n_data_files; @@ -35,6 +38,9 @@ extern char** srv_data_file_names; extern ulint* srv_data_file_sizes; extern ulint* srv_data_file_is_raw_partition; +extern ibool srv_auto_extend_last_data_file; +extern ulint srv_last_file_size_max; + extern ibool srv_created_new_raw; #define SRV_NEW_RAW 1 @@ -186,6 +192,19 @@ srv_boot(void); /*==========*/ /* out: DB_SUCCESS or error code */ /************************************************************************* +Initializes the server. */ + +void +srv_init(void); +/*==========*/ +/************************************************************************* +Initializes the synchronization primitives, memory system, and the thread +local storage. */ + +void +srv_general_init(void); +/*==================*/ +/************************************************************************* Gets the number of threads in the system. */ ulint diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 6dbdcd27250..01ac063e1c9 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -12,6 +12,56 @@ Created 10/10/1995 Heikki Tuuri #include "univ.i" +/************************************************************************* +Normalizes a directory path for Windows: converts slashes to backslashes. */ + +void +srv_normalize_path_for_win( +/*=======================*/ + char* str); /* in/out: null-terminated character string */ +/************************************************************************* +Adds a slash or a backslash to the end of a string if it is missing +and the string is not empty. */ + +char* +srv_add_path_separator_if_needed( +/*=============================*/ + /* out, own: string which has the separator if the + string is not empty */ + char* str); /* in: null-terminated character string */ +/************************************************************************* +Reads the data files and their sizes from a character string given in +the .cnf file. */ + +ibool +srv_parse_data_file_paths_and_sizes( +/*================================*/ + /* out: TRUE if ok, FALSE if parsing + error */ + char* str, /* in: the data file path string */ + char*** data_file_names, /* out, own: array of data file + names */ + ulint** data_file_sizes, /* out, own: array of data file sizes + in megabytes */ + ulint** data_file_is_raw_partition,/* out, own: array of flags + showing which data files are raw + partitions */ + ulint* n_data_files, /* out: number of data files */ + ibool* is_auto_extending, /* out: TRUE if the last data file is + auto-extending */ + ulint* max_auto_extend_size); /* out: max auto extend size for the + last file if specified, 0 if not */ +/************************************************************************* +Reads log group home directories from a character string given in +the .cnf file. */ + +ibool +srv_parse_log_group_home_dirs( +/*==========================*/ + /* out: TRUE if ok, FALSE if parsing + error */ + char* str, /* in: character string */ + char*** log_group_home_dirs); /* out, own: log group home dirs */ /******************************************************************** Starts Innobase and creates a new database if database files are not found and the user wants. Server parameters are diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic index 09580cfc497..43e9202360b 100644 --- a/innobase/include/sync0rw.ic +++ b/innobase/include/sync0rw.ic @@ -357,7 +357,7 @@ rw_lock_s_unlock_func( /* Reset the shared lock by decrementing the reader count */ - ut_ad(lock->reader_count > 0); + ut_a(lock->reader_count > 0); lock->reader_count--; #ifdef UNIV_SYNC_DEBUG diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 6c3bff66e27..4f55709a5d7 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -359,12 +359,17 @@ V Memory pool mutex */ /* Latching order levels */ + +/* User transaction locks are higher than any of the latch levels below: +no latches are allowed when a thread goes to wait for a normal table +or row lock! */ +#define SYNC_USER_TRX_LOCK 9999 #define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress latching order checking */ #define SYNC_LEVEL_NONE 2000 /* default: level not defined */ +#define SYNC_FOREIGN_KEY_CHECK 1001 #define SYNC_DICT 1000 #define SYNC_DICT_AUTOINC_MUTEX 999 -#define SYNC_FOREIGN_KEY_CHECK 998 #define SYNC_PURGE_IS_RUNNING 997 #define SYNC_DICT_HEADER 995 #define SYNC_IBUF_HEADER 914 @@ -429,7 +434,7 @@ implementation of a mutual exclusion semaphore. */ struct mutex_struct { ulint lock_word; /* This ulint is the target of the atomic test-and-set instruction in Win32 */ -#ifndef _WIN32 +#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER) os_fast_mutex_t os_fast_mutex; /* In other systems we use this OS mutex in place of lock_word */ diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index 9531377ce0b..9014eb5fb54 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -53,7 +53,7 @@ mutex_test_and_set( 1 */ mutex_t* mutex) /* in: mutex */ { -#ifdef _WIN32 +#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) ulint res; ulint* lw; /* assembler code is used to ensure that lock_word is loaded from memory */ @@ -120,7 +120,7 @@ mutex_reset_lock_word( /*==================*/ mutex_t* mutex) /* in: mutex */ { -#ifdef _WIN32 +#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) ulint* lw; /* assembler code is used to ensure that lock_word is loaded from memory */ ut_ad(mutex); diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index f2eded697ec..60d5adb72d1 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -44,6 +44,15 @@ half-written pages in the data files. */ void trx_sys_doublewrite_restore_corrupt_pages(void); /*===========================================*/ +/******************************************************************** +Determines if a page number is located inside the doublewrite buffer. */ + +ibool +trx_doublewrite_page_inside( +/*========================*/ + /* out: TRUE if the location is inside + the two blocks of the doublewrite buffer */ + ulint page_no); /* in: page number */ /******************************************************************* Checks if a page address is the trx sys header page. */ UNIV_INLINE @@ -250,7 +259,7 @@ therefore 256 */ /* The offset of the transaction system header on the page */ #define TRX_SYS FSEG_PAGE_DATA -/* Transaction system header; protected by trx_sys->mutex */ +/* Transaction system header */ /*-------------------------------------------------------------*/ #define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number modulo TRX_SYS_TRX_ID_UPDATE_MARGIN diff --git a/innobase/include/trx0sys.ic b/innobase/include/trx0sys.ic index 786e7905933..ada2d8cb19c 100644 --- a/innobase/include/trx0sys.ic +++ b/innobase/include/trx0sys.ic @@ -93,7 +93,6 @@ trx_sysf_get( { trx_sysf_t* header; - ut_ad(mutex_own(&(kernel_mutex))); ut_ad(mtr); header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 26c9ace08b6..261f33d3dc3 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -298,6 +298,17 @@ struct trx_struct{ of view of concurrency control: TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY, ... */ + ibool check_foreigns; /* normally TRUE, but if the user + wants to suppress foreign key checks, + (in table imports, for example) we + set this FALSE */ + ibool check_unique_secondary; + /* normally TRUE, but if the user + wants to speed up inserts by + suppressing unique key checks + for secondary indexes when we decide + if we can use the insert buffer for + them, we set this FALSE */ dulint id; /* transaction id */ dulint no; /* transaction serialization number == max trx id when the transaction is @@ -328,6 +339,9 @@ struct trx_struct{ /* how many tables the current SQL statement uses, except those in consistent read */ + ibool has_dict_foreign_key_check_lock; + /* TRUE if the trx currently holds + an s-lock on dict_foreign_... */ ibool has_search_latch; /* TRUE if this trx has latched the search system latch in S-mode */ diff --git a/innobase/include/univ.i b/innobase/include/univ.i index 8870d80f611..160a435319a 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -14,6 +14,13 @@ Created 1/20/1994 Heikki Tuuri #include <windows.h> +/* When compiling for Itanium IA64, undefine the flag below to prevent use +of 32-bit assembler */ + +#ifndef WIN64 +#define UNIV_CAN_USE_X86_ASSEMBLER +#endif + /* If you want to check for errors with compiler level -W4, comment out the above include of windows.h and let the following defines be defined: @@ -71,13 +78,14 @@ memory is read outside the allocated blocks. */ */ /* Make a non-inline debug version */ + /* #define UNIV_DEBUG #define UNIV_MEM_DEBUG -#define UNIV_SEARCH_DEBUG +#define UNIV_SYNC_DEBUG #define UNIV_IBUF_DEBUG -#define UNIV_SYNC_DEBUG +#define UNIV_SEARCH_DEBUG #define UNIV_SYNC_PERF_STAT #define UNIV_SEARCH_PERF_STAT */ diff --git a/innobase/include/ut0byte.h b/innobase/include/ut0byte.h index b45f2160392..4fb45221899 100644 --- a/innobase/include/ut0byte.h +++ b/innobase/include/ut0byte.h @@ -55,6 +55,15 @@ ut_dulint_get_low( /* out: 32 bits in ulint */ dulint d); /* in: dulint */ /*********************************************************** +Converts a dulint (a struct of 2 ulints) to ib_longlong, which is a 64-bit +integer type. */ +UNIV_INLINE +ib_longlong +ut_conv_dulint_to_longlong( +/*=======================*/ + /* out: value in ib_longlong type */ + dulint d); /* in: dulint */ +/*********************************************************** Tests if a dulint is zero. */ UNIV_INLINE ibool diff --git a/innobase/include/ut0byte.ic b/innobase/include/ut0byte.ic index b8170392c8f..f0df9cc35a3 100644 --- a/innobase/include/ut0byte.ic +++ b/innobase/include/ut0byte.ic @@ -52,6 +52,20 @@ ut_dulint_get_low( } /*********************************************************** +Converts a dulint (a struct of 2 ulints) to ib_longlong, which is a 64-bit +integer type. */ +UNIV_INLINE +ib_longlong +ut_conv_dulint_to_longlong( +/*=======================*/ + /* out: value in ib_longlong type */ + dulint d) /* in: dulint */ +{ + return((ib_longlong)d.low + + (((ib_longlong)d.high) << 32)); +} + +/*********************************************************** Tests if a dulint is zero. */ UNIV_INLINE ibool diff --git a/innobase/include/ut0rnd.h b/innobase/include/ut0rnd.h index a30251e6da0..c8ef0dd4001 100644 --- a/innobase/include/ut0rnd.h +++ b/innobase/include/ut0rnd.h @@ -35,7 +35,7 @@ ut_rnd_gen_next_ulint( /************************************************************* The following function generates 'random' ulint integers which enumerate the value space (let there be N of them) of ulint integers -in a pseudo random fashion. Note that the same integer is repeated +in a pseudo-random fashion. Note that the same integer is repeated always after N calls to the generator. */ UNIV_INLINE ulint diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 4366b832ff6..338460d7de9 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -17,6 +17,16 @@ Created 1/20/1994 Heikki Tuuri typedef time_t ib_time_t; +/************************************************************ +Gets the high 32 bits in a ulint. That is makes a shift >> 32, +but since there seem to be compiler bugs in both gcc and Visual C++, +we do this by a special conversion. */ + +ulint +ut_get_high32( +/*==========*/ + /* out: a >> 32 */ + ulint a); /* in: ulint */ /********************************************************** Calculates the minimum of two ulints. */ UNIV_INLINE @@ -144,6 +154,15 @@ void ut_print_timestamp( /*===============*/ FILE* file); /* in: file where to print */ +/************************************************************** +Returns current year, month, day. */ + +void +ut_get_year_month_day( +/*==================*/ + ulint* year, /* out: current year */ + ulint* month, /* out: month */ + ulint* day); /* out: day */ /***************************************************************** Runs an idle loop on CPU. The argument gives the desired delay in microseconds on 100 MHz Pentium + Visual C++. */ |