1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Commit Graph

141 Commits

Author SHA1 Message Date
forkfun
33240f3c96 Merge branch '11.8' into '12.3' 2026-07-30 11:41:55 +02:00
forkfun
eaca80bf32 Merge branch '11.4' into '11.8' 2026-07-29 12:27:46 +02:00
forkfun
08eeb6a417 Merge branch '10.11' into '11.4' 2026-07-28 13:14:38 +02:00
Sergei Golubchik
8699c851f2 MDEV-23486 RBR can bypass secure_timestamp=YES
fix TIMESTAMP DEFAULT NOW() and ON UPDATE NOW()

Caveat: rbr cannot work without an index - if the slave overwrites
timestamp columns, before-image won't match in full, this is expected.
2026-07-24 17:06:40 +02:00
Oleksandr Byelkin
7598e4e95d Merge branch '10.11' into 11.4 2026-05-08 08:00:01 +02:00
ParadoxV5
3234045953 MDEV-39240: Fix mixed-sign comparison on 32-bit
Until MDEV-32188 on 11.5, both `my_time_t` and the
literal behind the `UINT_MAX32` macro are `signed long`.
But on platforms whose `long` is 32-bit, the value of
`UINT_MAX32` exceeds the range of `signed long`, and so the
macro instead has the next closest data type, `unsigned long`.
2026-04-24 14:35:51 +10:00
ParadoxV5
f9c34a1442 MDEV-39240 10.6-11.4 Replication Allows Full Range for 32-bit Unsigned Timestamps
Row-based Replication did not validate serialized timestamps,
which allows (pre-11.5) slaves to accept “negative” timestamps
(between the Year 2038 limit and the 4-byte limit) via replication.
In particular, a completely valid source of those timestamps is 11.5.1+
masters, where MDEV-32188 has increased the upper limit of
timestamps to Year 2106 by utilizing this previously invalid range.

This commit fills in this pre-processing:
swap the Year 2106 max with the Year 2038 max,
or throw an “Incorrect timestamp value” error for the others.

Reviewed-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
2026-04-21 12:33:40 -06:00
Brandon Nesterenko
de15b1160d MDEV-38117: Replication stops with ERROR when Primary Key is not defined in Multi Master
When replicating tables with different structures between a master and
slave (via binlog_row_metadata=FULL, i.e. MDEV-36290), if the table
didn't have any keys, replication could break from a
  Can't find record in '<table>', Error_code: 1032;
error. This was due to the table's internal tracking of provided values
(i.e. TABLE::has_value_set) persisting across transactions. I.e., when
applying a new row event, the has_value_set bitset would start in a
state indicative of the last event. Then, if the new row event required
first finding a row, the has_value_set could represent a larger bitset
than what was actually unpacked from the master. More specifically, if
the last row event inserted something into the table, where slave-only
columns would be given default/auto-generated values, these would
update the TABLE::has_value_set. However, when the next row event would
come in, those auto-generated values from the last transaction would
not be present, but the row-search would include them to look-up the
row, and not be able to find anything.

This is fixed by resetting the table's internal state of provided
values (TABLE::has_value_set) before unpacking the row data. Doing so
revealed a bug where unpacked fields which explicitly provided NULL
values would skip indicating that an explicit value was provided
(and thereby couldn't be found by find_row()). To fix this, the
slave-side field will always call has_explicit_value() if it is
present in the packed data.

Test case based on work from: Deepthi Sreenivas <deepthi.sreenivas@mariadb.com>

Signed-off-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
Reviewed-by: Monty <monty@mariadb.com>
2026-01-27 12:59:30 -07:00
Monty
be237b3b0e MDEV-36290: Improved support of replication between tables of different structure
One can have data loss in multi-master setups when 1) both masters
update the same table, 2) ALTER TABLE is run on one master which
re-arranges the column ordering, and 3) transactions are binlogged
in ROW binlog_format.

This is because the slave assumes that all columns are in the same
order on the master and slave and all columns on the master also
exists on the slave. This happens even if binlog_row_metadata=FULL is
used.  If this is not the case, this will lead to silent data loss.

A new option for slave_type_conversions bit field,
ERROR_IF_MISSING_FIELD, has been added, along with a new error,
ER_SLAVE_INCOMPATIBLE_TABLE_DEF. This allows the user to define if
the slave should abort replication if it is missing some field that
existed on the master. The option is off by default to keep things
compatible with earlier versions.
If a field is missing on the slave and log_warnings >= 1, a warning
will be logged to the error log.

This patch fixes this, when binlog_row_metadata=FULL is used on the
master, by mapping fields with identical names on the master and slave.
If slave has fields that does not exist in the row event, these will
be set to their default value.

