Console View
|
Categories: connectors experimental galera main |
|
| connectors | experimental | galera | main | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Georg Richter
georg@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Added macro RPL_READ_FIELD_LENGTH which uses net_field_length_safe | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41583 Tests fail on platform-dependent max TIMESTAMP of current row versioning.partition (MDEV-41543) and main.grant2 (MDEV-41099) print row_end of the current row. Since MDEV-32188 in 11.5 the max TIMESTAMP is 2106-02-07 06:28:15.999999 on 64-bit and 2038-01-19 03:14:07.999999 on 32-bit, so the results recorded on 64-bit fail on 32-bit. The fix prints CURRENT instead of row_end of the current row in versioning.partition (using current_row_ts() from common.inc) and replaces row_end with # in main.grant2, where only the privilege to read it is tested. Affected since 11.8. The fix is committed to the originating 10.11 to minimize conflicts. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40380 vcol.races sporadic timeout After MDEV-39261 purge opens TABLE via open_purge_table() for any undo record of a table with indexed virtual columns, including the insert undo record. If purge does that after FLUSH TABLES, the TABLE is put back into the table cache. Then DELETE from con1 reuses the cached TABLE, skips open_table_from_share() and never hits the TABLE_after_field_clone sync point. DELETE completes immediately, wait_condition times out and SELECT returns an empty set. The fix waits for purge to complete before FLUSH TABLES. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-23864 BULK insert wrong values when command contain inner select Optimized array binding INSERT/REPLACE executes the statement once, so subqueries are executed with the first set of parameters only. Execute INSERT/REPLACE, where a subquery result depends on parameters, for every set of parameters (as not optimized array binding commands are executed), keeping the first generated id as the result of the whole operation. Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41583 Tests fail on platform-dependent max TIMESTAMP of current row versioning.partition (MDEV-41543) and main.grant2 (MDEV-41099) print row_end of the current row. Since MDEV-32188 in 11.5 the max TIMESTAMP is 2106-02-07 06:28:15.999999 on 64-bit and 2038-01-19 03:14:07.999999 on 32-bit, so the results recorded on 64-bit fail on 32-bit. The fix prints CURRENT instead of row_end of the current row in versioning.partition (using current_row_ts() from common.inc) and replaces row_end with # in main.grant2, where only the privilege to read it is tested. Affected since 11.8. The fix is committed to the originating 10.11 to minimize conflicts. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40380 vcol.races sporadic timeout After MDEV-39261 purge opens TABLE via open_purge_table() for any undo record of a table with indexed virtual columns, including the insert undo record. If purge does that after FLUSH TABLES, the TABLE is put back into the table cache. Then DELETE from con1 reuses the cached TABLE, skips open_table_from_share() and never hits the TABLE_after_field_clone sync point. DELETE completes immediately, wait_condition times out and SELECT returns an empty set. The fix waits for purge to complete before FLUSH TABLES. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
PranavKTiwari
pranav.tiwari@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-25515 User Account Host Names using CIDR notation CREATE USER u@'192.168.0.0/24'; -- same as '192.168.0.0/255.255.255.0' CIDR is an input spelling only, normalised to the netmask form while parsing. A malformed mask is now rejected instead of stored, and one already in the privilege tables is skipped at load with a warning instead of being honoured. Nothing rejected these before, and they are not merely useless: a non-contiguous mask such as 10.0.0.0/255.0.255.0 matches the scattered set 10.*.0.*. Skipping rather than erroring keeps such a row droppable and renamable. New error ER_INVALID_HOST_NETMASK. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CONNECT: more FILE and secure_file_priv checks in udfs Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
PranavKTiwari
pranav.tiwari@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-25515 User Account Host Names using CIDR notation CREATE USER u@'192.168.0.0/24'; -- same as '192.168.0.0/255.255.255.0' CIDR is an input spelling only, normalised to the netmask form while parsing. A malformed mask is now rejected instead of stored, and one already in the privilege tables is skipped at load with a warning instead of being honoured. Nothing rejected these before, and they are not merely useless: a non-contiguous mask such as 10.0.0.0/255.0.255.0 matches the scattered set 10.*.0.*. Skipping rather than erroring keeps such a row droppable and renamable. New error ER_INVALID_HOST_NETMASK. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40380 vcol.races sporadic timeout After MDEV-39261 purge opens TABLE via open_purge_table() for any undo record of a table with indexed virtual columns, including the insert undo record. If purge does that after FLUSH TABLES, the TABLE is put back into the table cache. Then DELETE from con1 reuses the cached TABLE, skips open_table_from_share() and never hits the TABLE_after_field_clone sync point. DELETE completes immediately, wait_condition times out and SELECT returns an empty set. The fix waits for purge to complete before FLUSH TABLES. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
forkfun
alice.sherepa@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-30295 mysqldump produces syntactically incorrect statement cover_definer_clause() wrapped DEFINER in "*/ /*!50017 ... */" and broke when the statement text contained a comment. Dump the server's DDL as returned. Also: - drop /*!NNNNN */ gates below 50700 in mysqldump, mysqlbinlog, mysqladmin, mysqlcheck, mysqlshow, mysqlimport, mysqlhotcopy, innotop and mtr_warnings.sql; mysqlbinlog's skip_replication becomes /*M! ...*/ - SHOW CREATE DATABASE no longer wraps IF NOT EXISTS and DEFAULT CHARACTER SET in comments - remove checks for servers older than 5.7 in mysqldump, mysqlcheck, mysql, innotop and the client library, including dump_trigger_old() and mysqlcheck's SHOW TABLES fallback - mysqldump warns on stderr if SHOW CREATE DATABASE fails Behavior changes: - --compatible=mysql323 and mysql40 are accepted and ignored. The other modes wrap only some SET and ALTER TABLE ... KEYS statements in /*!40101 */. - mysqlhotcopy --old_server is accepted, ignored, and prints a warning. Assisted-By: Claude:claude-5.5-sonnet |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-40380 vcol.races sporadic timeout After MDEV-39261 purge opens TABLE via open_purge_table() for any undo record of a table with indexed virtual columns, including the insert undo record. If purge does that after FLUSH TABLES, the TABLE is put back into the table cache. Then DELETE from con1 reuses the cached TABLE, skips open_table_from_share() and never hits the TABLE_after_field_clone sync point. DELETE completes immediately, wait_condition times out and SELECT returns an empty set. The fix waits for purge to complete before FLUSH TABLES. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Petrunia
sergey@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Add comments, Don't remove from THD::free_list. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alessandro Vetere
iminelink@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41398 Stale optimistic btr_pcur_t restore after buffer pool resize Problem: btr_pcur_t::restore_position() accepts a stored position optimistically when the block at the stored descriptor address has the same page id and the same buf_block_t::modify_clock. When buf_pool_t::resize() shrinks the buffer pool, the withdrawn block descriptors are freed. When it grows the buffer pool again, the new descriptors at the same addresses start with modify_clock=0. A cursor that was stored before the shrink can then find a different instance of the page with an equal modify_clock, and it restores to a record that is no longer correct. In a release build, an UPDATE can change a row that does not match its WHERE condition and skip the rows that match. Fix: Add buf_pool_t::withdrawn_modify_clock. buf_pool_t::shrink() sets it to the maximum modify_clock of the blocks that it withdraws. buf_pool_t::resize() sets the initial modify_clock of each block that it adds to one more than this. A relocation in shrink() increments only the modify_clock of the destination block, so a withdrawn block can keep the value that a cursor stored. Thus the modify_clock at a block descriptor address never repeats an earlier value, and a stale optimistic restore fails. The new member uses a hole before buf_pool_t::flush_list_mutex, so the layout of the other members does not change. The test innodb.buf_pool_resize_pcur_restore reads a page into the first new block after a grow, and makes a stored cursor for a read and for an UPDATE restore its position across a page reorganization, a shrink and a grow. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
forkfun
alice.sherepa@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39146 Fix stack-use-after-return in PROCESSLIST for event threads Event_job_data::execute() pointed thd->security_ctx at a local Security_context. A concurrent PROCESSLIST scan captures that pointer without a lock and can read it after execute() returns. Make the Security_context a member of Event_job_data, which lives in Event_worker_thread::run() until after thd is deleted. Add main.events_debug test |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Raghunandan Bhat
raghunandan.bhat96@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-34817: Performance schema is not cleared of removed package routines- part 2 Problem: 1. Package routines were instrumented as "<package>.<routine>", the same key as a standalone routine named `<package>.<routine>`. Their statistics were merged, and DROP PACKAGE BODY dropped the statistics of standalone routines named `<package>.<anything>`. 2. Routines of a package with a name of COL_OBJECT_NAME_SIZE bytes or longer were truncated to "<package>" and were never dropped. Solution: Instrument package routines with internal object types OBJECT_TYPE_PACKAGE_PROCEDURE and OBJECT_TYPE_PACKAGE_FUNCTION. They are used only in the hash key: SETUP_OBJECTS lookups and OBJECT_TYPE columns still use the old PROCEDURE and FUNCTION. When a package body is dropped, drop only records with these types, including names truncated to the package name. Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alessandro Vetere
iminelink@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-32286 Reuse remembered clustered leaves in secondary-index scans Row_sel_get_clust_rec_for_mysql::operator() descends the clustered B-tree from the root for every row whose clustered-index record a secondary-index scan must read, although consecutive rows land on the same clustered leaf page wherever the secondary order tracks the clustered one. A non-covering scan needs one for every row, a locking read needs one whatever the secondary index holds, because an exclusive select lock type makes ha_innobase::build_template() build its template against the clustered index, and a covering scan needs one for every row of a secondary leaf whose PAGE_MAX_TRX_ID its read view cannot see. ANALYZE FORMAT=JSON charges each descent its full height, and those descents are nearly the whole cost: the secondary index is charged its own descent and one page for each further leaf, and nothing per row, because the position that its cursor holds between two rows is restored optimistically, which latches the leaf again without counting an access. So pages_accessed is the row count times the height of the clustered index, plus a handful: 1000 rows over a 2-level clustered index cost 2006 and 750 rows over a 3-level one cost 2291, where a full table scan of the same data costs 23 and 110. Let a handle remember the clustered leaves that the lookups of one statement reached, and let the next lookup try them before it descends again. The reasoning behind each value and each rejection is in the comments beside it. row0mysql.h defines clust_leaf_hint_slot, which names one leaf: its page number, copies of its first and last user record truncated to the key fields, which bound the key range that the leaf held when it was remembered, and the rec_get_offsets() of both. A slot of a leaf that had no right sibling names no last key, because every key above the last record of the rightmost leaf still belongs to it. CLUST_LEAF_HINT_SLOTS (4) slots hang off the new row_prebuilt_t::clust_leaf_hint, beside clust_leaf_hint_mru, the most recently used order held as slot numbers, and clust_leaf_hint_n and clust_leaf_hint_miss, the used-slot count and the miss counter. row0sel.cc holds the policy. row_sel_clust_leaf_hint_covers() compares a key against the remembered ranges, so a lookup that no slot can answer costs no buffer pool access and no pages_accessed. row_sel_clust_leaf_hint_search() probes the first slot that covers the key and moves it to the front of the order. row_sel_clust_leaf_hint_remember() records the leaf that a descent landed on, and refreshes the slot of a leaf that is remembered already rather than spend a second one on the same page. Two descents fill no slot: the lookups of a statement before lookup CLUST_LEAF_HINT_MIN_LOOKUPS (4), and a leaf that is the root. row_sel_clust_leaf_hint_armed() stands a scan down once the slots stop paying for themselves: a miss adds CLUST_LEAF_HINT_MISS_WEIGHT (2) to the miss counter and a hit takes one away, so a scan gives the slots up where it answers too little of its lookups to pay for them, CLUST_LEAF_HINT_MAX_MISSES (8) misses with no hit between them still reach the threshold, and one lookup in CLUST_LEAF_HINT_RETRY (1024) starts the count again, so a scan whose order becomes correlated only later recovers. Both halves of the cost stop there, the test of the slots and the copies that refresh them. Row_sel_get_clust_rec_for_mysql::operator() calls all of this in place of its btr_pcur_open_with_no_init(), and only where the adaptive hash index is disabled. A guess of that index lands on the record with no page-local search and no page access to charge, but neither of the two is faster for every shape of index and scan, and a hint that runs first stops that index from adding entries. The adaptive hash index is off by default, so the hints are active in a default configuration. btr0cur.h and btr0cur.cc add btr_cur_t::try_leaf_hint(), a PAGE_CUR_LE, BTR_SEARCH_LEAF search on one named leaf, which starts from the record where the last search of that leaf landed while that record is still valid, and from a binary search of the page otherwise. It acquires the page with buf_page_try_get(): a hint is never derived from a latched parent page, so by the time it is tried it can precede the caller's already-latched secondary-index leaf in the latching order, where a blocking wait can deadlock. It then rejects the page unless the checks that it makes on the latched frame put the match on it. Those checks are the sole authority on the result, so a stale range costs a wasted probe or a needless descent, never a wrong result, and the ranges need no invalidation protocol. A slot also holds a btr_leaf_step, where the last search of its leaf landed: the block, its buf_block_t::modify_clock() and the record. A record pointer stays valid while the block holds the same page and the clock has not moved, because eviction, deletion and reorganization advance the clock and an insertion moves no record. While the step is valid, btr_cur_t::try_leaf_hint() starts from that record instead of a binary search of the page. page0cur.cc adds page_cur_search_near(), which compares the key with the record and with one neighbour, and positions the cursor on the record, on the record after it or on the record before it. It refuses any other answer and leaves it to page_cur_search_with_match(). So a scan whose consecutive rows are neighbours in the clustered index finds each row with two comparisons. A scan that reads the clustered leaf in falling key order does the same: a secondary key that falls as the primary key rises, or a secondary index read backward. Where the secondary order tracks the clustered one with gaps between the rows, the step fails, and btr_leaf_step::expect (below) leaves the leaf to the binary search. The step refuses the metadata pseudo-record, which compares below every key on 0 fields, and a record before it that is the infimum. A debug build checks every successful step against the binary search. A failed step costs comparisons whose outcome no branch predictor can guess, so btr_leaf_step::expect gates it. The next search tries the step only where this one landed where a step would have: on the remembered record, or right before or after it. The successor link of the landing record tells the record right before, because finding a predecessor takes a walk of the page directory. So a scan in random order over a few leaves, which the slots answer in full, keeps the binary search and pays only the tests that set expect. row_sel_clust_leaf_hint_remember() sets the step on the record where a descent landed, with expect set. ha_innodb.cc: ha_innobase::reset() zeroes the used-slot count and the miss counter per statement, matching autoinc_last_value. row0mysql.cc: row_prebuilt_free() frees the key buffers that the slots own. innodb.clust_leaf_hint measures pages_accessed over key orders that differ in how closely the secondary order tracks the clustered one, and further tables check query results over the record formats and key shapes that a clustered-index lookup has to read, down to the metadata pseudo-record of instant ALTER TABLE, to leaves that split and merge while a locking read walks them, and to a record that a remembered leaf supplies for a scan that must then rebuild an older version of it. Two of the tables scan a covering index, which reads a clustered record under an exclusive select lock type and under a PAGE_MAX_TRX_ID that the read view cannot see. clust_leaf_hint_off_debug runs the same body with the hints turned off, through a debug switch that returns before a lookup tests or refreshes the slots, so a diff of the two .result files is what the hints save: 2006 to 1031 (2-level clustered index), 2291 to 1011 (3-level), 4006 to 2015 (two interleaved key ranges), 12016 to 9078 (locality in the second half alone) and 20020 to 10045 for a covering scan that FOR UPDATE makes non-covering, where the same scan without FOR UPDATE costs 20 in both files. Two orders with too little locality to pay for the slots give them up early and end within a hundred accesses of the unhinted count: 20020 to 19966 (decorrelated) and 20020 to 19999 (shuffled). Two further tables in innodb.clust_leaf_hint cover the step back. t16 scans a secondary index whose keys fall as the primary key rises, and reads an ascending secondary index backward: 20020 to 10047 for both. t17 runs the inverse scan on ROW_FORMAT=REDUNDANT with an instantly added column. innodb.clust_leaf_hint_backward_debug reaches the two refusals of the step back that no count shows, at the infimum and at the metadata pseudo-record. A lookup reaches either only for a key that left the clustered index while the slot still covers it. The rollback of an insert over a delete-marked record removes the key while purge leaves the secondary entry, and a PAGE_MAX_TRX_ID that the read view cannot see makes the reader look that entry up. A debug switch writes each refusal to the error log, and the case reads both back. A slot stays valid when dict_index_t::clear_instant_alter() changes the index under a reader that holds a shared metadata lock, between two lookups or during one. That clear runs where purge or rollback removes the last user record of a single-page table whose only instant change was ADD COLUMN, and it raises dict_index_t::n_core_fields. rec_copy_prefix_to_buf() writes the copies in the format of an index without instant ADD COLUMN, their offsets are made with them, and the comparisons depend on the key fields alone, which no instant change moves. So the slots do not record n_core_fields, and the hints read it only under a latch on a clustered leaf. innodb.clust_leaf_hint_instant_alter makes a lookup compare against a slot that a clear has outlived. The clear needs the clustered index to lose the last user record of its root page, while no leaf that is the root fills a slot, so the tree has to shrink between the two, which purge does there. The reader therefore reads uncommitted rows at READ UNCOMMITTED and waits in a stored function while a rollback and purge take them away, and one row that arrives above the position it stopped at is the lookup that tests the slots. main.rowid_filter_innodb: 90 to 88, and its ahi combination unchanged. A static_assert in Row_sel_get_clust_rec_for_mysql::operator() fails to compile if btr_search.enabled stops being a Boolean that applies to every index, because the test !btr_search.enabled that stands the hints down would then have to become !btr_search.is_enabled(clust_index). |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Dmitry Shulga
dmitry.shulga@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN } Extended the system table mysql.event to support creation of system triggers (startup, shutdown, logon, logoff) and ddl triggers. The system table mysql.event is extended with three columns `kind`, `when`, `ddl_type`. For the task MDEV-30645 only the column `kind` is required, the other two columns are required for the tasks MENT-2355, MENT-2291 but since it is better to reduce a number of times the system table is changed and as a consequences a number of upgrades to be run, the entire set of columns is added at once. Type of the columns `kind` and `ddl_type` are specified as SET to allow storing of triggers that handle several events. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CONNECT udfs crash on long filename namely, json_get_item, jsonget_string, json_set_item, jbin_set_item, bson_get_item, bsonget_string, bson_set_item Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
mariadb-PranavTiwari
pranav.tiwari@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-37719: mysql_create_like_table() kept a stale TABLE pointer in table->table after OR REPLACE dropped the old table 1- temporary target: drop_temporary_table() frees the old TABLE but table->table was left pointing at it, so the table->table block that picks up the new table never ran and the binlog branch dereferenced freed memory. Reset table->table after the create so the new TABLE is used. 2- locked tables: if reopen_tables() failed, the function continued into the binlog branch with the freed pointer. Leave via err: instead. Note- Remove this fix when merging into main. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
PranavKTiwari
pranav.tiwari@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-25515 User Account Host Names using CIDR notation CREATE USER u@'192.168.0.0/24'; -- same as '192.168.0.0/255.255.255.0' CIDR is an input spelling only, normalised to the netmask form while parsing. A malformed mask is now rejected instead of stored, and one already in the privilege tables is skipped at load with a warning instead of being honoured. Nothing rejected these before, and they are not merely useless: a non-contiguous mask such as 10.0.0.0/255.0.255.0 matches the scattered set 10.*.0.*. Skipping rather than erroring keeps such a row droppable and renamable. New error ER_INVALID_HOST_NETMASK. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alessandro Vetere
iminelink@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-32286 Reuse remembered clustered leaves in secondary-index scans Row_sel_get_clust_rec_for_mysql::operator() descends the clustered B-tree from the root for every row whose clustered-index record a secondary-index scan must read, although consecutive rows land on the same clustered leaf page wherever the secondary order tracks the clustered one. A non-covering scan needs one for every row, a locking read needs one whatever the secondary index holds, because an exclusive select lock type makes ha_innobase::build_template() build its template against the clustered index, and a covering scan needs one for every row of a secondary leaf whose PAGE_MAX_TRX_ID its read view cannot see. ANALYZE FORMAT=JSON charges each descent its full height, and those descents are nearly the whole cost: the secondary index is charged its own descent and one page for each further leaf, and nothing per row, because the position that its cursor holds between two rows is restored optimistically, which latches the leaf again without counting an access. So pages_accessed is the row count times the height of the clustered index, plus a handful: 1000 rows over a 2-level clustered index cost 2006 and 750 rows over a 3-level one cost 2291, where a full table scan of the same data costs 23 and 110. Let a handle remember the clustered leaves that the lookups of one statement reached, and let the next lookup try them before it descends again. The reasoning behind each value and each rejection is in the comments beside it. row0mysql.h defines clust_leaf_hint_slot, which names one leaf: its page number, copies of its first and last user record truncated to the key fields, which bound the key range that the leaf held when it was remembered, and the rec_get_offsets() of both. A slot of a leaf that had no right sibling names no last key, because every key above the last record of the rightmost leaf still belongs to it. CLUST_LEAF_HINT_SLOTS (4) slots hang off the new row_prebuilt_t::clust_leaf_hint, beside clust_leaf_hint_mru, the most recently used order held as slot numbers, and clust_leaf_hint_n and clust_leaf_hint_miss, the used-slot count and the miss counter. row0sel.cc holds the policy. row_sel_clust_leaf_hint_covers() compares a key against the remembered ranges, so a lookup that no slot can answer costs no buffer pool access and no pages_accessed. row_sel_clust_leaf_hint_search() probes the first slot that covers the key and moves it to the front of the order. row_sel_clust_leaf_hint_remember() records the leaf that a descent landed on, and refreshes the slot of a leaf that is remembered already rather than spend a second one on the same page. Two descents fill no slot: the lookups of a statement before lookup CLUST_LEAF_HINT_MIN_LOOKUPS (4), and a leaf that is the root. row_sel_clust_leaf_hint_armed() stands a scan down once the slots stop paying for themselves: a miss adds CLUST_LEAF_HINT_MISS_WEIGHT (2) to the miss counter and a hit takes one away, so a scan gives the slots up where it answers too little of its lookups to pay for them, CLUST_LEAF_HINT_MAX_MISSES (8) misses with no hit between them still reach the threshold, and one lookup in CLUST_LEAF_HINT_RETRY (1024) starts the count again, so a scan whose order becomes correlated only later recovers. Both halves of the cost stop there, the test of the slots and the copies that refresh them. Row_sel_get_clust_rec_for_mysql::operator() calls all of this in place of its btr_pcur_open_with_no_init(), and only where the adaptive hash index is disabled. A guess of that index lands on the record with no page-local search and no page access to charge, but neither of the two is faster for every shape of index and scan, and a hint that runs first stops that index from adding entries. The adaptive hash index is off by default, so the hints are active in a default configuration. btr0cur.h and btr0cur.cc add btr_cur_t::try_leaf_hint(), a PAGE_CUR_LE, BTR_SEARCH_LEAF search on one named leaf, which starts from the record where the last search of that leaf landed while that record is still valid, and from a binary search of the page otherwise. It acquires the page with buf_page_try_get(): a hint is never derived from a latched parent page, so by the time it is tried it can precede the caller's already-latched secondary-index leaf in the latching order, where a blocking wait can deadlock. It then rejects the page unless the checks that it makes on the latched frame put the match on it. Those checks are the sole authority on the result, so a stale range costs a wasted probe or a needless descent, never a wrong result, and the ranges need no invalidation protocol. A slot also holds a btr_leaf_step, where the last search of its leaf landed: the block, its buf_block_t::modify_clock() and the record. A record pointer stays valid while the block holds the same page and the clock has not moved, because eviction, deletion and reorganization advance the clock and an insertion moves no record. While the step is valid, btr_cur_t::try_leaf_hint() starts from that record instead of a binary search of the page. page0cur.cc adds page_cur_search_near(), which compares the key with the record and with one neighbour, and positions the cursor on the record, on the record after it or on the record before it. It refuses any other answer and leaves it to page_cur_search_with_match(). So a scan whose consecutive rows are neighbours in the clustered index finds each row with two comparisons. A scan that reads the clustered leaf in falling key order does the same: a secondary key that falls as the primary key rises, or a secondary index read backward. Where the secondary order tracks the clustered one with gaps between the rows, the step fails, and btr_leaf_step::expect (below) leaves the leaf to the binary search. The step refuses the metadata pseudo-record, which compares below every key on 0 fields, and a record before it that is the infimum. A debug build checks every successful step against the binary search. A failed step costs comparisons whose outcome no branch predictor can guess, so btr_leaf_step::expect gates it. The next search tries the step only where this one landed where a step would have: on the remembered record, or right before or after it. The successor link of the landing record tells the record right before, because finding a predecessor takes a walk of the page directory. So a scan in random order over a few leaves, which the slots answer in full, keeps the binary search and pays only the tests that set expect. row_sel_clust_leaf_hint_remember() sets the step on the record where a descent landed, with expect set. ha_innodb.cc: ha_innobase::reset() zeroes the used-slot count and the miss counter per statement, matching autoinc_last_value. row0mysql.cc: row_prebuilt_free() frees the key buffers that the slots own. innodb.clust_leaf_hint measures pages_accessed over key orders that differ in how closely the secondary order tracks the clustered one, and further tables check query results over the record formats and key shapes that a clustered-index lookup has to read, down to the metadata pseudo-record of instant ALTER TABLE, to leaves that split and merge while a locking read walks them, and to a record that a remembered leaf supplies for a scan that must then rebuild an older version of it. Two of the tables scan a covering index, which reads a clustered record under an exclusive select lock type and under a PAGE_MAX_TRX_ID that the read view cannot see. clust_leaf_hint_off_debug runs the same body with the hints turned off, through a debug switch that returns before a lookup tests or refreshes the slots, so a diff of the two .result files is what the hints save: 2006 to 1031 (2-level clustered index), 2291 to 1011 (3-level), 4006 to 2015 (two interleaved key ranges), 12016 to 9078 (locality in the second half alone) and 20020 to 10045 for a covering scan that FOR UPDATE makes non-covering, where the same scan without FOR UPDATE costs 20 in both files. Two orders with too little locality to pay for the slots give them up early and end within a hundred accesses of the unhinted count: 20020 to 19966 (decorrelated) and 20020 to 19999 (shuffled). Two further tables in innodb.clust_leaf_hint cover the step back. t16 scans a secondary index whose keys fall as the primary key rises, and reads an ascending secondary index backward: 20020 to 10047 for both. t17 runs the inverse scan on ROW_FORMAT=REDUNDANT with an instantly added column. innodb.clust_leaf_hint_backward_debug reaches the two refusals of the step back that no count shows, at the infimum and at the metadata pseudo-record. A lookup reaches either only for a key that left the clustered index while the slot still covers it. The rollback of an insert over a delete-marked record removes the key while purge leaves the secondary entry, and a PAGE_MAX_TRX_ID that the read view cannot see makes the reader look that entry up. A debug switch writes each refusal to the error log, and the case reads both back. A slot stays valid when dict_index_t::clear_instant_alter() changes the index under a reader that holds a shared metadata lock, between two lookups or during one. That clear runs where purge or rollback removes the last user record of a single-page table whose only instant change was ADD COLUMN, and it raises dict_index_t::n_core_fields. rec_copy_prefix_to_buf() writes the copies in the format of an index without instant ADD COLUMN, their offsets are made with them, and the comparisons depend on the key fields alone, which no instant change moves. So the slots do not record n_core_fields, and the hints read it only under a latch on a clustered leaf. innodb.clust_leaf_hint_instant_alter makes a lookup compare against a slot that a clear has outlived. The clear needs the clustered index to lose the last user record of its root page, while no leaf that is the root fills a slot, so the tree has to shrink between the two, which purge does there. The reader therefore reads uncommitted rows at READ UNCOMMITTED and waits in a stored function while a rollback and purge take them away, and one row that arrives above the position it stopped at is the lookup that tests the slots. main.rowid_filter_innodb: 90 to 88, and its ahi combination unchanged. A static_assert in Row_sel_get_clust_rec_for_mysql::operator() fails to compile if btr_search.enabled stops being a Boolean that applies to every index, because the test !btr_search.enabled that stands the hints down would then have to become !btr_search.is_enabled(clust_index). |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pread_write(): Copy 1MiB at a time, and invoke Linux readahead(2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41502 Bulk INSERT: IN list and REGEXP with a parameter use the first parameter set for all rows Optimized array binding INSERT/REPLACE fixes the items once, and parameters are constants, so items cache values computed with the first set of parameters (IN array, compiled REGEXP pattern). Do not treat parameters as constants during optimized array binding execution. Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
fixup! c98b67beaaedf0bf72d036e1489daf465abf0b4c Do not duplicate queue in ctx.garbage_lsn |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Alessandro Vetere
iminelink@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Fix the build with cmake -DWITH_INNODB_AHI=OFF Without BTR_CUR_HASH_ADAPT, buf_block_t::index, btr_search and innodb_adaptive_hash_index_cells do not exist, so the assertion in buf_LRU_truncate_temp() and the derivation of btr_search.n_cells in innodb_init_params() are compiled only with it. mysql-test/collections/broken-no-innodb-ahi.list names the tests that fail in such a build, for --skip-test-list. They need the adaptive hash index variables or counters, or the IS_HASHED column of INFORMATION_SCHEMA.INNODB_BUFFER_PAGE and INNODB_BUFFER_PAGE_LRU, which the build omits together with the sys schema views that read it. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MDEV-39306 Comments on update_virtual_fields() modes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Oleksandr Byelkin
sanja@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-34817 Performance schema is not cleared of removed package routines Package routines are recorded in performance schema as PROCEDURE/FUNCTION "<package>.<routine>", but dropping a package body removed only the PACKAGE BODY record, so routine statistics survived DROP PACKAGE [BODY] and DROP DATABASE. Drop the routine records of the package together with the package body record. Also reset statistics of a newly allocated PFS_program (as in 089caf901f9), so a reused slot does not inherit stale counters. Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
PranavKTiwari
pranav.tiwari@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-25515 User Account Host Names using CIDR notation CREATE USER u@'192.168.0.0/24'; -- same as '192.168.0.0/255.255.255.0' CIDR is an input spelling only, normalised to the netmask form while parsing. A malformed mask is now rejected instead of stored, and one already in the privilege tables is skipped at load with a warning instead of being honoured. Nothing rejected these before, and they are not merely useless: a non-contiguous mask such as 10.0.0.0/255.0.255.0 matches the scattered set 10.*0.*. Skipping rather than erroring keeps such a row droppable and renamable, except for a literal CIDR host stored by an older version (for example 10.0.0.0/24): the parser converts that name, so it can no longer be named and must be removed with a direct DELETE from the privilege tables. New error ER_INVALID_HOST_NETMASK, ER_ACL_ENTRY_IGNORED_BAD_HOST_MASK |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Mohammad Tafzeel Shams
tafzeel.shams@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-26123: Always mark spatial index reads as locking A SELECT query could fail with ER_READ_ONLY_TRANSACTION when search on spatial index is done after search on non-spatial index. R-tree index search always require page locks. Previously, trx->will_lock was only set for spatial indexes when the transaction had not yet been started. If a transaction was already active due to a prior non-spatial index access, index_read() for spatial index returned HA_ERR_READ_ONLY_TRANSACTION instead of marking the transaction as locking. trx->will_lock must not be changed once a transaction has started, so index_read() cannot safely fix this up by itself. Fix: - ha_innobase::external_lock() : Set trx->will_lock before the transaction starts for any table with a spatial index (dict_table_t::has_spatial_index()), so this no longer depends on statement/index access order. - ha_innobase::index_read() : Drop the HA_ERR_READ_ONLY_TRANSACTION error; trx->will_lock is only set here as a pre-start fallback. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-39306 Index corruption on UPDATE when using versioned InnoDB table (on UPDATE) Duplicated by: MDEV-39711 UPDATE on System-Versioned Tables uses the after-value in Row-format Binlog's before-image MDEV-24646 ASAN heap-use-after-free in Field_blob::pack / THD::binlog_update_row upon DML on table with virtual column vers_update_fields() recomputed virtual fields with VCOL_UPDATE_FOR_READ. For BLOB virtual columns this mode swaps Field_blob::value and read_value after the computation (swap_values). After the swap, Field_blob::value holds the buffer that record[1] (the old row image) points to. The next VCOL_UPDATE_FOR_WRITE computation, done by fill_record() right after vers_update_fields(), stores the new value into that buffer and so overwrites the old row image. As a result, InnoDB builds the old secondary-index key from the new value (MDEV-39306), and the row-format binlog writes the new value into the before-image (MDEV-39711), or a freed buffer (MDEV-24646). The fix removes the virtual fields computation from vers_update_fields(). Its callers now recompute virtual fields with VCOL_UPDATE_FOR_WRITE after the system fields are set: fill_record() already did, while update_generated_fields(), multi_update::do_updates() and the RBR appliers do it explicitly. multi_update::do_updates() still computes virtual fields twice per row: before BEFORE triggers and after vers_update_fields(), since the system fields cannot be set before compare_record(). Based on the MDEV-24646/MDEV-39711 fix by ParadoxV5 (0c2f3de1a2d), which switched vers_update_fields() to VCOL_UPDATE_FOR_WRITE. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sergei Golubchik
serg@mariadb.org |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41613 CONNECT jfile_convert crashes on invalid file Assisted-by: Claude:claude-5.5-opus |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Georg Richter
georg@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Infer fixes (dead code) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Georg Richter
georg@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CONC-861: Bounds checks for length-encoded integers and binary rows Add net_field_length_safe()/net_field_length_ll_safe(), which take an end pointer, reject 0xFF, truncated prefixes and 32-bit overflow, and optionally reject the NULL marker (MARIADB_LENENC_FORBID_NULL). Export mariadb_net_field_length() (version node libmariadb_3_3_22). Use the checked decoders in cli_report_progress(), mthd_my_read_query_result(), mthd_my_read_one_row(), mysql_list_processes(), mthd_stmt_read_all_rows(), mthd_stmt_flush_unbuffered() and mthd_stmt_fetch_to_bind(). mthd_stmt_fetch_to_bind() now owns the column boundary: it validates the length prefix and the lengths of temporal types, and resyncs the row pointer after callbacks and conversion functions. Behavior changes: malformed text rows report CR_MALFORMED_PACKET instead of CR_UNKNOWN_ERROR; EOF packets shorter than 5 bytes are rejected. Assisted by Claude |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Marko Mäkelä
marko.makela@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Give better posix_fadvise | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Dmitry Shulga
dmitry.shulga@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-30645: CREATE TRIGGER FOR { STARTUP | SHUTDOWN } This patch add support of system triggers fired on server start up and shutdown. On start up triggers can be associated only with AFTER event time, on shutdown triggers associated with BEFORE event time. Several triggers can be created to be run on the same time/event type. Core implementation - Extended the sql grammar to support creation of system triggers on startup/shutdown - System triggers metadata is stored in the table mysql.event - Events and system triggers share the same name space since both are stored in the table mysql.event declared with the PRIMARY KEY (`db`,`name`). In result, attempt to create an event with the same name as existent trigger and vice versa results in failure with the new error ER_TRG_EVENT_CONFLICTS_NAME - Since system triggers metadata is stored in the mysql.event table, the table mysql.event is now opened on handling the DROP TRIGGER statement - In case server is started against old version of mysql.event table that missing columns required for support of system triggers, system trigger feature is disabled - System triggers are loaded from the table mysql.event right before their execution - System triggers can be created only by users with the SUPER privilege - Added the option --sys_triggers for mysqldump to dump system triggers. The option is turned off by default. In case this option is on, mysqldump first dump the table 'mysql' unconditionally, regardless whether it was listed in the option --ignore-database |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Aleksey Midenkov
midenok@gmail.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41583 Tests fail on platform-dependent max TIMESTAMP of current row versioning.partition (MDEV-41543) and main.grant2 (MDEV-41099) print row_end of the current row. Since MDEV-32188 in 11.5 the max TIMESTAMP is 2106-02-07 06:28:15.999999 on 64-bit and 2038-01-19 03:14:07.999999 on 32-bit, so the results recorded on 64-bit fail on 32-bit. The fix prints CURRENT instead of row_end of the current row in versioning.partition (using current_row_ts() from common.inc) and replaces row_end with # in main.grant2, where only the privilege to read it is tested. Affected since 11.8. The fix is committed to the originating 10.11 to minimize conflicts. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hemant Dangi
hemant.dangi@mariadb.com |
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
MDEV-41414: WSREP Binlog TC: analysis & design Commits of replicated write sets must finish in the same seqno order on every node, with or without a binlog. Make the server enforce that order, so binlog group commit, DDL, views and state transfer no longer depend on the commit monitor in the Galera library. The library registers a ticket for every certified write set. The new Commit_order_manager in the server makes each commit wait for the one before it, hands the turn on, tracks the committed position, and handles aborts, node failure and commits that never finish. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||