~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to sql/rpl_gtid_cache.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 
2
 
 
3
   This program is free software; you can redistribute it and/or
 
4
   modify it under the terms of the GNU General Public License as
 
5
   published by the Free Software Foundation; version 2 of the
 
6
   License.
 
7
 
 
8
   This program is distributed in the hope that it will be useful, but
 
9
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
   General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
16
   02110-1301 USA */
 
17
 
 
18
#include "rpl_gtid.h"
 
19
#include "sql_class.h"
 
20
#include "binlog.h"
 
21
 
 
22
 
 
23
Group_cache::Group_cache()
 
24
{
 
25
  DBUG_ENTER("Group_cache::Group_cache");
 
26
  my_init_dynamic_array(&groups, sizeof(Cached_group), 8, 8);
 
27
  DBUG_VOID_RETURN;
 
28
}
 
29
 
 
30
 
 
31
Group_cache::~Group_cache()
 
32
{
 
33
  DBUG_ENTER("Group_cache::~Group_cache");
 
34
  delete_dynamic(&groups);
 
35
  DBUG_VOID_RETURN;
 
36
}
 
37
 
 
38
 
 
39
void Group_cache::clear()
 
40
{
 
41
  DBUG_ENTER("Group_cache::clear");
 
42
  groups.elements= 0;
 
43
  DBUG_VOID_RETURN;
 
44
}
 
45
 
 
46
 
 
47
Group_cache::enum_add_group_status
 
48
Group_cache::add_logged_group(const THD *thd, my_off_t binlog_offset)
 
49
{
 
50
  DBUG_ENTER("Group_cache::add_logged_group(THD *, my_off_t)");
 
51
  const Gtid_specification &spec= thd->variables.gtid_next;
 
52
  DBUG_ASSERT(spec.type != UNDEFINED_GROUP);
 
53
  // merge with previous group if possible
 
54
  Cached_group *prev= get_last_group();
 
55
  if (prev != NULL && prev->spec.equals(spec))
 
56
    DBUG_RETURN(EXTEND_EXISTING_GROUP);
 
57
  // otherwise add a new group
 
58
  Cached_group *group= allocate_group();
 
59
  if (group ==  NULL)
 
60
    DBUG_RETURN(ERROR);
 
61
  group->spec= spec;
 
62
  group->binlog_offset= binlog_offset;
 
63
  // Update the internal status of this Group_cache (see comment above
 
64
  // definition of enum_group_cache_type).
 
65
  if (group->spec.type == GTID_GROUP)
 
66
  {
 
67
    /*
 
68
      @todo: currently group_is_logged() requires a linear scan
 
69
      through the cache. if this becomes a performance problem, we can
 
70
      add a Gtid_set Group_cache::logged_groups and add logged groups
 
71
      to it here. /Sven
 
72
    */
 
73
  }
 
74
  DBUG_RETURN(APPEND_NEW_GROUP);
 
75
}
 
76
 
 
77
 
 
78
bool Group_cache::contains_gtid(const Gtid &gtid) const
 
79
{
 
80
  int n_groups= get_n_groups();
 
81
  for (int i= 0; i < n_groups; i++)
 
82
  {
 
83
    const Cached_group *group= get_unsafe_pointer(i);
 
84
    if (group->spec.equals(gtid))
 
85
      return true;
 
86
  }
 
87
  return false;
 
88
}
 
89
 
 
90
 
 
91
/*
 
92
  Apparently this code is not being called. We need to
 
93
  investigate if this is a bug or this code is not
 
94
  necessary. /Alfranio
 
95
*/
 
96
#ifdef NON_ERROR_GTID
 
97
Group_cache::enum_add_group_status
 
98
Group_cache::add_empty_group(const Gtid &gtid)
 