The main idea is that we added two conversion tables:
m_tabledef.master_to_slave_map[master_column_index] -> slave_column_index
and m_tabledef.master_to_slave_error[master_column_index] which contains
an error number if the master_column does not exist on the slave or
it is not possible to convert the master data to the slave column.
master_to_slave_error[#] contains 0 if the column exists and is compatible.

General code changes:
- Instead of looping over row fields in the order of slave table
  we are instead looping over fields in the order of the binary log.
- We are using table->write_set to know which fields should be updated
  on the slave. This is reflected in unpack_row
- We are calling TABLE::mark_columns_per_binlog_row_image() to ensure
  that rpl_write_set is properly set. This is needed if the slave also
  is doing binary logging.
- Before replication aborted if the master and slave tables were too
  different.  Now replication is only aborted if the row actually uses
  columns that does not exists on the slave (and ERROR_IF_MISSING_FIELD
  is used) or uses columns that cannot be converted.
  - Instead of giving errors in compatible_with(), used when table is
    accessed by first the row event, we are instead giving errors
    when we examine a row event and notice that it is accessing
    a not existing or not compatible field.

Other code changes:
- Removed conv_table argument from compatible_with() and store it
  directly in RPL_TABLE_LIST->m_conv_table
- table_def::compatible_with() returns now 1 on error (not 0).
- Remove m_width and skip arguments from prepare_record() as we are
  now using table->write_set() to check which elements need a default
  value.
- Moved DBUG_ENTER() to it's proper place (after variable
  declarations) in a few functions.
- Some changes in unpack_row():
  - Replaced null_mask and null_ptr with an indexed bit check for
    simplicity.
  - Removed check of rgi == null and table_found which never worked.
  - Updated comments to reflect current code.
  - Indentation changes as the code now uses 'continue' instead of
    'if-else' in the main loop.
  - The code to throw away 'extra master fields' is not needed as we
    are now looping over fields in binary log, not over fields in
    slave table.
- Simplified get_table_data(TABLE *table_arg) by returning found
  table_list.
- Errors for row events are now initialized in compatible_with(),
  checked in check_wrong_column_usage() and reported in
  give_compatibility_error().

Co-authored-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
2026-01-27 12:59:30 -07:00
Sergei Golubchik
27c98794bb Merge branch '11.8' into 12.2 2026-01-08 12:02:45 +01:00
Marko Mäkelä
678ff03ee7 Merge 10.11 into 11.4 2026-01-02 11:53:09 +02:00
Marko Mäkelä
8fab129382 Merge 10.6 into 10.11 2026-01-02 11:06:05 +02:00
Marko Mäkelä
5d2da8ef1e MDEV-38408 WITH_DBUG_TRACE=OFF doesn't disable DBUG_DUMP or DBUG_LOG
DBUG_DUMP(), DBUG_LOG(): Null expand unless DBUG_TRACE is enabled.

Fixes up commit a69cf6f07e (MDEV-29613)
2025-12-22 08:29:57 +02:00
Oleksandr Byelkin
ecf0516257 Merge branch '12.1' into 12.2 2025-10-09 09:32:33 +02:00
Oleksandr Byelkin
c976b527db Merge branch '11.8' into bb-12.1-release 2025-10-08 09:05:38 +02:00
Monty
1125f59c71 Removed Rows_log_event::m_master_reclength as it is not used
The usage of the variable was removed in 2007

Other things (minor cleanups):
- Replaced variable 'f' with 'field' to get code more readable
- Removed not needed variable unpack_result
- Removed DBUG_OFF in middle of the code and replaced with attribute()
- Replaced 'auto' variable with real type (readability)
2025-09-30 21:23:19 +03:00
Oleksandr Byelkin
15b1426c3a Merge branch '10.11' into bb-11.4-release 2025-09-15 16:17:33 +02:00
Monty
882f6fa3aa Fixed typos
- Removed duplicate words, like "the the" and "to to"
- Removed duplicate lines (one double sort line found in mysql.cc)
- Fixed some typos found while searching for duplicate words.

Command used to find duplicate words:
egrep -rI "\s([a-zA-Z]+)\s+\1\s" | grep -v param

Thanks to Artjoms Rimdjonoks for the command and pointing out the
spelling errors.
2025-09-04 18:08:39 +03:00
Alexander Barkov
5360ccf8f4 Cleanup#2 for MDEV-34319: DECLARE TYPE .. TABLE OF .. INDEX BY - packed_col_length
Additional small cleanup (forgoten in the previous commit):
- Item_splocal_assoc_array_element_field::fix_fields()
  Fixing the error message for:
    SELECT marks('a').name; -- marks is a TABLE OF VARCHAR(10)
  From: ERROR 42S22: Unknown column '1' in 'SELECT'
  To:   ERROR 42S22: Unknown column 'name' in 'marks'

