1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-24 19:42:23 +03:00
Commit Graph

536 Commits

Author SHA1 Message Date
74883f5e2f MDEV-32082 Server crash in find_field_in_table
Attempt to resolve FOR SYSTEM_TIME expression as field for derived
table is done before derived table is fully prepared, so we fail on
assertion that table_list->table is missing.

Actually Vers_history_point::resolve_unit() is done under the call of
mysql_derived_prepare() itself (sql_derived.cc:824) and the table is
assigned later at 867.

The fix disables unit resolution for field type in FOR SYSTEM_TIME
expression as it does a little sense in any case: making historical
queries based on variable field values produces the result of multiple
time points.

fix_fields_if_needed() in resolve_units() was introduced by 46be31982a
2023-11-10 15:46:15 +03:00
e53e7cd134 MDEV-20545 Assertion col.vers_sys_end() in dict_index_t::vers_history_row
Index values for row_start/row_end was wrongly calculated for inplace
ALTER for some layout of virtual fields.

Possible impact

  1. history row is not detected upon build clustered index for
     inplace ALTER which may lead to duplicate key errors on
     auto-increment and FTS index add.
  2. foreign key constraint may falsely fail.
  3. after inplace ALTER before server restart trx-based system
     versioning can cause server crash or incorrect data written upon
     UPDATE.
2023-11-10 15:46:14 +03:00
952f06aa8b MDEV-29989 binlog_do_db option breaks versioning table
Problem:
=========
During commit, server calls prepare_commit_versioned to
determine the transaction modified system-versioned data.
Due to binlog_do_db option, we disable the binlog for the
statement. But prepare_commit_versioned() is being
called only when binlog is enabled for the statement.

Fix:
===
prepare_commit_versioned() should happen irrespective
of binlog state. So if the server has any read-write operation
then we should call prepare_commit_versioned().
2023-09-26 10:47:59 +05:30
9854fb6fa7 MDEV-31003: Second execution for ps-protocol
This patch adds for "--ps-protocol" second execution
of queries "SELECT".
Also in this patch it is added ability to disable/enable
(--disable_ps2_protocol/--enable_ps2_protocol) second
execution for "--ps-prototocol" in testcases.
2023-07-26 17:15:00 +07:00
14cc7e7d6e MDEV-25644 UPDATE not working properly on transaction precise system versioned table
First UPDATE under START TRANSACTION does nothing (nstate= nstate),
but anyway generates history. Since update vector is empty we get into
(!uvect->n_fields) branch which only adds history row, but does not do
update. After that we get current row with wrong (old) row_start value
and because of that second UPDATE tries to insert history row again
because it sees trx->id != row_start which is the guard to avoid
inserting multiple trx_id-based history rows under same transaction
(because we have same trx_id and we get duplicate error and this bug
demostrates that). But this try anyway fails because PK is based on
row_end which is constant under same transaction, so PK didn't change.

The fix moves vers_make_update() to an earlier stage of
calc_row_difference(). Therefore it prepares update vector before
(!uvect->n_fields) check and never gets into that branch, hence no
need to handle versioning inside that condition anymore.

Now trx->id and row_start are equal after first UPDATE and we don't
try to insert second history row.

== Cleanups and improvements ==

ha_innobase::update_row():

vers_set_fields and vers_ins_row are cleaned up into direct condition
check. SQLCOM_ALTER_TABLE check now is not used as this is dead code,
assertion is done instead.

upd_node->is_delete is set in calc_row_difference() just to keep
versioning code as much in one place as possible. vers_make_delete()
is still located in row_update_for_mysql() as this is required for
ha_innodbase::delete_row() as well.

row_ins_duplicate_error_in_clust():

Restrict DB_FOREIGN_DUPLICATE_KEY to the better conditions.
VERSIONED_DELETE is used specifically to help lower stack to
understand what caused current insert. Related to MDEV-29813.
2023-07-20 18:22:31 +03:00
c5a8341115 MDEV-23100 ODKU of non-versioning column inserts history row
Use vers_check_update() to avoid inserting history row for ODKU if now
versioned fields specified in update_fields.
2023-07-20 18:22:30 +03:00
fe618de691 MDEV-31313 SYSTEM VERSIONING and FOREIGN KEY CASCADE create orphan rows on replica
Constraints processing row_ins_check_foreign_constraint() was not
called because row_upd_check_references_constraints() didn't see
update as delete: node->is_delete was false.

Since MDEV-30378 we check for TRG_EVENT_DELETE to detect versioned
delete in ha_innobase::update_row().

Now we can use TRG_EVENT_DELETE to set upd_node->is_delete, so
constraints processing is triggered correctly.
2023-07-20 18:22:30 +03:00
29fb041007 MDEV-30430: Enabling system versioning on tables without primary key breaks replication
When replicating MDL events for a table that uses system versioning
without primary keys, ensure that for data sets with duplicate
records, the updates to these records with duplicates are enacted on
the correct row. That is, there was a bug (reported in MDEV-30430)
such that the function to find the row to update would stop after
finding the first matching record. However, in the absence of
primary keys, the version of the record is needed to compare the row
to ensure we are updating the correct one.

