diff options
author | Michael Widenius <monty@askmonty.org> | 2011-02-18 17:43:59 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-02-18 17:43:59 +0200 |
commit | b12e3796dc70466eca5ef3f25d51234b32af5113 (patch) | |
tree | 21c8dd65d7fd61dfbae3cc317ef961b850ff0886 /storage/maria/ma_rnext.c | |
parent | 6c7360b540315a85ed6011dd4b31471c345e886a (diff) | |
download | mariadb-git-b12e3796dc70466eca5ef3f25d51234b32af5113.tar.gz |
Fix for lp:711565 "Index Condition Pushdown can make a thread hold MyISAM locks as well as be unKILLable for long time"
- In Maria/MyISAM: Release/re-acquire locks to give queries that wait on them a chance to make progress
- In Maria/MyISAM: Change from numeric constants to ICP_RES values.
- In Maria: Do check index condition in maria_rprev() (was lost in the merge/backport?)
- In Maria/MyISAM/XtraDB: Check if the query was killed, and return immediately if it was.
Added new storage engine error: HA_ERR_ABORTED_BY_USER, for handler to signal that it detected a kill of the query and aborted
Authors: Sergey Petrunia & Monty
include/my_base.h:
Added HA_ERR_ABORTED_BY_USER, for handler to signal that it detected a kill of the query and aborted
include/my_handler.h:
Added comment
mysql-test/r/myisam_icp.result:
Updated test
mysql-test/t/myisam_icp.test:
Drop used tables at start of test
Added test case that can help with manual testing of killing index condition pushdown query.
mysys/my_handler_errors.h:
Text for new storage engine error
sql/handler.cc:
If engine got HA_ERR_ABORTED_BY_USER, send kill message.
sql/multi_range_read.cc:
Return error code
storage/maria/ha_maria.cc:
Added ma_killed_in_mariadb() to detect kill.
Ensure that file->external_ref points to TABLE object.
storage/maria/ma_extra.c:
Dummy test-if-killed for standalone
storage/maria/ma_key.c:
If ma_check_index_cond() fails, set my_errno and info->cur_row.lastpos
storage/maria/ma_rkey.c:
Release/re-acquire locks to give queries that wait on them a chance to make progress
Check if the query was killed, and return immediately if it was
storage/maria/ma_rnext.c:
Check if the query was killed, and return immediately if it was
Added missing fast_ma_writeinfo(info)
storage/maria/ma_rnext_same.c:
Check if the query was killed, and return immediately if it was
Added missing fast_ma_writeinfo(info)
storage/maria/ma_rprev.c:
Check if the query was killed, and return immediately if it was
Added missing fast_ma_writeinfo(info) and ma_check_index_cond()
storage/maria/ma_search.c:
Give error message if we find a wrong key
storage/maria/ma_static.c:
Added pointer to test-if-killed function
storage/maria/maria_def.h:
New prototypes
storage/myisam/ha_myisam.cc:
Added mi_killed_in_mariadb()
Ensure that file->external_ref points to TABLE object.
storage/myisam/mi_extra.c:
Dummy test-if-killed for standalone
storage/myisam/mi_key.c:
If ma_check_index_cond() fails, set my_errno and info->lastpos
storage/myisam/mi_rkey.c:
Ensure that info->lastpos= HA_OFFSET_ERROR in case of error
Release/re-acquire locks to give queries that wait on them a chance to make progress
Check if the query was killed, and return immediately if it was
Reorder code to do less things in case of error.
Added missing fast_mi_writeinfo()
storage/myisam/mi_rnext.c:
Check if the query was killed, and return immediately if it was
Simplify old ICP code
Added missing fast_ma_writeinfo(info)
storage/myisam/mi_rnext_same.c:
Check if the query was killed, and return immediately if it was
Added missing fast_mi_writeinfo(info)
storage/myisam/mi_rprev.c:
Check if the query was killed, and return immediately if it was
Simplify error handling of ICP
Added missing fast_mi_writeinfo(info)
storage/myisam/mi_search.c:
Give error message if we find a wrong key
storage/myisam/mi_static.c:
Added pointer to test-if-killed function
storage/myisam/myisamdef.h:
New prototypes
storage/xtradb/handler/ha_innodb.cc:
Added DB_SEARCH_ABORTED_BY_USER and ha_innobase::is_thd_killed()
Check if the query was killed, and return immediately if it was
storage/xtradb/handler/ha_innodb.h:
Added prototype
storage/xtradb/include/db0err.h:
Added DB_SEARCH_ABORTED_BY_USER
storage/xtradb/include/row0mysql.h:
Added possible ICP errors
storage/xtradb/row/row0sel.c:
Use ICP errors instead of constants.
Detect if killed and return B_SEARCH_ABORTED_BY_USER
Diffstat (limited to 'storage/maria/ma_rnext.c')
-rw-r--r-- | storage/maria/ma_rnext.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c index bdba5ff3a17..2fd8bf4e603 100644 --- a/storage/maria/ma_rnext.c +++ b/storage/maria/ma_rnext.c @@ -30,7 +30,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) uint flag; MARIA_SHARE *share= info->s; MARIA_KEYDEF *keyinfo; - int icp_res= 1; + ICP_RESULT icp_res= ICP_MATCH; DBUG_ENTER("maria_rnext"); if ((inx = _ma_check_index(info,inx)) < 0) @@ -92,8 +92,20 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) if (!error) { while (!(*share->row_is_visible)(info) || - ((icp_res= ma_check_index_cond(info, inx, buf)) == 0)) + ((icp_res= ma_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) { + /* + If we are at the last key on the key page, allow writers to + access the index. + */ + if (info->int_keypos >= info->int_maxpos && + ma_yield_and_check_if_killed(info, inx)) + { + /* my_errno is set by ma_yield_and_check_if_killed() */ + error= 1; + break; + } + /* Skip rows inserted by other threads since we got a lock */ if ((error= _ma_search_next(info, &info->last_key, SEARCH_BIGGER, @@ -108,16 +120,15 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_NEXT_FOUND; - if (icp_res == 2) - my_errno=HA_ERR_END_OF_FILE; /* got beyond the end of scanned range */ - - if (error || icp_res != 1) + if (error || icp_res != ICP_MATCH) { + fast_ma_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) - my_errno=HA_ERR_END_OF_FILE; + my_errno= HA_ERR_END_OF_FILE; } else if (!buf) { + fast_ma_writeinfo(info); DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0); } else if (!(*info->read_record)(info, buf, info->cur_row.lastpos)) |