summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
authorTeemu Ollakka <teemu.ollakka@galeracluster.com>2020-10-30 13:48:21 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2020-11-03 09:11:04 +0200
commit4489b66afbe2f8f589d83ea77e36cc879117f1ad (patch)
treecf3658c6f4a94d6fefa75a79288ac797419bc210 /sql/sql_prepare.cc
parent9e14a2df8c03bb06336fb5c174af52da00fe70e9 (diff)
downloadmariadb-git-4489b66afbe2f8f589d83ea77e36cc879117f1ad.tar.gz
MDEV-23872 Crash in galera::TrxHandle::state()
Prepared statements which were run over binary protocol crashed a server if the statement did not have CF_PS_ARRAY_BINDING_OPTIMIZED flag and the statement was executed in bulk mode and a BF abort occrurred. This was because the bulk execution resulted in several statements without calling wsrep_after_statement() between, which confused wsrep transaction state tracking. As a fix, call wsrep_after_statement() in bulk loop after each execution if CF_PS_ARRAY_BINDING_OPTIMIZED is not set. Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 518df6eb6a2..bf011bd2236 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -122,7 +122,10 @@ When one supplies long data for a placeholder:
#include "lock.h" // MYSQL_OPEN_FORCE_SHARED_MDL
#include "sql_handler.h"
#include "transaction.h" // trans_rollback_implicit
+#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
+#include "wsrep_trans_observer.h"
+#endif /* WITH_WSREP */
/**
A result class used to send cursor rows using the binary protocol.
@@ -4414,6 +4417,23 @@ reexecute:
thd->m_reprepare_observer= NULL;
+#ifdef WITH_WSREP
+ if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED) &&
+ WSREP(thd))
+ {
+ if (wsrep_after_statement(thd))
+ {
+ /*
+ Re-execution success is unlikely after an error from
+ wsrep_after_statement(), so retrun error immediately.
+ */
+ thd->get_stmt_da()->reset_diagnostics_area();
+ wsrep_override_error(thd, thd->wsrep_cs().current_error(),
+ thd->wsrep_cs().current_error_status());
+ }
+ }
+ else
+#endif /* WITH_WSREP */
if (unlikely(error) &&
(sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
!thd->is_fatal_error && !thd->killed &&