1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00
Commit Graph

680 Commits

Author SHA1 Message Date
Aleksey Midenkov
e056efdd6c MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY
1. In case of system-versioned table add row_end into FTS_DOC_ID index
   in fts_create_common_tables() and innobase_create_key_defs().
   fts_n_uniq() returns 1 or 2 depending on whether the table is
   system-versioned.

   After this patch recreate of FTS_DOC_ID index is required for
   existing system-versioned tables. If you see this message in error
   log or server warnings: "InnoDB: Table db/t1 contains 2 indexes
   inside InnoDB, which is different from the number of indexes 1
   defined in the MariaDB" use this command to fix the table:

      ALTER TABLE db.t1 FORCE;

2. Fix duplicate history for secondary unique index like it was done
   in MDEV-23644 for clustered index (932ec586aa). In case of
   existing history row which conflicts with currently inseted row we
   check in row_ins_scan_sec_index_for_duplicate() whether that row
   was inserted as part of current transaction. In that case we
   indicate with DB_FOREIGN_DUPLICATE_KEY that new history row is not
   needed and should be silently skipped.

3. Some parts of MDEV-21138 (7410ff436e) reverted. Skipping of
   FTS_DOC_ID index for history rows made problems with purge
   system. Now this is fixed differently by p.2.

4. wait_all_purged.inc checks that we didn't affect non-history rows
   so they are deleted and purged correctly.

Additional FTS fixes

  fts_init_get_doc_id(): exclude history rows from max_doc_id
  calculation. fts_init_get_doc_id() callback is used only for crash
  recovery.

  fts_add_doc_by_id(): set max value for row_end field.

  fts_read_stopword(): stopwords table can be system-versioned too. We
  now read stopwords only for current data.

  row_insert_for_mysql(): exclude history rows from doc_id validation.

  row_merge_read_clustered_index(): exclude history_rows from doc_id
  processing.

  fts_load_user_stopword(): for versioned table retrieve row_end field
  and skip history rows. For non-versioned table we retrieve 'value'
  field twice (just for uniformity).

FTS tests for System Versioning now include maybe_versioning.inc which
adds 3 combinations:

'vers'     for debug build sets sysvers_force and
	   sysvers_hide. sysvers_force makes every created table
	   system-versioned, sysvers_hide hides WITH SYSTEM VERSIONING
	   for SHOW CREATE.

	   Note: basic.test, stopword.test and versioning.test do not
	   require debug for 'vers' combination. This is controlled by
	   $modify_create_table in maybe_versioning.inc and these
	   tests run WITH SYSTEM VERSIONING explicitly which allows to
	   test 'vers' combination on non-debug builds.

'vers_trx' like 'vers' sets sysvers_force_trx and sysvers_hide. That
	   tests FTS with trx_id-based System Versioning.

'orig' 	   works like before: no System Versioning is added, no debug is
	   required.

Upgrade/downgrade test for System Versioning is done by
innodb_fts.versioning. It has 2 combinations:

'prepare' makes binaries in std_data (requires old server and OLD_BINDIR).
	  It tests upgrade/downgrade against old server as well.

'upgrade' tests upgrade against binaries in std_data.

Cleanups:

Removed innodb-fts-stopword.test as it duplicates stopword.test
2022-12-27 00:02:02 +03:00
Marko Mäkelä
7933367a27 Merge 10.10 into 10.11 2022-11-21 10:51:10 +02:00
Marko Mäkelä
b35a048ece Merge 10.8 into 10.9 2022-11-21 10:25:38 +02:00
Aleksey Midenkov
0e6f2757d1 MDEV-29841 More descriptive text for ER_PARTITION_WRONG_TYPE
For commands

  (1) alter table t1 add partition (partition p2);
  (2) alter table t1 add partition (partition px history);

It printed the same error message:

   Wrong partitioning type, expected type: `SYSTEM_TIME`

For (1) it is not clear from the syntax that we are trying to add
HASH partition. For (2) it is not clear that the table partitioning is
different than SYSTEM_TIME. Now it prints what type we are trying to
add to what type of partitioning.