Fixing wrong results of packed_col_length(): it returned a wrong result for:
- CHAR(N)
- BINARY(N)
- MEDIUMBLOB
- LONGBLOB

Note, this method was not used. Now it's used by the assoc array data type.

Details:

- Cleanup: adding "const" qualifier to:

  * Field::pack()
  * Field::max_packed_col_length()
  * Field::packed_col_length()

- Removing the "max_length" argument from Field::pack().
  The caller passed either UINT_MAX or Field::max_data_length() to it.
  So it was never used to limit the destination size and only
  made the code more complicated and confusing.

- Removing arguments from packed_col_length().
  Now it calculates the value for the Field, using its "ptr",
  and assuming the entire value will be packed,
  without limiting the destination size.

- Fixing Field_blob::packed_col_length(). It worked fine only for
  TINYBLOB and BLOB, and did not work for MEDIUMBLOB and LONGBLOB.

- Overriding Field_char::packed_col_length().
  Using the inherited method was wrong - it implemented
  variable length data behavior.

- Overriding Field_string::max_data_length(). It was also incorrect.
  Implementing fixed size behavior.
  Moving the old implementation of Field_longstring::max_data_length()
  to Field_varstring::max_data_length().

- Fixing class StringPack:
  * Removing the "length" argument from StringPack::packed_col_length().
    It now assumes that the packed length for the entire data buffer
    is needed, without limiting the destination size.

  * Fixing StringPack::packed_col_length() to implement fixed dat size behavior.
    It erroneously implemented VARCHAR style behavor
    (assumed that the length was stored in the leading 1 or 2 bytes).

  * Adding a helper method length_bytes(). Reusing it in packed_col_length()
    and max_packed_col_length().

  * Moving a part the method pack() into a new method trimmed_length().
    Reusing it in pack() and packed_col_length().

  * Rewriting the code in trimmed_length() in a more straightforward way.
    It was hard to understand what it was doing.
    Adding a comment.

- Adding a test sp-assoc-array-pack-debug.test covering packed_col_length()
  and pack() for various data types.