The fix, therefore, updates the record comparison functionality to
use system version columns when there are no primary keys on the
table.

Reviewed By:
============
Andrei Elkin <andrei.elkin@mariadb.com>
2023-04-24 15:09:40 -06:00
f33fc2fae5 MDEV-30539 EXPLAIN EXTENDED: no message with queries for DML statements
EXPLAIN EXTENDED for an UPDATE/DELETE/INSERT/REPLACE statement did not
produce the warning containing the text representation of the query
obtained after the optimization phase. Such warning was produced for
SELECT statements, but not for DML statements.
The patch fixes this defect of EXPLAIN EXTENDED for DML statements.
2023-03-25 12:36:59 -07:00
71e8e4934d Merge 10.3 into 10.4 2023-01-13 09:28:25 +02:00
7a98d232e4 MDEV-30378 Versioned REPLACE succeeds with ON DELETE RESTRICT constraint
node->is_delete was incorrectly set to NO_DELETE for a set of operations.

In general we shouldn't rely on sql_command and look for more abstract ways
to control the behavior.

trg_event_map seems to be a suitable way. To mind replica nodes, it is ORed
with slave_fk_event_map, which stores trg_event_map when replica has
triggers disabled.
2023-01-12 21:51:48 +03:00
fb0808c450 Merge 10.3 into 10.4 2023-01-03 16:10:02 +02:00
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
667d3fbbb5 Merge 10.3 into 10.4 2022-10-25 10:04:37 +03:00
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
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
d4f6d2f08f Merge branch '10.3' into 10.4 2022-10-01 23:07:26 +02:00
1f51d6c0f6 MDEV-28548: ER_TABLEACCESS_DENIED_ERROR is missing information about DB
- Added missing information about database of corresponding table for various types of commands
- Update some typos

- Reviewed by: <vicentiu@mariadb.org>
2022-09-30 08:48:57 +02:00
18795f5512 Merge 10.3 into 10.4 2022-09-13 16:36:38 +03:00
f1544424de MDEV-29446 Change SHOW CREATE TABLE to display default collation 2022-09-12 22:10:39 +04:00
23ddc3518f Merge branch '10.3' into 10.4 2022-05-18 01:25:30 +02:00
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
a70a1cf3f4 Merge branch '10.3' into 10.4 2022-05-08 23:03:08 +02:00
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
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
9286c9e647 MDEV-28254 Wrong position for row_start, row_end after adding column to implicit versioned table
Implicit system-versioned table does not contain system fields in SHOW
CREATE. Therefore after mysqldump recovery such table has system
fields in the last place in frm image. The original table meanwhile
does not guarantee these system fields on last place because adding
new fields via ALTER TABLE places them last. Thus the order of fields
may be different between master and slave, so row-based replication
may fail.

To fix this on ALTER TABLE we now place system-invisible fields always
last in frm image. If the table was created via old revision and has
an incorrect order of fields it can be fixed via any copy operation of
ALTER TABLE, f.ex.:

  ALTER TABLE t1 FORCE;

To check the order of fields in frm file one can use hexdump:

  hexdump -C t1.frm

Note, the replication fails only when all 3 conditions are met:

  1. row-based or mixed mode replication;
  2. table has new fields added via ALTER TABLE;
  3. table was rebuilt on some, but not all nodes via mysqldump image.

Otherwise it will operate properly even with incorrect order of
fields.
2022-04-22 15:49:37 +03:00
88a9f13a90 MDEV-25546 LIMIT partitioning does not respect ROLLBACK
vers_info->hist_part retained stale value after ROLLBACK. The
algorithm in vers_set_hist_part() continued iteration from that value.

The simplest solution is to process partitions each time from start
for LIMIT in vers_set_hist_part().
2022-04-22 15:49:37 +03:00
39cc2545af MDEV-24529 Assertion failed in vers_select_conds_t::print
This commit adds processing of SYSTEM_TIME_BEFORE and SYSTEM_TIME_HISTORY
to vers_select_conds_t::print().
2022-04-18 11:19:34 +03:00
d6d66c6e90 Merge 10.3 into 10.4 2022-04-06 08:59:09 +03:00
d7fd76456e MDEV-19525 fix the test for embedded
followup for 58cd2a8ded
2022-04-05 13:09:44 +02:00
1e859d4abc MDEV-22973 Assertion in compare_record upon multi-update involving versioned table via view
records_are_comparable() requires this condition:

  bitmap_is_subset(table->write_set, table->read_set)

On first iteration vers_update_fields() changes write_set and
read_set. On second iteration the above condition fails.

Added missing read bit for ROW_START. Also reorganized
bitmap_set_bit() so it is called only when needed.
2022-03-29 13:44:14 +03:00
58cd2a8ded MDEV-19525 remove ER_VERS_FIELD_WRONG_TYPE from init_from_binary_frm_image()
Throw ER_NOT_FORM_FILE if this is wrong FRM data (warning with
ER_VERS_FIELD_WRONG_TYPE is still printed for deeper knowledge of what
was happened).