Fixed warning unused function rename_field_in_list() for compilation
without partitioning.
2022-11-11 20:54:20 +03:00
Marko Mäkelä
91a7e9eb1e Merge 10.8 into 10.9 2022-11-10 09:50:30 +02:00
Oleksandr Byelkin
320de65135 Merge branch '10.7' into bb-10.7-release 2022-11-07 18:53:30 +01:00
Oleksandr Byelkin
ad937cf33a Merge branch '10.10' into 10.11 2022-11-02 13:08:01 +01:00
Oleksandr Byelkin
594bed9b42 MDEV-5215 prerequisite: remove test and test_* database hacks in the test suite 2022-11-01 16:33:00 +01:00
Oleksandr Byelkin
ebf2121529 Merge branch '10.8' into 10.9 2022-11-01 10:33:44 +01:00
Oleksandr Byelkin
6449af6f2d fix results after merge 2022-10-31 17:47:22 +01:00
Aleksey Midenkov
2092881984 MDEV-29841 Partition by system_time can be converted into table but not back
Wrong error code was returned because of prematurely tested condition
for wrong partition type. Now the condition for CONVERT IN is tested
first.
2022-10-31 16:32:05 +03:00
Oleksandr Byelkin
1ebfa2af62 Merge branch '10.6' into 10.7 2022-10-29 19:22:04 +02:00
Sergei Golubchik
2bd41fc5bf Revert MDEV-25292 Atomic CREATE OR REPLACE TABLE
Specifically:

Revert "MDEV-29664 Assertion `!n_mysql_tables_in_use' failed in innobase_close_connection"
This reverts commit ba875e9396.

Revert "MDEV-29620 Assertion `next_insert_id == 0' failed in handler::ha_external_lock"
This reverts commit aa08a7442a.

Revert "MDEV-29628 Memory leak after CREATE OR REPLACE with foreign key"
This reverts commit c579d66ba6.

Revert "MDEV-29609 create_not_windows test fails with different result"
This reverts commit cb583b2f1b.

Revert "MDEV-29544 SIGSEGV in HA_CREATE_INFO::finalize_locked_tables"
This reverts commit dcd66c3814.

Revert "MDEV-28933 CREATE OR REPLACE fails to recreate same constraint name"
This reverts commit cf6c517632.

Revert "MDEV-28933 Moved RENAME_CONSTRAINT_IDS to include/sql_funcs.h"
This reverts commit f1e1c1335b.

Revert "MDEV-28956 Locking is broken if CREATE OR REPLACE fails under LOCK TABLES"
This reverts commit a228ec80e3.

Revert "MDEV-25292 gcol.gcol_bugfixes --ps fix"
This reverts commit 24fff8267d.

Revert "MDEV-25292 Disable atomic replace for slave-generated or-replace"
This reverts commit 2af15914cb.

Revert "MDEV-25292 backup_log improved"
This reverts commit 34398a20b5.

Revert "MDEV-25292 Atomic CREATE OR REPLACE TABLE"
This reverts commit 93c8252f02.

Revert "MDEV-25292 Table_name class for (db, table_name, alias)"
This reverts commit d145dda9c7.

Revert "MDEV-25292 ha_table_exists() cleanup and improvement"
This reverts commit 409b8a86de.

Revert "MDEV-25292 Cleanups"
This reverts commit 595dad83ad.

