1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/storage
Jan Lindström 45ffb72a9f MDEV-41073: server aborts after "Unknown error" is logged for FK key exceeding 3500
Failure:
- wsrep_rec_get_foreign_key() returned DB_ERROR when a write set key
  exceeded WSREP_MAX_SUPPORTED_KEY_LENGTH; the caller does not know
  DB_ERROR and calls ib::fatal().
- wsrep_fk_key_space_left() needed two bytes for a NULL column instead
  of one; only the flag byte is ever written for NULL.
- Cutting a whole number, float or double to fit the remaining buffer
  produces a different value, not a shorter one, and for a float or
  double not even a valid one: mach_float_read()/mach_double_read()
  read a fixed 4 or 8 bytes regardless, past an assertion in a debug
  build and past the buffer itself in a release one.
- wsrep_store_key_val_for_row()'s equivalent fixed-length branch had
  the same unchecked copy, reachable only in theory given InnoDB's own
  index length limit, but inconsistent with every other branch in that
  function.
- The same function normalized a VARCHAR column's collation weights up
  to 3072 bytes while wsrep_rec_get_foreign_key() normalized it up to
  3500, so the two produced a different key for a value whose
  normalized form falls between the two limits.
- wsrep_store_key_val_for_row() kept iterating columns after one did
  not fit, relying on every later branch clamping to zero rather than
  stopping outright.
- MW-292 matched its two debug sync waiters by substring, not an exact
  match, independent of wait order.

Fix:
- wsrep_rec_get_foreign_key() now cuts the key the same way
  wsrep_store_key_val_for_row() does, reports the cut as a warning
  (ER_TOO_LONG_KEY under strict mode), and returns DB_TOO_BIG_RECORD.
- wsrep_fk_key_space_left() takes a fixed_len flag: a whole number,
  float or double must fit in full or is left out of the key entirely,
  the same way a value that does not fit even one byte already was.
- wsrep_store_key_val_for_row() applies the same all-or-nothing rule to
  its own fixed-length branch, reusing get_innobase_type_from_mysql_type()
  so both functions agree on which types that covers, and now stops
  storing further columns as soon as one does not fit, in every branch.
- wsrep_store_key_val_for_row()'s VARCHAR branch normalizes up to
  WSREP_MAX_SUPPORTED_KEY_LENGTH, matching wsrep_rec_get_foreign_key(),
  with its buffer grown to match.

Test:
- galera_ws_datatypes.test and galera_ws_datatypes_plugin.test cover
  every MariaDB data type in a primary key, unique key, plain key and
  foreign key (referencing a primary or unique key), including NULL
  foreign key columns.
- galera_ws_datatypes_fixed_length.test covers a foreign key column cut
  to fewer bytes than a whole number, float or double needs.
- galera_ws_datatypes_varchar_cap.test covers a VARCHAR foreign key
  column whose normalized form falls between the two limits above.

Assisted-by: https://mariadb.org/governance/governance-ai-policy/
2026-10-07 07:23:19 +03:00
..
2026-08-19 08:13:54 +02:00
2026-08-19 08:13:54 +02:00
2026-03-11 09:06:05 +02:00
2026-08-19 08:13:54 +02:00
2026-07-23 11:12:27 +02:00
2026-08-19 08:13:54 +02:00
2024-11-29 12:37:46 +02:00
2024-06-24 13:09:47 +03:00