1 /* Copyright 2018 Codership Oy <info@codership.com>
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 of the License.
6 
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11 
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
15 
16 #ifndef WSREP_HIGH_PRIORITY_SERVICE_H
17 #define WSREP_HIGH_PRIORITY_SERVICE_H
18 
19 #include "wsrep/high_priority_service.hpp"
20 #include "my_global.h"
21 #include "sql_error.h" /* Diagnostics area */
22 #include "sql_class.h" /* rpl_group_info */
23 
24 class THD;
25 class Relay_log_info;
26 class Wsrep_server_service;
27 
28 class Wsrep_high_priority_service :
29   public wsrep::high_priority_service,
30   public wsrep::high_priority_context
31 {
32 public:
33   Wsrep_high_priority_service(THD*);
34   ~Wsrep_high_priority_service();
35   int start_transaction(const wsrep::ws_handle&,
36                         const wsrep::ws_meta&);
37   int next_fragment(const wsrep::ws_meta&);
38   const wsrep::transaction& transaction() const;
39   int adopt_transaction(const wsrep::transaction&);
40   int apply_write_set(const wsrep::ws_meta&, const wsrep::const_buffer&,
41                       wsrep::mutable_buffer&) = 0;
42   int append_fragment_and_commit(const wsrep::ws_handle&,
43                                  const wsrep::ws_meta&,
44                                  const wsrep::const_buffer&,
45                                  const wsrep::xid&);
46   int remove_fragments(const wsrep::ws_meta&);
47   int commit(const wsrep::ws_handle&, const wsrep::ws_meta&);
48   int rollback(const wsrep::ws_handle&, const wsrep::ws_meta&);
49   int apply_toi(const wsrep::ws_meta&, const wsrep::const_buffer&,
50                 wsrep::mutable_buffer&);
51   void store_globals();
52   void reset_globals();
53   void switch_execution_context(wsrep::high_priority_service&);
54   int log_dummy_write_set(const wsrep::ws_handle&,
55                           const wsrep::ws_meta&,
56                           wsrep::mutable_buffer&);
57   void adopt_apply_error(wsrep::mutable_buffer&);
58 
59   virtual bool check_exit_status() const = 0;
60   void debug_crash(const char*);
61 protected:
62   friend Wsrep_server_service;
63   THD* m_thd;
64   Relay_log_info*   m_rli;
65   rpl_group_info*   m_rgi;
66   struct shadow
67   {
68     ulonglong      option_bits;
69     uint           server_status;
70     struct st_vio* vio;
71     ulong          tx_isolation;
72     char*          db;
73     size_t         db_length;
74     //struct timeval user_time;
75     my_hrtime_t user_time;
76     longlong       row_count_func;
77     bool           wsrep_applier;
78   } m_shadow;
79 };
80 
81 class Wsrep_applier_service : public Wsrep_high_priority_service
82 {
83 public:
84   Wsrep_applier_service(THD*);
85   ~Wsrep_applier_service();
86   int apply_write_set(const wsrep::ws_meta&, const wsrep::const_buffer&,
87                       wsrep::mutable_buffer&);
88   int apply_nbo_begin(const wsrep::ws_meta&, const wsrep::const_buffer& data,
89                       wsrep::mutable_buffer& err);
90   void after_apply();
is_replaying()91   bool is_replaying() const { return false; }
92   bool check_exit_status() const;
93 };
94 
95 class Wsrep_replayer_service : public Wsrep_high_priority_service
96 {
97 public:
98   Wsrep_replayer_service(THD* replayer_thd, THD* orig_thd);
99   ~Wsrep_replayer_service();
100   int apply_write_set(const wsrep::ws_meta&, const wsrep::const_buffer&,
101                       wsrep::mutable_buffer&);
apply_nbo_begin(const wsrep::ws_meta &,const wsrep::const_buffer & data,wsrep::mutable_buffer & err)102   int apply_nbo_begin(const wsrep::ws_meta&, const wsrep::const_buffer& data,
103                       wsrep::mutable_buffer& err)
104   {
105     DBUG_ASSERT(0); /* DDL should never cause replaying */
106     return 0;
107   }
after_apply()108   void after_apply() { }
is_replaying()109   bool is_replaying() const { return true; }
replay_status(enum wsrep::provider::status status)110   void replay_status(enum wsrep::provider::status status)
111   { m_replay_status = status; }
replay_status()112   enum wsrep::provider::status replay_status() const
113   { return m_replay_status; }
114   /* Replayer should never be forced to exit */
check_exit_status()115   bool check_exit_status() const { return false; }
116 private:
117   THD* m_orig_thd;
118   struct da_shadow
119   {
120     enum Diagnostics_area::enum_diagnostics_status status;
121     ulonglong affected_rows;
122     ulonglong last_insert_id;
123     char message[MYSQL_ERRMSG_SIZE];
da_shadowda_shadow124     da_shadow()
125       : status()
126       , affected_rows()
127       , last_insert_id()
128       , message()
129     { }
130   } m_da_shadow;
131   enum wsrep::provider::status m_replay_status;
132 };
133 
134 #endif /* WSREP_HIGH_PRIORITY_SERVICE_H */
135