diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
commit | a2a2e32c02643a0cec111511220227703fda1cd5 (patch) | |
tree | 69cc2b631234c2a8e026b9cd4d72676c61c594df /storage/maria | |
parent | Releasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff) | |
download | mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip |
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'storage/maria')
27 files changed, 380 insertions, 154 deletions
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 426a19f0..9bdd7298 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -135,4 +135,5 @@ IF(TARGET s3) TARGET_LINK_LIBRARIES(aria_s3_copy aria myisam mysys mysys_ssl ${CURL_LIBRARIES} ${ZLIB_LIBRARIES}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libmarias3) ADD_DEFINITIONS(-DWITH_S3_STORAGE_ENGINE) + INSTALL_MANPAGES(s3-engine aria_s3_copy.1) ENDIF() diff --git a/storage/maria/aria_chk.c b/storage/maria/aria_chk.c index 4bbe513b..b7ce90bb 100644 --- a/storage/maria/aria_chk.c +++ b/storage/maria/aria_chk.c @@ -15,6 +15,7 @@ /* Describe, check and repair of MARIA tables */ +#define VER "1.3" #include "ma_fulltext.h" #include <myisamchk.h> #include <my_bit.h> @@ -25,6 +26,7 @@ /* Remove next line if you want aria_chk to produce a stack trace */ #undef HAVE_BACKTRACE #include <my_stacktrace.h> +#include <welcome_copyright_notice.h> static uint decode_bits; static char **default_argv; @@ -79,7 +81,6 @@ static char default_open_errmsg[]= "%d when opening Aria table '%s'"; static char default_close_errmsg[]= "%d when closing Aria table '%s'"; static void get_options(int *argc,char * * *argv); -static void print_version(void); static void usage(void); static int maria_chk(HA_CHECK *param, char *filename); static void descript(HA_CHECK *param, register MARIA_HA *info, char *name); @@ -473,13 +474,6 @@ static struct my_option my_long_options[] = }; -static void print_version(void) -{ - printf("%s Ver 1.3 for %s on %s\n", my_progname, SYSTEM_TYPE, - MACHINE_TYPE); -} - - static void usage(void) { print_version(); @@ -1626,6 +1620,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) pos=strmov(pos,"sorted index pages,"); if (!(share->state.changed & STATE_NOT_ZEROFILLED)) pos=strmov(pos,"zerofilled,"); + if (test_all_bits(share->state.changed, (STATE_NOT_ZEROFILLED | STATE_HAS_LSN))) + pos=strmov(pos,"has_lsn,"); if (!(share->state.changed & STATE_NOT_MOVABLE)) pos=strmov(pos,"movable,"); if (have_control_file && (share->state.changed & STATE_MOVED)) diff --git a/storage/maria/aria_dump_log.c b/storage/maria/aria_dump_log.c index e64c97fc..4317e1b6 100644 --- a/storage/maria/aria_dump_log.c +++ b/storage/maria/aria_dump_log.c @@ -13,8 +13,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ +#define VER "1.1" #include "maria_def.h" #include <my_getopt.h> +#include <welcome_copyright_notice.h> + extern void translog_example_table_init(); static const char *load_default_groups[]= { "aria_dump_log",0 }; static void get_options(int *argc,char * * *argv); @@ -64,13 +67,6 @@ static struct my_option my_long_options[] = }; -static void print_version(void) -{ - printf("%s Ver 1.1 for %s on %s\n", - my_progname_short, SYSTEM_TYPE, MACHINE_TYPE); -} - - static void usage(void) { print_version(); diff --git a/storage/maria/aria_pack.c b/storage/maria/aria_pack.c index 464a08fb..ee694931 100644 --- a/storage/maria/aria_pack.c +++ b/storage/maria/aria_pack.c @@ -19,6 +19,7 @@ #define USE_MY_FUNC /* We need at least my_malloc */ #endif +#define VER "1.0" #include "maria_def.h" #include "trnman_public.h" #include "trnman.h" @@ -33,6 +34,7 @@ #endif #include <my_getopt.h> #include <my_handler_errors.h> +#include <welcome_copyright_notice.h> #if SIZEOF_LONG_LONG > 4 #define BITS_SAVED 64 @@ -354,12 +356,6 @@ static struct my_option my_long_options[] = }; -static void print_version(void) -{ - printf("%s Ver 1.0 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); -} - - static void usage(void) { print_version(); diff --git a/storage/maria/aria_read_log.c b/storage/maria/aria_read_log.c index 2997314d..cde28e91 100644 --- a/storage/maria/aria_read_log.c +++ b/storage/maria/aria_read_log.c @@ -139,6 +139,12 @@ int main(int argc, char **argv) if (opt_display_only) printf("You are using --display-only, NOTHING will be written to disk\n"); + if (translog_get_horizon() == LSN_IMPOSSIBLE) + { + fprintf(stdout, "The transaction log is empty\n"); + goto end; + } + lsn= translog_first_lsn_in_log(); if (lsn == LSN_ERROR) { @@ -147,7 +153,8 @@ int main(int argc, char **argv) } if (lsn == LSN_IMPOSSIBLE) { - fprintf(stdout, "The transaction log is empty\n"); + fprintf(stdout, "The transaction log is empty\n"); + goto end; } if (opt_start_from_checkpoint && !opt_start_from_lsn && last_checkpoint_lsn != LSN_IMPOSSIBLE) @@ -300,7 +307,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - printf("%s Ver 1.5 for %s on %s\n", + printf("%s Ver 1.6 for %s on %s\n", my_progname_short, SYSTEM_TYPE, MACHINE_TYPE); } @@ -308,7 +315,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2007 MySQL AB, 2009-2011 Monty Program Ab, 2020 MariaDB Corporation"); + puts("Copyright (C) 2007 MySQL AB, 2009-2011 Monty Program Ab, 2022 MariaDB Corporation"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); puts("and you are welcome to modify and redistribute it under the GPL license\n"); diff --git a/storage/maria/aria_s3_copy.1 b/storage/maria/aria_s3_copy.1 new file mode 100644 index 00000000..5844d5a7 --- /dev/null +++ b/storage/maria/aria_s3_copy.1 @@ -0,0 +1,52 @@ +.TH ARIA_S3_COPY "1" "June 2020" "aria_s3_copy Ver 1.0" "User Commands" +.SH NAME +aria_s3_copy \- Copy an Aria table to and from s3 +.SH DESCRIPTION +Usage: aria_s3_copy \-\-aws\-access\-key=# \-\-aws\-secret\-access\-key=# \-\-aws\-region=# \-\-op=(from_s3 | to_s3 | delete_from_s3) [OPTIONS] tables[.MAI] +.TP +\fB\-?\fR, \fB\-h\fR, \fB\-\-help\fR +Display help and exit. +.TP +\fB\-k\fR, \fB\-\-s3\-access\-key=name\fR +AWS access key ID +.TP +\fB\-r\fR, \fB\-s3\-region=name\fR +AWS region +.TP +\fB\-K\fR, \fB\-s3\-secret\-key=name\fR +AWS secret access key ID +.TP +\fB\-b\fR, \fB\-s3\-bucket=name\fR +AWS prefix for tables +.TP +\fB\-h\fR, \fB\-s3\-host\-name=name\fR +Host name to S3 provider +.TP +\fB\-c\fR, \fB\-compress\fR +Use compression +.TP +\fB\-o\fR, \fB\-op=name\fR +Operation to execute. One of 'from_s3', 'to_s3' or 'delete_from_s3' +.TP +\fB\-d\fR, \fB\-database=name\fR +Database for copied table (second prefix). If not given, the directory of the table file is used +.TP +\fB\-B\fR, \fB\-s3\-block\-size=#\fR +Block size for data/index blocks in s3 +.TP +\fB\-L\fR, \fB\-s3\-protocol\-version=name\fR +Protocol used to communication with S3. One of "Auto", "Amazon" or "Original". +.TP +\fB\-f\fR, \fB\-force\fR +Force copy even if target exists +.TP +\fB\-V\fR, \fB\-version\fR +Print version and exit. +.TP +\fB\-\-s3\-debug\fR +Output debug log from marias3 to stdout +.TP +\fB\-v\fR, \fB\-\-verbose\fR +Be verbose. +.PP +For more information, please refer to the MariaDB Knowledge Base page https://mariadb.com/kb/en/aria_s3_copy/ diff --git a/storage/maria/aria_s3_copy.cc b/storage/maria/aria_s3_copy.cc index b8a0f5b7..6dfe7572 100644 --- a/storage/maria/aria_s3_copy.cc +++ b/storage/maria/aria_s3_copy.cc @@ -17,6 +17,7 @@ Allow copying of Aria tables to and from S3 and also delete them from S3 */ +#define VER "1.0" #include <my_global.h> #include <m_string.h> #include "maria_def.h" @@ -28,6 +29,7 @@ #include <zlib.h> #include <libmarias3/marias3.h> #include "s3_func.h" +#include <welcome_copyright_notice.h> static const char *op_types[]= {"to_s3", "from_s3", "delete_from_s3", NullS}; static TYPELIB op_typelib= {array_elements(op_types)-1,"", op_types, NULL}; @@ -111,12 +113,6 @@ static struct my_option my_long_options[] = static bool get_database_from_path(char *to, size_t to_length, const char *path); -static void print_version(void) -{ - printf("%s Ver 1.0 for %s on %s\n", my_progname, SYSTEM_TYPE, - MACHINE_TYPE); -} - static void usage(void) { print_version(); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index b3b0ba0f..eeb613ac 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1066,7 +1066,8 @@ const char *ha_maria::index_type(uint key_number) ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const { ulong flags; - if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) + if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT || + table_share->key_info[inx].algorithm == HA_KEY_ALG_UNIQUE_HASH) flags= 0; else if ((table_share->key_info[inx].flags & HA_SPATIAL || @@ -1078,21 +1079,52 @@ ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const } else { - flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | - HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN; + flags= (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | + HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN | + HA_DO_RANGE_FILTER_PUSHDOWN); } return flags; } -double ha_maria::scan_time() +/* + Update costs that are unique for this TABLE instance +*/ + +void ha_maria::update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + /* + Default costs for Aria with BLOCK_FORMAT is the same as MariaDB default + costs. + */ + if (file->s->data_file_type != BLOCK_RECORD) + { + /* + MyISAM format row lookup costs are slow as the row data is on a not + cached file. Costs taken from ha_myisam.cc + */ + costs->row_next_find_cost= 0.000063539; + costs->row_lookup_cost= 0.001014818; + } +} + + +IO_AND_CPU_COST ha_maria::rnd_pos_time(ha_rows rows) { - if (file->s->data_file_type == BLOCK_RECORD) - return (ulonglong2double(stats.data_file_length - file->s->block_size) / - file->s->block_size) + 2; - return handler::scan_time(); + IO_AND_CPU_COST cost= handler::rnd_pos_time(rows); + /* file may be 0 if this is an internal temporary file that is not yet opened */ + if (file && file->s->data_file_type != BLOCK_RECORD) + { + /* + Row data is not cached. costs.row_lookup_cost includes the cost of + the reading the row from system (probably cached by the OS). + */ + cost.io= 0; + } + return cost; } + /* We need to be able to store at least 2 keys on an index page as the splitting algorithms depends on this. (With only one key on a page @@ -2483,10 +2515,12 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, end_range= NULL; if (index == pushed_idx_cond_keyno) ma_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); error= maria_rkey(file, buf, index, key, keypart_map, find_flag); - ma_set_index_cond_func(file, NULL, 0); + ma_reset_index_filter_functions(file); return error; } @@ -2560,18 +2594,22 @@ int ha_maria::index_next_same(uchar * buf, int ha_maria::index_init(uint idx, bool sorted) { - active_index=idx; + active_index= idx; if (pushed_idx_cond_keyno == idx) ma_set_index_cond_func(file, handler_index_cond_check, this); + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); return 0; } - int ha_maria::index_end() { + /* + in_range_check_pushed_down and index_id_cond_keyno are reset in + handler::cancel_pushed_idx_cond() + */ active_index=MAX_KEY; - ma_set_index_cond_func(file, NULL, 0); - in_range_check_pushed_down= FALSE; + ma_reset_index_filter_functions(file); ds_mrr.dsmrr_close(); return 0; } @@ -2685,8 +2723,8 @@ int ha_maria::info(uint flag) } } /* - Set data_file_name and index_file_name to point at the symlink value - if table is symlinked (Ie; Real name is not same as generated name) + Set data_file_name and index_file_name to point at the symlink value + if table is symlinked (Ie; Real name is not same as generated name) */ data_file_name= index_file_name= 0; fn_format(name_buff, file->s->open_file_name.str, "", MARIA_NAME_DEXT, @@ -2769,7 +2807,7 @@ int ha_maria::extra(enum ha_extra_function operation) int ha_maria::reset(void) { - ma_set_index_cond_func(file, NULL, 0); + ma_reset_index_filter_functions(file); ds_mrr.dsmrr_close(); if (file->trn) { @@ -2803,8 +2841,9 @@ bool ha_maria::auto_repair(int error) const int ha_maria::delete_all_rows() { THD *thd= table->in_use; - TRN *trn= file->trn; + TRN *trn= file->s->now_transactional ? file->trn : (TRN*) 0; CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("TRUNCATE in WRITE CONCURRENT"); + #ifdef EXTRA_DEBUG if (trn && ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED)) { @@ -2818,8 +2857,7 @@ int ha_maria::delete_all_rows() If we are under LOCK TABLES, we have to do a commit as delete_all_rows() can't be rolled back */ - if (table->in_use->locked_tables_mode && trn && - trnman_has_locked_tables(trn)) + if (trn && table->in_use->locked_tables_mode && trnman_has_locked_tables(trn)) { int error; if ((error= implicit_commit(thd, 1))) @@ -2899,8 +2937,11 @@ int ha_maria::external_lock(THD *thd, int lock_type) tons of archived logs to roll-forward, we could then not disable REDOs/UNDOs in this case. */ - DBUG_PRINT("info", ("Disabling logging for table")); - _ma_tmp_disable_logging_for_table(file, TRUE); + if (likely(file->s->now_transactional)) + { + DBUG_PRINT("info", ("Disabling logging for table")); + _ma_tmp_disable_logging_for_table(file, TRUE); + } file->autocommit= 0; } else @@ -3829,6 +3870,10 @@ bool ha_maria::is_changed() const return file->state->changed; } +static void aria_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ +} + static int ha_maria_init(void *p) { @@ -3861,6 +3906,7 @@ static int ha_maria_init(void *p) maria_hton->show_status= maria_show_status; maria_hton->prepare_for_backup= maria_prepare_for_backup; maria_hton->end_backup= maria_end_backup; + maria_hton->update_optimizer_costs= aria_update_optimizer_costs; /* TODO: decide if we support Maria being used for log tables */ maria_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | @@ -4162,7 +4208,8 @@ int ha_maria::multi_range_read_next(range_id_t *range_info) ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) + uint *flags, ha_rows limit, + Cost_estimate *cost) { /* This call is here because there is no location where this->table would @@ -4171,7 +4218,7 @@ ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, */ ds_mrr.init(this, table); return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz, - flags, cost); + flags, limit, cost); } ha_rows ha_maria::multi_range_read_info(uint keyno, uint n_ranges, uint keys, @@ -4222,6 +4269,26 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) return NULL; } +bool ha_maria::rowid_filter_push(Rowid_filter* rowid_filter) +{ + /* This will be used in index_init() */ + pushed_rowid_filter= rowid_filter; + return false; +} + + +/* Enable / disable rowid filter depending if it's active or not */ + +void ha_maria::rowid_filter_changed() +{ + if (pushed_rowid_filter && handler_rowid_filter_is_active(this)) + ma_set_rowid_filter_func(file, handler_rowid_filter_check, this); + else + ma_set_rowid_filter_func(file, NULL, this); +} + + + /** Find record by unique constrain (used in temporary tables) diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 41f64436..3c0d0cc4 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -67,7 +67,7 @@ public: ~ha_maria() = default; handler *clone(const char *name, MEM_ROOT *mem_root) override final; const char *index_type(uint key_number) override final; - ulonglong table_flags() const override final + ulonglong table_flags() const override { return int_table_flags; } ulong index_flags(uint inx, uint part, bool all_parts) const override final; uint max_supported_keys() const override final @@ -77,8 +77,6 @@ public: { return max_supported_key_length(); } enum row_type get_row_type() const override final; void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) override final; - virtual double scan_time() override final; - int open(const char *name, int mode, uint test_if_locked) override; int close(void) override final; int write_row(const uchar * buf) override; @@ -114,6 +112,8 @@ public: int remember_rnd_pos() override final; int restart_rnd_next(uchar * buf) override final; void position(const uchar * record) override final; + void update_optimizer_costs(OPTIMIZER_COSTS *costs) override final; + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override final; int info(uint) override final; int info(uint, my_bool); int extra(enum ha_extra_function operation) override final; @@ -175,7 +175,8 @@ public: ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint *bufsz, - uint *flags, Cost_estimate *cost) override final; + uint *flags, ha_rows limit, + Cost_estimate *cost) override final; ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, uint key_parts, uint *bufsz, uint *flags, Cost_estimate *cost) override final; @@ -183,6 +184,8 @@ public: /* Index condition pushdown implementation */ Item *idx_cond_push(uint keyno, Item* idx_cond) override final; + bool rowid_filter_push(Rowid_filter* rowid_filter) override; + void rowid_filter_changed() override; int find_unique_row(uchar *record, uint unique_idx) override final; diff --git a/storage/maria/ha_s3.cc b/storage/maria/ha_s3.cc index 0abb3f07..d8bc7e86 100644 --- a/storage/maria/ha_s3.cc +++ b/storage/maria/ha_s3.cc @@ -264,6 +264,7 @@ ha_s3::ha_s3(handlerton *hton, TABLE_SHARE *table_arg) /* Remove things that S3 doesn't support */ int_table_flags&= ~(HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_CAN_EXPORT); + int_table_flags|= HA_NO_ONLINE_ALTER; can_enable_indexes= 0; } @@ -852,7 +853,7 @@ static int s3_discover_table_existence(handlerton *hton, const char *db, */ static int s3_discover_table_names(handlerton *hton __attribute__((unused)), - LEX_CSTRING *db, + const LEX_CSTRING *db, MY_DIR *dir __attribute__((unused)), handlerton::discovered_list *result) { diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 91f93755..dfd1cf9a 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -1172,6 +1172,7 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap) { pgcache_page_no_t page= bitmap->page; MARIA_STATE_INFO *state= &info->s->state; + my_bool res; DBUG_ENTER("move_to_next_bitmap"); if (state->first_bitmap_with_space != ~(pgcache_page_no_t) 0 && @@ -1186,7 +1187,8 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap) page+= bitmap->pages_covered; DBUG_ASSERT(page % bitmap->pages_covered == 0); } - DBUG_RETURN(_ma_change_bitmap_page(info, bitmap, page)); + res= _ma_change_bitmap_page(info, bitmap, page); + DBUG_RETURN(res); } diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index e4ba0726..8c07e3c6 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3656,28 +3656,35 @@ err: int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const char *name) { - my_bool error, reenable_logging, + my_bool error= 0, reenable_logging, zero_lsn= !(param->testflag & T_ZEROFILL_KEEP_LSN); MARIA_SHARE *share= info->s; DBUG_ENTER("maria_zerofill"); if ((reenable_logging= share->now_transactional)) _ma_tmp_disable_logging_for_table(info, 0); - if (!(error= (maria_zerofill_index(param, info, name) || - maria_zerofill_data(param, info, name) || - _ma_set_uuid(info->s, 0)))) + + if (share->state.changed & (STATE_NOT_ZEROFILLED | (zero_lsn ? STATE_HAS_LSN : 0))) + error= (maria_zerofill_index(param, info, name) || + maria_zerofill_data(param, info, name)); + if (!error) + error= _ma_set_uuid(info->s, 0); + + if (!error) { /* - Mark that we have done zerofill of data and index. If we zeroed pages' - LSN, table is movable. + Mark that we have done zerofill of data and index. If we zeroed the LSN + on the pages, table is movable. */ share->state.changed&= ~STATE_NOT_ZEROFILLED; if (zero_lsn) { - share->state.changed&= ~(STATE_NOT_MOVABLE | STATE_MOVED); + share->state.changed&= ~(STATE_NOT_MOVABLE | STATE_MOVED | STATE_HAS_LSN); /* Table should get new LSNs */ share->state.create_rename_lsn= share->state.is_of_horizon= share->state.skip_redo_lsn= LSN_NEEDS_NEW_STATE_LSNS; } + else + share->state.changed|= STATE_HAS_LSN; /* Ensure state is later flushed to disk, if within maria_chk */ info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 03513c46..a90a1261 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -104,7 +104,7 @@ one should increment the control file version number. This LSN serves for the two-checkpoint rule, and also to find the checkpoint record when doing a recovery. */ -LSN last_checkpoint_lsn= LSN_IMPOSSIBLE; +volatile LSN last_checkpoint_lsn= LSN_IMPOSSIBLE; uint32 last_logno= FILENO_IMPOSSIBLE; /** The maximum transaction id given to a transaction. It is only updated at diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index b2b95e36..35ad4a67 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -37,7 +37,7 @@ C_MODE_START LSN of the last checkoint (if last_checkpoint_lsn == LSN_IMPOSSIBLE then there was never a checkpoint) */ -extern LSN last_checkpoint_lsn; +extern volatile LSN last_checkpoint_lsn; /* Last log number (if last_logno == FILENO_IMPOSSIBLE then there is no log file yet) diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index 1714fc6e..fe1ea09e 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -482,7 +482,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, uint *key_version) { int rc; - uint32 dstlen= 0; /* Must be set because of error message */ + uint32 dstlen= size; *key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id); if (unlikely(*key_version == ENCRYPTION_KEY_VERSION_INVALID)) @@ -509,6 +509,9 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, DBUG_ASSERT(!my_assert_on_error || dstlen == size); if (! (rc == MY_AES_OK && dstlen == size)) { + if (rc != MY_AES_OK) + dstlen= 0; /* reset dstlen if failed, to match expected message */ + my_errno= HA_ERR_DECRYPTION_FAILED; my_printf_error(HA_ERR_DECRYPTION_FAILED, "failed to encrypt '%s' rc: %d dstlen: %u size: %u\n", @@ -526,7 +529,7 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, uint key_version) { int rc; - uint32 dstlen= 0; /* Must be set because of error message */ + uint32 dstlen= size; rc= encryption_scheme_decrypt(src, size, dst, &dstlen, &crypt_data->scheme, key_version, @@ -536,6 +539,8 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, DBUG_ASSERT(!my_assert_on_error || dstlen == size); if (! (rc == MY_AES_OK && dstlen == size)) { + if (rc != MY_AES_OK) + dstlen= 0; /* reset dstlen if failed, to match expected message */ my_errno= HA_ERR_DECRYPTION_FAILED; if (!share->silence_encryption_errors) my_printf_error(HA_ERR_DECRYPTION_FAILED, diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index 9ffc551c..e73ac95c 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -502,8 +502,17 @@ void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func, { info->index_cond_func= func; info->index_cond_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); } +void ma_set_rowid_filter_func(MARIA_HA *info, + rowid_filter_func_t check_func, + void *func_arg) +{ + info->rowid_filter_func= check_func; + info->rowid_filter_func_arg= func_arg; + info->has_cond_pushdown= (info->index_cond_func || info->rowid_filter_func); +} /* Start/Stop Inserting Duplicates Into a Table, WL#1648. diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c index ddf92654..3de6b8b7 100644 --- a/storage/maria/ma_info.c +++ b/storage/maria/ma_info.c @@ -20,14 +20,6 @@ #include <sys/stat.h> #endif - /* Get position to last record */ - -MARIA_RECORD_POS maria_position(MARIA_HA *info) -{ - return info->cur_row.lastpos; -} - - uint maria_max_key_length() { uint tmp= (_ma_max_key_length() - 8 - HA_MAX_KEY_SEG*3); diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index d47e8cf7..1b58c1c1 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -678,22 +678,44 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos) CHECK_OUT_OF_RANGE to indicate that we don't have any active row. */ -check_result_t ma_check_index_cond(register MARIA_HA *info, uint keynr, - uchar *record) +check_result_t ma_check_index_cond_real(register MARIA_HA *info, uint keynr, + uchar *record) { check_result_t res= CHECK_POS; + DBUG_ASSERT(info->index_cond_func || info->rowid_filter_func); + + if (_ma_put_key_in_record(info, keynr, FALSE, record)) + { + /* Impossible case; Can only happen if bug in code */ + _ma_print_error(info, HA_ERR_CRASHED, 0); + info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ + my_errno= HA_ERR_CRASHED; + return CHECK_ERROR; + } + if (info->index_cond_func) { - if (_ma_put_key_in_record(info, keynr, FALSE, record)) + if ((res= info->index_cond_func(info->index_cond_func_arg)) == + CHECK_OUT_OF_RANGE) { - /* Impossible case; Can only happen if bug in code */ - _ma_print_error(info, HA_ERR_CRASHED, 0); + /* We got beyond the end of scanned range */ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ - my_errno= HA_ERR_CRASHED; - res= CHECK_ERROR; + my_errno= HA_ERR_END_OF_FILE; + return res; } - else if ((res= info->index_cond_func(info->index_cond_func_arg)) == - CHECK_OUT_OF_RANGE) + /* + If we got an error, out-of-range condition, or ICP condition computed to + FALSE - we don't need to check the Rowid Filter. + */ + if (res != CHECK_POS) + return res; + } + + /* Check the Rowid Filter, if present */ + if (info->rowid_filter_func) + { + if ((res= info->rowid_filter_func(info->rowid_filter_func_arg)) == + CHECK_OUT_OF_RANGE) { /* We got beyond the end of scanned range */ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 05347b2d..ca197202 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -478,7 +478,7 @@ static my_bool translog_page_validator(int res, PAGECACHE_IO_HOOK_ARGS *args); static my_bool translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner); static uint32 translog_first_file(TRANSLOG_ADDRESS horizon, int is_protected); LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon); - +static void translog_free_link(PAGECACHE_BLOCK_LINK *direct_link); /* Initialize log_record_type_descriptors @@ -3112,7 +3112,10 @@ restart: PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_LEFT_UNLOCKED, NULL))) + { + translog_unlock(); DBUG_RETURN(NULL); + } } else skipped_data= 0; /* Read after skipped in buffer data */ @@ -3213,6 +3216,11 @@ restart: PAGECACHE_LOCK_READ : PAGECACHE_LOCK_LEFT_UNLOCKED), direct_link); + if (!buffer && direct_link) + { + translog_free_link(*direct_link); + *direct_link= 0; + } DBUG_PRINT("info", ("Direct link is assigned to : %p * %p", direct_link, (direct_link ? *direct_link : NULL))); @@ -3785,16 +3793,26 @@ my_bool translog_init_with_table(const char *directory, } else if (LSN_OFFSET(last_page) == 0) { - if (LSN_FILE_NO(last_page) == 1) + if (LSN_FILE_NO(last_page) == 1 || + !translog_is_file(LSN_FILE_NO(last_page-1))) { logs_found= 0; /* file #1 has no pages */ DBUG_PRINT("info", ("log found. But is is empty => no log assumed")); } else { - last_page-= LSN_ONE_FILE; - if (translog_get_last_page_addr(&last_page, &pageok, 0)) - goto err; + do + { + last_page-= LSN_ONE_FILE; + if (translog_get_last_page_addr(&last_page, &pageok, 0)) + goto err; + } + while (LSN_OFFSET(last_page) == 0 && LSN_FILE_NO(last_page) >= 1); + if (LSN_OFFSET(last_page) == 0) + { + /* All files have a size less than TRANSLOG_PAGE_SIZE */ + logs_found= 0; + } } } if (logs_found) @@ -3892,36 +3910,38 @@ my_bool translog_init_with_table(const char *directory, old_log_was_recovered= 1; /* This file is not written till the end so it should be last */ last_page= current_file_last_page; - /* TODO: issue warning */ } - do + if (LSN_OFFSET(current_file_last_page) >= TRANSLOG_PAGE_SIZE) { - TRANSLOG_VALIDATOR_DATA data; - TRANSLOG_PAGE_SIZE_BUFF psize_buff; - uchar *page; - data.addr= ¤t_page; - if ((page= translog_get_page(&data, psize_buff.buffer, NULL)) == NULL) - goto err; - if (data.was_recovered) + do { - DBUG_PRINT("error", ("file no: %lu (%d) " - "rec_offset: 0x%lx (%lu) (%d)", - (ulong) LSN_FILE_NO(current_page), - (uint3korr(page + 3) != - LSN_FILE_NO(current_page)), - (ulong) LSN_OFFSET(current_page), - (ulong) (LSN_OFFSET(current_page) / - TRANSLOG_PAGE_SIZE), - (uint3korr(page) != - LSN_OFFSET(current_page) / - TRANSLOG_PAGE_SIZE))); - old_log_was_recovered= 1; - break; - } - old_flags= page[TRANSLOG_PAGE_FLAGS]; - last_valid_page= current_page; - current_page+= TRANSLOG_PAGE_SIZE; /* increase offset */ - } while (current_page <= current_file_last_page); + TRANSLOG_VALIDATOR_DATA data; + TRANSLOG_PAGE_SIZE_BUFF psize_buff; + uchar *page; + data.addr= ¤t_page; + if ((page= translog_get_page(&data, psize_buff.buffer, NULL)) == NULL) + goto err; + if (data.was_recovered) + { + DBUG_PRINT("error", ("file no: %lu (%d) " + "rec_offset: 0x%lx (%lu) (%d)", + (ulong) LSN_FILE_NO(current_page), + (uint3korr(page + 3) != + LSN_FILE_NO(current_page)), + (ulong) LSN_OFFSET(current_page), + (ulong) (LSN_OFFSET(current_page) / + TRANSLOG_PAGE_SIZE), + (uint3korr(page) != + LSN_OFFSET(current_page) / + TRANSLOG_PAGE_SIZE))); + old_log_was_recovered= 1; + break; + } + old_flags= page[TRANSLOG_PAGE_FLAGS]; + last_valid_page= current_page; + current_page+= TRANSLOG_PAGE_SIZE; /* increase offset */ + } while (current_page <= current_file_last_page); + } current_page+= LSN_ONE_FILE; current_page= LSN_REPLACE_OFFSET(current_page, TRANSLOG_PAGE_SIZE); } while (LSN_FILE_NO(current_page) <= LSN_FILE_NO(last_page) && @@ -4013,7 +4033,7 @@ my_bool translog_init_with_table(const char *directory, } DBUG_PRINT("info", ("Logs found: %d was recovered: %d", logs_found, old_log_was_recovered)); - if (!logs_found) + if (!logs_found && !readonly) { TRANSLOG_FILE *file= (TRANSLOG_FILE*)my_malloc(PSI_INSTRUMENT_ME, sizeof(TRANSLOG_FILE), MYF(MY_WME)); @@ -4063,6 +4083,10 @@ my_bool translog_init_with_table(const char *directory, translog_start_buffer(log_descriptor.buffers, &log_descriptor.bc, 0); translog_new_page_header(&log_descriptor.horizon, &log_descriptor.bc); } + else if (readonly && !logs_found) + { + log_descriptor.horizon= LSN_IMPOSSIBLE; + } /* all LSNs that are on disk are flushed */ log_descriptor.log_start= log_descriptor.sent_to_disk= @@ -4144,21 +4168,24 @@ my_bool translog_init_with_table(const char *directory, uint32 file_no= LSN_FILE_NO(page_addr); my_bool last_page_ok; /* it is beginning of the current file */ - if (unlikely(file_no == 1)) + do { - /* - It is beginning of the log => there is no LSNs in the log => - There is no harm in leaving it "as-is". + if (unlikely(file_no == 1)) + { + /* + It is beginning of the log => there is no LSNs in the log => + There is no harm in leaving it "as-is". */ - log_descriptor.previous_flush_horizon= log_descriptor.horizon; - DBUG_PRINT("info", ("previous_flush_horizon: " LSN_FMT, - LSN_IN_PARTS(log_descriptor. + log_descriptor.previous_flush_horizon= log_descriptor.horizon; + DBUG_PRINT("info", ("previous_flush_horizon: " LSN_FMT, + LSN_IN_PARTS(log_descriptor. previous_flush_horizon))); - DBUG_RETURN(0); - } - file_no--; - page_addr= MAKE_LSN(file_no, TRANSLOG_PAGE_SIZE); - translog_get_last_page_addr(&page_addr, &last_page_ok, 0); + DBUG_RETURN(0); + } + file_no--; + page_addr= MAKE_LSN(file_no, TRANSLOG_PAGE_SIZE); + translog_get_last_page_addr(&page_addr, &last_page_ok, 0); + } while (LSN_OFFSET(page_addr) == 0); /* page should be OK as it is not the last file */ DBUG_ASSERT(last_page_ok); } @@ -6905,17 +6932,19 @@ translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner) /* if it is log end it have to be caught before */ DBUG_ASSERT(LSN_FILE_NO(scanner->horizon) > LSN_FILE_NO(scanner->page_addr)); - scanner->page_addr+= LSN_ONE_FILE; - scanner->page_addr= LSN_REPLACE_OFFSET(scanner->page_addr, - TRANSLOG_PAGE_SIZE); - if (translog_scanner_set_last_page(scanner)) - DBUG_RETURN(1); + do + { + scanner->page_addr+= LSN_ONE_FILE; + scanner->page_addr= LSN_REPLACE_OFFSET(scanner->page_addr, + TRANSLOG_PAGE_SIZE); + if (translog_scanner_set_last_page(scanner)) + DBUG_RETURN(1); + } while (!LSN_OFFSET(scanner->last_file_page)); } else { scanner->page_addr+= TRANSLOG_PAGE_SIZE; /* offset increased */ } - if (translog_scanner_get_page(scanner)) DBUG_RETURN(1); @@ -6926,7 +6955,9 @@ translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner) scanner->page_offset= 0; DBUG_RETURN(0); } +#ifdef CHECK_EMPTY_PAGE DBUG_ASSERT(scanner->page[scanner->page_offset] != TRANSLOG_FILLER); +#endif } DBUG_RETURN(0); } diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index db592adf..02d7b747 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -25,7 +25,11 @@ /* minimum possible transaction log size */ #define TRANSLOG_MIN_FILE_SIZE (8*MB) /* transaction log default flags (TODO: make it global variable) */ +#ifdef HAVE_DBUG_TRANSLOG_CRC +#define TRANSLOG_DEFAULT_FLAGS IF_DBUG(TRANSLOG_PAGE_CRC,0) +#else #define TRANSLOG_DEFAULT_FLAGS 0 +#endif /* Transaction log flags. diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 49981e79..bc92eb66 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -3878,7 +3878,7 @@ restart: { pagecache_pthread_mutex_unlock(&pagecache->cache_lock); DBUG_ASSERT(0); - return (uchar*) 0; + DBUG_RETURN((uchar*) 0); } } /* @@ -5229,7 +5229,7 @@ int flush_pagecache_blocks_with_filter(PAGECACHE *pagecache, { int res; DBUG_ENTER("flush_pagecache_blocks_with_filter"); - DBUG_PRINT("enter", ("pagecache: %p", pagecache)); + DBUG_PRINT("enter", ("pagecache: %p fd: %di", pagecache, file->file)); if (pagecache->disk_blocks <= 0) DBUG_RETURN(0); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index df9b2024..f05b366f 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -133,7 +133,7 @@ static void new_transaction(uint16 sid, TrID long_id, LSN undo_lsn, static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id); static int new_page(uint32 fileid, pgcache_page_no_t pageid, LSN rec_lsn, struct st_dirty_page *dirty_page); -static int close_all_tables(void); +static int close_all_tables(my_bool force_end_newline); static my_bool close_one_table(const char *name, TRANSLOG_ADDRESS addr); static void print_redo_phase_progress(TRANSLOG_ADDRESS addr); static void delete_all_transactions(); @@ -467,7 +467,7 @@ int maria_apply_log(LSN from_lsn, LSN end_redo_lsn, LSN end_undo_lsn, we don't use maria_panic() because it would maria_end(), and Recovery does not want that (we want to keep some modules initialized for runtime). */ - if (close_all_tables()) + if (close_all_tables(0)) { ma_message_no_user(0, "closing of tables failed"); goto err; @@ -495,6 +495,8 @@ int maria_apply_log(LSN from_lsn, LSN end_redo_lsn, LSN end_undo_lsn, /* No dirty pages, all tables are closed, no active transactions, save: */ if (ma_checkpoint_execute(CHECKPOINT_FULL, FALSE)) goto err; + tprint(tracef, "checkpoint done at " LSN_FMT "\n", + LSN_IN_PARTS(last_checkpoint_lsn)); } goto end; @@ -505,7 +507,7 @@ err2: delete_all_transactions(); if (!abort_message_printed) error= 1; - if (close_all_tables()) + if (close_all_tables(1)) { ma_message_no_user(0, "closing of tables failed"); } @@ -3480,7 +3482,7 @@ static int new_page(uint32 fileid, pgcache_page_no_t pageid, LSN rec_lsn, } -static int close_all_tables(void) +static int close_all_tables(my_bool force_end_newline) { int error= 0; uint count= 0; @@ -3545,7 +3547,7 @@ static int close_all_tables(void) } } end: - if (recovery_message_printed == REC_MSG_FLUSH) + if (recovery_message_printed == REC_MSG_FLUSH && (force_end_newline || error)) { fputc('\n', stderr); fflush(stderr); diff --git a/storage/maria/ma_recovery_util.c b/storage/maria/ma_recovery_util.c index fe43d812..b8123c42 100644 --- a/storage/maria/ma_recovery_util.c +++ b/storage/maria/ma_recovery_util.c @@ -87,7 +87,7 @@ void eprint(FILE *trace_file __attribute__ ((unused)), if (!trace_file) trace_file= stderr; - if (procent_printed) + if (procent_printed && trace_file == stderr) { procent_printed= 0; /* In silent mode, print on another line than the 0% 10% 20% line */ diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c index 8cd82e1c..7e43ed4b 100644 --- a/storage/maria/ma_rkey.c +++ b/storage/maria/ma_rkey.c @@ -120,6 +120,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, /* The key references a concurrently inserted record. */ if (search_flag == HA_READ_KEY_EXACT && + (keyinfo->flag & HA_NOSAME) && last_used_keyseg == keyinfo->seg + keyinfo->keysegs) { /* Simply ignore the key if it matches exactly. (Bug #29838) */ diff --git a/storage/maria/ma_scan.c b/storage/maria/ma_scan.c index 5f2945a3..3e789489 100644 --- a/storage/maria/ma_scan.c +++ b/storage/maria/ma_scan.c @@ -48,10 +48,12 @@ int maria_scan_init(register MARIA_HA *info) int maria_scan(MARIA_HA *info, uchar *record) { + int res; DBUG_ENTER("maria_scan"); /* Init all but update-flag */ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); - DBUG_RETURN((*info->s->scan)(info, record, info->cur_row.nextpos, 1)); + res= (*info->s->scan)(info, record, info->cur_row.nextpos, 1); + DBUG_RETURN(res); } diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 95cc1203..9a6859bf 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -428,14 +428,15 @@ err2: my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key) { + my_bool tmp; DBUG_ENTER("_ma_ck_write"); if (info->bulk_insert && is_tree_inited(&info->bulk_insert[key->keyinfo->key_nr])) - { - DBUG_RETURN(_ma_ck_write_tree(info, key)); - } - DBUG_RETURN(_ma_ck_write_btree(info, key)); + tmp= _ma_ck_write_tree(info, key); + else + tmp= _ma_ck_write_btree(info, key); + DBUG_RETURN(tmp); } /* _ma_ck_write */ diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index b12f21e3..147dc83d 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -43,6 +43,14 @@ C_MODE_START +#ifdef _WIN32 +/* + We cannot use mmap() on Windows with Aria as mmap() can cause file + size to increase in _ma_dynmap_file(). The extra \0 data causes + the file to be regarded as corrupted. +*/ +#undef HAVE_MMAP +#endif /* Limit max keys according to HA_MAX_POSSIBLE_KEY; See myisamchk.h for details */ @@ -213,7 +221,6 @@ extern int maria_rsame_with_pos(MARIA_HA *file, uchar *record, extern int maria_update(MARIA_HA *file, const uchar *old, const uchar *new_record); extern int maria_write(MARIA_HA *file, const uchar *buff); -extern MARIA_RECORD_POS maria_position(MARIA_HA *file); extern int maria_status(MARIA_HA *info, MARIA_INFO *x, uint flag); extern int maria_lock_database(MARIA_HA *file, int lock_type); extern int maria_delete_table(const char *name); @@ -1018,6 +1025,7 @@ struct st_maria_handler my_bool switched_transactional; /* If transaction will autocommit */ my_bool autocommit; + my_bool has_cond_pushdown; #ifdef _WIN32 my_bool owned_by_merge; /* This Maria table is part of a merge union */ #endif @@ -1029,6 +1037,8 @@ struct st_maria_handler my_bool create_unique_index_by_sort; index_cond_func_t index_cond_func; /* Index condition function */ void *index_cond_func_arg; /* parameter for the func */ + rowid_filter_func_t rowid_filter_func; /* rowid filter check function */ + void *rowid_filter_func_arg; /* parameter for the func */ }; /* Table options for the Aria and S3 storage engine */ @@ -1070,6 +1080,7 @@ struct ha_table_option_struct #define STATE_IN_REPAIR 1024U /* We are running repair on table */ #define STATE_CRASHED_PRINTED 2048U #define STATE_DATA_FILE_FULL 4096U +#define STATE_HAS_LSN 8192U /* Some page still has LSN */ #define STATE_CRASHED_FLAGS (STATE_CRASHED | STATE_CRASHED_ON_REPAIR | STATE_CRASHED_PRINTED) @@ -1353,7 +1364,11 @@ extern int _ma_read_rnd_no_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos, my_bool skip_deleted_blocks); my_off_t _ma_no_keypos_to_recpos(MARIA_SHARE *share, my_off_t pos); - +/* Get position to last record */ +static inline MARIA_RECORD_POS maria_position(MARIA_HA *info) +{ + return info->cur_row.lastpos; +} extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key); extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, MARIA_RECORD_POS *root); @@ -1739,7 +1754,25 @@ extern my_bool maria_flush_log_for_page_none(PAGECACHE_IO_HOOK_ARGS *args); extern PAGECACHE *maria_log_pagecache; extern void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func, void *func_arg); -check_result_t ma_check_index_cond(MARIA_HA *info, uint keynr, uchar *record); +extern void ma_set_rowid_filter_func(MARIA_HA *info, + rowid_filter_func_t check_func, + void *func_arg); +static inline void ma_reset_index_filter_functions(MARIA_HA *info) +{ + info->index_cond_func= NULL; + info->rowid_filter_func= NULL; + info->has_cond_pushdown= 0; +} +check_result_t ma_check_index_cond_real(MARIA_HA *info, uint keynr, + uchar *record); +static inline check_result_t ma_check_index_cond(MARIA_HA *info, uint keynr, + uchar *record) +{ + if (!info->has_cond_pushdown) + return CHECK_POS; + return ma_check_index_cond_real(info, keynr, record); +} + extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx); extern my_bool ma_killed_standalone(MARIA_HA *); |