Keep ER_VERS_FIELD_WRONG_TYPE for creating partitioned table with
trx-versioning. Tested by MDEV-15951 in trx_id.test
2022-03-29 13:44:14 +03:00
1ec3205703 Merge 10.3 into 10.4 2022-03-07 16:46:00 +03:00
86c1bf118a MDEV-27992 DELETE fails to delete record after blocking is released
MDEV-27025 allows to insert records before the record on which DELETE is
locked, as a result the DELETE misses those records, what causes serious ACID
violation.

Revert MDEV-27025, MDEV-27550. The test which shows the scenario of ACID
violation is added.
2022-03-07 16:42:05 +03:00
f6f055a191 Merge 10.3 into 10.4 2022-02-21 14:10:27 +03:00
5f001bd7b8 MDEV-27025 insert-intention lock conflicts with waiting ORDINARY lock
The code was backported from 10.5 be8113861c
commit. See that commit message for details.
2022-02-21 12:49:54 +03:00
a576a1cea5 Merge branch '10.3' into 10.4 2022-01-30 09:46:52 +01:00
585cb18ed1 MDEV-27452 TIMESTAMP(0) system field is allowed for certain creation of system-versioned table
First, we do not add VERS_UPDATE_UNVERSIONED_FLAG for system field and
that fixes SHOW CREATE result.

Second, we have to call check_sys_fields() for any CREATE TABLE and
there correct type is checked for system fields.

Third, we update system_time like as_row structures for ALTER TABLE
and that makes check_sys_fields() happy for ALTER TABLE when we make
system fields hidden.
2022-01-13 23:35:17 +03:00
241ac79e49 MDEV-26778 row_start is not updated in current row for InnoDB
Update was skipped (need_update was false) because compare_record()
used HA_PARTIAL_COLUMN_READ branch and it skipped row_start check
has_explicit_value() was false. When we set bit for row_start in
has_value_set the row is updated with new row_start value.

The bug was caused by combination of MDEV-23446 and 3789692d17. The
latter one says:

  ... But generated columns that are written to the table are always
  deterministic and cannot change unless normal non-generated columns
  were changed. ...

Since MDEV-23446 generated row_start can change while non-generated
columns are not changed.

Explicit value flag came from HAS_EXPLICIT_DEFAULT which was used to
distinguish default-generated value from user-supplied one.
2022-01-13 23:35:17 +03:00
4d5ae2b325 MDEV-27217 DELETE partition selection doesn't work for history partitions
LIMIT history switching requires the number of history partitions to
be marked for read: from first to last non-empty plus one empty. The
least we can do is to fail with error message if the needed partition
was not marked for read. As this is handler interface we require new
handler error code to display user-friendly error message.

Switching by INTERVAL works out-of-the-box with
ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET error.
2022-01-13 23:35:16 +03:00
f9f6b190cc Versioning test suite cleanups
Merged truncate_privilege and sysvars-notembedded into not_embedded.test
Merged partition_innodb into trx_id.test
2022-01-13 23:35:16 +03:00
6d8794e567 MDEV-21650 Non-empty statement transaction on global rollback after TRT update error
TRT opens statement transaction. Cleanup it in case of error.
2022-01-12 23:50:23 +03:00
681b7784b6 Merge branch 10.3 into 10.4 2021-12-25 12:13:03 +01:00
3fd80d0874 MDEV-27244 Table corruption upon adding serial data type
MDEV-25803 excluded some cases from key sort upon alter table. That
particularly depends on ALTER_ADD_INDEX flag. Creating a column of
SERIAL data type missed that flag. Though equivalent operation

  alter table t1 add x bigint unsigned not null auto_increment unique;

has ALTER_ADD_INDEX flag.
2021-12-16 23:13:45 +03:00
47ab793d71 Merge 10.3 into 10.4 2021-11-09 08:40:14 +02:00
c8cece9144 MDEV-26928 Column-inclusive WITH SYSTEM VERSIONING doesn't work with explicit system fields
versioning_fields flag indicates that any columns were specified WITH
SYSTEM VERSIONING. In that case we imply WITH SYSTEM VERSIONING for
the whole table and WITHOUT SYSTEM VERSIONING for the other columns.
2021-11-02 11:49:47 +03:00
1be39f86cc MDEV-25552 system versioned partitioned by LIMIT tables break CHECK TABLE
Replaced HA_ADMIN_NOT_IMPLEMENTED error code by HA_ADMIN_OK. Now CHECK
TABLE does not fail by unsupported check_misplaced_rows(). Admin
message is not needed as well.

Test case is the same as for MDEV-21011 (a7cf0db3d8), the result have
been changed.
2021-11-02 04:52:03 +03:00
a736a3174a Merge 10.3 into 10.4 2021-10-13 12:03:32 +03:00
d31f953789 MDEV-22660 SIGSEGV on adding system versioning and modifying system column
Second alter subcommand correctly removed VERS_ROW_END flag. We throw
ER_VERS_PERIOD_COLUMNS in such case.
2021-10-11 13:36:07 +03:00
f84e28c119 Merge 10.3 into 10.4 2021-08-18 16:51:52 +03:00