2025-08-01 18:03:20 +02:00
Libing Song
be6d48fd53 MDEV-33049 Assertion `marked_for_write_or_computed()' failed in bool
Field_new_decimal::store_value(const my_decimal*, int*)

Analysis
========
When rpl applier is unpacking a before row image, Field::reset() will be
called before setting a field to null if null bit of the field is set in
the row image. For Field_new_decimal::reset(), it calls
Field_new_decimal::store_value() to reset the value. store_value() asserts
that the field is in the write_set bitmap since it thinks the field is
updating.

But that is not true for the row image generated in FULL_NODUP
mode. In the mode, the before image includes all fields and the after
image includes only updated fields.

Fix
===
In the case unpacking binlog row images, the assertion is meaningless.
So the unpacking field is marked in write_set temporarily to avoid the
assertion failure.
2024-01-12 08:32:22 +00:00
Vladislav Vaintroub
bb8e1bf7a2 Merge 11.3 into 11.4 2023-11-21 15:43:20 +01:00
Monty
3e50b4ecbc Fixed (wrong) compiler warning about uninitialized memory 2023-11-01 13:02:19 +02:00
Kristian Nielsen
b8f9f796ff MDEV-31273: Precompute binlog checksums
Compute binlog checksums (when enabled) already when writing events
into the statement or transaction caches, where before it was done
when the caches are copied to the real binlog file. This moves the
checksum computation outside of holding LOCK_log, improving
scalabitily.

At stmt/trx cache write time, the final end_log_pos values are not
known, so with this patch these will be set to 0. Events that are
written directly to the binlog file (not through stmt/trx cache) keep
the correct end_log_pos value. The GTID and COMMIT/XID events at the
start and end of event groups are written directly, so the zero
end_log_pos is only for events in the middle of event groups, which
do not negatively affect replication.

An option --binlog-legacy-event-pos, off by default, is provided to
disable this behavior to provide backwards compatibility with any
external applications that might rely on end_log_pos in events in the
middle of event groups.

Checksums cannot be pre-computed when binlog encryption is enabled, as
encryption relies on correct end_log_pos to provide part of the
nonce/IV.

Checksum pre-computation is also disabled for WSREP/Galera, as it uses
events differently in its write-sets and so on. Extending pre-computation of
checksums to Galera where it makes sense could be added in a future patch.

The current --binlog-checksum configuration is saved in
binlog_cache_data at transaction start and used to pre-compute
checksums in cache, if applicable. When the cache is later copied to
the binlog, a check is made if the saved value still matches the
configured global value; if so, the events are block-copied directly
into the binlog file. If --binlog-checksum was changed during the
transaction, events are re-written to the binlog file one-by-one and
the checksums recomputed/discarded as appropriate.

Reviewed-by: Monty <monty@mariadb.org>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2023-10-27 19:57:43 +02:00
Nikita Malyavin
3a42f2869e refactor unpack_row
Online alter and replication paths differ quite noticeably. It's time to
fix the mess. Online alter has to unpack the old table's data
(here conv_table), and then convert, while replication requires more
sophisticated track: handle possible conversions, treat extra replica
fields, and carefully deduce master's record length.

* Extract unpack_field.
* handle the unpacking progress through a state machine presented by
  Unpack_record_state struct.
* Stick most of the online alter unpacking together under a single
  conditional branch.
2023-08-15 10:16:13 +02:00
Nikita Malyavin
500379cf49 unpack_row: unpack a correct number of fields 2023-08-15 10:16:13 +02:00
Nikita Malyavin
af82d56a51 unpack_row: set the correct fields in has_value_set for online alter 2023-08-15 10:16:13 +02:00
Nikita Malyavin
2be4c836e5 MDEV-29069 ER_KEY_NOT_FOUND on online autoinc addition + concurrent DELETE
We can't rely on keys formed with columns that were added during this
ALTER. These columns can be set with non-deterministic values, which can
end up with broken or incorrect search.

The same applies to the keys that contain reliable columns, but also have
bogus ones. Using them can narrow the search, but they're also ignored.

Also, added columns shouldn't be considered during the record match. To
determine them, table->has_value_set bitmap is used.

To fill has_value_set bitmap in the find_key call, extra unpack_row call
has been added.

For replication case, extra replica columns can be considered for this
case. We try to ignore them, too.
2023-08-15 10:16:13 +02:00
Sergei Golubchik
e72ed758c7 cleanup: remove rpl_group_info::get_table_data()
use table->pos_in_table_list instead.

Also, table->in_use is always set
2023-08-15 10:16:13 +02:00
Nikita Malyavin
0311b11225 few rgi assertions. this can proof that rgi is always present 2023-08-15 10:16:12 +02:00
Sergei Golubchik
d6e0d29f84 Fix write_set too
* in online ALTER it must include the complete new row,
  note that an UPDATE should set all extra columns to their
  default values, as if UPDATE was completely done before the ALTER.
* in rpl WRITE_ROWS_EVENT it must include all extra slave columns,
  but not existing columns unmarked in the m_cols (sequences do that)
* in rpl UPDATE/DELETE events it should follow m_cols_ai

also: default values must be updated for WRITE_ROWS_EVENT and
for UPDATE/DELETE in the online ALTER mode, see above.
Update the result file accordingly.

Extend bitmap_copy() to support arguments of different lengths
2023-08-15 10:16:12 +02:00
Nikita Malyavin
da5df33927 rpl: check should go after defaults and vcols update 2023-08-15 10:16:12 +02:00
Sergei Golubchik
aa1a2507f5 MDEV-29067 Online alter ignores check constraint violation 2023-08-15 10:16:12 +02:00
Nikita Malyavin
bdbd357362 Simplify rgi->get_table_data call 2023-08-15 10:16:12 +02:00
Sergei Golubchik
a3d1d1485a MDEV-29021 mark fields that have explicit values
so that table->update_default_fields() would know what to update
2023-08-15 10:16:12 +02:00
Nikita Malyavin
93fb92d3f9 MDEV-29021 ALTER TABLE fails when a stored virtual column is dropped+added
We shouldn't rely on `fill_extra_persistent_columns`, as it only updates
fields which have an index > cols->n_bits (replication bitmap width).
Actually, it should never be used, as its approach is error-prone.

Normal update_virtual_fields+update_default_fields should be done.
2023-08-15 10:16:12 +02:00
Sergei Golubchik
ea46fdcea4 cleanup, remove dead code 2023-08-15 10:16:12 +02:00
Sergei Golubchik
01b3cb2f46 cleanup: whitespace, etc 2023-08-15 10:16:12 +02:00
Nikita Malyavin
ab4bfad206 MDEV-16329 [5/5] ALTER ONLINE TABLE
* Log rows in online_alter_binlog.
* Table online data is replicated within dedicated binlog file
* Cached data is written on commit.
* Versioning is fully supported.
* Works both wit and without binlog enabled.

* For now savepoints setup is forbidden while ONLINE ALTER goes on.
  Extra support is required. We can simply log the SAVEPOINT query events
  and replicate them together with row events. But it's not implemented
  for now.

* Cache flipping:

  We want to care for the possible bottleneck in the online alter binlog
  reading/writing in advance.

  IO_CACHE does not provide anything better that sequential access,
  besides, only a single write is mutex-protected, which is not suitable,
  since we should write a transaction atomically.

  To solve this, a special layer on top Event_log is implemented.
  There are two IO_CACHE files underneath: one for reading, and one for
  writing.

  Once the read cache is empty, an exclusive lock is acquired (we can wait
  for a currently active transaction finish writing), and flip() is emitted,
  i.e. the write cache is reopened for read, and the read cache is emptied,
  and reopened for writing.

  This reminds a buffer flip that happens in accelerated graphics
  (DirectX/OpenGL/etc).

  Cache_flip_event_log is considered non-blocking for a single reader and a
  single writer in this sense, with the only lock held by reader during flip.

  An alternative approach by implementing a fair concurrent circular buffer
  is described in MDEV-24676.

* Cache managers:
  We have two cache sinks: statement and transactional.
  It is important that the changes are first cached per-statement and
  per-transaction.
  If a statement fails, then only statement data is rolled back. The
  transaction moves along, however.

  Turns out, there's no guarantee that TABLE well persist in
  thd->open_tables to the transaction commit moment.
  If an error occurs, tables from statement are purged.
  Therefore, we can't store te caches in TABLE. Ideally, it should be
  handlerton, but we cut the corner and store it in THD in a list.
2023-08-15 10:16:11 +02:00
Sergei Golubchik
9545eb969e Fix recalculation of vcols in binlog_row_image=minimal
unpack_row() must calculate all stored and indexed vcols
(in fill_extra_persistent_columns()).

Also Update and Delete row events must mark in read_set
all columns needed for calculating all stored and indexed vcols.

If it's done properly in do_apply_event(), it no longer needs
to be repeated per row.
2023-08-15 10:16:11 +02:00
Marko Mäkelä
a69cf6f07e MDEV-29613 Improve WITH_DBUG_TRACE=OFF
In commit 28325b0863
a compile-time option was introduced to disable the macros
DBUG_ENTER and DBUG_RETURN or DBUG_VOID_RETURN.

The parameter name WITH_DBUG_TRACE would hint that it also
covers DBUG_PRINT statements. Let us do that: WITH_DBUG_TRACE=OFF
shall disable DBUG_PRINT() as well.

A few InnoDB recovery tests used to check that some output from
DBUG_PRINT("ib_log", ...) is present. We can live without those checks.

Reviewed by: Vladislav Vaintroub
2022-09-23 13:40:42 +03:00
Jan Lindström
93475aff8d MDEV-22203: WSREP_ON is unnecessarily expensive to evaluate
Replaced WSREP_ON macro by single global variable WSREP_ON
that is then updated at server statup and on wsrep_on and
wsrep_provider update functions.
2020-04-24 13:12:46 +03:00
Alexander Barkov
dc588e3d3f Merge remote-tracking branch 'origin/10.3' into 10.4 2019-10-01 10:45:52 +04:00
Alexander Barkov
7e44c455f4 Merge remote-tracking branch 'origin/10.2' into 10.3 2019-10-01 09:37:40 +04:00
Marko Mäkelä
46b785262b Fix -Wunused for CMAKE_BUILD_TYPE=RelWithDebInfo
For release builds, do not declare unused variables.

unpack_row(): Omit a debug-only variable from WSREP diagnostic message.

create_wsrep_THD(): Fix -Wmaybe-uninitialized for the PSI_thread_key.
2019-09-30 12:49:53 +03:00
Oleksandr Byelkin
c07325f932 Merge branch '10.3' into 10.4 2019-05-19 20:55:37 +02:00
Marko Mäkelä
be85d3e61b Merge 10.2 into 10.3 2019-05-14 17:18:46 +03:00
Marko Mäkelä
26a14ee130 Merge 10.1 into 10.2 2019-05-13 17:54:04 +03:00
Vicențiu Ciorbaru
cb248f8806 Merge branch '5.5' into 10.1 2019-05-11 22:19:05 +03:00
Vicențiu Ciorbaru
5543b75550 Update FSF Address
* Update wrong zip-code
2019-05-11 21:29:06 +03:00
Brave Galera Crew
36a2a185fe Galera4 2019-01-23 15:30:00 +04:00