99
{
 
100
  DBUG_ENTER("Group_cache::add_empty_group");
 
101
  // merge with previous group if possible
 
102
  Cached_group *prev= get_last_group();
 
103
  if (prev != NULL && prev->spec.equals(gtid))
 
104
    DBUG_RETURN(EXTEND_EXISTING_GROUP);
 
105
  // otherwise add new group
 
106
  Cached_group *group= allocate_group();
 
107
  if (group == NULL)
 
108
    DBUG_RETURN(ERROR);
 
109
  group->spec.type= GTID_GROUP;
 
110
  group->spec.gtid= gtid;
 
111
  group->binlog_offset= prev != NULL ? prev->binlog_offset : 0;
 
112
  // Update the internal status of this Group_cache (see comment above
 
113
  // definition of enum_group_cache_type).
 
114
  if (group->spec.type == GTID_GROUP)
 
115
  {
 
116
    /*
 
117
      @todo: currently group_is_logged() requires a linear scan
 
118
      through the cache. if this becomes a performance problem, we can
 
119
      add a Gtid_set Group_cache::logged_groups and add logged groups
 
120
      to it here. /Sven
 
121
    */
 
122
  }
 
123
  DBUG_RETURN(APPEND_NEW_GROUP);
 
124
}
 
125
#endif
 
126
 
 
127
 
 
128
enum_return_status Group_cache::generate_automatic_gno(THD *thd)
 
129
{
 
130
  DBUG_ENTER("Group_cache::generate_automatic_gno");
 
131
  DBUG_ASSERT(thd->variables.gtid_next.type == AUTOMATIC_GROUP);
 
132
  DBUG_ASSERT(thd->variables.gtid_next_list.get_gtid_set() == NULL);
 
133
  int n_groups= get_n_groups();
 
134
  enum_group_type automatic_type= INVALID_GROUP;
 
135
  Gtid automatic_gtid= { 0, 0 };
 
136
  for (int i= 0; i < n_groups; i++)
 
137
  {
 
138
    Cached_group *group= get_unsafe_pointer(i);
 
139
    if (group->spec.type == AUTOMATIC_GROUP)
 
140
    {
 
141
      if (automatic_type == INVALID_GROUP)
 
142
      {
 
143
        if (gtid_mode <= 1)
 
144
        {
 
145
          automatic_type= ANONYMOUS_GROUP;
 
146
        }
 
147
        else
 
148
        {
 
149
          automatic_type= GTID_GROUP;
 
150
          automatic_gtid.sidno= gtid_state->get_server_sidno();
 
151
          gtid_state->lock_sidno(automatic_gtid.sidno);
 
152
          automatic_gtid.gno=
 
153
            gtid_state->get_automatic_gno(automatic_gtid.sidno);
 
154
          if (automatic_gtid.gno == -1)
 
155
          {
 
156
            gtid_state->unlock_sidno(automatic_gtid.sidno);
 
157
            RETURN_REPORTED_ERROR;
 
158
          }
 
159
          gtid_state->acquire_ownership(thd, automatic_gtid);
 
160
          gtid_state->unlock_sidno(automatic_gtid.sidno);
 
161
        }
 
162
      }
 
163
      group->spec.type= automatic_type;
 
164
      group->spec.gtid= automatic_gtid;
 
165
    }
 
166
  }
 
167
  RETURN_OK;
 
168
}
 
169
 
 
170
 
 
171
enum_return_status Group_cache::get_gtids(Gtid_set *gs) const
 
172
{
 
173
  DBUG_ENTER("Group_cache::get_groups");
 
174
  int n_groups= get_n_groups();
 
175
  PROPAGATE_REPORTED_ERROR(gs->ensure_sidno(gs->get_sid_map()->get_max_sidno()));
 
176
  for (int i= 0; i < n_groups; i++)
 
177
  {
 
178
    Cached_group *group= get_unsafe_pointer(i);
 
179
    /*
 
180
      Cached groups only have GTIDs if SET @@SESSION.GTID_NEXT statement
 
181
      was executed before group.
 
182
    */
 
183
    if (group->spec.type == GTID_GROUP)
 
184
      PROPAGATE_REPORTED_ERROR(gs->_add_gtid(group->spec.gtid));
 
185
  }
 
186
  RETURN_OK;
 
187
}