Revert "MDEV-25292 Refactoring: moved select_field_count into Alter_info."
This reverts commit f02af1d229.
2022-10-27 23:13:41 +02:00
Sergei Golubchik
7bdc024fb0 MDEV-29830 Assertion `table->versioned()' in THD::vers_insert_history_fast
remove assert temporarily, the proper fix comes after MDEV-29833
2022-10-26 15:30:39 +02:00
Sergei Golubchik
73b2a326d2 MDEV-29730 mysqldump --dump-history creates broken dump if there are precision-versioned tables 2022-10-26 15:30:39 +02:00
Sergei Golubchik
d249761ae5 MDEV-16029 mysqldump: dump and restore historical data 2022-10-26 15:30:39 +02:00
Sergei Golubchik
ab50321508 MDEV-29813 REPLACE/IGNORE does not work with historical records in InnoDB
note that replace no longer supports system_versioning_insert_history,
the test case is only for ignore
2022-10-26 15:30:39 +02:00
Sergei Golubchik
3b6742a106 don't support REPLACE and INSERT ODKU with system_versioning_insert_history
they'll ignore the value of system_versioning_insert_history,
just as DELETE and UPDATE do
2022-10-26 15:30:39 +02:00
Sergei Golubchik
fe44d46a03 MDEV-29721 Inconsistency upon inserting history with visible system versioning columns 2022-10-26 15:30:38 +02:00
Sergei Golubchik
e536cb8845 MDEV-29732 mysqlbinlog produces syntactically incorrect output with system_versioning_insert_history 2022-10-26 15:30:38 +02:00
Sergei Golubchik
4d1e3671d3 MDEV-29741 SHOW BINLOG EVENTS shows garbage with system_versioning_insert_history=on 2022-10-26 15:30:38 +02:00
Sergei Golubchik
d94ed0bb2a MDEV-29721 Inconsistency upon inserting history with visible period columns
don't set vers_write=false if one vers column was used explicitly,
instead do vers_update_fields() for columns that do not have explicit
value. So, if row_start has the value and row_end not, row_end will
get max by default.
2022-10-26 15:30:38 +02:00
Sergei Golubchik
8d2ec37a40 MDEV-16546 post-review fixes
* clarify the help text for --system-versioning-insert-history
* move the vers_write=false check from Item_field::fix_fields()
  next to other vers field checks in find_field_in_table()
* move row_start validation from handler::write_row() next to
  vers_update_fields()
* make secure_timestamp check to happen in one place only,
  extract it into a function is_set_timestamp_vorbidden().
* overwriting vers fields is an error, just like setting @@timestamp
* don't run vers_insert_history() for every row
2022-10-26 15:30:38 +02:00
Aleksey Midenkov
a2cda88631 MDEV-16546 System versioning setting to allow history modification
1. system_versioning_insert_history session variable allows
pseudocolumns ROW_START and ROW_END be specified in INSERT,
INSERT..SELECT and LOAD DATA.

2. Cleaned up select_insert::send_data() from setting vers_write as
this parameter is now set on TABLE initialization.

4. Replication of system_versioning_insert_history via option_bits in
OPTIONS_WRITTEN_TO_BIN_LOG.
2022-10-26 15:30:38 +02:00
Sergei Golubchik
1f7840088f MDEV-29833 CREATE ... SELECT system_versioned_table causes invalid defaults
ROW START/END fields shold have no default value
2022-10-26 15:30:38 +02:00
Marko Mäkelä
aeccbbd926 Merge 10.5 into 10.6
To prevent ASAN heap-use-after-poison in the MDEV-16549 part of
./mtr --repeat=6 main.derived
the initialization of Name_resolution_context was cleaned up.
2022-10-25 14:25:42 +03:00
Marko Mäkelä
4b4c2b8cc0 Merge 10.4 into 10.5 2022-10-25 11:43:59 +03:00
Marko Mäkelä
9a0b9e3360 Merge 10.4 into 10.5 2022-10-25 11:26:37 +03:00
Marko Mäkelä
667d3fbbb5 Merge 10.3 into 10.4 2022-10-25 10:04:37 +03:00
Alexey Botchkov
9de37e07de MDEV-19569 Assertion `table_list->table' failed in find_field_in_table_ref.
Disallow subqueries in The PARTITIN BY INTERVAL syntax.
Fix various interval types that now fail as they break syntax in the par
file.
2022-10-19 14:37:34 +04:00
Sergei Golubchik
e0b4db5ba3 MDEV-29750 triggers can modify history
should be the same behavior as for virtual columns:
* a warning on every inserted row
* silently ignored in a trigger
2022-10-16 01:24:30 +02:00
Aleksey Midenkov
cf6c517632 MDEV-28933 CREATE OR REPLACE fails to recreate same constraint name
Use temporary constraint names for temporary tables. The constraints
are not added to cache (skipped in dict_table_rename_in_cache()).

The scheme for temporary constraint names is as follows:

    for old table: db_name/\xFFconstraint_name
    for new table: db_name/\xFF\xFFconstraint_name

normalize_table_name_c_low(): wrong comparison "less than FN_REFLEN -
1". Somewhere array of FN_REFLEN includes the trailing 0, somewhere
array of FN_REFLEN + 1 includes trailing 0, but nowhere array of
FN_REFLEN - 1 must include trailing 0.
2022-08-31 11:55:06 +03:00
Aleksey Midenkov
2b9fb342cf MDEV-28978 Assertion failure in THD::binlog_query or unexpected
ER_ERROR_ON_WRITE with auto-partitioning

