Skip to content
/ server Public

Commit aa48555

Browse files
MDEV-24813 Signal full scan to storage engines, with innodb implementation
1 parent ae5c8bf commit aa48555

File tree

10 files changed

+58
-2
lines changed

10 files changed

+58
-2
lines changed

include/my_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ enum ha_extra_function {
231231
/** Abort of writing rows during ALTER TABLE..ALGORITHM=COPY or
232232
CREATE..SELCT */
233233
HA_EXTRA_ABORT_ALTER_COPY
234+
, HA_EXTRA_FULL_SCAN_NO_FILTER
234235
};
235236

236237
/* Compatible option, to be deleted in 6.0 */
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# MDEV-24813 Locking full table scan fails to use table-level locking
3+
#
4+
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
5+
insert into t values (42);
6+
set global innodb_monitor_enable="lock_rec_lock_created";
7+
BEGIN;
8+
SELECT * FROM t LOCK IN SHARE MODE;
9+
a
10+
42
11+
COMMIT;
12+
SELECT COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME = 'lock_rec_lock_created';
13+
COUNT
14+
0
15+
set global innodb_monitor_enable=default;
16+
Warnings:
17+
Warning 1230 Default value is not defined for this set option. Please specify correct counter or module name.
18+
DROP TABLE t;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--source include/have_innodb.inc
2+
--echo #
3+
--echo # MDEV-24813 Locking full table scan fails to use table-level locking
4+
--echo #
5+
6+
CREATE TABLE t (a INT PRIMARY KEY) ENGINE=InnoDB;
7+
insert into t values (42);
8+
9+
set global innodb_monitor_enable="lock_rec_lock_created";
10+
BEGIN;
11+
SELECT * FROM t LOCK IN SHARE MODE;
12+
COMMIT;
13+
SELECT COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME = 'lock_rec_lock_created';
14+
set global innodb_monitor_enable=default;
15+
DROP TABLE t;

sql/ha_partition.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9495,6 +9495,8 @@ int ha_partition::extra(enum ha_extra_function operation)
94959495
case HA_EXTRA_END_ALTER_COPY:
94969496
case HA_EXTRA_ABORT_ALTER_COPY:
94979497
DBUG_RETURN(loop_partitions(extra_cb, &operation));
9498+
case HA_EXTRA_FULL_SCAN_NO_FILTER:
9499+
break;
94989500
default:
94999501
{
95009502
/* Temporary crash to discover what is wrong */

sql/handler.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8692,6 +8692,12 @@ int get_select_field_pos(Alter_info *alter_info, int select_field_count,
86928692
return select_field_pos;
86938693
}
86948694

8695+
void init_table_full_scan_if_needed(TABLE *table, Item *cond, ha_rows limit)
8696+
{
8697+
if (!cond && !limit)
8698+
table->file->extra(HA_EXTRA_FULL_SCAN_NO_FILTER);
8699+
}
8700+
86958701

86968702
bool Table_scope_and_contents_source_st::vers_check_system_fields(
86978703
THD *thd, Alter_info *alter_info, const Lex_table_name &table_name,

sql/handler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5811,4 +5811,5 @@ int get_select_field_pos(Alter_info *alter_info, int select_field_count,
58115811
#ifndef DBUG_OFF
58125812
String dbug_format_row(TABLE *table, const uchar *rec, bool print_names= true);
58135813
#endif /* DBUG_OFF */
5814+
void init_table_full_scan_if_needed(TABLE *table, Item *cond, ha_rows limit);
58145815
#endif /* HANDLER_INCLUDED */

sql/records.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
336336
(void) table->file->extra_opt(HA_EXTRA_CACHE,
337337
thd->variables.read_buff_size);
338338
}
339+
/* TODO: we are passing 0 as LIMIT */
340+
if (select)
341+
init_table_full_scan_if_needed(table, select->cond, 0);
339342
/* Condition pushdown to storage engine */
340343
if ((table->file->ha_table_flags() & HA_CAN_TABLE_CONDITION_PUSHDOWN) &&
341344
select && select->cond &&

storage/innobase/handler/ha_innodb.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15892,6 +15892,9 @@ ha_innobase::extra(
1589215892
return(HA_ERR_ROLLBACK);
1589315893
}
1589415894
break;
15895+
case HA_EXTRA_FULL_SCAN_NO_FILTER:
15896+
m_prebuilt->full_table_scan= true;
15897+
break;
1589515898
default:/* Do nothing */
1589615899
;
1589715900
}

storage/innobase/include/row0mysql.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,11 @@ struct row_prebuilt_t {
695695
/** The MySQL table object */
696696
TABLE* m_mysql_table;
697697

698+
bool full_table_scan; /*!< Whether the full table will need to be
699+
scanned. Set when the sql layer passes NULL cond in
700+
cond_push. Will cause to use X/S locks in select rather than
701+
IX/IS locks */
702+
698703
/** Get template by dict_table_t::cols[] number */
699704
const mysql_row_templ_t* get_template_by_col(ulint col) const
700705
{

storage/innobase/row/row0sel.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4718,8 +4718,10 @@ row_search_mvcc(
47184718
} else {
47194719
wait_table_again:
47204720
err = lock_table(prebuilt->table, nullptr,
4721-
prebuilt->select_lock_type == LOCK_S
4722-
? LOCK_IS : LOCK_IX, thr);
4721+
prebuilt->full_table_scan ?
4722+
prebuilt->select_lock_type :
4723+
(prebuilt->select_lock_type == LOCK_S
4724+
? LOCK_IS : LOCK_IX), thr);
47234725

47244726
if (err != DB_SUCCESS) {
47254727

0 commit comments

Comments
 (0)