Added check whether binlogging is enabled before doing binlog_query().
2022-07-05 13:23:51 +03:00
Sergei Golubchik
152921174d fix sporadic versioning.rpl_row failures 2022-06-16 09:57:31 +02:00
Sergei Golubchik
bf2bdd1a1a Merge branch '10.8' into 10.9 2022-05-19 14:07:55 +02:00
Sergei Golubchik
99a433ed1c Merge branch '10.6' into 10.7 2022-05-18 10:34:38 +02:00
Sergei Golubchik
b2187662bc Merge branch '10.5' into 10.6 2022-05-18 10:30:47 +02:00
Sergei Golubchik
7970ac7fe8 Merge branch '10.4' into 10.5 2022-05-18 09:50:26 +02:00
Sergei Golubchik
23ddc3518f Merge branch '10.3' into 10.4 2022-05-18 01:25:30 +02:00
Aleksey Midenkov
107623c5c5 MDEV-28552 Assertion `inited==RND' failed in handler::ha_rnd_end
We cannot permanently change bits in read_partitions in the middle of
processing because ha_rnd_init()/ha_rnd_end() depends on that.
2022-05-18 01:22:29 +02:00
Sergei Golubchik
fd132be117 Merge branch '10.6' into 10.7 2022-05-11 11:25:33 +02:00
Sergei Golubchik
3bc98a4ec4 Merge branch '10.5' into 10.6 2022-05-10 14:01:23 +02:00
Sergei Golubchik
ef781162ff Merge branch '10.4' into 10.5 2022-05-09 22:04:06 +02:00
Sergei Golubchik
a70a1cf3f4 Merge branch '10.3' into 10.4 2022-05-08 23:03:08 +02:00
Aleksey Midenkov
706a8232da MDEV-25477 Auto-create breaks replication when triggering event was not replicated
If UPDATE/DELETE does not change data it is skipped from
replication. We now force replication of such events when they trigger
partition auto-creation.

For ROLLBACK it is as simple as set OPTION_KEEP_LOG
flag. trans_cannot_safely_rollback() does the rest.

For UPDATE/DELETE .. LIMIT 0 we make additional binlog_query() calls
at the early points of return.

As a safety measure we also convert row format into statement if it is
needed. The condition is decided by
binlog_need_stmt_format(). Basically if there are some row events in
cache we don't need that: table open of row event will trigger
auto-creation anyway.

Multi-update/delete works via mysql_select(). There is no early points
of return, so binlogging is always checked by
send_eof()/abort_resultset(). But we must comply with the above
measure of converting into statement.
2022-05-06 15:11:02 +03:00
Aleksey Midenkov
92bfc0e8c4 MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
:: Syntax change ::

Keyword AUTO enables history partition auto-creation.

Examples:

    CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

    CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH
    STARTS '2021-01-01 00:00:00' AUTO PARTITIONS 12;

    CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME LIMIT 1000 AUTO;

Or with explicit partitions:

    CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO
    (PARTITION p0 HISTORY, PARTITION pn CURRENT);

To disable or enable auto-creation one can use ALTER TABLE by adding
or removing AUTO from partitioning specification:

    CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

    # Disables auto-creation:
    ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR;

    # Enables auto-creation:
    ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

If the rest of partitioning specification is identical to CREATE TABLE
no repartitioning will be done (for details see MDEV-27328).

:: Description ::

Before executing history-generating DML command (see the list of commands below)
add N history partitions, so that N would be sufficient for potentially
generated history. N > 1 may be required when history partitions are switched
by INTERVAL and current_timestamp is N times further than the interval
boundary of the last history partition.

If the last history partition equals or exceeds LIMIT records then new history
partition is created and selected as the working partition. According to
MDEV-28411 partitions cannot be switched (or created) while the command is
running. Thus LIMIT does not carry strict limitation and the history partition
size must be planned as LIMIT value plus average number of history one DML
command can generate.

Auto-creation is implemented by synchronous fast_alter_partition_table() call
from the thread of the executed DML command before the command itself is run
(by the fallback and retry mechanism similar to Discovery feature,
see Open_table_context).

The name for newly added partitions are generated like default partition names
with extension of MDEV-22155 (which avoids name clashes by extending assignment
counter to next free-enough gap).

These DML commands can trigger auto-creation:

    DELETE (including multitable DELETE, excluding DELETE HISTORY)
    UPDATE (including multitable UPDATE)
    REPLACE (including REPLACE .. SELECT)
    INSERT .. ON DUPLICATE KEY UPDATE (including INSERT .. SELECT .. ODKU)
    LOAD DATA .. REPLACE

:: Bug fixes ::

MDEV-23642 Locking timeout caused by auto-creation affects original DML

    The reasons for this are:

    - Do not disrupt main business process (the history is auxiliary service);

    - Consequences are non-fatal (history is not lost, but comes into wrong
      partition; fixed by partitioning rebuild);

    - There is more freedom for application to fail in this case or not: it may
      read warning info and find corresponding error number.

    - While non-failing command is easy to handle by an application and fail it,
      the opposite is hard to handle: there is no automatic actions to fix
      failed command and retry, DBA intervention is required and until then
      application is non-functioning.

MDEV-23639 Auto-create does not work under LOCK TABLES or inside triggers

    Don't do tdc_remove_table() for OT_ADD_HISTORY_PARTITION because it is
    not possible in locked tables mode.

    LTM_LOCK_TABLES mode (and LTM_PRELOCKED_UNDER_LOCK_TABLES) works out
    of the box as fast_alter_partition_table() can reopen tables via
    locked_tables_list.

    In LTM_PRELOCKED we reopen and relock table manually.

:: More fixes ::

* some_table_marked_for_reopen flag fix

  some_table_marked_for_reopen affets only reopen of
  m_locked_tables. I.e. Locked_tables_list::reopen_tables() reopens only
  tables from m_locked_tables.

* Unused can_recover_from_failed_open() condition

  Is recover_from_failed_open() can be really used after
  open_and_process_routine()?

:: Reviewed by ::

Sergei Golubchik <serg@mariadb.org>
2022-05-06 15:11:02 +03:00
Aleksey Midenkov
75ede427e4 MDEV-27328 Change of SYSTEM_TIME partitioning options is not possible without data copy
When we need to add/remove or change LIMIT, INTERVAL, AUTO we have to
recreate partitioning from scratch (via data copy). Such operations
should be done fast. To remove options like LIMIT or INTERVAL one
should write:

  alter table t1 partition by system_time;

The command checks whether it is new or existing SYSTEM_TIME
partitioning. And in the case of new it behaves as CREATE would do:
adds default number of partitions (2). If SYSTEM_TIME partitioning
already existed it just changes its options: removes unspecified ones
and adds/changes those specified explicitly. In case when partitions
list was supplied it behaves as usual: does full repartitioning.

Examples:

  create or replace table t1 (x int) with system versioning
  partition by system_time limit 100 partitions 4;

  # Change LIMIT
  alter table t1 partition by system_time limit 33;

  # Remove LIMIT
  alter table t1 partition by system_time;

  # This does full repartitioning
  alter table t1 partition by system_time limit 33 partitions 4;

  # This does data copy as pruning will require records in correct partitions
  alter table t1 partition by system_time interval 1 hour
  starts '2000-01-01 00:00:00';

  # But this works fast, LIMIT will apply to DML commands
  alter table t1 partition by system_time limit 33;

To sum up, ALTER for SYSTEM_TIME partitioning does full repartitioning
when:

  - INTERVAL was added or changed;
  - partition list or partition number was specified;

Otherwise it does fast alter table.

Cleaned up dead condition in set_up_default_partitions().

Reviewed by:

  Oleksandr Byelkin <sanja@mariadb.com>
  Nikita Malyavin <nikitamalyavin@gmail.com>
2022-05-06 10:45:17 +03:00
Aleksey Midenkov
ddc416c606 MDEV-20077 Warning on full history partition is delayed until next DML statement
Moved LIMIT warning from vers_set_hist_part() to new call
vers_check_limit() at table unlock phase. At that point
read_partitions bitmap is already pruned by DML code (see
prune_partitions(), find_used_partitions()) so we have to set
corresponding bits for working history partition.

Also we don't do my_error(ME_WARNING|ME_ERROR_LOG), because at that
point it doesn't update warnings number, so command reports 0 warnings
(but warning list is still updated). Instead we do
push_warning_printf() and sql_print_warning() separately.

Under LOCK TABLES external_lock(F_UNLCK) is not executed. There is
start_stmt(), but no corresponding "stop_stmt()". So for that mode we
call vers_check_limit() directly from close_thread_tables().

Test result has been changed according to new LIMIT and warning
printing algorithm. For convenience all LIMIT warnings are marked with
"You see warning above ^".

TODO MDEV-20345 fixed. Now vers_history_generating() contains
fine-grained list of DML-commands that can generate history (and TODO
mechanism worked well).
2022-04-29 13:31:42 +03:00
Aleksey Midenkov
ea2f09979f MDEV-28271 Assertion on TRUNCATE PARTITION for PARTITION BY SYSTEM_TIME
Like in MDEV-27217 vers_set_hist_part() for LIMIT depends on all
partitions selected in read_partitions. That bugfix just disabled
partition selection for DELETE with this check:

  if (table->pos_in_table_list &&
      table->pos_in_table_list->partition_names)
  {
    return HA_ERR_PARTITION_LIST;
  }

ALTER TABLE TRUNCATE PARTITION is a different story. First, it doesn't
update pos_in_table_list->partition_names, but
thd->lex->alter_info.partition_names. But we cannot depend on that
since alter_info will be stale for DML. Second, we should not disable
TRUNCATE PARTITION for that to be consistent with TRUNCATE TABLE
behavior.

Now we don't do vers_set_hist_part() for ALTER TABLE as this command
is not DML, so it does not produce history.
2022-04-29 13:31:41 +03:00
Marko Mäkelä
638afc4acf Merge 10.6 into 10.7 2022-04-26 18:59:40 +03:00