Merge lp:~jaypipes/drizzle/replication-ddl into lp:~drizzle-trunk/drizzle/development
- replication-ddl
- Merge into development
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jaypipes/drizzle/replication-ddl |
Merge into: | lp:~drizzle-trunk/drizzle/development |
Prerequisite: | lp:~jaypipes/drizzle/replication-write-buffers |
Diff against target: |
2587 lines (+894/-424) 49 files modified
drizzled/atomic/gcc_traits.h (+11/-10) drizzled/atomic/pthread_traits.h (+20/-8) drizzled/atomic/sun_studio.h (+152/-29) drizzled/atomics.h (+16/-11) drizzled/cursor.cc (+1/-4) drizzled/include.am (+1/-0) drizzled/plugin/replication.h (+46/-0) drizzled/plugin/transaction_applier.h (+7/-2) drizzled/plugin/transaction_replicator.h (+8/-4) drizzled/replication_services.cc (+20/-13) drizzled/replication_services.h (+4/-1) drizzled/session.cc (+5/-5) drizzled/set_var.cc (+1/-1) drizzled/sql_delete.cc (+1/-1) drizzled/sql_insert.cc (+2/-2) drizzled/sql_parse.cc (+1/-1) drizzled/sql_table.cc (+3/-3) drizzled/sql_update.cc (+1/-1) drizzled/statement/alter_table.cc (+3/-3) drizzled/statement/release_savepoint.cc (+1/-1) drizzled/statement/rollback_to_savepoint.cc (+2/-2) drizzled/statement/savepoint.cc (+2/-2) drizzled/transaction_services.cc (+47/-145) drizzled/transaction_services.h (+40/-10) plugin/default_replicator/default_replicator.cc (+5/-2) plugin/default_replicator/default_replicator.h (+6/-1) plugin/filtered_replicator/filtered_replicator.cc (+6/-3) plugin/filtered_replicator/filtered_replicator.h (+6/-2) plugin/innobase/handler/ha_innodb.cc (+0/-30) plugin/transaction_log/module.cc (+26/-4) plugin/transaction_log/plugin.ini (+2/-2) plugin/transaction_log/tests/r/ddl_transaction_id.result (+36/-0) plugin/transaction_log/tests/r/filtered_replicator.result (+4/-0) plugin/transaction_log/tests/r/information_schema.result (+8/-5) plugin/transaction_log/tests/r/insert.result (+4/-0) plugin/transaction_log/tests/r/truncate_log.result (+2/-1) plugin/transaction_log/tests/r/udf_print_transaction_message.result (+1/-0) plugin/transaction_log/tests/r/variables.result (+2/-1) plugin/transaction_log/tests/t/ddl_transaction_id-master.opt (+1/-0) plugin/transaction_log/tests/t/ddl_transaction_id.inc (+29/-0) plugin/transaction_log/tests/t/ddl_transaction_id.test (+14/-0) plugin/transaction_log/tests/t/information_schema.test (+2/-2) plugin/transaction_log/tests/t/insert.inc (+2/-0) plugin/transaction_log/transaction_log.cc (+83/-32) plugin/transaction_log/transaction_log.h (+32/-5) plugin/transaction_log/transaction_log_applier.cc (+47/-72) plugin/transaction_log/transaction_log_applier.h (+20/-3) plugin/transaction_log/write_buffer.cc (+71/-0) plugin/transaction_log/write_buffer.h (+90/-0) |
To merge this branch: | bzr merge lp:~jaypipes/drizzle/replication-ddl |
Related bugs: | |
Related blueprints: |
Ensure DDL operations generate a transaction ID
(Essential)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brian Aker | Needs Fixing | ||
Jay Pipes (community) | Needs Resubmitting | ||
Monty Taylor | Needs Fixing | ||
Review via email:
|
Commit message
Description of the change
* Fixes drizzled's atomics:
- fetch_and_add() was actually add_and_fetch() - fixed to have both methods correct
- compare_and_swap() was incorrect for all traits classes. Fixed to return a bool
true only when the supplied value is actually swapped
- fixes increment() and decrement() methods and operator+=() in outer atomics class
template to call proper add_and_fetch() methods on traits classes
- Now that above are fixed, removed the hacks in Query_id and TransactionLog to
have query ID and the new transactoin ID start properly at 1.
* Transaction messages sent over replication stream now use
a real transaction ID, managed by drizzled:
the Query_id was being used, resulting in SELECT statements incrementing the
transaction ID.
* Added a test case to ensure that DDL ops are given a transaction ID and SELECT
ops do not increment the transaction ID.
The transaction ID will be paired with a channel ID to become the global
transaction identifier. ReplicationServices will manage the pairing of
channel and transaction ID and understand how far a particular subscriber
node has applied.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jay Pipes (jaypipes) wrote : | # |
Pushed Sun atomics fixes. Please review r1419. If we could run it through a hudson builder for Sun-only, that would be cool...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jay Pipes (jaypipes) wrote : | # |
OK, all green in build. Fixed Sun Studio atomics.
- 1423. By Jay Pipes <jpipes@serialcoder>
-
Fix cpplint header guard.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Brian Aker (brianaker) wrote : | # |
This needs to be remerged with Trunk.
Thanks,
-Brian
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jay Pipes (jaypipes) wrote : | # |
This has already been merged with trunk.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Brian Aker (brianaker) wrote : | # |
Sorry, I must have clicked on the wrong link. Though I am not seeing
this in the merge history.
On Apr 1, 2010, at 12:55 PM, Jay Pipes wrote:
> This has already been merged with trunk.
> --
> https:/
> You are reviewing the proposed merge of lp:~jaypipes/drizzle/
> replication-ddl into lp:drizzle.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jay Pipes (jaypipes) wrote : | # |
No worries. I'm pretty sure I'm all merged up, though, as I see no revisions to pull if I bzr merge trunk locally...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jay Pipes (jaypipes) wrote : | # |
fyi, r1422 on this branch contains the most recent merge with trunk
Preview Diff
1 | === modified file 'drizzled/atomic/gcc_traits.h' | |||
2 | --- drizzled/atomic/gcc_traits.h 2009-07-17 20:59:45 +0000 | |||
3 | +++ drizzled/atomic/gcc_traits.h 2010-04-06 19:16:34 +0000 | |||
4 | @@ -32,36 +32,37 @@ | |||
5 | 32 | 32 | ||
6 | 33 | gcc_traits() {} | 33 | gcc_traits() {} |
7 | 34 | 34 | ||
11 | 35 | /* YES. I know these are semantically backwards... | 35 | inline value_type add_and_fetch(volatile value_type *value, D addend ) |
12 | 36 | * so... TODO: Ensure we're doing the "right" thing here | 36 | { |
13 | 37 | */ | 37 | return __sync_add_and_fetch(value, addend); |
14 | 38 | } | ||
15 | 39 | |||
16 | 38 | inline value_type fetch_and_add(volatile value_type *value, D addend ) | 40 | inline value_type fetch_and_add(volatile value_type *value, D addend ) |
17 | 39 | { | 41 | { |
19 | 40 | return __sync_add_and_fetch(value, addend); | 42 | return __sync_fetch_and_add(value, addend); |
20 | 41 | } | 43 | } |
21 | 42 | 44 | ||
22 | 43 | inline value_type fetch_and_increment(volatile value_type *value) | 45 | inline value_type fetch_and_increment(volatile value_type *value) |
23 | 44 | { | 46 | { |
25 | 45 | return __sync_add_and_fetch(value, 1); | 47 | return __sync_fetch_and_add(value, 1); |
26 | 46 | } | 48 | } |
27 | 47 | 49 | ||
28 | 48 | inline value_type fetch_and_decrement(volatile value_type *value) | 50 | inline value_type fetch_and_decrement(volatile value_type *value) |
29 | 49 | { | 51 | { |
31 | 50 | return __sync_sub_and_fetch(value, 1); | 52 | return __sync_fetch_and_sub(value, 1); |
32 | 51 | } | 53 | } |
33 | 52 | 54 | ||
34 | 53 | inline value_type fetch_and_store(volatile value_type *value, | 55 | inline value_type fetch_and_store(volatile value_type *value, |
35 | 54 | value_type new_value) | 56 | value_type new_value) |
36 | 55 | { | 57 | { |
37 | 56 | /* TODO: Is this the right one? */ | ||
38 | 57 | return __sync_lock_test_and_set(value, new_value); | 58 | return __sync_lock_test_and_set(value, new_value); |
39 | 58 | } | 59 | } |
40 | 59 | 60 | ||
42 | 60 | inline value_type compare_and_swap(volatile value_type *value, | 61 | inline bool compare_and_swap(volatile value_type *value, |
43 | 61 | value_type new_value, | 62 | value_type new_value, |
44 | 62 | value_type comparand ) | 63 | value_type comparand ) |
45 | 63 | { | 64 | { |
47 | 64 | return __sync_val_compare_and_swap(value, comparand, new_value); | 65 | return __sync_bool_compare_and_swap(value, comparand, new_value); |
48 | 65 | } | 66 | } |
49 | 66 | 67 | ||
50 | 67 | inline value_type fetch(const volatile value_type *value) const volatile | 68 | inline value_type fetch(const volatile value_type *value) const volatile |
51 | @@ -76,7 +77,7 @@ | |||
52 | 76 | * Look at how to rewrite the below to something that ICC feels is | 77 | * Look at how to rewrite the below to something that ICC feels is |
53 | 77 | * OK and yet respects memory barriers. | 78 | * OK and yet respects memory barriers. |
54 | 78 | */ | 79 | */ |
56 | 79 | return __sync_add_and_fetch(const_cast<value_type *>(value), 0); | 80 | return __sync_fetch_and_add(const_cast<value_type *>(value), 0); |
57 | 80 | } | 81 | } |
58 | 81 | 82 | ||
59 | 82 | inline value_type store_with_release(volatile value_type *value, | 83 | inline value_type store_with_release(volatile value_type *value, |
60 | 83 | 84 | ||
61 | === modified file 'drizzled/atomic/pthread_traits.h' | |||
62 | --- drizzled/atomic/pthread_traits.h 2009-12-14 19:51:51 +0000 | |||
63 | +++ drizzled/atomic/pthread_traits.h 2010-04-06 19:16:34 +0000 | |||
64 | @@ -67,11 +67,20 @@ | |||
65 | 67 | 67 | ||
66 | 68 | pthread_traits() {} | 68 | pthread_traits() {} |
67 | 69 | 69 | ||
68 | 70 | inline value_type add_and_fetch(volatile value_type *value, D addend ) | ||
69 | 71 | { | ||
70 | 72 | my_lock.lock(); | ||
71 | 73 | *value += addend; | ||
72 | 74 | value_type ret= *value; | ||
73 | 75 | my_lock.unlock(); | ||
74 | 76 | return ret; | ||
75 | 77 | } | ||
76 | 78 | |||
77 | 70 | inline value_type fetch_and_add(volatile value_type *value, D addend ) | 79 | inline value_type fetch_and_add(volatile value_type *value, D addend ) |
78 | 71 | { | 80 | { |
79 | 72 | my_lock.lock(); | 81 | my_lock.lock(); |
80 | 82 | value_type ret= *value; | ||
81 | 73 | *value += addend; | 83 | *value += addend; |
82 | 74 | value_type ret= *value; | ||
83 | 75 | my_lock.unlock(); | 84 | my_lock.unlock(); |
84 | 76 | return ret; | 85 | return ret; |
85 | 77 | } | 86 | } |
86 | @@ -79,8 +88,8 @@ | |||
87 | 79 | inline value_type fetch_and_increment(volatile value_type *value) | 88 | inline value_type fetch_and_increment(volatile value_type *value) |
88 | 80 | { | 89 | { |
89 | 81 | my_lock.lock(); | 90 | my_lock.lock(); |
90 | 91 | value_type ret= *value; | ||
91 | 82 | *value++; | 92 | *value++; |
92 | 83 | value_type ret= *value; | ||
93 | 84 | my_lock.unlock(); | 93 | my_lock.unlock(); |
94 | 85 | return ret; | 94 | return ret; |
95 | 86 | } | 95 | } |
96 | @@ -88,8 +97,8 @@ | |||
97 | 88 | inline value_type fetch_and_decrement(volatile value_type *value) | 97 | inline value_type fetch_and_decrement(volatile value_type *value) |
98 | 89 | { | 98 | { |
99 | 90 | my_lock.lock(); | 99 | my_lock.lock(); |
100 | 100 | value_type ret= *value; | ||
101 | 91 | *value--; | 101 | *value--; |
102 | 92 | value_type ret= *value; | ||
103 | 93 | my_lock.unlock(); | 102 | my_lock.unlock(); |
104 | 94 | return ret; | 103 | return ret; |
105 | 95 | } | 104 | } |
106 | @@ -98,27 +107,30 @@ | |||
107 | 98 | value_type new_value ) | 107 | value_type new_value ) |
108 | 99 | { | 108 | { |
109 | 100 | my_lock.lock(); | 109 | my_lock.lock(); |
110 | 110 | value_type ret= *value; | ||
111 | 101 | *value= new_value; | 111 | *value= new_value; |
112 | 102 | value_type ret= *value; | ||
113 | 103 | my_lock.unlock(); | 112 | my_lock.unlock(); |
114 | 104 | return ret; | 113 | return ret; |
115 | 105 | } | 114 | } |
116 | 106 | 115 | ||
118 | 107 | inline value_type compare_and_swap(volatile value_type *value, | 116 | inline bool compare_and_swap(volatile value_type *value, |
119 | 108 | value_type new_value, | 117 | value_type new_value, |
120 | 109 | value_type comparand ) | 118 | value_type comparand ) |
121 | 110 | { | 119 | { |
122 | 111 | my_lock.lock(); | 120 | my_lock.lock(); |
124 | 112 | if (*value == comparand) | 121 | bool ret= (*value == comparand); |
125 | 122 | if (ret) | ||
126 | 113 | *value= new_value; | 123 | *value= new_value; |
127 | 114 | value_type ret= *value; | ||
128 | 115 | my_lock.unlock(); | 124 | my_lock.unlock(); |
129 | 116 | return ret; | 125 | return ret; |
130 | 117 | } | 126 | } |
131 | 118 | 127 | ||
132 | 119 | inline value_type fetch(const volatile value_type *value) const volatile | 128 | inline value_type fetch(const volatile value_type *value) const volatile |
133 | 120 | { | 129 | { |
135 | 121 | return *value; | 130 | const_cast<pthread_traits *>(this)->my_lock.lock(); |
136 | 131 | value_type ret= *value; | ||
137 | 132 | const_cast<pthread_traits *>(this)->my_lock.unlock(); | ||
138 | 133 | return ret; | ||
139 | 122 | } | 134 | } |
140 | 123 | 135 | ||
141 | 124 | inline value_type store_with_release(volatile value_type *value, | 136 | inline value_type store_with_release(volatile value_type *value, |
142 | 125 | 137 | ||
143 | === modified file 'drizzled/atomic/sun_studio.h' | |||
144 | --- drizzled/atomic/sun_studio.h 2009-08-30 00:26:17 +0000 | |||
145 | +++ drizzled/atomic/sun_studio.h 2010-04-06 19:16:34 +0000 | |||
146 | @@ -24,91 +24,177 @@ | |||
147 | 24 | #include <atomic.h> | 24 | #include <atomic.h> |
148 | 25 | #undef _KERNEL | 25 | #undef _KERNEL |
149 | 26 | 26 | ||
150 | 27 | inline bool __sync_fetch_and_add(volatile bool* ptr, bool val) | ||
151 | 28 | { | ||
152 | 29 | bool ret= *ptr; | ||
153 | 30 | (val == true) ? atomic_inc_8((volatile uint8_t *)ptr) : atomic_add_8((volatile uint8_t *)ptr, (int8_t)val); | ||
154 | 31 | return ret; | ||
155 | 32 | } | ||
156 | 33 | |||
157 | 34 | inline int8_t __sync_fetch_and_add(volatile int8_t* ptr, int8_t val) | ||
158 | 35 | { | ||
159 | 36 | int8_t ret= *ptr; | ||
160 | 37 | (val == 1) ? atomic_inc_8((volatile uint8_t*)ptr) : atomic_add_8((volatile uint8_t*)ptr, val); | ||
161 | 38 | return ret; | ||
162 | 39 | } | ||
163 | 40 | |||
164 | 41 | inline int16_t __sync_fetch_and_add(volatile int16_t* ptr, int16_t val) | ||
165 | 42 | { | ||
166 | 43 | int16_t ret= *ptr; | ||
167 | 44 | (val == 1) ? atomic_inc_16((volatile uint16_t*)ptr) : atomic_add_16((volatile uint16_t*)ptr, val); | ||
168 | 45 | return ret; | ||
169 | 46 | } | ||
170 | 47 | |||
171 | 48 | inline int32_t __sync_fetch_and_add(volatile int32_t* ptr, int32_t val) | ||
172 | 49 | { | ||
173 | 50 | int32_t ret= *ptr; | ||
174 | 51 | (val == 1) ? atomic_inc_32((volatile uint32_t*)ptr) : atomic_add_32((volatile uint32_t*)ptr, val); | ||
175 | 52 | return ret; | ||
176 | 53 | } | ||
177 | 54 | |||
178 | 55 | inline uint8_t __sync_fetch_and_add(volatile uint8_t* ptr, uint8_t val) | ||
179 | 56 | { | ||
180 | 57 | uint8_t ret= *ptr; | ||
181 | 58 | (val == 1) ? atomic_inc_8(ptr) : atomic_add_8(ptr, (int8_t)val); | ||
182 | 59 | return ret; | ||
183 | 60 | } | ||
184 | 61 | |||
185 | 62 | inline uint16_t __sync_fetch_and_add(volatile uint16_t* ptr, uint16_t val) | ||
186 | 63 | { | ||
187 | 64 | uint16_t ret= *ptr; | ||
188 | 65 | (val == 1) ? atomic_inc_16(ptr) : atomic_add_16(ptr, (int16_t)val); | ||
189 | 66 | return ret; | ||
190 | 67 | } | ||
191 | 68 | |||
192 | 69 | inline uint32_t __sync_fetch_and_add(volatile uint32_t* ptr, uint32_t val) | ||
193 | 70 | { | ||
194 | 71 | uint32_t ret= *ptr; | ||
195 | 72 | (val == 1) ? atomic_inc_32(ptr) : atomic_add_32(ptr, (int32_t)val); | ||
196 | 73 | return ret; | ||
197 | 74 | } | ||
198 | 75 | |||
199 | 76 | # if defined(_KERNEL) || defined(_INT64_TYPE) | ||
200 | 77 | inline uint64_t __sync_fetch_and_add(volatile uint64_t* ptr, uint64_t val) | ||
201 | 78 | { | ||
202 | 79 | uint64_t ret= *ptr; | ||
203 | 80 | (val == 1) ? atomic_inc_64(ptr) : atomic_add_64(ptr, (int64_t)val); | ||
204 | 81 | return ret; | ||
205 | 82 | } | ||
206 | 83 | |||
207 | 84 | inline int64_t __sync_fetch_and_add(volatile int64_t* ptr, int64_t val) | ||
208 | 85 | { | ||
209 | 86 | int64_t ret= *ptr; | ||
210 | 87 | (val == 1) ? atomic_inc_64((volatile uint64_t*)ptr) : atomic_add_64((volatile uint64_t*)ptr, val); | ||
211 | 88 | return ret; | ||
212 | 89 | } | ||
213 | 90 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | ||
214 | 91 | |||
215 | 92 | inline uint8_t __sync_fetch_and_sub(volatile uint8_t* ptr, uint8_t val) | ||
216 | 93 | { | ||
217 | 94 | uint8_t ret= *ptr; | ||
218 | 95 | (val == 1) ? atomic_dec_8(ptr) : atomic_add_8(ptr, 0-(int8_t)val); | ||
219 | 96 | return ret; | ||
220 | 97 | } | ||
221 | 98 | |||
222 | 99 | inline uint16_t __sync_fetch_and_sub(volatile uint16_t* ptr, uint16_t val) | ||
223 | 100 | { | ||
224 | 101 | uint16_t ret= *ptr; | ||
225 | 102 | (val == 1) ? atomic_dec_16(ptr) : atomic_add_16(ptr, 0-(int16_t)val); | ||
226 | 103 | return ret; | ||
227 | 104 | } | ||
228 | 105 | |||
229 | 106 | inline uint32_t __sync_fetch_and_sub(volatile uint32_t* ptr, uint32_t val) | ||
230 | 107 | { | ||
231 | 108 | uint32_t ret= *ptr; | ||
232 | 109 | (val == 1) ? atomic_dec_32(ptr) : atomic_add_32(ptr, 0-(int32_t)val); | ||
233 | 110 | return ret; | ||
234 | 111 | } | ||
235 | 112 | |||
236 | 113 | # if defined(_KERNEL) || defined(_INT64_TYPE) | ||
237 | 114 | inline uint64_t __sync_fetch_and_sub(volatile uint64_t* ptr, uint64_t val) | ||
238 | 115 | { | ||
239 | 116 | uint64_t ret= *ptr; | ||
240 | 117 | (val == 1) ? atomic_dec_64(ptr) : atomic_add_64(ptr, 0-(int64_t)val); | ||
241 | 118 | return ret; | ||
242 | 119 | } | ||
243 | 120 | inline int64_t __sync_fetch_and_sub(volatile int64_t* ptr, uint64_t val) | ||
244 | 121 | { | ||
245 | 122 | int64_t ret= *ptr; | ||
246 | 123 | (val == 1) ? atomic_dec_64((volatile uint64_t *) ptr) : atomic_add_64((volatile uint64_t *) ptr, 0-(int64_t)val); | ||
247 | 124 | return ret; | ||
248 | 125 | } | ||
249 | 126 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | ||
250 | 127 | |||
251 | 27 | inline bool __sync_add_and_fetch(volatile bool* ptr, bool val) | 128 | inline bool __sync_add_and_fetch(volatile bool* ptr, bool val) |
252 | 28 | { | 129 | { |
255 | 29 | (val == true) ? atomic_inc_8((volatile uint8_t *)ptr) : atomic_add_8((volatile uint8_t *)ptr, (int8_t)val); | 130 | return (val == true) ? atomic_inc_8_nv((volatile uint8_t *)ptr) : atomic_add_8_nv((volatile uint8_t *)ptr, (int8_t)val); |
254 | 30 | return *ptr; | ||
256 | 31 | } | 131 | } |
257 | 32 | 132 | ||
258 | 33 | inline int8_t __sync_add_and_fetch(volatile int8_t* ptr, int8_t val) | 133 | inline int8_t __sync_add_and_fetch(volatile int8_t* ptr, int8_t val) |
259 | 34 | { | 134 | { |
262 | 35 | (val == 1) ? atomic_inc_8((volatile uint8_t*)ptr) : atomic_add_8((volatile uint8_t*)ptr, val); | 135 | return (val == 1) ? atomic_inc_8_nv((volatile uint8_t*)ptr) : atomic_add_8_nv((volatile uint8_t*)ptr, val); |
261 | 36 | return *ptr; | ||
263 | 37 | } | 136 | } |
264 | 38 | 137 | ||
265 | 39 | inline int16_t __sync_add_and_fetch(volatile int16_t* ptr, int16_t val) | 138 | inline int16_t __sync_add_and_fetch(volatile int16_t* ptr, int16_t val) |
266 | 40 | { | 139 | { |
269 | 41 | (val == 1) ? atomic_inc_16((volatile uint16_t*)ptr) : atomic_add_16((volatile uint16_t*)ptr, val); | 140 | return (val == 1) ? atomic_inc_16_nv((volatile uint16_t*)ptr) : atomic_add_16_nv((volatile uint16_t*)ptr, val); |
268 | 42 | return *ptr; | ||
270 | 43 | } | 141 | } |
271 | 44 | 142 | ||
272 | 45 | inline int32_t __sync_add_and_fetch(volatile int32_t* ptr, int32_t val) | 143 | inline int32_t __sync_add_and_fetch(volatile int32_t* ptr, int32_t val) |
273 | 46 | { | 144 | { |
276 | 47 | (val == 1) ? atomic_inc_32((volatile uint32_t*)ptr) : atomic_add_32((volatile uint32_t*)ptr, val); | 145 | return (val == 1) ? atomic_inc_32_nv((volatile uint32_t*)ptr) : atomic_add_32_nv((volatile uint32_t*)ptr, val); |
275 | 48 | return *ptr; | ||
277 | 49 | } | 146 | } |
278 | 50 | 147 | ||
279 | 51 | inline uint8_t __sync_add_and_fetch(volatile uint8_t* ptr, uint8_t val) | 148 | inline uint8_t __sync_add_and_fetch(volatile uint8_t* ptr, uint8_t val) |
280 | 52 | { | 149 | { |
283 | 53 | (val == 1) ? atomic_inc_8(ptr) : atomic_add_8(ptr, (int8_t)val); | 150 | return (val == 1) ? atomic_inc_8_nv(ptr) : atomic_add_8_nv(ptr, (int8_t)val); |
282 | 54 | return *ptr; | ||
284 | 55 | } | 151 | } |
285 | 56 | 152 | ||
286 | 57 | inline uint16_t __sync_add_and_fetch(volatile uint16_t* ptr, uint16_t val) | 153 | inline uint16_t __sync_add_and_fetch(volatile uint16_t* ptr, uint16_t val) |
287 | 58 | { | 154 | { |
290 | 59 | (val == 1) ? atomic_inc_16(ptr) : atomic_add_16(ptr, (int16_t)val); | 155 | return (val == 1) ? atomic_inc_16_nv(ptr) : atomic_add_16_nv(ptr, (int16_t)val); |
289 | 60 | return *ptr; | ||
291 | 61 | } | 156 | } |
292 | 62 | 157 | ||
293 | 63 | inline uint32_t __sync_add_and_fetch(volatile uint32_t* ptr, uint32_t val) | 158 | inline uint32_t __sync_add_and_fetch(volatile uint32_t* ptr, uint32_t val) |
294 | 64 | { | 159 | { |
297 | 65 | (val == 1) ? atomic_inc_32(ptr) : atomic_add_32(ptr, (int32_t)val); | 160 | return (val == 1) ? atomic_inc_32_nv(ptr) : atomic_add_32_nv(ptr, (int32_t)val); |
296 | 66 | return *ptr; | ||
298 | 67 | } | 161 | } |
299 | 68 | 162 | ||
300 | 69 | # if defined(_KERNEL) || defined(_INT64_TYPE) | 163 | # if defined(_KERNEL) || defined(_INT64_TYPE) |
301 | 70 | inline uint64_t __sync_add_and_fetch(volatile uint64_t* ptr, uint64_t val) | 164 | inline uint64_t __sync_add_and_fetch(volatile uint64_t* ptr, uint64_t val) |
302 | 71 | { | 165 | { |
305 | 72 | (val == 1) ? atomic_inc_64(ptr) : atomic_add_64(ptr, (int64_t)val); | 166 | return (val == 1) ? atomic_inc_64_nv(ptr) : atomic_add_64_nv(ptr, (int64_t)val); |
304 | 73 | return *ptr; | ||
306 | 74 | } | 167 | } |
307 | 75 | 168 | ||
308 | 76 | inline int64_t __sync_add_and_fetch(volatile int64_t* ptr, int64_t val) | 169 | inline int64_t __sync_add_and_fetch(volatile int64_t* ptr, int64_t val) |
309 | 77 | { | 170 | { |
312 | 78 | (val == 1) ? atomic_inc_64((volatile uint64_t*)ptr) : atomic_add_64((volatile uint64_t*)ptr, val); | 171 | return (val == 1) ? atomic_inc_64_nv((volatile uint64_t*)ptr) : atomic_add_64_nv((volatile uint64_t*)ptr, val); |
311 | 79 | return *ptr; | ||
313 | 80 | } | 172 | } |
314 | 81 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | 173 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ |
315 | 82 | 174 | ||
316 | 83 | |||
317 | 84 | inline uint8_t __sync_sub_and_fetch(volatile uint8_t* ptr, uint8_t val) | 175 | inline uint8_t __sync_sub_and_fetch(volatile uint8_t* ptr, uint8_t val) |
318 | 85 | { | 176 | { |
321 | 86 | (val == 1) ? atomic_dec_8(ptr) : atomic_add_8(ptr, 0-(int8_t)val); | 177 | return (val == 1) ? atomic_dec_8_nv(ptr) : atomic_add_8_nv(ptr, 0-(int8_t)val); |
320 | 87 | return *ptr; | ||
322 | 88 | } | 178 | } |
323 | 89 | 179 | ||
324 | 90 | inline uint16_t __sync_sub_and_fetch(volatile uint16_t* ptr, uint16_t val) | 180 | inline uint16_t __sync_sub_and_fetch(volatile uint16_t* ptr, uint16_t val) |
325 | 91 | { | 181 | { |
328 | 92 | (val == 1) ? atomic_dec_16(ptr) : atomic_add_16(ptr, 0-(int16_t)val); | 182 | return (val == 1) ? atomic_dec_16_nv(ptr) : atomic_add_16_nv(ptr, 0-(int16_t)val); |
327 | 93 | return *ptr; | ||
329 | 94 | } | 183 | } |
330 | 95 | 184 | ||
331 | 96 | inline uint32_t __sync_sub_and_fetch(volatile uint32_t* ptr, uint32_t val) | 185 | inline uint32_t __sync_sub_and_fetch(volatile uint32_t* ptr, uint32_t val) |
332 | 97 | { | 186 | { |
335 | 98 | (val == 1) ? atomic_dec_32(ptr) : atomic_add_32(ptr, 0-(int32_t)val); | 187 | return (val == 1) ? atomic_dec_32_nv(ptr) : atomic_add_32_nv(ptr, 0-(int32_t)val); |
334 | 99 | return *ptr; | ||
336 | 100 | } | 188 | } |
337 | 101 | 189 | ||
338 | 102 | # if defined(_KERNEL) || defined(_INT64_TYPE) | 190 | # if defined(_KERNEL) || defined(_INT64_TYPE) |
339 | 103 | inline uint64_t __sync_sub_and_fetch(volatile uint64_t* ptr, uint64_t val) | 191 | inline uint64_t __sync_sub_and_fetch(volatile uint64_t* ptr, uint64_t val) |
340 | 104 | { | 192 | { |
343 | 105 | (val == 1) ? atomic_dec_64(ptr) : atomic_add_64(ptr, 0-(int64_t)val); | 193 | return (val == 1) ? atomic_dec_64_nv(ptr) : atomic_add_64_nv(ptr, 0-(int64_t)val); |
342 | 106 | return *ptr; | ||
344 | 107 | } | 194 | } |
345 | 108 | inline int64_t __sync_sub_and_fetch(volatile int64_t* ptr, uint64_t val) | 195 | inline int64_t __sync_sub_and_fetch(volatile int64_t* ptr, uint64_t val) |
346 | 109 | { | 196 | { |
349 | 110 | (val == 1) ? atomic_dec_64((volatile uint64_t *) ptr) : atomic_add_64((volatile uint64_t *) ptr, 0-(int64_t)val); | 197 | return (val == 1) ? atomic_dec_64_nv((volatile uint64_t *) ptr) : atomic_add_64_nv((volatile uint64_t *) ptr, 0-(int64_t)val); |
348 | 111 | return *ptr; | ||
350 | 112 | } | 198 | } |
351 | 113 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | 199 | # endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ |
352 | 114 | 200 | ||
353 | @@ -175,4 +261,41 @@ | |||
354 | 175 | } | 261 | } |
355 | 176 | #endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | 262 | #endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ |
356 | 177 | 263 | ||
357 | 264 | inline int8_t __sync_bool_compare_and_swap(volatile int8_t* ptr, | ||
358 | 265 | int8_t old_val, int8_t val) | ||
359 | 266 | { | ||
360 | 267 | int8_t orig= *ptr; | ||
361 | 268 | return orig == atomic_cas_8((volatile uint8_t *)ptr, old_val, val); | ||
362 | 269 | } | ||
363 | 270 | |||
364 | 271 | inline uint8_t __sync_bool_compare_and_swap(volatile uint8_t* ptr, | ||
365 | 272 | uint8_t old_val, uint8_t val) | ||
366 | 273 | { | ||
367 | 274 | uint8_t orig= *ptr; | ||
368 | 275 | return orig == atomic_cas_8(ptr, old_val, val); | ||
369 | 276 | } | ||
370 | 277 | |||
371 | 278 | inline uint16_t __sync_bool_compare_and_swap(volatile uint16_t* ptr, | ||
372 | 279 | uint16_t old_val, uint16_t val) | ||
373 | 280 | { | ||
374 | 281 | uint16_t orig= *ptr; | ||
375 | 282 | return orig == atomic_cas_16(ptr, old_val, val); | ||
376 | 283 | } | ||
377 | 284 | |||
378 | 285 | inline uint32_t __sync_bool_compare_and_swap(volatile uint32_t* ptr, | ||
379 | 286 | uint32_t old_val, uint32_t val) | ||
380 | 287 | { | ||
381 | 288 | uint32_t orig= *ptr; | ||
382 | 289 | return orig == atomic_cas_32(ptr, old_val, val); | ||
383 | 290 | } | ||
384 | 291 | |||
385 | 292 | # if defined(_KERNEL) || defined(_INT64_TYPE) | ||
386 | 293 | inline uint64_t __sync_bool_compare_and_swap(volatile uint64_t* ptr, | ||
387 | 294 | uint64_t old_val, uint64_t val) | ||
388 | 295 | { | ||
389 | 296 | uint64_t orig= *ptr; | ||
390 | 297 | return orig == atomic_cas_64(ptr, old_val, val); | ||
391 | 298 | } | ||
392 | 299 | #endif /* defined(_KERNEL) || defined(_INT64_TYPE) */ | ||
393 | 300 | |||
394 | 178 | #endif /* DRIZZLED_ATOMIC_SUN_STUDIO_H */ | 301 | #endif /* DRIZZLED_ATOMIC_SUN_STUDIO_H */ |
395 | 179 | 302 | ||
396 | === modified file 'drizzled/atomics.h' | |||
397 | --- drizzled/atomics.h 2010-01-04 22:52:52 +0000 | |||
398 | +++ drizzled/atomics.h 2010-04-06 19:16:34 +0000 | |||
399 | @@ -58,6 +58,11 @@ | |||
400 | 58 | 58 | ||
401 | 59 | atomic_impl() : atomic_base<I>(), traits() {} | 59 | atomic_impl() : atomic_base<I>(), traits() {} |
402 | 60 | 60 | ||
403 | 61 | value_type add_and_fetch( D addend ) | ||
404 | 62 | { | ||
405 | 63 | return traits.add_and_fetch(&this->my_value, addend); | ||
406 | 64 | } | ||
407 | 65 | |||
408 | 61 | value_type fetch_and_add( D addend ) | 66 | value_type fetch_and_add( D addend ) |
409 | 62 | { | 67 | { |
410 | 63 | return traits.fetch_and_add(&this->my_value, addend); | 68 | return traits.fetch_and_add(&this->my_value, addend); |
411 | @@ -78,7 +83,7 @@ | |||
412 | 78 | return traits.fetch_and_store(&this->my_value, value); | 83 | return traits.fetch_and_store(&this->my_value, value); |
413 | 79 | } | 84 | } |
414 | 80 | 85 | ||
416 | 81 | value_type compare_and_swap( value_type value, value_type comparand ) | 86 | bool compare_and_swap( value_type value, value_type comparand ) |
417 | 82 | { | 87 | { |
418 | 83 | return traits.compare_and_swap(&this->my_value, value, comparand); | 88 | return traits.compare_and_swap(&this->my_value, value, comparand); |
419 | 84 | } | 89 | } |
420 | @@ -102,7 +107,7 @@ | |||
421 | 102 | public: | 107 | public: |
422 | 103 | atomic_impl<I,D,T>& operator+=( D addend ) | 108 | atomic_impl<I,D,T>& operator+=( D addend ) |
423 | 104 | { | 109 | { |
425 | 105 | fetch_and_add(addend)+addend; | 110 | increment(addend); |
426 | 106 | return *this; | 111 | return *this; |
427 | 107 | } | 112 | } |
428 | 108 | 113 | ||
429 | @@ -113,15 +118,15 @@ | |||
430 | 113 | return operator+=(D(0)-addend); | 118 | return operator+=(D(0)-addend); |
431 | 114 | } | 119 | } |
432 | 115 | 120 | ||
442 | 116 | value_type increment() { | 121 | value_type increment() |
443 | 117 | return fetch_and_add(1)+1; | 122 | { |
444 | 118 | } | 123 | return add_and_fetch(1); |
445 | 119 | 124 | } | |
446 | 120 | value_type decrement() { | 125 | |
447 | 121 | return fetch_and_add(D(-1))-1; | 126 | value_type decrement() |
448 | 122 | } | 127 | { |
449 | 123 | 128 | return add_and_fetch(D(-1)); | |
450 | 124 | 129 | } | |
451 | 125 | }; | 130 | }; |
452 | 126 | 131 | ||
453 | 127 | } /* namespace internal */ | 132 | } /* namespace internal */ |
454 | 128 | 133 | ||
455 | === modified file 'drizzled/cursor.cc' | |||
456 | --- drizzled/cursor.cc 2010-04-01 06:30:46 +0000 | |||
457 | +++ drizzled/cursor.cc 2010-04-06 19:16:34 +0000 | |||
458 | @@ -36,7 +36,6 @@ | |||
459 | 36 | #include "drizzled/session.h" | 36 | #include "drizzled/session.h" |
460 | 37 | #include "drizzled/sql_base.h" | 37 | #include "drizzled/sql_base.h" |
461 | 38 | #include "drizzled/transaction_services.h" | 38 | #include "drizzled/transaction_services.h" |
462 | 39 | #include "drizzled/replication_services.h" | ||
463 | 40 | #include "drizzled/lock.h" | 39 | #include "drizzled/lock.h" |
464 | 41 | #include "drizzled/item/int.h" | 40 | #include "drizzled/item/int.h" |
465 | 42 | #include "drizzled/item/empty_string.h" | 41 | #include "drizzled/item/empty_string.h" |
466 | @@ -44,7 +43,6 @@ | |||
467 | 44 | #include "drizzled/message/table.pb.h" | 43 | #include "drizzled/message/table.pb.h" |
468 | 45 | #include "drizzled/plugin/client.h" | 44 | #include "drizzled/plugin/client.h" |
469 | 46 | #include "drizzled/internal/my_sys.h" | 45 | #include "drizzled/internal/my_sys.h" |
470 | 47 | #include "drizzled/transaction_services.h" | ||
471 | 48 | 46 | ||
472 | 49 | using namespace std; | 47 | using namespace std; |
473 | 50 | 48 | ||
474 | @@ -1297,10 +1295,9 @@ | |||
475 | 1297 | const unsigned char *after_record) | 1295 | const unsigned char *after_record) |
476 | 1298 | { | 1296 | { |
477 | 1299 | TransactionServices &transaction_services= TransactionServices::singleton(); | 1297 | TransactionServices &transaction_services= TransactionServices::singleton(); |
478 | 1300 | ReplicationServices &replication_services= ReplicationServices::singleton(); | ||
479 | 1301 | Session *const session= table->in_use; | 1298 | Session *const session= table->in_use; |
480 | 1302 | 1299 | ||
482 | 1303 | if (table->s->tmp_table || not replication_services.isActive()) | 1300 | if (table->s->tmp_table || not transaction_services.shouldConstructMessages()) |
483 | 1304 | return false; | 1301 | return false; |
484 | 1305 | 1302 | ||
485 | 1306 | bool result= false; | 1303 | bool result= false; |
486 | 1307 | 1304 | ||
487 | === modified file 'drizzled/include.am' | |||
488 | --- drizzled/include.am 2010-04-02 07:45:12 +0000 | |||
489 | +++ drizzled/include.am 2010-04-06 19:16:34 +0000 | |||
490 | @@ -307,6 +307,7 @@ | |||
491 | 307 | drizzled/plugin/query_cache.h \ | 307 | drizzled/plugin/query_cache.h \ |
492 | 308 | drizzled/plugin/query_rewrite.h \ | 308 | drizzled/plugin/query_rewrite.h \ |
493 | 309 | drizzled/plugin/registry.h \ | 309 | drizzled/plugin/registry.h \ |
494 | 310 | drizzled/plugin/replication.h \ | ||
495 | 310 | drizzled/plugin/scheduler.h \ | 311 | drizzled/plugin/scheduler.h \ |
496 | 311 | drizzled/plugin/storage_engine.h \ | 312 | drizzled/plugin/storage_engine.h \ |
497 | 312 | drizzled/plugin/table_function.h \ | 313 | drizzled/plugin/table_function.h \ |
498 | 313 | 314 | ||
499 | === added file 'drizzled/plugin/replication.h' | |||
500 | --- drizzled/plugin/replication.h 1970-01-01 00:00:00 +0000 | |||
501 | +++ drizzled/plugin/replication.h 2010-04-06 19:16:34 +0000 | |||
502 | @@ -0,0 +1,46 @@ | |||
503 | 1 | /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
504 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
505 | 3 | * | ||
506 | 4 | * Copyright (c) 2010 Jay Pipes | ||
507 | 5 | * | ||
508 | 6 | * Authors: | ||
509 | 7 | * | ||
510 | 8 | * Jay Pipes <jaypipes@gmail.com> | ||
511 | 9 | * | ||
512 | 10 | * This program is free software; you can redistribute it and/or modify | ||
513 | 11 | * it under the terms of the GNU General Public License as published by | ||
514 | 12 | * the Free Software Foundation; version 2 of the License. | ||
515 | 13 | * | ||
516 | 14 | * This program is distributed in the hope that it will be useful, | ||
517 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
518 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
519 | 17 | * GNU General Public License for more details. | ||
520 | 18 | * | ||
521 | 19 | * You should have received a copy of the GNU General Public License | ||
522 | 20 | * along with this program; if not, write to the Free Software | ||
523 | 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
524 | 22 | */ | ||
525 | 23 | |||
526 | 24 | #ifndef DRIZZLED_PLUGIN_REPLICATION_H | ||
527 | 25 | #define DRIZZLED_PLUGIN_REPLICATION_H | ||
528 | 26 | |||
529 | 27 | /** | ||
530 | 28 | * @file Common structs and enums for the replication API | ||
531 | 29 | */ | ||
532 | 30 | |||
533 | 31 | namespace drizzled | ||
534 | 32 | { | ||
535 | 33 | |||
536 | 34 | namespace plugin | ||
537 | 35 | { | ||
538 | 36 | |||
539 | 37 | enum ReplicationReturnCode | ||
540 | 38 | { | ||
541 | 39 | SUCCESS= 0, /* no error */ | ||
542 | 40 | UNKNOWN_ERROR= 1 | ||
543 | 41 | }; | ||
544 | 42 | |||
545 | 43 | } /* namespace plugin */ | ||
546 | 44 | } /* namespace drizzled */ | ||
547 | 45 | |||
548 | 46 | #endif /* DRIZZLED_PLUGIN_REPLICATION_H */ | ||
549 | 0 | 47 | ||
550 | === modified file 'drizzled/plugin/transaction_applier.h' | |||
551 | --- drizzled/plugin/transaction_applier.h 2009-10-28 16:38:30 +0000 | |||
552 | +++ drizzled/plugin/transaction_applier.h 2010-04-06 19:16:34 +0000 | |||
553 | @@ -2,10 +2,11 @@ | |||
554 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
555 | 3 | * | 3 | * |
556 | 4 | * Copyright (C) 2008-2009 Sun Microsystems | 4 | * Copyright (C) 2008-2009 Sun Microsystems |
557 | 5 | * Copyright (c) 2010 Jay Pipes | ||
558 | 5 | * | 6 | * |
559 | 6 | * Authors: | 7 | * Authors: |
560 | 7 | * | 8 | * |
562 | 8 | * Jay Pipes <joinfu@sun.com> | 9 | * Jay Pipes <jaypipes@gmail.com> |
563 | 9 | * | 10 | * |
564 | 10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
565 | 11 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
566 | @@ -33,11 +34,14 @@ | |||
567 | 33 | */ | 34 | */ |
568 | 34 | 35 | ||
569 | 35 | #include "drizzled/plugin/plugin.h" | 36 | #include "drizzled/plugin/plugin.h" |
570 | 37 | #include "drizzled/plugin/replication.h" | ||
571 | 36 | #include "drizzled/atomics.h" | 38 | #include "drizzled/atomics.h" |
572 | 37 | 39 | ||
573 | 38 | namespace drizzled | 40 | namespace drizzled |
574 | 39 | { | 41 | { |
575 | 40 | 42 | ||
576 | 43 | class Session; | ||
577 | 44 | |||
578 | 41 | namespace message { class Transaction; } | 45 | namespace message { class Transaction; } |
579 | 42 | 46 | ||
580 | 43 | namespace plugin | 47 | namespace plugin |
581 | @@ -74,7 +78,8 @@ | |||
582 | 74 | * | 78 | * |
583 | 75 | * @param Transaction message to be replicated | 79 | * @param Transaction message to be replicated |
584 | 76 | */ | 80 | */ |
586 | 77 | virtual void apply(const message::Transaction &to_apply)= 0; | 81 | virtual ReplicationReturnCode apply(Session &in_session, |
587 | 82 | const message::Transaction &to_apply)= 0; | ||
588 | 78 | 83 | ||
589 | 79 | static bool addPlugin(TransactionApplier *applier); | 84 | static bool addPlugin(TransactionApplier *applier); |
590 | 80 | static void removePlugin(TransactionApplier *applier); | 85 | static void removePlugin(TransactionApplier *applier); |
591 | 81 | 86 | ||
592 | === modified file 'drizzled/plugin/transaction_replicator.h' | |||
593 | --- drizzled/plugin/transaction_replicator.h 2009-12-04 23:47:14 +0000 | |||
594 | +++ drizzled/plugin/transaction_replicator.h 2010-04-06 19:16:34 +0000 | |||
595 | @@ -2,10 +2,11 @@ | |||
596 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
597 | 3 | * | 3 | * |
598 | 4 | * Copyright (C) 2008-2009 Sun Microsystems | 4 | * Copyright (C) 2008-2009 Sun Microsystems |
599 | 5 | * Copyright (c) 2010 Jay Pipes | ||
600 | 5 | * | 6 | * |
601 | 6 | * Authors: | 7 | * Authors: |
602 | 7 | * | 8 | * |
604 | 8 | * Jay Pipes <joinfu@sun.com> | 9 | * Jay Pipes <jaypipes@gmail.com> |
605 | 9 | * | 10 | * |
606 | 10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
607 | 11 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
608 | @@ -25,6 +26,7 @@ | |||
609 | 25 | #define DRIZZLED_PLUGIN_TRANSACTION_REPLICATOR_H | 26 | #define DRIZZLED_PLUGIN_TRANSACTION_REPLICATOR_H |
610 | 26 | 27 | ||
611 | 27 | #include "drizzled/atomics.h" | 28 | #include "drizzled/atomics.h" |
612 | 29 | #include "drizzled/plugin/replication.h" | ||
613 | 28 | #include "drizzled/plugin/plugin.h" | 30 | #include "drizzled/plugin/plugin.h" |
614 | 29 | 31 | ||
615 | 30 | /** | 32 | /** |
616 | @@ -36,7 +38,6 @@ | |||
617 | 36 | * An applier is responsible for applying events, not a replicator... | 38 | * An applier is responsible for applying events, not a replicator... |
618 | 37 | */ | 39 | */ |
619 | 38 | 40 | ||
620 | 39 | |||
621 | 40 | namespace drizzled | 41 | namespace drizzled |
622 | 41 | { | 42 | { |
623 | 42 | namespace message | 43 | namespace message |
624 | @@ -45,6 +46,8 @@ | |||
625 | 45 | class Statement; | 46 | class Statement; |
626 | 46 | } | 47 | } |
627 | 47 | 48 | ||
628 | 49 | class Session; | ||
629 | 50 | |||
630 | 48 | namespace plugin | 51 | namespace plugin |
631 | 49 | { | 52 | { |
632 | 50 | 53 | ||
633 | @@ -83,8 +86,9 @@ | |||
634 | 83 | * @param Pointer to the applier of the command message | 86 | * @param Pointer to the applier of the command message |
635 | 84 | * @param Transaction message to be replicated | 87 | * @param Transaction message to be replicated |
636 | 85 | */ | 88 | */ |
639 | 86 | virtual void replicate(TransactionApplier *in_applier, | 89 | virtual ReplicationReturnCode replicate(TransactionApplier *in_applier, |
640 | 87 | message::Transaction &to_replicate)= 0; | 90 | Session &session, |
641 | 91 | message::Transaction &to_replicate)= 0; | ||
642 | 88 | static bool addPlugin(TransactionReplicator *replicator); | 92 | static bool addPlugin(TransactionReplicator *replicator); |
643 | 89 | static void removePlugin(TransactionReplicator *replicator); | 93 | static void removePlugin(TransactionReplicator *replicator); |
644 | 90 | 94 | ||
645 | 91 | 95 | ||
646 | === modified file 'drizzled/replication_services.cc' | |||
647 | --- drizzled/replication_services.cc 2010-03-17 03:11:34 +0000 | |||
648 | +++ drizzled/replication_services.cc 2010-04-06 19:16:34 +0000 | |||
649 | @@ -39,8 +39,6 @@ | |||
650 | 39 | #include "drizzled/plugin/transaction_replicator.h" | 39 | #include "drizzled/plugin/transaction_replicator.h" |
651 | 40 | #include "drizzled/plugin/transaction_applier.h" | 40 | #include "drizzled/plugin/transaction_applier.h" |
652 | 41 | #include "drizzled/message/transaction.pb.h" | 41 | #include "drizzled/message/transaction.pb.h" |
653 | 42 | #include "drizzled/message/table.pb.h" | ||
654 | 43 | #include "drizzled/message/statement_transform.h" | ||
655 | 44 | #include "drizzled/gettext.h" | 42 | #include "drizzled/gettext.h" |
656 | 45 | #include "drizzled/session.h" | 43 | #include "drizzled/session.h" |
657 | 46 | #include "drizzled/error.h" | 44 | #include "drizzled/error.h" |
658 | @@ -145,7 +143,8 @@ | |||
659 | 145 | return is_active; | 143 | return is_active; |
660 | 146 | } | 144 | } |
661 | 147 | 145 | ||
663 | 148 | void ReplicationServices::pushTransactionMessage(message::Transaction &to_push) | 146 | plugin::ReplicationReturnCode ReplicationServices::pushTransactionMessage(Session &in_session, |
664 | 147 | message::Transaction &to_push) | ||
665 | 149 | { | 148 | { |
666 | 150 | vector<plugin::TransactionReplicator *>::iterator repl_iter= replicators.begin(); | 149 | vector<plugin::TransactionReplicator *>::iterator repl_iter= replicators.begin(); |
667 | 151 | vector<plugin::TransactionApplier *>::iterator appl_start_iter, appl_iter; | 150 | vector<plugin::TransactionApplier *>::iterator appl_start_iter, appl_iter; |
668 | @@ -154,6 +153,8 @@ | |||
669 | 154 | plugin::TransactionReplicator *cur_repl; | 153 | plugin::TransactionReplicator *cur_repl; |
670 | 155 | plugin::TransactionApplier *cur_appl; | 154 | plugin::TransactionApplier *cur_appl; |
671 | 156 | 155 | ||
672 | 156 | plugin::ReplicationReturnCode result= plugin::SUCCESS; | ||
673 | 157 | |||
674 | 157 | while (repl_iter != replicators.end()) | 158 | while (repl_iter != replicators.end()) |
675 | 158 | { | 159 | { |
676 | 159 | cur_repl= *repl_iter; | 160 | cur_repl= *repl_iter; |
677 | @@ -174,19 +175,25 @@ | |||
678 | 174 | continue; | 175 | continue; |
679 | 175 | } | 176 | } |
680 | 176 | 177 | ||
691 | 177 | cur_repl->replicate(cur_appl, to_push); | 178 | result= cur_repl->replicate(cur_appl, in_session, to_push); |
692 | 178 | 179 | ||
693 | 179 | /* | 180 | if (result == plugin::SUCCESS) |
694 | 180 | * We update the timestamp for the last applied Transaction so that | 181 | { |
695 | 181 | * publisher plugins can ask the replication services when the | 182 | /* |
696 | 182 | * last known applied Transaction was using the getLastAppliedTimestamp() | 183 | * We update the timestamp for the last applied Transaction so that |
697 | 183 | * method. | 184 | * publisher plugins can ask the replication services when the |
698 | 184 | */ | 185 | * last known applied Transaction was using the getLastAppliedTimestamp() |
699 | 185 | last_applied_timestamp.fetch_and_store(to_push.transaction_context().end_timestamp()); | 186 | * method. |
700 | 186 | ++appl_iter; | 187 | */ |
701 | 188 | last_applied_timestamp.fetch_and_store(to_push.transaction_context().end_timestamp()); | ||
702 | 189 | ++appl_iter; | ||
703 | 190 | } | ||
704 | 191 | else | ||
705 | 192 | return result; | ||
706 | 187 | } | 193 | } |
707 | 188 | ++repl_iter; | 194 | ++repl_iter; |
708 | 189 | } | 195 | } |
709 | 196 | return result; | ||
710 | 190 | } | 197 | } |
711 | 191 | 198 | ||
712 | 192 | } /* namespace drizzled */ | 199 | } /* namespace drizzled */ |
713 | 193 | 200 | ||
714 | === modified file 'drizzled/replication_services.h' | |||
715 | --- drizzled/replication_services.h 2010-03-16 21:30:44 +0000 | |||
716 | +++ drizzled/replication_services.h 2010-04-06 19:16:34 +0000 | |||
717 | @@ -26,6 +26,7 @@ | |||
718 | 26 | #define DRIZZLED_REPLICATION_SERVICES_H | 26 | #define DRIZZLED_REPLICATION_SERVICES_H |
719 | 27 | 27 | ||
720 | 28 | #include "drizzled/atomics.h" | 28 | #include "drizzled/atomics.h" |
721 | 29 | #include "drizzled/plugin/replication.h" | ||
722 | 29 | 30 | ||
723 | 30 | #include <vector> | 31 | #include <vector> |
724 | 31 | 32 | ||
725 | @@ -96,9 +97,11 @@ | |||
726 | 96 | * Helper method which pushes a constructed message out to the registered | 97 | * Helper method which pushes a constructed message out to the registered |
727 | 97 | * replicator and applier plugins. | 98 | * replicator and applier plugins. |
728 | 98 | * | 99 | * |
729 | 100 | * @param Session descriptor | ||
730 | 99 | * @param Message to push out | 101 | * @param Message to push out |
731 | 100 | */ | 102 | */ |
733 | 101 | void pushTransactionMessage(message::Transaction &to_push); | 103 | plugin::ReplicationReturnCode pushTransactionMessage(Session &in_session, |
734 | 104 | message::Transaction &to_push); | ||
735 | 102 | /** | 105 | /** |
736 | 103 | * Constructor | 106 | * Constructor |
737 | 104 | */ | 107 | */ |
738 | 105 | 108 | ||
739 | === modified file 'drizzled/session.cc' | |||
740 | --- drizzled/session.cc 2010-03-31 22:22:16 +0000 | |||
741 | +++ drizzled/session.cc 2010-04-06 19:16:34 +0000 | |||
742 | @@ -369,7 +369,7 @@ | |||
743 | 369 | #endif | 369 | #endif |
744 | 370 | { | 370 | { |
745 | 371 | TransactionServices &transaction_services= TransactionServices::singleton(); | 371 | TransactionServices &transaction_services= TransactionServices::singleton(); |
747 | 372 | transaction_services.ha_rollback_trans(this, true); | 372 | transaction_services.rollbackTransaction(this, true); |
748 | 373 | xid_cache_delete(&transaction.xid_state); | 373 | xid_cache_delete(&transaction.xid_state); |
749 | 374 | } | 374 | } |
750 | 375 | hash_free(&user_vars); | 375 | hash_free(&user_vars); |
751 | @@ -772,7 +772,7 @@ | |||
752 | 772 | * (Which of course should never happen...) | 772 | * (Which of course should never happen...) |
753 | 773 | */ | 773 | */ |
754 | 774 | server_status&= ~SERVER_STATUS_IN_TRANS; | 774 | server_status&= ~SERVER_STATUS_IN_TRANS; |
756 | 775 | if (transaction_services.ha_commit_trans(this, true)) | 775 | if (transaction_services.commitTransaction(this, true)) |
757 | 776 | result= false; | 776 | result= false; |
758 | 777 | options&= ~(OPTION_BEGIN); | 777 | options&= ~(OPTION_BEGIN); |
759 | 778 | break; | 778 | break; |
760 | @@ -789,7 +789,7 @@ | |||
761 | 789 | case ROLLBACK_AND_CHAIN: | 789 | case ROLLBACK_AND_CHAIN: |
762 | 790 | { | 790 | { |
763 | 791 | server_status&= ~SERVER_STATUS_IN_TRANS; | 791 | server_status&= ~SERVER_STATUS_IN_TRANS; |
765 | 792 | if (transaction_services.ha_rollback_trans(this, true)) | 792 | if (transaction_services.rollbackTransaction(this, true)) |
766 | 793 | result= false; | 793 | result= false; |
767 | 794 | options&= ~(OPTION_BEGIN); | 794 | options&= ~(OPTION_BEGIN); |
768 | 795 | if (result == true && (completion == ROLLBACK_AND_CHAIN)) | 795 | if (result == true && (completion == ROLLBACK_AND_CHAIN)) |
769 | @@ -822,7 +822,7 @@ | |||
770 | 822 | if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) | 822 | if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) |
771 | 823 | { | 823 | { |
772 | 824 | server_status&= ~SERVER_STATUS_IN_TRANS; | 824 | server_status&= ~SERVER_STATUS_IN_TRANS; |
774 | 825 | if (transaction_services.ha_commit_trans(this, true)) | 825 | if (transaction_services.commitTransaction(this, true)) |
775 | 826 | result= false; | 826 | result= false; |
776 | 827 | } | 827 | } |
777 | 828 | options&= ~(OPTION_BEGIN); | 828 | options&= ~(OPTION_BEGIN); |
778 | @@ -1947,7 +1947,7 @@ | |||
779 | 1947 | { | 1947 | { |
780 | 1948 | TransactionServices &transaction_services= TransactionServices::singleton(); | 1948 | TransactionServices &transaction_services= TransactionServices::singleton(); |
781 | 1949 | main_da.can_overwrite_status= true; | 1949 | main_da.can_overwrite_status= true; |
783 | 1950 | transaction_services.ha_autocommit_or_rollback(this, is_error()); | 1950 | transaction_services.autocommitOrRollback(this, is_error()); |
784 | 1951 | main_da.can_overwrite_status= false; | 1951 | main_da.can_overwrite_status= false; |
785 | 1952 | transaction.stmt.reset(); | 1952 | transaction.stmt.reset(); |
786 | 1953 | } | 1953 | } |
787 | 1954 | 1954 | ||
788 | === modified file 'drizzled/set_var.cc' | |||
789 | --- drizzled/set_var.cc 2010-03-30 09:29:02 +0000 | |||
790 | +++ drizzled/set_var.cc 2010-04-06 19:16:34 +0000 | |||
791 | @@ -1381,7 +1381,7 @@ | |||
792 | 1381 | session->options&= ~(uint64_t) (OPTION_BEGIN); | 1381 | session->options&= ~(uint64_t) (OPTION_BEGIN); |
793 | 1382 | session->server_status|= SERVER_STATUS_AUTOCOMMIT; | 1382 | session->server_status|= SERVER_STATUS_AUTOCOMMIT; |
794 | 1383 | TransactionServices &transaction_services= TransactionServices::singleton(); | 1383 | TransactionServices &transaction_services= TransactionServices::singleton(); |
796 | 1384 | if (transaction_services.ha_commit_trans(session, true)) | 1384 | if (transaction_services.commitTransaction(session, true)) |
797 | 1385 | return 1; | 1385 | return 1; |
798 | 1386 | } | 1386 | } |
799 | 1387 | else | 1387 | else |
800 | 1388 | 1388 | ||
801 | === modified file 'drizzled/sql_delete.cc' | |||
802 | --- drizzled/sql_delete.cc 2010-02-06 03:22:59 +0000 | |||
803 | +++ drizzled/sql_delete.cc 2010-04-06 19:16:34 +0000 | |||
804 | @@ -396,7 +396,7 @@ | |||
805 | 396 | Safety, in case the engine ignored ha_enable_transaction(false) | 396 | Safety, in case the engine ignored ha_enable_transaction(false) |
806 | 397 | above. Also clears session->transaction.*. | 397 | above. Also clears session->transaction.*. |
807 | 398 | */ | 398 | */ |
809 | 399 | error= transaction_services.ha_autocommit_or_rollback(&session, error); | 399 | error= transaction_services.autocommitOrRollback(&session, error); |
810 | 400 | session.options= save_options; | 400 | session.options= save_options; |
811 | 401 | 401 | ||
812 | 402 | return error; | 402 | return error; |
813 | 403 | 403 | ||
814 | === modified file 'drizzled/sql_insert.cc' | |||
815 | --- drizzled/sql_insert.cc 2010-03-31 21:15:40 +0000 | |||
816 | +++ drizzled/sql_insert.cc 2010-04-06 19:16:34 +0000 | |||
817 | @@ -1325,7 +1325,7 @@ | |||
818 | 1325 | { | 1325 | { |
819 | 1326 | /* | 1326 | /* |
820 | 1327 | We must invalidate the table in the query cache before binlog writing | 1327 | We must invalidate the table in the query cache before binlog writing |
822 | 1328 | and ha_autocommit_or_rollback. | 1328 | and autocommitOrRollback. |
823 | 1329 | */ | 1329 | */ |
824 | 1330 | if (session->transaction.stmt.hasModifiedNonTransData()) | 1330 | if (session->transaction.stmt.hasModifiedNonTransData()) |
825 | 1331 | session->transaction.all.markModifiedNonTransData(); | 1331 | session->transaction.all.markModifiedNonTransData(); |
826 | @@ -1711,7 +1711,7 @@ | |||
827 | 1711 | if (!table->s->tmp_table) | 1711 | if (!table->s->tmp_table) |
828 | 1712 | { | 1712 | { |
829 | 1713 | TransactionServices &transaction_services= TransactionServices::singleton(); | 1713 | TransactionServices &transaction_services= TransactionServices::singleton(); |
831 | 1714 | transaction_services.ha_autocommit_or_rollback(session, 0); | 1714 | transaction_services.autocommitOrRollback(session, 0); |
832 | 1715 | (void) session->endActiveTransaction(); | 1715 | (void) session->endActiveTransaction(); |
833 | 1716 | } | 1716 | } |
834 | 1717 | 1717 | ||
835 | 1718 | 1718 | ||
836 | === modified file 'drizzled/sql_parse.cc' | |||
837 | --- drizzled/sql_parse.cc 2010-03-31 21:15:40 +0000 | |||
838 | +++ drizzled/sql_parse.cc 2010-04-06 19:16:34 +0000 | |||
839 | @@ -254,7 +254,7 @@ | |||
840 | 254 | /* If commit fails, we should be able to reset the OK status. */ | 254 | /* If commit fails, we should be able to reset the OK status. */ |
841 | 255 | session->main_da.can_overwrite_status= true; | 255 | session->main_da.can_overwrite_status= true; |
842 | 256 | TransactionServices &transaction_services= TransactionServices::singleton(); | 256 | TransactionServices &transaction_services= TransactionServices::singleton(); |
844 | 257 | transaction_services.ha_autocommit_or_rollback(session, session->is_error()); | 257 | transaction_services.autocommitOrRollback(session, session->is_error()); |
845 | 258 | session->main_da.can_overwrite_status= false; | 258 | session->main_da.can_overwrite_status= false; |
846 | 259 | 259 | ||
847 | 260 | session->transaction.stmt.reset(); | 260 | session->transaction.stmt.reset(); |
848 | 261 | 261 | ||
849 | === modified file 'drizzled/sql_table.cc' | |||
850 | --- drizzled/sql_table.cc 2010-03-31 21:15:40 +0000 | |||
851 | +++ drizzled/sql_table.cc 2010-04-06 19:16:34 +0000 | |||
852 | @@ -1829,7 +1829,7 @@ | |||
853 | 1829 | length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), | 1829 | length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), |
854 | 1830 | table_name); | 1830 | table_name); |
855 | 1831 | session->client->store(buff, length); | 1831 | session->client->store(buff, length); |
857 | 1832 | transaction_services.ha_autocommit_or_rollback(session, false); | 1832 | transaction_services.autocommitOrRollback(session, false); |
858 | 1833 | session->endTransaction(COMMIT); | 1833 | session->endTransaction(COMMIT); |
859 | 1834 | session->close_thread_tables(); | 1834 | session->close_thread_tables(); |
860 | 1835 | lex->reset_query_tables_list(false); | 1835 | lex->reset_query_tables_list(false); |
861 | @@ -1952,7 +1952,7 @@ | |||
862 | 1952 | } | 1952 | } |
863 | 1953 | } | 1953 | } |
864 | 1954 | } | 1954 | } |
866 | 1955 | transaction_services.ha_autocommit_or_rollback(session, false); | 1955 | transaction_services.autocommitOrRollback(session, false); |
867 | 1956 | session->endTransaction(COMMIT); | 1956 | session->endTransaction(COMMIT); |
868 | 1957 | session->close_thread_tables(); | 1957 | session->close_thread_tables(); |
869 | 1958 | table->table=0; // For query cache | 1958 | table->table=0; // For query cache |
870 | @@ -1964,7 +1964,7 @@ | |||
871 | 1964 | return(false); | 1964 | return(false); |
872 | 1965 | 1965 | ||
873 | 1966 | err: | 1966 | err: |
875 | 1967 | transaction_services.ha_autocommit_or_rollback(session, true); | 1967 | transaction_services.autocommitOrRollback(session, true); |
876 | 1968 | session->endTransaction(ROLLBACK); | 1968 | session->endTransaction(ROLLBACK); |
877 | 1969 | session->close_thread_tables(); // Shouldn't be needed | 1969 | session->close_thread_tables(); // Shouldn't be needed |
878 | 1970 | if (table) | 1970 | if (table) |
879 | 1971 | 1971 | ||
880 | === modified file 'drizzled/sql_update.cc' | |||
881 | --- drizzled/sql_update.cc 2010-03-26 21:33:42 +0000 | |||
882 | +++ drizzled/sql_update.cc 2010-04-06 19:16:34 +0000 | |||
883 | @@ -523,7 +523,7 @@ | |||
884 | 523 | last one without error. error > 0 means an error (e.g. unique key | 523 | last one without error. error > 0 means an error (e.g. unique key |
885 | 524 | violation and no IGNORE or REPLACE). error == 0 is also an error (if | 524 | violation and no IGNORE or REPLACE). error == 0 is also an error (if |
886 | 525 | preparing the record or invoking before triggers fails). See | 525 | preparing the record or invoking before triggers fails). See |
888 | 526 | ha_autocommit_or_rollback(error>=0) and return(error>=0) below. | 526 | autocommitOrRollback(error>=0) and return(error>=0) below. |
889 | 527 | Sometimes we want to binlog even if we updated no rows, in case user used | 527 | Sometimes we want to binlog even if we updated no rows, in case user used |
890 | 528 | it to be sure master and slave are in same state. | 528 | it to be sure master and slave are in same state. |
891 | 529 | */ | 529 | */ |
892 | 530 | 530 | ||
893 | === modified file 'drizzled/statement/alter_table.cc' | |||
894 | --- drizzled/statement/alter_table.cc 2010-03-31 22:22:16 +0000 | |||
895 | +++ drizzled/statement/alter_table.cc 2010-04-06 19:16:34 +0000 | |||
896 | @@ -619,7 +619,7 @@ | |||
897 | 619 | goto err; | 619 | goto err; |
898 | 620 | 620 | ||
899 | 621 | /* The ALTER Table is always in its own transaction */ | 621 | /* The ALTER Table is always in its own transaction */ |
901 | 622 | error= transaction_services.ha_autocommit_or_rollback(session, false); | 622 | error= transaction_services.autocommitOrRollback(session, false); |
902 | 623 | if (! session->endActiveTransaction()) | 623 | if (! session->endActiveTransaction()) |
903 | 624 | error=1; | 624 | error=1; |
904 | 625 | if (error) | 625 | if (error) |
905 | @@ -627,7 +627,7 @@ | |||
906 | 627 | write_bin_log(session, session->query.c_str()); | 627 | write_bin_log(session, session->query.c_str()); |
907 | 628 | 628 | ||
908 | 629 | err: | 629 | err: |
910 | 630 | (void) transaction_services.ha_autocommit_or_rollback(session, error); | 630 | (void) transaction_services.autocommitOrRollback(session, error); |
911 | 631 | session->tablespace_op=false; | 631 | session->tablespace_op=false; |
912 | 632 | 632 | ||
913 | 633 | if (error == 0) | 633 | if (error == 0) |
914 | @@ -1480,7 +1480,7 @@ | |||
915 | 1480 | Ensure that the new table is saved properly to disk so that we | 1480 | Ensure that the new table is saved properly to disk so that we |
916 | 1481 | can do a rename | 1481 | can do a rename |
917 | 1482 | */ | 1482 | */ |
919 | 1483 | if (transaction_services.ha_autocommit_or_rollback(session, false)) | 1483 | if (transaction_services.autocommitOrRollback(session, false)) |
920 | 1484 | error=1; | 1484 | error=1; |
921 | 1485 | if (! session->endActiveTransaction()) | 1485 | if (! session->endActiveTransaction()) |
922 | 1486 | error=1; | 1486 | error=1; |
923 | 1487 | 1487 | ||
924 | === modified file 'drizzled/statement/release_savepoint.cc' | |||
925 | --- drizzled/statement/release_savepoint.cc 2010-01-28 20:48:31 +0000 | |||
926 | +++ drizzled/statement/release_savepoint.cc 2010-04-06 19:16:34 +0000 | |||
927 | @@ -59,7 +59,7 @@ | |||
928 | 59 | if (iter != savepoints.end()) | 59 | if (iter != savepoints.end()) |
929 | 60 | { | 60 | { |
930 | 61 | NamedSavepoint &sv= *iter; | 61 | NamedSavepoint &sv= *iter; |
932 | 62 | (void) transaction_services.ha_release_savepoint(session, sv); | 62 | (void) transaction_services.releaseSavepoint(session, sv); |
933 | 63 | savepoints.erase(iter); | 63 | savepoints.erase(iter); |
934 | 64 | session->my_ok(); | 64 | session->my_ok(); |
935 | 65 | } | 65 | } |
936 | 66 | 66 | ||
937 | === modified file 'drizzled/statement/rollback_to_savepoint.cc' | |||
938 | --- drizzled/statement/rollback_to_savepoint.cc 2010-02-06 03:22:59 +0000 | |||
939 | +++ drizzled/statement/rollback_to_savepoint.cc 2010-04-06 19:16:34 +0000 | |||
940 | @@ -73,7 +73,7 @@ | |||
941 | 73 | first_savepoint_name.size()) == 0) | 73 | first_savepoint_name.size()) == 0) |
942 | 74 | { | 74 | { |
943 | 75 | /* Found the named savepoint we want to rollback to */ | 75 | /* Found the named savepoint we want to rollback to */ |
945 | 76 | (void) transaction_services.ha_rollback_to_savepoint(session, first_savepoint); | 76 | (void) transaction_services.rollbackToSavepoint(session, first_savepoint); |
946 | 77 | 77 | ||
947 | 78 | if (session->transaction.all.hasModifiedNonTransData()) | 78 | if (session->transaction.all.hasModifiedNonTransData()) |
948 | 79 | { | 79 | { |
949 | @@ -111,7 +111,7 @@ | |||
950 | 111 | /* Found the named savepoint we want to rollback to */ | 111 | /* Found the named savepoint we want to rollback to */ |
951 | 112 | found= true; | 112 | found= true; |
952 | 113 | 113 | ||
954 | 114 | (void) transaction_services.ha_rollback_to_savepoint(session, sv); | 114 | (void) transaction_services.rollbackToSavepoint(session, sv); |
955 | 115 | } | 115 | } |
956 | 116 | if (found) | 116 | if (found) |
957 | 117 | { | 117 | { |
958 | 118 | 118 | ||
959 | === modified file 'drizzled/statement/savepoint.cc' | |||
960 | --- drizzled/statement/savepoint.cc 2010-01-28 20:48:31 +0000 | |||
961 | +++ drizzled/statement/savepoint.cc 2010-04-06 19:16:34 +0000 | |||
962 | @@ -65,13 +65,13 @@ | |||
963 | 65 | if (iter != savepoints.end()) | 65 | if (iter != savepoints.end()) |
964 | 66 | { | 66 | { |
965 | 67 | NamedSavepoint &sv= *iter; | 67 | NamedSavepoint &sv= *iter; |
967 | 68 | (void) transaction_services.ha_release_savepoint(session, sv); | 68 | (void) transaction_services.releaseSavepoint(session, sv); |
968 | 69 | savepoints.erase(iter); | 69 | savepoints.erase(iter); |
969 | 70 | } | 70 | } |
970 | 71 | 71 | ||
971 | 72 | NamedSavepoint newsv(session->lex->ident.str, session->lex->ident.length); | 72 | NamedSavepoint newsv(session->lex->ident.str, session->lex->ident.length); |
972 | 73 | 73 | ||
974 | 74 | if (transaction_services.ha_savepoint(session, newsv)) | 74 | if (transaction_services.setSavepoint(session, newsv)) |
975 | 75 | { | 75 | { |
976 | 76 | return true; | 76 | return true; |
977 | 77 | } | 77 | } |
978 | 78 | 78 | ||
979 | === modified file 'drizzled/transaction_services.cc' | |||
980 | --- drizzled/transaction_services.cc 2010-03-17 03:11:34 +0000 | |||
981 | +++ drizzled/transaction_services.cc 2010-04-06 19:16:34 +0000 | |||
982 | @@ -427,65 +427,6 @@ | |||
983 | 427 | } | 427 | } |
984 | 428 | 428 | ||
985 | 429 | /** | 429 | /** |
986 | 430 | Check if we can skip the two-phase commit. | ||
987 | 431 | |||
988 | 432 | A helper function to evaluate if two-phase commit is mandatory. | ||
989 | 433 | As a side effect, propagates the read-only/read-write flags | ||
990 | 434 | of the statement transaction to its enclosing normal transaction. | ||
991 | 435 | |||
992 | 436 | @retval true we must run a two-phase commit. Returned | ||
993 | 437 | if we have at least two engines with read-write changes. | ||
994 | 438 | @retval false Don't need two-phase commit. Even if we have two | ||
995 | 439 | transactional engines, we can run two independent | ||
996 | 440 | commits if changes in one of the engines are read-only. | ||
997 | 441 | */ | ||
998 | 442 | static | ||
999 | 443 | bool | ||
1000 | 444 | ha_check_and_coalesce_trx_read_only(Session *session, | ||
1001 | 445 | TransactionContext::ResourceContexts &resource_contexts, | ||
1002 | 446 | bool normal_transaction) | ||
1003 | 447 | { | ||
1004 | 448 | /* The number of storage engines that have actual changes. */ | ||
1005 | 449 | unsigned num_resources_modified_data= 0; | ||
1006 | 450 | ResourceContext *resource_context; | ||
1007 | 451 | |||
1008 | 452 | for (TransactionContext::ResourceContexts::iterator it= resource_contexts.begin(); | ||
1009 | 453 | it != resource_contexts.end(); | ||
1010 | 454 | ++it) | ||
1011 | 455 | { | ||
1012 | 456 | resource_context= *it; | ||
1013 | 457 | if (resource_context->hasModifiedData()) | ||
1014 | 458 | ++num_resources_modified_data; | ||
1015 | 459 | |||
1016 | 460 | if (! normal_transaction) | ||
1017 | 461 | { | ||
1018 | 462 | ResourceContext *resource_context_normal= session->getResourceContext(resource_context->getMonitored(), true); | ||
1019 | 463 | assert(resource_context != resource_context_normal); | ||
1020 | 464 | /* | ||
1021 | 465 | Merge read-only/read-write information about statement | ||
1022 | 466 | transaction to its enclosing normal transaction. Do this | ||
1023 | 467 | only if in a real transaction -- that is, if we know | ||
1024 | 468 | that resource_context_all is registered in session->transaction.all. | ||
1025 | 469 | Since otherwise we only clutter the normal transaction flags. | ||
1026 | 470 | */ | ||
1027 | 471 | if (resource_context_normal->isStarted()) /* false if autocommit. */ | ||
1028 | 472 | resource_context_normal->coalesceWith(resource_context); | ||
1029 | 473 | } | ||
1030 | 474 | else if (num_resources_modified_data > 1) | ||
1031 | 475 | { | ||
1032 | 476 | /* | ||
1033 | 477 | It is a normal transaction, so we don't need to merge read/write | ||
1034 | 478 | information up, and the need for two-phase commit has been | ||
1035 | 479 | already established. Break the loop prematurely. | ||
1036 | 480 | */ | ||
1037 | 481 | break; | ||
1038 | 482 | } | ||
1039 | 483 | } | ||
1040 | 484 | return num_resources_modified_data > 1; | ||
1041 | 485 | } | ||
1042 | 486 | |||
1043 | 487 | |||
1044 | 488 | /** | ||
1045 | 489 | @retval | 430 | @retval |
1046 | 490 | 0 ok | 431 | 0 ok |
1047 | 491 | @retval | 432 | @retval |
1048 | @@ -499,7 +440,7 @@ | |||
1049 | 499 | stored functions or triggers. So we simply do nothing now. | 440 | stored functions or triggers. So we simply do nothing now. |
1050 | 500 | TODO: This should be fixed in later ( >= 5.1) releases. | 441 | TODO: This should be fixed in later ( >= 5.1) releases. |
1051 | 501 | */ | 442 | */ |
1053 | 502 | int TransactionServices::ha_commit_trans(Session *session, bool normal_transaction) | 443 | int TransactionServices::commitTransaction(Session *session, bool normal_transaction) |
1054 | 503 | { | 444 | { |
1055 | 504 | int error= 0, cookie= 0; | 445 | int error= 0, cookie= 0; |
1056 | 505 | /* | 446 | /* |
1057 | @@ -522,17 +463,18 @@ | |||
1058 | 522 | 463 | ||
1059 | 523 | if (resource_contexts.empty() == false) | 464 | if (resource_contexts.empty() == false) |
1060 | 524 | { | 465 | { |
1061 | 525 | bool must_2pc; | ||
1062 | 526 | |||
1063 | 527 | if (is_real_trans && wait_if_global_read_lock(session, 0, 0)) | 466 | if (is_real_trans && wait_if_global_read_lock(session, 0, 0)) |
1064 | 528 | { | 467 | { |
1066 | 529 | ha_rollback_trans(session, normal_transaction); | 468 | rollbackTransaction(session, normal_transaction); |
1067 | 530 | return 1; | 469 | return 1; |
1068 | 531 | } | 470 | } |
1069 | 532 | 471 | ||
1073 | 533 | must_2pc= ha_check_and_coalesce_trx_read_only(session, resource_contexts, normal_transaction); | 472 | /* |
1074 | 534 | 473 | * If replication is on, we do a PREPARE on the resource managers, push the | |
1075 | 535 | if (! trans->no_2pc && must_2pc) | 474 | * Transaction message across the replication stream, and then COMMIT if the |
1076 | 475 | * replication stream returned successfully. | ||
1077 | 476 | */ | ||
1078 | 477 | if (shouldConstructMessages()) | ||
1079 | 536 | { | 478 | { |
1080 | 537 | for (TransactionContext::ResourceContexts::iterator it= resource_contexts.begin(); | 479 | for (TransactionContext::ResourceContexts::iterator it= resource_contexts.begin(); |
1081 | 538 | it != resource_contexts.end() && ! error; | 480 | it != resource_contexts.end() && ! error; |
1082 | @@ -563,14 +505,22 @@ | |||
1083 | 563 | } | 505 | } |
1084 | 564 | } | 506 | } |
1085 | 565 | } | 507 | } |
1086 | 508 | if (error == 0 && is_real_trans) | ||
1087 | 509 | { | ||
1088 | 510 | /* | ||
1089 | 511 | * Push the constructed Transaction messages across to | ||
1090 | 512 | * replicators and appliers. | ||
1091 | 513 | */ | ||
1092 | 514 | error= commitTransactionMessage(session); | ||
1093 | 515 | } | ||
1094 | 566 | if (error) | 516 | if (error) |
1095 | 567 | { | 517 | { |
1097 | 568 | ha_rollback_trans(session, normal_transaction); | 518 | rollbackTransaction(session, normal_transaction); |
1098 | 569 | error= 1; | 519 | error= 1; |
1099 | 570 | goto end; | 520 | goto end; |
1100 | 571 | } | 521 | } |
1101 | 572 | } | 522 | } |
1103 | 573 | error= ha_commit_one_phase(session, normal_transaction) ? (cookie ? 2 : 1) : 0; | 523 | error= commitPhaseOne(session, normal_transaction) ? (cookie ? 2 : 1) : 0; |
1104 | 574 | end: | 524 | end: |
1105 | 575 | if (is_real_trans) | 525 | if (is_real_trans) |
1106 | 576 | start_waiting_global_read_lock(session); | 526 | start_waiting_global_read_lock(session); |
1107 | @@ -582,7 +532,7 @@ | |||
1108 | 582 | @note | 532 | @note |
1109 | 583 | This function does not care about global read lock. A caller should. | 533 | This function does not care about global read lock. A caller should. |
1110 | 584 | */ | 534 | */ |
1112 | 585 | int TransactionServices::ha_commit_one_phase(Session *session, bool normal_transaction) | 535 | int TransactionServices::commitPhaseOne(Session *session, bool normal_transaction) |
1113 | 586 | { | 536 | { |
1114 | 587 | int error=0; | 537 | int error=0; |
1115 | 588 | TransactionContext *trans= normal_transaction ? &session->transaction.all : &session->transaction.stmt; | 538 | TransactionContext *trans= normal_transaction ? &session->transaction.all : &session->transaction.stmt; |
1116 | @@ -638,21 +588,10 @@ | |||
1117 | 638 | } | 588 | } |
1118 | 639 | } | 589 | } |
1119 | 640 | trans->reset(); | 590 | trans->reset(); |
1120 | 641 | if (error == 0) | ||
1121 | 642 | { | ||
1122 | 643 | if (is_real_trans) | ||
1123 | 644 | { | ||
1124 | 645 | /* | ||
1125 | 646 | * We commit the normal transaction by finalizing the transaction message | ||
1126 | 647 | * and propogating the message to all registered replicators. | ||
1127 | 648 | */ | ||
1128 | 649 | commitTransactionMessage(session); | ||
1129 | 650 | } | ||
1130 | 651 | } | ||
1131 | 652 | return error; | 591 | return error; |
1132 | 653 | } | 592 | } |
1133 | 654 | 593 | ||
1135 | 655 | int TransactionServices::ha_rollback_trans(Session *session, bool normal_transaction) | 594 | int TransactionServices::rollbackTransaction(Session *session, bool normal_transaction) |
1136 | 656 | { | 595 | { |
1137 | 657 | int error= 0; | 596 | int error= 0; |
1138 | 658 | TransactionContext *trans= normal_transaction ? &session->transaction.all : &session->transaction.stmt; | 597 | TransactionContext *trans= normal_transaction ? &session->transaction.all : &session->transaction.stmt; |
1139 | @@ -751,20 +690,20 @@ | |||
1140 | 751 | the user has used LOCK TABLES then that mechanism does not know to do the | 690 | the user has used LOCK TABLES then that mechanism does not know to do the |
1141 | 752 | commit. | 691 | commit. |
1142 | 753 | */ | 692 | */ |
1144 | 754 | int TransactionServices::ha_autocommit_or_rollback(Session *session, int error) | 693 | int TransactionServices::autocommitOrRollback(Session *session, int error) |
1145 | 755 | { | 694 | { |
1146 | 756 | if (session->transaction.stmt.getResourceContexts().empty() == false) | 695 | if (session->transaction.stmt.getResourceContexts().empty() == false) |
1147 | 757 | { | 696 | { |
1148 | 758 | if (! error) | 697 | if (! error) |
1149 | 759 | { | 698 | { |
1151 | 760 | if (ha_commit_trans(session, false)) | 699 | if (commitTransaction(session, false)) |
1152 | 761 | error= 1; | 700 | error= 1; |
1153 | 762 | } | 701 | } |
1154 | 763 | else | 702 | else |
1155 | 764 | { | 703 | { |
1157 | 765 | (void) ha_rollback_trans(session, false); | 704 | (void) rollbackTransaction(session, false); |
1158 | 766 | if (session->transaction_rollback_request) | 705 | if (session->transaction_rollback_request) |
1160 | 767 | (void) ha_rollback_trans(session, true); | 706 | (void) rollbackTransaction(session, true); |
1161 | 768 | } | 707 | } |
1162 | 769 | 708 | ||
1163 | 770 | session->variables.tx_isolation= session->session_tx_isolation; | 709 | session->variables.tx_isolation= session->session_tx_isolation; |
1164 | @@ -772,51 +711,6 @@ | |||
1165 | 772 | return error; | 711 | return error; |
1166 | 773 | } | 712 | } |
1167 | 774 | 713 | ||
1168 | 775 | /** | ||
1169 | 776 | return the list of XID's to a client, the same way SHOW commands do. | ||
1170 | 777 | |||
1171 | 778 | @note | ||
1172 | 779 | I didn't find in XA specs that an RM cannot return the same XID twice, | ||
1173 | 780 | so mysql_xa_recover does not filter XID's to ensure uniqueness. | ||
1174 | 781 | It can be easily fixed later, if necessary. | ||
1175 | 782 | */ | ||
1176 | 783 | bool TransactionServices::mysql_xa_recover(Session *session) | ||
1177 | 784 | { | ||
1178 | 785 | List<Item> field_list; | ||
1179 | 786 | int i= 0; | ||
1180 | 787 | XID_STATE *xs; | ||
1181 | 788 | |||
1182 | 789 | field_list.push_back(new Item_int("formatID", 0, MY_INT32_NUM_DECIMAL_DIGITS)); | ||
1183 | 790 | field_list.push_back(new Item_int("gtrid_length", 0, MY_INT32_NUM_DECIMAL_DIGITS)); | ||
1184 | 791 | field_list.push_back(new Item_int("bqual_length", 0, MY_INT32_NUM_DECIMAL_DIGITS)); | ||
1185 | 792 | field_list.push_back(new Item_empty_string("data", DRIZZLE_XIDDATASIZE)); | ||
1186 | 793 | |||
1187 | 794 | if (session->client->sendFields(&field_list)) | ||
1188 | 795 | return 1; | ||
1189 | 796 | |||
1190 | 797 | pthread_mutex_lock(&LOCK_xid_cache); | ||
1191 | 798 | while ((xs= (XID_STATE*)hash_element(&xid_cache, i++))) | ||
1192 | 799 | { | ||
1193 | 800 | if (xs->xa_state==XA_PREPARED) | ||
1194 | 801 | { | ||
1195 | 802 | session->client->store((int64_t)xs->xid.formatID); | ||
1196 | 803 | session->client->store((int64_t)xs->xid.gtrid_length); | ||
1197 | 804 | session->client->store((int64_t)xs->xid.bqual_length); | ||
1198 | 805 | session->client->store(xs->xid.data, | ||
1199 | 806 | xs->xid.gtrid_length+xs->xid.bqual_length); | ||
1200 | 807 | if (session->client->flush()) | ||
1201 | 808 | { | ||
1202 | 809 | pthread_mutex_unlock(&LOCK_xid_cache); | ||
1203 | 810 | return 1; | ||
1204 | 811 | } | ||
1205 | 812 | } | ||
1206 | 813 | } | ||
1207 | 814 | |||
1208 | 815 | pthread_mutex_unlock(&LOCK_xid_cache); | ||
1209 | 816 | session->my_eof(); | ||
1210 | 817 | return 0; | ||
1211 | 818 | } | ||
1212 | 819 | |||
1213 | 820 | struct ResourceContextCompare : public std::binary_function<ResourceContext *, ResourceContext *, bool> | 714 | struct ResourceContextCompare : public std::binary_function<ResourceContext *, ResourceContext *, bool> |
1214 | 821 | { | 715 | { |
1215 | 822 | result_type operator()(const ResourceContext *lhs, const ResourceContext *rhs) const | 716 | result_type operator()(const ResourceContext *lhs, const ResourceContext *rhs) const |
1216 | @@ -827,7 +721,7 @@ | |||
1217 | 827 | } | 721 | } |
1218 | 828 | }; | 722 | }; |
1219 | 829 | 723 | ||
1221 | 830 | int TransactionServices::ha_rollback_to_savepoint(Session *session, NamedSavepoint &sv) | 724 | int TransactionServices::rollbackToSavepoint(Session *session, NamedSavepoint &sv) |
1222 | 831 | { | 725 | { |
1223 | 832 | int error= 0; | 726 | int error= 0; |
1224 | 833 | TransactionContext *trans= &session->transaction.all; | 727 | TransactionContext *trans= &session->transaction.all; |
1225 | @@ -923,7 +817,7 @@ | |||
1226 | 923 | section "4.33.4 SQL-statements and transaction states", | 817 | section "4.33.4 SQL-statements and transaction states", |
1227 | 924 | NamedSavepoint is *not* transaction-initiating SQL-statement | 818 | NamedSavepoint is *not* transaction-initiating SQL-statement |
1228 | 925 | */ | 819 | */ |
1230 | 926 | int TransactionServices::ha_savepoint(Session *session, NamedSavepoint &sv) | 820 | int TransactionServices::setSavepoint(Session *session, NamedSavepoint &sv) |
1231 | 927 | { | 821 | { |
1232 | 928 | int error= 0; | 822 | int error= 0; |
1233 | 929 | TransactionContext *trans= &session->transaction.all; | 823 | TransactionContext *trans= &session->transaction.all; |
1234 | @@ -961,7 +855,7 @@ | |||
1235 | 961 | return error; | 855 | return error; |
1236 | 962 | } | 856 | } |
1237 | 963 | 857 | ||
1239 | 964 | int TransactionServices::ha_release_savepoint(Session *session, NamedSavepoint &sv) | 858 | int TransactionServices::releaseSavepoint(Session *session, NamedSavepoint &sv) |
1240 | 965 | { | 859 | { |
1241 | 966 | int error= 0; | 860 | int error= 0; |
1242 | 967 | 861 | ||
1243 | @@ -988,6 +882,12 @@ | |||
1244 | 988 | return error; | 882 | return error; |
1245 | 989 | } | 883 | } |
1246 | 990 | 884 | ||
1247 | 885 | bool TransactionServices::shouldConstructMessages() | ||
1248 | 886 | { | ||
1249 | 887 | ReplicationServices &replication_services= ReplicationServices::singleton(); | ||
1250 | 888 | return replication_services.isActive(); | ||
1251 | 889 | } | ||
1252 | 890 | |||
1253 | 991 | message::Transaction *TransactionServices::getActiveTransactionMessage(Session *in_session) | 891 | message::Transaction *TransactionServices::getActiveTransactionMessage(Session *in_session) |
1254 | 992 | { | 892 | { |
1255 | 993 | message::Transaction *transaction= in_session->getTransactionMessage(); | 893 | message::Transaction *transaction= in_session->getTransactionMessage(); |
1256 | @@ -1013,7 +913,7 @@ | |||
1257 | 1013 | { | 913 | { |
1258 | 1014 | message::TransactionContext *trx= in_transaction.mutable_transaction_context(); | 914 | message::TransactionContext *trx= in_transaction.mutable_transaction_context(); |
1259 | 1015 | trx->set_server_id(in_session->getServerId()); | 915 | trx->set_server_id(in_session->getServerId()); |
1261 | 1016 | trx->set_transaction_id(in_session->getQueryId()); | 916 | trx->set_transaction_id(getNextTransactionId()); |
1262 | 1017 | trx->set_start_timestamp(in_session->getCurrentTimestamp()); | 917 | trx->set_start_timestamp(in_session->getCurrentTimestamp()); |
1263 | 1018 | } | 918 | } |
1264 | 1019 | 919 | ||
1265 | @@ -1032,11 +932,11 @@ | |||
1266 | 1032 | in_session->setTransactionMessage(NULL); | 932 | in_session->setTransactionMessage(NULL); |
1267 | 1033 | } | 933 | } |
1268 | 1034 | 934 | ||
1270 | 1035 | void TransactionServices::commitTransactionMessage(Session *in_session) | 935 | int TransactionServices::commitTransactionMessage(Session *in_session) |
1271 | 1036 | { | 936 | { |
1272 | 1037 | ReplicationServices &replication_services= ReplicationServices::singleton(); | 937 | ReplicationServices &replication_services= ReplicationServices::singleton(); |
1273 | 1038 | if (! replication_services.isActive()) | 938 | if (! replication_services.isActive()) |
1275 | 1039 | return; | 939 | return 0; |
1276 | 1040 | 940 | ||
1277 | 1041 | /* If there is an active statement message, finalize it */ | 941 | /* If there is an active statement message, finalize it */ |
1278 | 1042 | message::Statement *statement= in_session->getStatementMessage(); | 942 | message::Statement *statement= in_session->getStatementMessage(); |
1279 | @@ -1046,15 +946,17 @@ | |||
1280 | 1046 | finalizeStatementMessage(*statement, in_session); | 946 | finalizeStatementMessage(*statement, in_session); |
1281 | 1047 | } | 947 | } |
1282 | 1048 | else | 948 | else |
1284 | 1049 | return; /* No data modification occurred inside the transaction */ | 949 | return 0; /* No data modification occurred inside the transaction */ |
1285 | 1050 | 950 | ||
1286 | 1051 | message::Transaction* transaction= getActiveTransactionMessage(in_session); | 951 | message::Transaction* transaction= getActiveTransactionMessage(in_session); |
1287 | 1052 | 952 | ||
1288 | 1053 | finalizeTransactionMessage(*transaction, in_session); | 953 | finalizeTransactionMessage(*transaction, in_session); |
1289 | 1054 | 954 | ||
1291 | 1055 | replication_services.pushTransactionMessage(*transaction); | 955 | plugin::ReplicationReturnCode result= replication_services.pushTransactionMessage(*in_session, *transaction); |
1292 | 1056 | 956 | ||
1293 | 1057 | cleanupTransactionMessage(transaction, in_session); | 957 | cleanupTransactionMessage(transaction, in_session); |
1294 | 958 | |||
1295 | 959 | return static_cast<int>(result); | ||
1296 | 1058 | } | 960 | } |
1297 | 1059 | 961 | ||
1298 | 1060 | void TransactionServices::initStatementMessage(message::Statement &statement, | 962 | void TransactionServices::initStatementMessage(message::Statement &statement, |
1299 | @@ -1114,7 +1016,7 @@ | |||
1300 | 1114 | 1016 | ||
1301 | 1115 | finalizeTransactionMessage(*transaction, in_session); | 1017 | finalizeTransactionMessage(*transaction, in_session); |
1302 | 1116 | 1018 | ||
1304 | 1117 | replication_services.pushTransactionMessage(*transaction); | 1019 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1305 | 1118 | } | 1020 | } |
1306 | 1119 | cleanupTransactionMessage(transaction, in_session); | 1021 | cleanupTransactionMessage(transaction, in_session); |
1307 | 1120 | } | 1022 | } |
1308 | @@ -1552,7 +1454,7 @@ | |||
1309 | 1552 | 1454 | ||
1310 | 1553 | finalizeTransactionMessage(*transaction, in_session); | 1455 | finalizeTransactionMessage(*transaction, in_session); |
1311 | 1554 | 1456 | ||
1313 | 1555 | replication_services.pushTransactionMessage(*transaction); | 1457 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1314 | 1556 | 1458 | ||
1315 | 1557 | cleanupTransactionMessage(transaction, in_session); | 1459 | cleanupTransactionMessage(transaction, in_session); |
1316 | 1558 | 1460 | ||
1317 | @@ -1582,7 +1484,7 @@ | |||
1318 | 1582 | 1484 | ||
1319 | 1583 | finalizeTransactionMessage(*transaction, in_session); | 1485 | finalizeTransactionMessage(*transaction, in_session); |
1320 | 1584 | 1486 | ||
1322 | 1585 | replication_services.pushTransactionMessage(*transaction); | 1487 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1323 | 1586 | 1488 | ||
1324 | 1587 | cleanupTransactionMessage(transaction, in_session); | 1489 | cleanupTransactionMessage(transaction, in_session); |
1325 | 1588 | 1490 | ||
1326 | @@ -1611,7 +1513,7 @@ | |||
1327 | 1611 | 1513 | ||
1328 | 1612 | finalizeTransactionMessage(*transaction, in_session); | 1514 | finalizeTransactionMessage(*transaction, in_session); |
1329 | 1613 | 1515 | ||
1331 | 1614 | replication_services.pushTransactionMessage(*transaction); | 1516 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1332 | 1615 | 1517 | ||
1333 | 1616 | cleanupTransactionMessage(transaction, in_session); | 1518 | cleanupTransactionMessage(transaction, in_session); |
1334 | 1617 | } | 1519 | } |
1335 | @@ -1647,7 +1549,7 @@ | |||
1336 | 1647 | 1549 | ||
1337 | 1648 | finalizeTransactionMessage(*transaction, in_session); | 1550 | finalizeTransactionMessage(*transaction, in_session); |
1338 | 1649 | 1551 | ||
1340 | 1650 | replication_services.pushTransactionMessage(*transaction); | 1552 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1341 | 1651 | 1553 | ||
1342 | 1652 | cleanupTransactionMessage(transaction, in_session); | 1554 | cleanupTransactionMessage(transaction, in_session); |
1343 | 1653 | } | 1555 | } |
1344 | @@ -1682,7 +1584,7 @@ | |||
1345 | 1682 | 1584 | ||
1346 | 1683 | finalizeTransactionMessage(*transaction, in_session); | 1585 | finalizeTransactionMessage(*transaction, in_session); |
1347 | 1684 | 1586 | ||
1349 | 1685 | replication_services.pushTransactionMessage(*transaction); | 1587 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1350 | 1686 | 1588 | ||
1351 | 1687 | cleanupTransactionMessage(transaction, in_session); | 1589 | cleanupTransactionMessage(transaction, in_session); |
1352 | 1688 | } | 1590 | } |
1353 | @@ -1702,7 +1604,7 @@ | |||
1354 | 1702 | 1604 | ||
1355 | 1703 | finalizeTransactionMessage(*transaction, in_session); | 1605 | finalizeTransactionMessage(*transaction, in_session); |
1356 | 1704 | 1606 | ||
1358 | 1705 | replication_services.pushTransactionMessage(*transaction); | 1607 | (void) replication_services.pushTransactionMessage(*in_session, *transaction); |
1359 | 1706 | 1608 | ||
1360 | 1707 | cleanupTransactionMessage(transaction, in_session); | 1609 | cleanupTransactionMessage(transaction, in_session); |
1361 | 1708 | } | 1610 | } |
1362 | 1709 | 1611 | ||
1363 | === modified file 'drizzled/transaction_services.h' | |||
1364 | --- drizzled/transaction_services.h 2010-03-16 21:30:44 +0000 | |||
1365 | +++ drizzled/transaction_services.h 2010-04-06 19:16:34 +0000 | |||
1366 | @@ -25,6 +25,7 @@ | |||
1367 | 25 | #ifndef DRIZZLED_TRANSACTION_SERVICES_H | 25 | #ifndef DRIZZLED_TRANSACTION_SERVICES_H |
1368 | 26 | #define DRIZZLED_TRANSACTION_SERVICES_H | 26 | #define DRIZZLED_TRANSACTION_SERVICES_H |
1369 | 27 | 27 | ||
1370 | 28 | #include "drizzled/atomics.h" | ||
1371 | 28 | #include "drizzled/message/transaction.pb.h" | 29 | #include "drizzled/message/transaction.pb.h" |
1372 | 29 | 30 | ||
1373 | 30 | namespace drizzled | 31 | namespace drizzled |
1374 | @@ -49,10 +50,17 @@ | |||
1375 | 49 | { | 50 | { |
1376 | 50 | public: | 51 | public: |
1377 | 51 | static const size_t DEFAULT_RECORD_SIZE= 100; | 52 | static const size_t DEFAULT_RECORD_SIZE= 100; |
1378 | 53 | typedef uint64_t TransactionId; | ||
1379 | 52 | /** | 54 | /** |
1380 | 53 | * Constructor | 55 | * Constructor |
1381 | 54 | */ | 56 | */ |
1383 | 55 | TransactionServices() {} | 57 | TransactionServices() |
1384 | 58 | { | ||
1385 | 59 | /** | ||
1386 | 60 | * @todo set transaction ID to the last one from an applier... | ||
1387 | 61 | */ | ||
1388 | 62 | current_transaction_id= 0; | ||
1389 | 63 | } | ||
1390 | 56 | 64 | ||
1391 | 57 | /** | 65 | /** |
1392 | 58 | * Singleton method | 66 | * Singleton method |
1393 | @@ -63,6 +71,12 @@ | |||
1394 | 63 | static TransactionServices transaction_services; | 71 | static TransactionServices transaction_services; |
1395 | 64 | return transaction_services; | 72 | return transaction_services; |
1396 | 65 | } | 73 | } |
1397 | 74 | |||
1398 | 75 | /** | ||
1399 | 76 | * Returns true if the transaction manager should construct | ||
1400 | 77 | * Transaction and Statement messages, false otherwise. | ||
1401 | 78 | */ | ||
1402 | 79 | bool shouldConstructMessages(); | ||
1403 | 66 | /** | 80 | /** |
1404 | 67 | * Method which returns the active Transaction message | 81 | * Method which returns the active Transaction message |
1405 | 68 | * for the supplied Session. If one is not found, a new Transaction | 82 | * for the supplied Session. If one is not found, a new Transaction |
1406 | @@ -189,7 +203,7 @@ | |||
1407 | 189 | * | 203 | * |
1408 | 190 | * @param Pointer to the Session committing the transaction | 204 | * @param Pointer to the Session committing the transaction |
1409 | 191 | */ | 205 | */ |
1411 | 192 | void commitTransactionMessage(Session *in_session); | 206 | int commitTransactionMessage(Session *in_session); |
1412 | 193 | /** | 207 | /** |
1413 | 194 | * Marks the current active transaction message as being rolled back and | 208 | * Marks the current active transaction message as being rolled back and |
1414 | 195 | * pushes the transaction message out to replicators. | 209 | * pushes the transaction message out to replicators. |
1415 | @@ -293,18 +307,17 @@ | |||
1416 | 293 | */ | 307 | */ |
1417 | 294 | void rawStatement(Session *in_session, const std::string &query); | 308 | void rawStatement(Session *in_session, const std::string &query); |
1418 | 295 | /* transactions: interface to plugin::StorageEngine functions */ | 309 | /* transactions: interface to plugin::StorageEngine functions */ |
1421 | 296 | int ha_commit_one_phase(Session *session, bool all); | 310 | int commitPhaseOne(Session *session, bool all); |
1422 | 297 | int ha_rollback_trans(Session *session, bool all); | 311 | int rollbackTransaction(Session *session, bool all); |
1423 | 298 | 312 | ||
1424 | 299 | /* transactions: these functions never call plugin::StorageEngine functions directly */ | 313 | /* transactions: these functions never call plugin::StorageEngine functions directly */ |
1427 | 300 | int ha_commit_trans(Session *session, bool all); | 314 | int commitTransaction(Session *session, bool all); |
1428 | 301 | int ha_autocommit_or_rollback(Session *session, int error); | 315 | int autocommitOrRollback(Session *session, int error); |
1429 | 302 | 316 | ||
1430 | 303 | /* savepoints */ | 317 | /* savepoints */ |
1435 | 304 | int ha_rollback_to_savepoint(Session *session, NamedSavepoint &sv); | 318 | int rollbackToSavepoint(Session *session, NamedSavepoint &sv); |
1436 | 305 | int ha_savepoint(Session *session, NamedSavepoint &sv); | 319 | int setSavepoint(Session *session, NamedSavepoint &sv); |
1437 | 306 | int ha_release_savepoint(Session *session, NamedSavepoint &sv); | 320 | int releaseSavepoint(Session *session, NamedSavepoint &sv); |
1434 | 307 | bool mysql_xa_recover(Session *session); | ||
1438 | 308 | 321 | ||
1439 | 309 | /** | 322 | /** |
1440 | 310 | * Marks a storage engine as participating in a statement | 323 | * Marks a storage engine as participating in a statement |
1441 | @@ -383,6 +396,23 @@ | |||
1442 | 383 | plugin::MonitoredInTransaction *monitored, | 396 | plugin::MonitoredInTransaction *monitored, |
1443 | 384 | plugin::TransactionalStorageEngine *engine, | 397 | plugin::TransactionalStorageEngine *engine, |
1444 | 385 | plugin::XaResourceManager *resource_manager); | 398 | plugin::XaResourceManager *resource_manager); |
1445 | 399 | TransactionId getNextTransactionId() | ||
1446 | 400 | { | ||
1447 | 401 | return current_transaction_id.increment(); | ||
1448 | 402 | } | ||
1449 | 403 | TransactionId getCurrentTransactionId() | ||
1450 | 404 | { | ||
1451 | 405 | return current_transaction_id; | ||
1452 | 406 | } | ||
1453 | 407 | /** | ||
1454 | 408 | * DEBUG ONLY. See plugin::TransactionLog::truncate() | ||
1455 | 409 | */ | ||
1456 | 410 | void resetTransactionId() | ||
1457 | 411 | { | ||
1458 | 412 | current_transaction_id= 0; | ||
1459 | 413 | } | ||
1460 | 414 | private: | ||
1461 | 415 | atomic<TransactionId> current_transaction_id; | ||
1462 | 386 | }; | 416 | }; |
1463 | 387 | 417 | ||
1464 | 388 | } /* namespace drizzled */ | 418 | } /* namespace drizzled */ |
1465 | 389 | 419 | ||
1466 | === modified file 'plugin/default_replicator/default_replicator.cc' | |||
1467 | --- plugin/default_replicator/default_replicator.cc 2010-03-06 02:08:13 +0000 | |||
1468 | +++ plugin/default_replicator/default_replicator.cc 2010-04-06 19:16:34 +0000 | |||
1469 | @@ -62,13 +62,16 @@ | |||
1470 | 62 | sysvar_default_replicator_enable= false; | 62 | sysvar_default_replicator_enable= false; |
1471 | 63 | } | 63 | } |
1472 | 64 | 64 | ||
1474 | 65 | void DefaultReplicator::replicate(plugin::TransactionApplier *in_applier, message::Transaction &to_replicate) | 65 | plugin::ReplicationReturnCode |
1475 | 66 | DefaultReplicator::replicate(plugin::TransactionApplier *in_applier, | ||
1476 | 67 | Session &in_session, | ||
1477 | 68 | message::Transaction &to_replicate) | ||
1478 | 66 | { | 69 | { |
1479 | 67 | /* | 70 | /* |
1480 | 68 | * We do absolutely nothing but call the applier's apply() method, passing | 71 | * We do absolutely nothing but call the applier's apply() method, passing |
1481 | 69 | * along the supplied Transaction. Yep, told you it was simple... | 72 | * along the supplied Transaction. Yep, told you it was simple... |
1482 | 70 | */ | 73 | */ |
1484 | 71 | in_applier->apply(to_replicate); | 74 | return in_applier->apply(in_session, to_replicate); |
1485 | 72 | } | 75 | } |
1486 | 73 | 76 | ||
1487 | 74 | static DefaultReplicator *default_replicator= NULL; /* The singleton replicator */ | 77 | static DefaultReplicator *default_replicator= NULL; /* The singleton replicator */ |
1488 | 75 | 78 | ||
1489 | === modified file 'plugin/default_replicator/default_replicator.h' | |||
1490 | --- plugin/default_replicator/default_replicator.h 2009-10-19 19:19:38 +0000 | |||
1491 | +++ plugin/default_replicator/default_replicator.h 2010-04-06 19:16:34 +0000 | |||
1492 | @@ -66,9 +66,14 @@ | |||
1493 | 66 | * the supplied message to their own controlled memory storage | 66 | * the supplied message to their own controlled memory storage |
1494 | 67 | * area. | 67 | * area. |
1495 | 68 | * | 68 | * |
1496 | 69 | * @param Applier to replicate to | ||
1497 | 70 | * @param Session descriptor | ||
1498 | 69 | * @param Transaction message to be replicated | 71 | * @param Transaction message to be replicated |
1499 | 70 | */ | 72 | */ |
1501 | 71 | void replicate(drizzled::plugin::TransactionApplier *in_applier, drizzled::message::Transaction &to_replicate); | 73 | drizzled::plugin::ReplicationReturnCode |
1502 | 74 | replicate(drizzled::plugin::TransactionApplier *in_applier, | ||
1503 | 75 | drizzled::Session &in_session, | ||
1504 | 76 | drizzled::message::Transaction &to_replicate); | ||
1505 | 72 | 77 | ||
1506 | 73 | }; | 78 | }; |
1507 | 74 | 79 | ||
1508 | 75 | 80 | ||
1509 | === modified file 'plugin/filtered_replicator/filtered_replicator.cc' | |||
1510 | --- plugin/filtered_replicator/filtered_replicator.cc 2010-03-06 02:08:13 +0000 | |||
1511 | +++ plugin/filtered_replicator/filtered_replicator.cc 2010-04-06 19:16:34 +0000 | |||
1512 | @@ -214,8 +214,10 @@ | |||
1513 | 214 | sysvar_filtered_replicator_enabled= false; | 214 | sysvar_filtered_replicator_enabled= false; |
1514 | 215 | } | 215 | } |
1515 | 216 | 216 | ||
1518 | 217 | void FilteredReplicator::replicate(plugin::TransactionApplier *in_applier, | 217 | plugin::ReplicationReturnCode |
1519 | 218 | message::Transaction &to_replicate) | 218 | FilteredReplicator::replicate(plugin::TransactionApplier *in_applier, |
1520 | 219 | Session &in_session, | ||
1521 | 220 | message::Transaction &to_replicate) | ||
1522 | 219 | { | 221 | { |
1523 | 220 | string schema_name; | 222 | string schema_name; |
1524 | 221 | string table_name; | 223 | string table_name; |
1525 | @@ -287,8 +289,9 @@ | |||
1526 | 287 | */ | 289 | */ |
1527 | 288 | message::TransactionContext *tc= filtered_transaction.mutable_transaction_context(); | 290 | message::TransactionContext *tc= filtered_transaction.mutable_transaction_context(); |
1528 | 289 | *tc= to_replicate.transaction_context(); /* copy construct */ | 291 | *tc= to_replicate.transaction_context(); /* copy construct */ |
1530 | 290 | in_applier->apply(filtered_transaction); | 292 | return in_applier->apply(in_session, filtered_transaction); |
1531 | 291 | } | 293 | } |
1532 | 294 | return plugin::SUCCESS; | ||
1533 | 292 | } | 295 | } |
1534 | 293 | 296 | ||
1535 | 294 | void FilteredReplicator::populateFilter(std::string input, | 297 | void FilteredReplicator::populateFilter(std::string input, |
1536 | 295 | 298 | ||
1537 | === modified file 'plugin/filtered_replicator/filtered_replicator.h' | |||
1538 | --- plugin/filtered_replicator/filtered_replicator.h 2009-10-19 19:19:38 +0000 | |||
1539 | +++ plugin/filtered_replicator/filtered_replicator.h 2010-04-06 19:16:34 +0000 | |||
1540 | @@ -84,10 +84,14 @@ | |||
1541 | 84 | * the supplied message to their own controlled memory storage | 84 | * the supplied message to their own controlled memory storage |
1542 | 85 | * area. | 85 | * area. |
1543 | 86 | * | 86 | * |
1544 | 87 | * @param Applier to replicate to | ||
1545 | 88 | * @param Session descriptor | ||
1546 | 87 | * @param Transaction message to be replicated | 89 | * @param Transaction message to be replicated |
1547 | 88 | */ | 90 | */ |
1550 | 89 | void replicate(drizzled::plugin::TransactionApplier *in_applier, | 91 | drizzled::plugin::ReplicationReturnCode |
1551 | 90 | drizzled::message::Transaction &to_replicate); | 92 | replicate(drizzled::plugin::TransactionApplier *in_applier, |
1552 | 93 | drizzled::Session &in_session, | ||
1553 | 94 | drizzled::message::Transaction &to_replicate); | ||
1554 | 91 | 95 | ||
1555 | 92 | /** | 96 | /** |
1556 | 93 | * Populate the vector of schemas to filter from the | 97 | * Populate the vector of schemas to filter from the |
1557 | 94 | 98 | ||
1558 | === modified file 'plugin/innobase/handler/ha_innodb.cc' | |||
1559 | --- plugin/innobase/handler/ha_innodb.cc 2010-04-01 15:54:57 +0000 | |||
1560 | +++ plugin/innobase/handler/ha_innodb.cc 2010-04-06 19:16:34 +0000 | |||
1561 | @@ -2259,11 +2259,6 @@ | |||
1562 | 2259 | pthread_mutex_unlock(&commit_cond_m); | 2259 | pthread_mutex_unlock(&commit_cond_m); |
1563 | 2260 | } | 2260 | } |
1564 | 2261 | 2261 | ||
1565 | 2262 | if (trx->conc_state == TRX_PREPARED) { | ||
1566 | 2263 | |||
1567 | 2264 | pthread_mutex_unlock(&prepare_commit_mutex); | ||
1568 | 2265 | } | ||
1569 | 2266 | |||
1570 | 2267 | /* Now do a write + flush of logs. */ | 2262 | /* Now do a write + flush of logs. */ |
1571 | 2268 | trx_commit_complete_for_mysql(trx); | 2263 | trx_commit_complete_for_mysql(trx); |
1572 | 2269 | 2264 | ||
1573 | @@ -8150,31 +8145,6 @@ | |||
1574 | 8150 | 8145 | ||
1575 | 8151 | srv_active_wake_master_thread(); | 8146 | srv_active_wake_master_thread(); |
1576 | 8152 | 8147 | ||
1577 | 8153 | if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) | ||
1578 | 8154 | { | ||
1579 | 8155 | |||
1580 | 8156 | /* For ibbackup to work the order of transactions in binlog | ||
1581 | 8157 | and InnoDB must be the same. Consider the situation | ||
1582 | 8158 | |||
1583 | 8159 | thread1> prepare; write to binlog; ... | ||
1584 | 8160 | <context switch> | ||
1585 | 8161 | thread2> prepare; write to binlog; commit | ||
1586 | 8162 | thread1> ... commit | ||
1587 | 8163 | |||
1588 | 8164 | To ensure this will not happen we're taking the mutex on | ||
1589 | 8165 | prepare, and releasing it on commit. | ||
1590 | 8166 | |||
1591 | 8167 | Note: only do it for normal commits, done via ha_commit_trans. | ||
1592 | 8168 | If 2pc protocol is executed by external transaction | ||
1593 | 8169 | coordinator, it will be just a regular MySQL client | ||
1594 | 8170 | executing XA PREPARE and XA COMMIT commands. | ||
1595 | 8171 | In this case we cannot know how many minutes or hours | ||
1596 | 8172 | will be between XA PREPARE and XA COMMIT, and we don't want | ||
1597 | 8173 | to block for undefined period of time. | ||
1598 | 8174 | */ | ||
1599 | 8175 | pthread_mutex_lock(&prepare_commit_mutex); | ||
1600 | 8176 | trx->conc_state = TRX_PREPARED; | ||
1601 | 8177 | } | ||
1602 | 8178 | return(error); | 8148 | return(error); |
1603 | 8179 | } | 8149 | } |
1604 | 8180 | 8150 | ||
1605 | 8181 | 8151 | ||
1606 | === modified file 'plugin/transaction_log/module.cc' | |||
1607 | --- plugin/transaction_log/module.cc 2010-03-15 22:27:00 +0000 | |||
1608 | +++ plugin/transaction_log/module.cc 2010-04-06 19:16:34 +0000 | |||
1609 | @@ -61,6 +61,10 @@ | |||
1610 | 61 | * in truncating the log file. | 61 | * in truncating the log file. |
1611 | 62 | */ | 62 | */ |
1612 | 63 | static bool sysvar_transaction_log_truncate_debug= false; | 63 | static bool sysvar_transaction_log_truncate_debug= false; |
1613 | 64 | /** | ||
1614 | 65 | * The name of the main transaction log file on disk. With no prefix, | ||
1615 | 66 | * this goes into Drizzle's $datadir. | ||
1616 | 67 | */ | ||
1617 | 64 | static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */ | 68 | static const char DEFAULT_LOG_FILE_PATH[]= "transaction.log"; /* In datadir... */ |
1618 | 65 | /** | 69 | /** |
1619 | 66 | * Transaction Log plugin system variable - Should we write a CRC32 checksum for | 70 | * Transaction Log plugin system variable - Should we write a CRC32 checksum for |
1620 | @@ -76,6 +80,11 @@ | |||
1621 | 76 | * TransactionLog::SYNC_METHOD_EVERY_SECOND == 2 ... sync at most once a second | 80 | * TransactionLog::SYNC_METHOD_EVERY_SECOND == 2 ... sync at most once a second |
1622 | 77 | */ | 81 | */ |
1623 | 78 | static uint32_t sysvar_transaction_log_sync_method= 0; | 82 | static uint32_t sysvar_transaction_log_sync_method= 0; |
1624 | 83 | /** | ||
1625 | 84 | * Transaction Log plugin system variable - Number of slots to create | ||
1626 | 85 | * for managing write buffers | ||
1627 | 86 | */ | ||
1628 | 87 | static uint32_t sysvar_transaction_log_num_write_buffers= 8; | ||
1629 | 79 | 88 | ||
1630 | 80 | /** DATA_DICTIONARY views */ | 89 | /** DATA_DICTIONARY views */ |
1631 | 81 | static TransactionLogTool *transaction_log_tool; | 90 | static TransactionLogTool *transaction_log_tool; |
1632 | @@ -99,7 +108,8 @@ | |||
1633 | 99 | if (sysvar_transaction_log_enabled) | 108 | if (sysvar_transaction_log_enabled) |
1634 | 100 | { | 109 | { |
1635 | 101 | transaction_log= new (nothrow) TransactionLog(string(sysvar_transaction_log_file), | 110 | transaction_log= new (nothrow) TransactionLog(string(sysvar_transaction_log_file), |
1637 | 102 | sysvar_transaction_log_sync_method); | 111 | sysvar_transaction_log_sync_method, |
1638 | 112 | sysvar_transaction_log_checksum_enabled); | ||
1639 | 103 | 113 | ||
1640 | 104 | if (transaction_log == NULL) | 114 | if (transaction_log == NULL) |
1641 | 105 | { | 115 | { |
1642 | @@ -120,7 +130,7 @@ | |||
1643 | 120 | /* Create the applier plugin and register it */ | 130 | /* Create the applier plugin and register it */ |
1644 | 121 | transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier", | 131 | transaction_log_applier= new (nothrow) TransactionLogApplier("transaction_log_applier", |
1645 | 122 | *transaction_log, | 132 | *transaction_log, |
1647 | 123 | sysvar_transaction_log_checksum_enabled); | 133 | sysvar_transaction_log_num_write_buffers); |
1648 | 124 | if (transaction_log_applier == NULL) | 134 | if (transaction_log_applier == NULL) |
1649 | 125 | { | 135 | { |
1650 | 126 | errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogApplier instance. Got error: %s\n"), | 136 | errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the TransactionLogApplier instance. Got error: %s\n"), |
1651 | @@ -212,7 +222,7 @@ | |||
1652 | 212 | set_truncate_debug, /* update func */ | 222 | set_truncate_debug, /* update func */ |
1653 | 213 | false /* default */); | 223 | false /* default */); |
1654 | 214 | 224 | ||
1656 | 215 | static DRIZZLE_SYSVAR_STR(log_file, | 225 | static DRIZZLE_SYSVAR_STR(file, |
1657 | 216 | sysvar_transaction_log_file, | 226 | sysvar_transaction_log_file, |
1658 | 217 | PLUGIN_VAR_READONLY, | 227 | PLUGIN_VAR_READONLY, |
1659 | 218 | N_("Path to the file to use for transaction log"), | 228 | N_("Path to the file to use for transaction log"), |
1660 | @@ -241,12 +251,24 @@ | |||
1661 | 241 | 2, | 251 | 2, |
1662 | 242 | 0); | 252 | 0); |
1663 | 243 | 253 | ||
1664 | 254 | static DRIZZLE_SYSVAR_UINT(num_write_buffers, | ||
1665 | 255 | sysvar_transaction_log_num_write_buffers, | ||
1666 | 256 | PLUGIN_VAR_OPCMDARG, | ||
1667 | 257 | N_("Number of slots for in-memory write buffers (default=8)."), | ||
1668 | 258 | NULL, /* check func */ | ||
1669 | 259 | NULL, /* update func */ | ||
1670 | 260 | 8, /* default */ | ||
1671 | 261 | 4, | ||
1672 | 262 | 8192, | ||
1673 | 263 | 0); | ||
1674 | 264 | |||
1675 | 244 | static drizzle_sys_var* sys_variables[]= { | 265 | static drizzle_sys_var* sys_variables[]= { |
1676 | 245 | DRIZZLE_SYSVAR(enable), | 266 | DRIZZLE_SYSVAR(enable), |
1677 | 246 | DRIZZLE_SYSVAR(truncate_debug), | 267 | DRIZZLE_SYSVAR(truncate_debug), |
1679 | 247 | DRIZZLE_SYSVAR(log_file), | 268 | DRIZZLE_SYSVAR(file), |
1680 | 248 | DRIZZLE_SYSVAR(enable_checksum), | 269 | DRIZZLE_SYSVAR(enable_checksum), |
1681 | 249 | DRIZZLE_SYSVAR(sync_method), | 270 | DRIZZLE_SYSVAR(sync_method), |
1682 | 271 | DRIZZLE_SYSVAR(num_write_buffers), | ||
1683 | 250 | NULL | 272 | NULL |
1684 | 251 | }; | 273 | }; |
1685 | 252 | 274 | ||
1686 | 253 | 275 | ||
1687 | === modified file 'plugin/transaction_log/plugin.ini' | |||
1688 | --- plugin/transaction_log/plugin.ini 2010-03-05 18:08:49 +0000 | |||
1689 | +++ plugin/transaction_log/plugin.ini 2010-04-06 19:16:34 +0000 | |||
1690 | @@ -6,8 +6,8 @@ | |||
1691 | 6 | title=Transaction Log | 6 | title=Transaction Log |
1692 | 7 | description=Log of Transaction Messages | 7 | description=Log of Transaction Messages |
1693 | 8 | load_by_default=yes | 8 | load_by_default=yes |
1696 | 9 | sources= background_worker.cc hexdump_transaction_message.cc module.cc print_transaction_message.cc transaction_log.cc transaction_log_applier.cc transaction_log_entry.cc transaction_log_index.cc transaction_log_reader.cc data_dictionary_schema.cc | 9 | sources= background_worker.cc hexdump_transaction_message.cc module.cc print_transaction_message.cc transaction_log.cc transaction_log_applier.cc transaction_log_entry.cc transaction_log_index.cc transaction_log_reader.cc data_dictionary_schema.cc write_buffer.cc |
1697 | 10 | headers= background_worker.h hexdump_transaction_message.h print_transaction_message.h transaction_log.h transaction_log_applier.h transaction_log_entry.h transaction_log_index.h transaction_log_reader.h data_dictionary_schema.h | 10 | headers= background_worker.h hexdump_transaction_message.h print_transaction_message.h transaction_log.h transaction_log_applier.h transaction_log_entry.h transaction_log_index.h transaction_log_reader.h data_dictionary_schema.h write_buffer.h |
1698 | 11 | libs=${top_builddir}/drizzled/algorithm/libhash.la | 11 | libs=${top_builddir}/drizzled/algorithm/libhash.la |
1699 | 12 | libadd=$(LIBZ) | 12 | libadd=$(LIBZ) |
1700 | 13 | cxxflags=${PROTOSKIP_WARNINGS} | 13 | cxxflags=${PROTOSKIP_WARNINGS} |
1701 | 14 | 14 | ||
1702 | === added file 'plugin/transaction_log/tests/r/ddl_transaction_id.result' | |||
1703 | --- plugin/transaction_log/tests/r/ddl_transaction_id.result 1970-01-01 00:00:00 +0000 | |||
1704 | +++ plugin/transaction_log/tests/r/ddl_transaction_id.result 2010-04-06 19:16:34 +0000 | |||
1705 | @@ -0,0 +1,36 @@ | |||
1706 | 1 | SET GLOBAL transaction_log_truncate_debug= true; | ||
1707 | 2 | DROP TABLE IF EXISTS t1; | ||
1708 | 3 | CREATE TABLE t1 ( | ||
1709 | 4 | id INT NOT NULL PRIMARY KEY | ||
1710 | 5 | , padding VARCHAR(200) NOT NULL | ||
1711 | 6 | ); | ||
1712 | 7 | INSERT INTO t1 VALUES (1, "I love testing."); | ||
1713 | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); | ||
1714 | 9 | SELECT * FROM t1; | ||
1715 | 10 | id padding | ||
1716 | 11 | 1 I love testing. | ||
1717 | 12 | 2 I hate testing. | ||
1718 | 13 | ALTER TABLE t1 CHANGE COLUMN padding less_padding VARCHAR(180) NOT NULL; | ||
1719 | 14 | SELECT * FROM t1 WHERE id = 3; | ||
1720 | 15 | id less_padding | ||
1721 | 16 | DROP TABLE t1; | ||
1722 | 17 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; | ||
1723 | 18 | FILE_NAME FILE_LENGTH NUM_LOG_ENTRIES NUM_TRANSACTIONS MIN_TRANSACTION_ID MAX_TRANSACTION_ID MIN_END_TIMESTAMP MAX_END_TIMESTAMP INDEX_SIZE_IN_BYTES | ||
1724 | 19 | transaction.log X 6 6 1 6 X X X | ||
1725 | 20 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; | ||
1726 | 21 | ENTRY_OFFSET ENTRY_TYPE ENTRY_LENGTH | ||
1727 | 22 | X TRANSACTION X | ||
1728 | 23 | X TRANSACTION X | ||
1729 | 24 | X TRANSACTION X | ||
1730 | 25 | X TRANSACTION X | ||
1731 | 26 | X TRANSACTION X | ||
1732 | 27 | X TRANSACTION X | ||
1733 | 28 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; | ||
1734 | 29 | ENTRY_OFFSET TRANSACTION_ID SERVER_ID START_TIMESTAMP END_TIMESTAMP NUM_STATEMENTS CHECKSUM | ||
1735 | 30 | X 1 1 X X 1 0 | ||
1736 | 31 | X 2 1 X X 1 0 | ||
1737 | 32 | X 3 1 X X 1 0 | ||
1738 | 33 | X 4 1 X X 1 0 | ||
1739 | 34 | X 5 1 X X 1 0 | ||
1740 | 35 | X 6 1 X X 1 0 | ||
1741 | 36 | SET GLOBAL transaction_log_truncate_debug= true; | ||
1742 | 0 | 37 | ||
1743 | === modified file 'plugin/transaction_log/tests/r/filtered_replicator.result' | |||
1744 | --- plugin/transaction_log/tests/r/filtered_replicator.result 2010-02-27 23:47:33 +0000 | |||
1745 | +++ plugin/transaction_log/tests/r/filtered_replicator.result 2010-04-06 19:16:34 +0000 | |||
1746 | @@ -6,6 +6,7 @@ | |||
1747 | 6 | ); | 6 | ); |
1748 | 7 | INSERT INTO t1 VALUES (1, "I love testing."); | 7 | INSERT INTO t1 VALUES (1, "I love testing."); |
1749 | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1750 | 9 | DROP TABLE t1; | ||
1751 | 9 | DROP TABLE IF EXISTS t1; | 10 | DROP TABLE IF EXISTS t1; |
1752 | 10 | CREATE TABLE t1 ( | 11 | CREATE TABLE t1 ( |
1753 | 11 | id INT NOT NULL PRIMARY KEY | 12 | id INT NOT NULL PRIMARY KEY |
1754 | @@ -134,6 +135,9 @@ | |||
1755 | 134 | INSERT INTO `test`.`t1` (`id`,`padding`) VALUES (2,'I hate testing.'); | 135 | INSERT INTO `test`.`t1` (`id`,`padding`) VALUES (2,'I hate testing.'); |
1756 | 135 | COMMIT; | 136 | COMMIT; |
1757 | 136 | START TRANSACTION; | 137 | START TRANSACTION; |
1758 | 138 | DROP TABLE `test`.`t1`; | ||
1759 | 139 | COMMIT; | ||
1760 | 140 | START TRANSACTION; | ||
1761 | 137 | DROP TABLE IF EXISTS `test`.`t1`; | 141 | DROP TABLE IF EXISTS `test`.`t1`; |
1762 | 138 | COMMIT; | 142 | COMMIT; |
1763 | 139 | START TRANSACTION; | 143 | START TRANSACTION; |
1764 | 140 | 144 | ||
1765 | === modified file 'plugin/transaction_log/tests/r/information_schema.result' | |||
1766 | --- plugin/transaction_log/tests/r/information_schema.result 2010-03-05 04:44:58 +0000 | |||
1767 | +++ plugin/transaction_log/tests/r/information_schema.result 2010-04-06 19:16:34 +0000 | |||
1768 | @@ -6,19 +6,22 @@ | |||
1769 | 6 | ); | 6 | ); |
1770 | 7 | INSERT INTO t1 VALUES (1, "I love testing."); | 7 | INSERT INTO t1 VALUES (1, "I love testing."); |
1771 | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1772 | 9 | DROP TABLE t1; | ||
1773 | 9 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; | 10 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; |
1774 | 10 | FILE_NAME FILE_LENGTH NUM_LOG_ENTRIES NUM_TRANSACTIONS MIN_TRANSACTION_ID MAX_TRANSACTION_ID MIN_END_TIMESTAMP MAX_END_TIMESTAMP INDEX_SIZE_IN_BYTES | 11 | FILE_NAME FILE_LENGTH NUM_LOG_ENTRIES NUM_TRANSACTIONS MIN_TRANSACTION_ID MAX_TRANSACTION_ID MIN_END_TIMESTAMP MAX_END_TIMESTAMP INDEX_SIZE_IN_BYTES |
1776 | 11 | transaction.log X 4 4 X X X X X | 12 | transaction.log X 5 5 1 5 X X X |
1777 | 12 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; | 13 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; |
1778 | 13 | ENTRY_OFFSET ENTRY_TYPE ENTRY_LENGTH | 14 | ENTRY_OFFSET ENTRY_TYPE ENTRY_LENGTH |
1779 | 14 | X TRANSACTION X | 15 | X TRANSACTION X |
1780 | 15 | X TRANSACTION X | 16 | X TRANSACTION X |
1781 | 16 | X TRANSACTION X | 17 | X TRANSACTION X |
1782 | 17 | X TRANSACTION X | 18 | X TRANSACTION X |
1783 | 19 | X TRANSACTION X | ||
1784 | 18 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; | 20 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; |
1785 | 19 | ENTRY_OFFSET TRANSACTION_ID SERVER_ID START_TIMESTAMP END_TIMESTAMP NUM_STATEMENTS CHECKSUM | 21 | ENTRY_OFFSET TRANSACTION_ID SERVER_ID START_TIMESTAMP END_TIMESTAMP NUM_STATEMENTS CHECKSUM |
1790 | 20 | X X 1 X X 1 0 | 22 | X 1 1 X X 1 0 |
1791 | 21 | X X 1 X X 1 0 | 23 | X 2 1 X X 1 0 |
1792 | 22 | X X 1 X X 1 0 | 24 | X 3 1 X X 1 0 |
1793 | 23 | X X 1 X X 1 0 | 25 | X 4 1 X X 1 0 |
1794 | 26 | X 5 1 X X 1 0 | ||
1795 | 24 | SET GLOBAL transaction_log_truncate_debug= true; | 27 | SET GLOBAL transaction_log_truncate_debug= true; |
1796 | 25 | 28 | ||
1797 | === modified file 'plugin/transaction_log/tests/r/insert.result' | |||
1798 | --- plugin/transaction_log/tests/r/insert.result 2010-02-27 23:47:33 +0000 | |||
1799 | +++ plugin/transaction_log/tests/r/insert.result 2010-04-06 19:16:34 +0000 | |||
1800 | @@ -5,6 +5,7 @@ | |||
1801 | 5 | ); | 5 | ); |
1802 | 6 | INSERT INTO t1 VALUES (1, "I love testing."); | 6 | INSERT INTO t1 VALUES (1, "I love testing."); |
1803 | 7 | INSERT INTO t1 VALUES (2, "I hate testing."); | 7 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1804 | 8 | DROP TABLE t1; | ||
1805 | 8 | START TRANSACTION; | 9 | START TRANSACTION; |
1806 | 9 | DROP TABLE IF EXISTS `test`.`t1`; | 10 | DROP TABLE IF EXISTS `test`.`t1`; |
1807 | 10 | COMMIT; | 11 | COMMIT; |
1808 | @@ -17,4 +18,7 @@ | |||
1809 | 17 | START TRANSACTION; | 18 | START TRANSACTION; |
1810 | 18 | INSERT INTO `test`.`t1` (`id`,`padding`) VALUES (2,'I hate testing.'); | 19 | INSERT INTO `test`.`t1` (`id`,`padding`) VALUES (2,'I hate testing.'); |
1811 | 19 | COMMIT; | 20 | COMMIT; |
1812 | 21 | START TRANSACTION; | ||
1813 | 22 | DROP TABLE `test`.`t1`; | ||
1814 | 23 | COMMIT; | ||
1815 | 20 | SET GLOBAL transaction_log_truncate_debug= true; | 24 | SET GLOBAL transaction_log_truncate_debug= true; |
1816 | 21 | 25 | ||
1817 | === modified file 'plugin/transaction_log/tests/r/truncate_log.result' | |||
1818 | --- plugin/transaction_log/tests/r/truncate_log.result 2010-03-05 04:44:58 +0000 | |||
1819 | +++ plugin/transaction_log/tests/r/truncate_log.result 2010-04-06 19:16:34 +0000 | |||
1820 | @@ -6,6 +6,7 @@ | |||
1821 | 6 | ); | 6 | ); |
1822 | 7 | INSERT INTO t1 VALUES (1, "I love testing."); | 7 | INSERT INTO t1 VALUES (1, "I love testing."); |
1823 | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); | 8 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1825 | 9 | 24var/master-data/transaction.log | 9 | DROP TABLE t1; |
1826 | 10 | 29var/master-data/transaction.log | ||
1827 | 10 | SET GLOBAL transaction_log_truncate_debug= true; | 11 | SET GLOBAL transaction_log_truncate_debug= true; |
1828 | 11 | 0var/master-data/transaction.log | 12 | 0var/master-data/transaction.log |
1829 | 12 | 13 | ||
1830 | === modified file 'plugin/transaction_log/tests/r/udf_print_transaction_message.result' | |||
1831 | --- plugin/transaction_log/tests/r/udf_print_transaction_message.result 2010-02-11 04:18:03 +0000 | |||
1832 | +++ plugin/transaction_log/tests/r/udf_print_transaction_message.result 2010-04-06 19:16:34 +0000 | |||
1833 | @@ -5,6 +5,7 @@ | |||
1834 | 5 | ); | 5 | ); |
1835 | 6 | INSERT INTO t1 VALUES (1, "I love testing."); | 6 | INSERT INTO t1 VALUES (1, "I love testing."); |
1836 | 7 | INSERT INTO t1 VALUES (2, "I hate testing."); | 7 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1837 | 8 | DROP TABLE t1; | ||
1838 | 8 | SELECT LENGTH(PRINT_TRANSACTION_MESSAGE('transaction.log', ENTRY_OFFSET)) > 0 as checked | 9 | SELECT LENGTH(PRINT_TRANSACTION_MESSAGE('transaction.log', ENTRY_OFFSET)) > 0 as checked |
1839 | 9 | FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES | 10 | FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES |
1840 | 10 | LIMIT 1; | 11 | LIMIT 1; |
1841 | 11 | 12 | ||
1842 | === renamed file 'plugin/transaction_log/tests/r/sync_method_every_write.result' => 'plugin/transaction_log/tests/r/variables.result' | |||
1843 | --- plugin/transaction_log/tests/r/sync_method_every_write.result 2010-02-05 08:11:15 +0000 | |||
1844 | +++ plugin/transaction_log/tests/r/variables.result 2010-04-06 19:16:34 +0000 | |||
1845 | @@ -3,6 +3,7 @@ | |||
1846 | 3 | VARIABLE_NAME VARIABLE_VALUE | 3 | VARIABLE_NAME VARIABLE_VALUE |
1847 | 4 | transaction_log_enable ON | 4 | transaction_log_enable ON |
1848 | 5 | transaction_log_enable_checksum OFF | 5 | transaction_log_enable_checksum OFF |
1850 | 6 | transaction_log_log_file transaction.log | 6 | transaction_log_file transaction.log |
1851 | 7 | transaction_log_num_write_buffers 8 | ||
1852 | 7 | transaction_log_sync_method 1 | 8 | transaction_log_sync_method 1 |
1853 | 8 | transaction_log_truncate_debug OFF | 9 | transaction_log_truncate_debug OFF |
1854 | 9 | 10 | ||
1855 | === added file 'plugin/transaction_log/tests/t/ddl_transaction_id-master.opt' | |||
1856 | --- plugin/transaction_log/tests/t/ddl_transaction_id-master.opt 1970-01-01 00:00:00 +0000 | |||
1857 | +++ plugin/transaction_log/tests/t/ddl_transaction_id-master.opt 2010-04-06 19:16:34 +0000 | |||
1858 | @@ -0,0 +1,1 @@ | |||
1859 | 1 | --default-replicator-enable --transaction-log-enable --scheduler=multi_thread | ||
1860 | 0 | 2 | ||
1861 | === added file 'plugin/transaction_log/tests/t/ddl_transaction_id.inc' | |||
1862 | --- plugin/transaction_log/tests/t/ddl_transaction_id.inc 1970-01-01 00:00:00 +0000 | |||
1863 | +++ plugin/transaction_log/tests/t/ddl_transaction_id.inc 2010-04-06 19:16:34 +0000 | |||
1864 | @@ -0,0 +1,29 @@ | |||
1865 | 1 | # | ||
1866 | 2 | # Tests ordering of transaction ID, that SELECT queries | ||
1867 | 3 | # do not increment the transaction ID, and that the proper | ||
1868 | 4 | # generation of transaction IDs is done for DDL operations. | ||
1869 | 5 | # | ||
1870 | 6 | |||
1871 | 7 | --disable_warnings | ||
1872 | 8 | DROP TABLE IF EXISTS t1; | ||
1873 | 9 | --enable_warnings | ||
1874 | 10 | |||
1875 | 11 | CREATE TABLE t1 ( | ||
1876 | 12 | id INT NOT NULL PRIMARY KEY | ||
1877 | 13 | , padding VARCHAR(200) NOT NULL | ||
1878 | 14 | ); | ||
1879 | 15 | |||
1880 | 16 | INSERT INTO t1 VALUES (1, "I love testing."); | ||
1881 | 17 | INSERT INTO t1 VALUES (2, "I hate testing."); | ||
1882 | 18 | |||
1883 | 19 | SELECT * FROM t1; | ||
1884 | 20 | |||
1885 | 21 | ALTER TABLE t1 CHANGE COLUMN padding less_padding VARCHAR(180) NOT NULL; | ||
1886 | 22 | |||
1887 | 23 | # | ||
1888 | 24 | # Should be no result here... | ||
1889 | 25 | # | ||
1890 | 26 | |||
1891 | 27 | SELECT * FROM t1 WHERE id = 3; | ||
1892 | 28 | |||
1893 | 29 | DROP TABLE t1; | ||
1894 | 0 | 30 | ||
1895 | === added file 'plugin/transaction_log/tests/t/ddl_transaction_id.test' | |||
1896 | --- plugin/transaction_log/tests/t/ddl_transaction_id.test 1970-01-01 00:00:00 +0000 | |||
1897 | +++ plugin/transaction_log/tests/t/ddl_transaction_id.test 2010-04-06 19:16:34 +0000 | |||
1898 | @@ -0,0 +1,14 @@ | |||
1899 | 1 | # Truncate the log file to reset for the next test | ||
1900 | 2 | --source ../plugin/transaction_log/tests/t/truncate_log.inc | ||
1901 | 3 | |||
1902 | 4 | --source ../plugin/transaction_log/tests/t/ddl_transaction_id.inc | ||
1903 | 5 | |||
1904 | 6 | --replace_column 2 X 7 X 8 X 9 X | ||
1905 | 7 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; | ||
1906 | 8 | --replace_column 1 X 3 X | ||
1907 | 9 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; | ||
1908 | 10 | --replace_column 1 X 4 X 5 X | ||
1909 | 11 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; | ||
1910 | 12 | |||
1911 | 13 | # Truncate the log file to reset for the next test | ||
1912 | 14 | --source ../plugin/transaction_log/tests/t/truncate_log.inc | ||
1913 | 0 | 15 | ||
1914 | === modified file 'plugin/transaction_log/tests/t/information_schema.test' | |||
1915 | --- plugin/transaction_log/tests/t/information_schema.test 2010-03-05 04:44:58 +0000 | |||
1916 | +++ plugin/transaction_log/tests/t/information_schema.test 2010-04-06 19:16:34 +0000 | |||
1917 | @@ -13,11 +13,11 @@ | |||
1918 | 13 | # that the information contained in them matches | 13 | # that the information contained in them matches |
1919 | 14 | # the transaction log. | 14 | # the transaction log. |
1920 | 15 | 15 | ||
1922 | 16 | --replace_column 2 X 5 X 6 X 7 X 8 X 9 X | 16 | --replace_column 2 X 7 X 8 X 9 X |
1923 | 17 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; | 17 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG; |
1924 | 18 | --replace_column 1 X 3 X | 18 | --replace_column 1 X 3 X |
1925 | 19 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; | 19 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_ENTRIES; |
1927 | 20 | --replace_column 1 X 2 X 4 X 5 X | 20 | --replace_column 1 X 4 X 5 X |
1928 | 21 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; | 21 | SELECT * FROM DATA_DICTIONARY.TRANSACTION_LOG_TRANSACTIONS; |
1929 | 22 | 22 | ||
1930 | 23 | # Truncate the log file to reset for the next test | 23 | # Truncate the log file to reset for the next test |
1931 | 24 | 24 | ||
1932 | === modified file 'plugin/transaction_log/tests/t/insert.inc' | |||
1933 | --- plugin/transaction_log/tests/t/insert.inc 2009-12-11 19:08:29 +0000 | |||
1934 | +++ plugin/transaction_log/tests/t/insert.inc 2010-04-06 19:16:34 +0000 | |||
1935 | @@ -18,3 +18,5 @@ | |||
1936 | 18 | 18 | ||
1937 | 19 | INSERT INTO t1 VALUES (1, "I love testing."); | 19 | INSERT INTO t1 VALUES (1, "I love testing."); |
1938 | 20 | INSERT INTO t1 VALUES (2, "I hate testing."); | 20 | INSERT INTO t1 VALUES (2, "I hate testing."); |
1939 | 21 | |||
1940 | 22 | DROP TABLE t1; | ||
1941 | 21 | 23 | ||
1942 | === renamed file 'plugin/transaction_log/tests/t/sync_method_every_write-master.opt' => 'plugin/transaction_log/tests/t/variables-master.opt' | |||
1943 | === renamed file 'plugin/transaction_log/tests/t/sync_method_every_write.test' => 'plugin/transaction_log/tests/t/variables.test' | |||
1944 | === modified file 'plugin/transaction_log/transaction_log.cc' | |||
1945 | --- plugin/transaction_log/transaction_log.cc 2010-03-10 18:22:56 +0000 | |||
1946 | +++ plugin/transaction_log/transaction_log.cc 2010-04-06 19:16:34 +0000 | |||
1947 | @@ -6,7 +6,7 @@ | |||
1948 | 6 | * | 6 | * |
1949 | 7 | * Authors: | 7 | * Authors: |
1950 | 8 | * | 8 | * |
1952 | 9 | * Jay Pipes <jaypipes@gmail.com.com> | 9 | * Jay Pipes <jaypipes@gmail.com.com> |
1953 | 10 | * | 10 | * |
1954 | 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
1955 | 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
1956 | @@ -30,31 +30,37 @@ | |||
1957 | 30 | * | 30 | * |
1958 | 31 | * @details | 31 | * @details |
1959 | 32 | * | 32 | * |
1961 | 33 | * Currently, the log file uses this implementation: | 33 | * Currently, the transaction log file uses a simple, single-file, append-only |
1962 | 34 | * format. | ||
1963 | 34 | * | 35 | * |
1964 | 35 | * We have an atomic off_t called log_offset which keeps track of the | 36 | * We have an atomic off_t called log_offset which keeps track of the |
1987 | 36 | * offset into the log file for writing the next Transaction. | 37 | * offset into the log file for writing the next log entry. The log |
1988 | 37 | * | 38 | * entries are written, one after the other, in the following way: |
1989 | 38 | * We write Transaction message encapsulated in an 8-byte length/type header and a | 39 | * |
1990 | 39 | * 4-byte checksum trailer. | 40 | * <pre> |
1991 | 40 | * | 41 | * -------------------------------------- |
1992 | 41 | * When writing a Transaction to the log, we calculate the length of the | 42 | * |<- 4 bytes ->|<- # Bytes of Entry ->| |
1993 | 42 | * Transaction to be written. We then increment log_offset by the length | 43 | * -------------------------------------- |
1994 | 43 | * of the Transaction plus 2 * sizeof(uint32_t) plus sizeof(uint32_t) and store | 44 | * | Entry Type | Serialized Entry | |
1995 | 44 | * this new offset in a local off_t called cur_offset (see TransactionLog::apply(). | 45 | * -------------------------------------- |
1996 | 45 | * This compare and set is done in an atomic instruction. | 46 | * </pre> |
1997 | 46 | * | 47 | * |
1998 | 47 | * We then adjust the local off_t (cur_offset) back to the original | 48 | * The Entry Type is an integer defined as an enumeration in the |
1999 | 48 | * offset by subtracting the length and sizeof(uint32_t) and sizeof(uint32_t). | 49 | * /drizzled/message/transaction.proto file called TransactionLogEntry::Type. |
2000 | 49 | * | 50 | * |
2001 | 50 | * We then first write a 64-bit length and then the serialized transaction/transaction | 51 | * Each transaction log entry type is written to the log differently. Here, |
2002 | 51 | * and optional checksum to our log file at our local cur_offset. | 52 | * we cover the format of each log entry type. |
2003 | 52 | * | 53 | * |
2004 | 53 | * -------------------------------------------------------------------------------- | 54 | * Committed and Prepared Transaction Log Entries |
2005 | 54 | * |<- 4 bytes ->|<- 4 bytes ->|<- # Bytes of Transaction Message ->|<- 4 bytes ->| | 55 | * ----------------------------------------------- |
2006 | 55 | * -------------------------------------------------------------------------------- | 56 | * |
2007 | 56 | * | Msg Type | Length | Serialized Transaction Message | Checksum | | 57 | * <pre> |
2008 | 57 | * -------------------------------------------------------------------------------- | 58 | * ------------------------------------------------------------------ |
2009 | 59 | * |<- 4 bytes ->|<- # Bytes of Transaction Message ->|<- 4 bytes ->| | ||
2010 | 60 | * ------------------------------------------------------------------ | ||
2011 | 61 | * | Length | Serialized Transaction Message | Checksum | | ||
2012 | 62 | * ------------------------------------------------------------------ | ||
2013 | 63 | * </pre> | ||
2014 | 58 | * | 64 | * |
2015 | 59 | * @todo | 65 | * @todo |
2016 | 60 | * | 66 | * |
2017 | @@ -77,19 +83,27 @@ | |||
2018 | 77 | #include <drizzled/internal/my_sys.h> /* for internal::my_sync */ | 83 | #include <drizzled/internal/my_sys.h> /* for internal::my_sync */ |
2019 | 78 | #include <drizzled/errmsg_print.h> | 84 | #include <drizzled/errmsg_print.h> |
2020 | 79 | #include <drizzled/gettext.h> | 85 | #include <drizzled/gettext.h> |
2021 | 86 | #include <drizzled/message/transaction.pb.h> | ||
2022 | 87 | #include <drizzled/transaction_services.h> | ||
2023 | 88 | #include <drizzled/algorithm/crc32.h> | ||
2024 | 89 | |||
2025 | 90 | #include <google/protobuf/io/coded_stream.h> | ||
2026 | 80 | 91 | ||
2027 | 81 | using namespace std; | 92 | using namespace std; |
2028 | 82 | using namespace drizzled; | 93 | using namespace drizzled; |
2029 | 94 | using namespace google; | ||
2030 | 83 | 95 | ||
2031 | 84 | TransactionLog *transaction_log= NULL; /* The singleton transaction log */ | 96 | TransactionLog *transaction_log= NULL; /* The singleton transaction log */ |
2032 | 85 | 97 | ||
2033 | 86 | TransactionLog::TransactionLog(const string in_log_file_path, | 98 | TransactionLog::TransactionLog(const string in_log_file_path, |
2035 | 87 | uint32_t in_sync_method) : | 99 | uint32_t in_sync_method, |
2036 | 100 | bool in_do_checksum) : | ||
2037 | 88 | state(OFFLINE), | 101 | state(OFFLINE), |
2038 | 89 | log_file_path(in_log_file_path), | 102 | log_file_path(in_log_file_path), |
2039 | 90 | has_error(false), | 103 | has_error(false), |
2040 | 91 | error_message(), | 104 | error_message(), |
2042 | 92 | sync_method(in_sync_method) | 105 | sync_method(in_sync_method), |
2043 | 106 | do_checksum(in_do_checksum) | ||
2044 | 93 | { | 107 | { |
2045 | 94 | /* Setup our log file and determine the next write offset... */ | 108 | /* Setup our log file and determine the next write offset... */ |
2046 | 95 | log_file= open(log_file_path.c_str(), O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU); | 109 | log_file= open(log_file_path.c_str(), O_APPEND|O_CREAT|O_SYNC|O_WRONLY, S_IRWXU); |
2047 | @@ -133,6 +147,43 @@ | |||
2048 | 133 | } | 147 | } |
2049 | 134 | } | 148 | } |
2050 | 135 | 149 | ||
2051 | 150 | uint8_t *TransactionLog::packTransactionIntoLogEntry(const message::Transaction &trx, | ||
2052 | 151 | uint8_t *buffer, | ||
2053 | 152 | uint32_t *checksum_out) | ||
2054 | 153 | { | ||
2055 | 154 | uint8_t *orig_buffer= buffer; | ||
2056 | 155 | size_t message_byte_length= trx.ByteSize(); | ||
2057 | 156 | |||
2058 | 157 | /* | ||
2059 | 158 | * Write the header information, which is the message type and | ||
2060 | 159 | * the length of the transaction message into the buffer | ||
2061 | 160 | */ | ||
2062 | 161 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray( | ||
2063 | 162 | static_cast<uint32_t>(ReplicationServices::TRANSACTION), buffer); | ||
2064 | 163 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray( | ||
2065 | 164 | static_cast<uint32_t>(message_byte_length), buffer); | ||
2066 | 165 | |||
2067 | 166 | /* | ||
2068 | 167 | * Now write the serialized transaction message, followed | ||
2069 | 168 | * by the optional checksum into the buffer. | ||
2070 | 169 | */ | ||
2071 | 170 | buffer= trx.SerializeWithCachedSizesToArray(buffer); | ||
2072 | 171 | |||
2073 | 172 | if (do_checksum) | ||
2074 | 173 | { | ||
2075 | 174 | *checksum_out= drizzled::algorithm::crc32( | ||
2076 | 175 | reinterpret_cast<char *>(buffer) - message_byte_length, message_byte_length); | ||
2077 | 176 | } | ||
2078 | 177 | else | ||
2079 | 178 | *checksum_out= 0; | ||
2080 | 179 | |||
2081 | 180 | /* We always write in network byte order */ | ||
2082 | 181 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(*checksum_out, buffer); | ||
2083 | 182 | /* Reset the pointer back to its original location... */ | ||
2084 | 183 | buffer= orig_buffer; | ||
2085 | 184 | return orig_buffer; | ||
2086 | 185 | } | ||
2087 | 186 | |||
2088 | 136 | off_t TransactionLog::writeEntry(const uint8_t *data, size_t data_length) | 187 | off_t TransactionLog::writeEntry(const uint8_t *data, size_t data_length) |
2089 | 137 | { | 188 | { |
2090 | 138 | ssize_t written= 0; | 189 | ssize_t written= 0; |
2091 | @@ -142,12 +193,6 @@ | |||
2092 | 142 | */ | 193 | */ |
2093 | 143 | off_t cur_offset= log_offset.fetch_and_add(static_cast<off_t>(data_length)); | 194 | off_t cur_offset= log_offset.fetch_and_add(static_cast<off_t>(data_length)); |
2094 | 144 | 195 | ||
2095 | 145 | /* | ||
2096 | 146 | * We adjust cur_offset back to the original log_offset before | ||
2097 | 147 | * the increment above... | ||
2098 | 148 | */ | ||
2099 | 149 | cur_offset-= static_cast<off_t>(data_length); | ||
2100 | 150 | |||
2101 | 151 | /* | 196 | /* |
2102 | 152 | * Quick safety...if an error occurs above in another writer, the log | 197 | * Quick safety...if an error occurs above in another writer, the log |
2103 | 153 | * file will be in a crashed state. | 198 | * file will be in a crashed state. |
2104 | @@ -243,6 +288,7 @@ | |||
2105 | 243 | result= ftruncate(log_file, log_offset); | 288 | result= ftruncate(log_file, log_offset); |
2106 | 244 | } | 289 | } |
2107 | 245 | while (result == -1 && errno == EINTR); | 290 | while (result == -1 && errno == EINTR); |
2108 | 291 | drizzled::TransactionServices::singleton().resetTransactionId(); | ||
2109 | 246 | } | 292 | } |
2110 | 247 | 293 | ||
2111 | 248 | bool TransactionLog::findLogFilenameContainingTransactionId(const ReplicationServices::GlobalTransactionId&, | 294 | bool TransactionLog::findLogFilenameContainingTransactionId(const ReplicationServices::GlobalTransactionId&, |
2112 | @@ -272,3 +318,8 @@ | |||
2113 | 272 | { | 318 | { |
2114 | 273 | return error_message; | 319 | return error_message; |
2115 | 274 | } | 320 | } |
2116 | 321 | |||
2117 | 322 | size_t TransactionLog::getLogEntrySize(const message::Transaction &trx) | ||
2118 | 323 | { | ||
2119 | 324 | return trx.ByteSize() + HEADER_TRAILER_BYTES; | ||
2120 | 325 | } | ||
2121 | 275 | 326 | ||
2122 | === modified file 'plugin/transaction_log/transaction_log.h' | |||
2123 | --- plugin/transaction_log/transaction_log.h 2010-03-05 18:08:49 +0000 | |||
2124 | +++ plugin/transaction_log/transaction_log.h 2010-04-06 19:16:34 +0000 | |||
2125 | @@ -49,10 +49,6 @@ | |||
2126 | 49 | class TransactionLog | 49 | class TransactionLog |
2127 | 50 | { | 50 | { |
2128 | 51 | public: | 51 | public: |
2129 | 52 | static const uint32_t HEADER_TRAILER_BYTES= sizeof(uint32_t) + /* 4-byte msg type header */ | ||
2130 | 53 | sizeof(uint32_t) + /* 4-byte length header */ | ||
2131 | 54 | sizeof(uint32_t); /* 4 byte checksum trailer */ | ||
2132 | 55 | |||
2133 | 56 | typedef std::vector<TransactionLogEntry> Entries; | 52 | typedef std::vector<TransactionLogEntry> Entries; |
2134 | 57 | typedef std::vector<TransactionLogTransactionEntry> TransactionEntries; | 53 | typedef std::vector<TransactionLogTransactionEntry> TransactionEntries; |
2135 | 58 | /** | 54 | /** |
2136 | @@ -70,7 +66,8 @@ | |||
2137 | 70 | static const uint32_t SYNC_METHOD_EVERY_SECOND= 2; ///< Sync no more than once a second | 66 | static const uint32_t SYNC_METHOD_EVERY_SECOND= 2; ///< Sync no more than once a second |
2138 | 71 | public: | 67 | public: |
2139 | 72 | TransactionLog(const std::string in_log_file_path, | 68 | TransactionLog(const std::string in_log_file_path, |
2141 | 73 | uint32_t in_sync_method); | 69 | uint32_t in_sync_method, |
2142 | 70 | bool in_do_checksum); | ||
2143 | 74 | 71 | ||
2144 | 75 | /** Destructor */ | 72 | /** Destructor */ |
2145 | 76 | ~TransactionLog(); | 73 | ~TransactionLog(); |
2146 | @@ -102,6 +99,31 @@ | |||
2147 | 102 | } | 99 | } |
2148 | 103 | 100 | ||
2149 | 104 | /** | 101 | /** |
2150 | 102 | * Static helper method which returns the transaction | ||
2151 | 103 | * log entry size in bytes of a given transaction | ||
2152 | 104 | * message. | ||
2153 | 105 | * | ||
2154 | 106 | * @param[in] Transaction message | ||
2155 | 107 | */ | ||
2156 | 108 | static size_t getLogEntrySize(const drizzled::message::Transaction &trx); | ||
2157 | 109 | |||
2158 | 110 | /** | ||
2159 | 111 | * Method which packs into a raw byte buffer | ||
2160 | 112 | * a transaction log entry. Supplied buffer should | ||
2161 | 113 | * be of adequate size. | ||
2162 | 114 | * | ||
2163 | 115 | * Returns a pointer to the start of the original | ||
2164 | 116 | * buffer. | ||
2165 | 117 | * | ||
2166 | 118 | * @param[in] Transaction message to pack | ||
2167 | 119 | * @param[in] Raw byte buffer | ||
2168 | 120 | * @param[out] Pointer to storage for checksum of message | ||
2169 | 121 | */ | ||
2170 | 122 | uint8_t *packTransactionIntoLogEntry(const drizzled::message::Transaction &trx, | ||
2171 | 123 | uint8_t *buffer, | ||
2172 | 124 | uint32_t *checksum_out); | ||
2173 | 125 | |||
2174 | 126 | /** | ||
2175 | 105 | * Writes a chunk of data to the log file of a specified | 127 | * Writes a chunk of data to the log file of a specified |
2176 | 106 | * length and returns the offset at which the chunk of | 128 | * length and returns the offset at which the chunk of |
2177 | 107 | * data was written. | 129 | * data was written. |
2178 | @@ -153,6 +175,10 @@ | |||
2179 | 153 | */ | 175 | */ |
2180 | 154 | const std::string &getErrorMessage() const; | 176 | const std::string &getErrorMessage() const; |
2181 | 155 | private: | 177 | private: |
2182 | 178 | static const uint32_t HEADER_TRAILER_BYTES= sizeof(uint32_t) + /* 4-byte msg type header */ | ||
2183 | 179 | sizeof(uint32_t) + /* 4-byte length header */ | ||
2184 | 180 | sizeof(uint32_t); /* 4 byte checksum trailer */ | ||
2185 | 181 | |||
2186 | 156 | /* Don't allows these */ | 182 | /* Don't allows these */ |
2187 | 157 | TransactionLog(); | 183 | TransactionLog(); |
2188 | 158 | TransactionLog(const TransactionLog &other); | 184 | TransactionLog(const TransactionLog &other); |
2189 | @@ -181,6 +207,7 @@ | |||
2190 | 181 | std::string error_message; ///< Current error message | 207 | std::string error_message; ///< Current error message |
2191 | 182 | uint32_t sync_method; ///< Determines behaviour of syncing log file | 208 | uint32_t sync_method; ///< Determines behaviour of syncing log file |
2192 | 183 | time_t last_sync_time; ///< Last time the log file was synced (only set in SYNC_METHOD_EVERY_SECOND) | 209 | time_t last_sync_time; ///< Last time the log file was synced (only set in SYNC_METHOD_EVERY_SECOND) |
2193 | 210 | bool do_checksum; ///< Do a CRC32 checksum when writing Transaction message to log? | ||
2194 | 184 | }; | 211 | }; |
2195 | 185 | 212 | ||
2196 | 186 | #endif /* PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_H */ | 213 | #endif /* PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_H */ |
2197 | 187 | 214 | ||
2198 | === modified file 'plugin/transaction_log/transaction_log_applier.cc' | |||
2199 | --- plugin/transaction_log/transaction_log_applier.cc 2010-03-29 22:01:35 +0000 | |||
2200 | +++ plugin/transaction_log/transaction_log_applier.cc 2010-04-06 19:16:34 +0000 | |||
2201 | @@ -6,7 +6,7 @@ | |||
2202 | 6 | * | 6 | * |
2203 | 7 | * Authors: | 7 | * Authors: |
2204 | 8 | * | 8 | * |
2206 | 9 | * Jay Pipes <jaypipes@gmail.com.com> | 9 | * Jay Pipes <jaypipes@gmail.com> |
2207 | 10 | * | 10 | * |
2208 | 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
2209 | 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
2210 | @@ -43,24 +43,19 @@ | |||
2211 | 43 | */ | 43 | */ |
2212 | 44 | 44 | ||
2213 | 45 | #include "config.h" | 45 | #include "config.h" |
2214 | 46 | #include "write_buffer.h" | ||
2215 | 46 | #include "transaction_log.h" | 47 | #include "transaction_log.h" |
2216 | 47 | #include "transaction_log_applier.h" | 48 | #include "transaction_log_applier.h" |
2217 | 48 | #include "transaction_log_index.h" | 49 | #include "transaction_log_index.h" |
2218 | 49 | 50 | ||
2223 | 50 | #include <sys/stat.h> | 51 | #include <vector> |
2220 | 51 | #include <fcntl.h> | ||
2221 | 52 | #include <unistd.h> | ||
2222 | 53 | #include <errno.h> | ||
2224 | 54 | 52 | ||
2225 | 55 | #include <drizzled/errmsg_print.h> | ||
2226 | 56 | #include <drizzled/gettext.h> | ||
2227 | 57 | #include <drizzled/algorithm/crc32.h> | ||
2228 | 58 | #include <drizzled/message/transaction.pb.h> | 53 | #include <drizzled/message/transaction.pb.h> |
2230 | 59 | #include <google/protobuf/io/coded_stream.h> | 54 | #include <drizzled/util/functors.h> |
2231 | 55 | #include <drizzled/session.h> | ||
2232 | 60 | 56 | ||
2233 | 61 | using namespace std; | 57 | using namespace std; |
2234 | 62 | using namespace drizzled; | 58 | using namespace drizzled; |
2235 | 63 | using namespace google; | ||
2236 | 64 | 59 | ||
2237 | 65 | TransactionLogApplier *transaction_log_applier= NULL; /* The singleton transaction log applier */ | 60 | TransactionLogApplier *transaction_log_applier= NULL; /* The singleton transaction log applier */ |
2238 | 66 | 61 | ||
2239 | @@ -68,79 +63,59 @@ | |||
2240 | 68 | 63 | ||
2241 | 69 | TransactionLogApplier::TransactionLogApplier(const string name_arg, | 64 | TransactionLogApplier::TransactionLogApplier(const string name_arg, |
2242 | 70 | TransactionLog &in_transaction_log, | 65 | TransactionLog &in_transaction_log, |
2244 | 71 | bool in_do_checksum) : | 66 | uint32_t in_num_write_buffers) : |
2245 | 72 | plugin::TransactionApplier(name_arg), | 67 | plugin::TransactionApplier(name_arg), |
2246 | 73 | transaction_log(in_transaction_log), | 68 | transaction_log(in_transaction_log), |
2248 | 74 | do_checksum(in_do_checksum) | 69 | num_write_buffers(in_num_write_buffers), |
2249 | 70 | write_buffers() | ||
2250 | 75 | { | 71 | { |
2251 | 72 | /* | ||
2252 | 73 | * Create each of the buffers we need for undo log entries | ||
2253 | 74 | */ | ||
2254 | 75 | write_buffers.reserve(num_write_buffers); | ||
2255 | 76 | for (size_t x= 0; x < num_write_buffers; ++x) | ||
2256 | 77 | { | ||
2257 | 78 | write_buffers.push_back(new WriteBuffer()); | ||
2258 | 79 | } | ||
2259 | 76 | } | 80 | } |
2260 | 77 | 81 | ||
2261 | 78 | TransactionLogApplier::~TransactionLogApplier() | 82 | TransactionLogApplier::~TransactionLogApplier() |
2262 | 79 | { | 83 | { |
2321 | 80 | } | 84 | for_each(write_buffers.begin(), |
2322 | 81 | 85 | write_buffers.end(), | |
2323 | 82 | void TransactionLogApplier::apply(const message::Transaction &to_apply) | 86 | DeletePtr()); |
2324 | 83 | { | 87 | write_buffers.clear(); |
2325 | 84 | uint8_t *buffer; /* Buffer we will write serialized header, | 88 | } |
2326 | 85 | message and trailing checksum to */ | 89 | |
2327 | 86 | uint8_t *orig_buffer; | 90 | WriteBuffer *TransactionLogApplier::getWriteBuffer(const Session &session) |
2328 | 87 | 91 | { | |
2329 | 88 | size_t message_byte_length= to_apply.ByteSize(); | 92 | return write_buffers[session.getSessionId() % num_write_buffers]; |
2330 | 89 | size_t total_envelope_length= TransactionLog::HEADER_TRAILER_BYTES + message_byte_length; | 93 | } |
2331 | 90 | 94 | ||
2332 | 91 | /* | 95 | plugin::ReplicationReturnCode |
2333 | 92 | * Attempt allocation of raw memory buffer for the header, | 96 | TransactionLogApplier::apply(Session &in_session, |
2334 | 93 | * message and trailing checksum bytes. | 97 | const message::Transaction &to_apply) |
2335 | 94 | */ | 98 | { |
2336 | 95 | buffer= static_cast<uint8_t *>(malloc(total_envelope_length)); | 99 | size_t entry_size= TransactionLog::getLogEntrySize(to_apply); |
2337 | 96 | if (buffer == NULL) | 100 | WriteBuffer *write_buffer= getWriteBuffer(in_session); |
2338 | 97 | { | 101 | |
2339 | 98 | errmsg_printf(ERRMSG_LVL_ERROR, | 102 | uint32_t checksum; |
2340 | 99 | _("Failed to allocate enough memory to buffer header, " | 103 | |
2341 | 100 | "transaction message, and trailing checksum bytes. Tried to allocate %" PRId64 | 104 | write_buffer->lock(); |
2342 | 101 | " bytes. Error: %s\n"), | 105 | write_buffer->resize(entry_size); |
2343 | 102 | static_cast<int64_t>(total_envelope_length), | 106 | uint8_t *bytes= write_buffer->getRawBytes(); |
2344 | 103 | strerror(errno)); | 107 | bytes= transaction_log.packTransactionIntoLogEntry(to_apply, |
2345 | 104 | return; | 108 | bytes, |
2346 | 105 | } | 109 | &checksum); |
2347 | 106 | else | 110 | |
2348 | 107 | orig_buffer= buffer; /* We will free() orig_buffer, as buffer is moved during write */ | 111 | off_t written_to= transaction_log.writeEntry(bytes, entry_size); |
2349 | 108 | 112 | write_buffer->unlock(); | |
2292 | 109 | /* | ||
2293 | 110 | * Write the header information, which is the message type and | ||
2294 | 111 | * the length of the transaction message into the buffer | ||
2295 | 112 | */ | ||
2296 | 113 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray( | ||
2297 | 114 | static_cast<uint32_t>(ReplicationServices::TRANSACTION), buffer); | ||
2298 | 115 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray( | ||
2299 | 116 | static_cast<uint32_t>(message_byte_length), buffer); | ||
2300 | 117 | |||
2301 | 118 | /* | ||
2302 | 119 | * Now write the serialized transaction message, followed | ||
2303 | 120 | * by the optional checksum into the buffer. | ||
2304 | 121 | */ | ||
2305 | 122 | buffer= to_apply.SerializeWithCachedSizesToArray(buffer); | ||
2306 | 123 | |||
2307 | 124 | uint32_t checksum= 0; | ||
2308 | 125 | if (do_checksum) | ||
2309 | 126 | { | ||
2310 | 127 | checksum= drizzled::algorithm::crc32( | ||
2311 | 128 | buffer - message_byte_length, message_byte_length); | ||
2312 | 129 | } | ||
2313 | 130 | |||
2314 | 131 | /* We always write in network byte order */ | ||
2315 | 132 | buffer= protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(checksum, buffer); | ||
2316 | 133 | |||
2317 | 134 | /* Ask the transaction log to write the entry and return where it wrote it */ | ||
2318 | 135 | off_t written_to= transaction_log.writeEntry(orig_buffer, total_envelope_length); | ||
2319 | 136 | |||
2320 | 137 | free(orig_buffer); | ||
2350 | 138 | 113 | ||
2351 | 139 | /* Add an entry to the index describing what was just applied */ | 114 | /* Add an entry to the index describing what was just applied */ |
2352 | 140 | transaction_log_index->addEntry(TransactionLogEntry(ReplicationServices::TRANSACTION, | 115 | transaction_log_index->addEntry(TransactionLogEntry(ReplicationServices::TRANSACTION, |
2353 | 141 | written_to, | 116 | written_to, |
2355 | 142 | total_envelope_length), | 117 | entry_size), |
2356 | 143 | to_apply, | 118 | to_apply, |
2357 | 144 | checksum); | 119 | checksum); |
2359 | 145 | 120 | return plugin::SUCCESS; | |
2360 | 146 | } | 121 | } |
2361 | 147 | 122 | ||
2362 | === modified file 'plugin/transaction_log/transaction_log_applier.h' | |||
2363 | --- plugin/transaction_log/transaction_log_applier.h 2010-03-05 18:08:49 +0000 | |||
2364 | +++ plugin/transaction_log/transaction_log_applier.h 2010-04-06 19:16:34 +0000 | |||
2365 | @@ -43,14 +43,20 @@ | |||
2366 | 43 | #include <vector> | 43 | #include <vector> |
2367 | 44 | #include <string> | 44 | #include <string> |
2368 | 45 | 45 | ||
2369 | 46 | namespace drizzled | ||
2370 | 47 | { | ||
2371 | 48 | class Session; | ||
2372 | 49 | } | ||
2373 | 50 | |||
2374 | 46 | class TransactionLog; | 51 | class TransactionLog; |
2375 | 52 | class WriteBuffer; | ||
2376 | 47 | 53 | ||
2377 | 48 | class TransactionLogApplier: public drizzled::plugin::TransactionApplier | 54 | class TransactionLogApplier: public drizzled::plugin::TransactionApplier |
2378 | 49 | { | 55 | { |
2379 | 50 | public: | 56 | public: |
2380 | 51 | TransactionLogApplier(const std::string name_arg, | 57 | TransactionLogApplier(const std::string name_arg, |
2381 | 52 | TransactionLog &in_transaction_log, | 58 | TransactionLog &in_transaction_log, |
2383 | 53 | bool in_do_checksum); | 59 | uint32_t in_num_write_buffers); |
2384 | 54 | 60 | ||
2385 | 55 | /** Destructor */ | 61 | /** Destructor */ |
2386 | 56 | ~TransactionLogApplier(); | 62 | ~TransactionLogApplier(); |
2387 | @@ -68,16 +74,27 @@ | |||
2388 | 68 | * the supplied message to their own controlled memory storage | 74 | * the supplied message to their own controlled memory storage |
2389 | 69 | * area. | 75 | * area. |
2390 | 70 | * | 76 | * |
2391 | 77 | * @param Session descriptor | ||
2392 | 71 | * @param Transaction message to be replicated | 78 | * @param Transaction message to be replicated |
2393 | 72 | */ | 79 | */ |
2395 | 73 | void apply(const drizzled::message::Transaction &to_apply); | 80 | drizzled::plugin::ReplicationReturnCode |
2396 | 81 | apply(drizzled::Session &in_session, | ||
2397 | 82 | const drizzled::message::Transaction &to_apply); | ||
2398 | 74 | private: | 83 | private: |
2399 | 75 | /* Don't allows these */ | 84 | /* Don't allows these */ |
2400 | 76 | TransactionLogApplier(); | 85 | TransactionLogApplier(); |
2401 | 77 | TransactionLogApplier(const TransactionLogApplier &other); | 86 | TransactionLogApplier(const TransactionLogApplier &other); |
2402 | 78 | TransactionLogApplier &operator=(const TransactionLogApplier &other); | 87 | TransactionLogApplier &operator=(const TransactionLogApplier &other); |
2403 | 79 | TransactionLog &transaction_log; | 88 | TransactionLog &transaction_log; |
2405 | 80 | bool do_checksum; ///< Do a CRC32 checksum when writing Transaction message to log? | 89 | uint32_t num_write_buffers; ///< Number of write buffers used |
2406 | 90 | std::vector<WriteBuffer *> write_buffers; ///< array of write buffers | ||
2407 | 91 | |||
2408 | 92 | /** | ||
2409 | 93 | * Returns the write buffer for the supplied session | ||
2410 | 94 | * | ||
2411 | 95 | * @param Session descriptor | ||
2412 | 96 | */ | ||
2413 | 97 | WriteBuffer *getWriteBuffer(const drizzled::Session &session); | ||
2414 | 81 | }; | 98 | }; |
2415 | 82 | 99 | ||
2416 | 83 | #endif /* PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_APPLIER_H */ | 100 | #endif /* PLUGIN_TRANSACTION_LOG_TRANSACTION_LOG_APPLIER_H */ |
2417 | 84 | 101 | ||
2418 | === added file 'plugin/transaction_log/write_buffer.cc' | |||
2419 | --- plugin/transaction_log/write_buffer.cc 1970-01-01 00:00:00 +0000 | |||
2420 | +++ plugin/transaction_log/write_buffer.cc 2010-04-06 19:16:34 +0000 | |||
2421 | @@ -0,0 +1,71 @@ | |||
2422 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2423 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2424 | 3 | * | ||
2425 | 4 | * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com> | ||
2426 | 5 | * | ||
2427 | 6 | * Authors: | ||
2428 | 7 | * | ||
2429 | 8 | * Jay Pipes <jaypipes@gmail.com> | ||
2430 | 9 | * | ||
2431 | 10 | * This program is free software; you can redistribute it and/or modify | ||
2432 | 11 | * it under the terms of the GNU General Public License as published by | ||
2433 | 12 | * the Free Software Foundation; either version 2 of the License, or | ||
2434 | 13 | * (at your option) any later version. | ||
2435 | 14 | * | ||
2436 | 15 | * This program is distributed in the hope that it will be useful, | ||
2437 | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2438 | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2439 | 18 | * GNU General Public License for more details. | ||
2440 | 19 | * | ||
2441 | 20 | * You should have received a copy of the GNU General Public License | ||
2442 | 21 | * along with this program; if not, write to the Free Software | ||
2443 | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2444 | 23 | */ | ||
2445 | 24 | |||
2446 | 25 | /** | ||
2447 | 26 | * @file | ||
2448 | 27 | * | ||
2449 | 28 | * Defines the implementation of a simple locked write buffer | ||
2450 | 29 | * | ||
2451 | 30 | * @details | ||
2452 | 31 | * | ||
2453 | 32 | * The write buffer keeps a block of allocated raw bytes available for | ||
2454 | 33 | * callers. | ||
2455 | 34 | */ | ||
2456 | 35 | |||
2457 | 36 | #include "config.h" | ||
2458 | 37 | #include "write_buffer.h" | ||
2459 | 38 | |||
2460 | 39 | #include <drizzled/errmsg_print.h> | ||
2461 | 40 | #include <drizzled/gettext.h> | ||
2462 | 41 | |||
2463 | 42 | #include <vector> | ||
2464 | 43 | |||
2465 | 44 | using namespace std; | ||
2466 | 45 | using namespace drizzled; | ||
2467 | 46 | |||
2468 | 47 | WriteBuffer::WriteBuffer() : | ||
2469 | 48 | buffer() | ||
2470 | 49 | { | ||
2471 | 50 | buffer.reserve(DEFAULT_WRITE_BUFFER_SIZE); | ||
2472 | 51 | pthread_mutex_init(&latch, NULL); | ||
2473 | 52 | } | ||
2474 | 53 | |||
2475 | 54 | WriteBuffer::~WriteBuffer() | ||
2476 | 55 | { | ||
2477 | 56 | buffer.clear(); | ||
2478 | 57 | pthread_mutex_destroy(&latch); | ||
2479 | 58 | } | ||
2480 | 59 | |||
2481 | 60 | void WriteBuffer::resize(size_t new_size) | ||
2482 | 61 | { | ||
2483 | 62 | /* | ||
2484 | 63 | * Attempt allocation of raw memory buffer for the | ||
2485 | 64 | * requested size. Does nothing if already allocated size | ||
2486 | 65 | * if greater... | ||
2487 | 66 | */ | ||
2488 | 67 | if (buffer.capacity() >= new_size) | ||
2489 | 68 | return; | ||
2490 | 69 | |||
2491 | 70 | buffer.reserve(new_size); | ||
2492 | 71 | } | ||
2493 | 0 | 72 | ||
2494 | === added file 'plugin/transaction_log/write_buffer.h' | |||
2495 | --- plugin/transaction_log/write_buffer.h 1970-01-01 00:00:00 +0000 | |||
2496 | +++ plugin/transaction_log/write_buffer.h 2010-04-06 19:16:34 +0000 | |||
2497 | @@ -0,0 +1,90 @@ | |||
2498 | 1 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- | ||
2499 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
2500 | 3 | * | ||
2501 | 4 | * Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com> | ||
2502 | 5 | * | ||
2503 | 6 | * Authors: | ||
2504 | 7 | * | ||
2505 | 8 | * Jay Pipes <jaypipes@gmail.com> | ||
2506 | 9 | * | ||
2507 | 10 | * This program is free software; you can redistribute it and/or modify | ||
2508 | 11 | * it under the terms of the GNU General Public License as published by | ||
2509 | 12 | * the Free Software Foundation; either version 2 of the License, or | ||
2510 | 13 | * (at your option) any later version. | ||
2511 | 14 | * | ||
2512 | 15 | * This program is distributed in the hope that it will be useful, | ||
2513 | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2514 | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2515 | 18 | * GNU General Public License for more details. | ||
2516 | 19 | * | ||
2517 | 20 | * You should have received a copy of the GNU General Public License | ||
2518 | 21 | * along with this program; if not, write to the Free Software | ||
2519 | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
2520 | 23 | */ | ||
2521 | 24 | |||
2522 | 25 | /** | ||
2523 | 26 | * @file | ||
2524 | 27 | * | ||
2525 | 28 | * Defines a simple structure for maintaining a write buffer. | ||
2526 | 29 | */ | ||
2527 | 30 | |||
2528 | 31 | #ifndef PLUGIN_TRANSACTION_LOG_WRITE_BUFFER_H | ||
2529 | 32 | #define PLUGIN_TRANSACTION_LOG_WRITE_BUFFER_H | ||
2530 | 33 | |||
2531 | 34 | #include <stdint.h> | ||
2532 | 35 | #include <vector> | ||
2533 | 36 | #include <pthread.h> | ||
2534 | 37 | |||
2535 | 38 | class WriteBuffer | ||
2536 | 39 | { | ||
2537 | 40 | public: | ||
2538 | 41 | static const size_t DEFAULT_WRITE_BUFFER_SIZE= 1024; /* Many GPB messages are < 1 KB... */ | ||
2539 | 42 | /** | ||
2540 | 43 | * Constructor. | ||
2541 | 44 | */ | ||
2542 | 45 | WriteBuffer(); | ||
2543 | 46 | ~WriteBuffer(); | ||
2544 | 47 | /** | ||
2545 | 48 | * Locks the log write buffer | ||
2546 | 49 | */ | ||
2547 | 50 | void lock() | ||
2548 | 51 | { | ||
2549 | 52 | pthread_mutex_lock(&latch); | ||
2550 | 53 | } | ||
2551 | 54 | /** | ||
2552 | 55 | * Unlocks the log's write buffer | ||
2553 | 56 | */ | ||
2554 | 57 | void unlock() | ||
2555 | 58 | { | ||
2556 | 59 | pthread_mutex_unlock(&latch); | ||
2557 | 60 | } | ||
2558 | 61 | /** | ||
2559 | 62 | * Resizes the internal raw byte buffer | ||
2560 | 63 | * | ||
2561 | 64 | * @param[in] New size to allocate | ||
2562 | 65 | */ | ||
2563 | 66 | void resize(size_t new_size); | ||
2564 | 67 | /** | ||
2565 | 68 | * Returns the pointer to the raw bytes. | ||
2566 | 69 | */ | ||
2567 | 70 | uint8_t *getRawBytes() | ||
2568 | 71 | { | ||
2569 | 72 | return &buffer[0]; | ||
2570 | 73 | } | ||
2571 | 74 | /** | ||
2572 | 75 | * Returns the size of the write buffer | ||
2573 | 76 | */ | ||
2574 | 77 | size_t getCapacity() | ||
2575 | 78 | { | ||
2576 | 79 | return buffer.size(); | ||
2577 | 80 | } | ||
2578 | 81 | private: | ||
2579 | 82 | /* Prohibit these */ | ||
2580 | 83 | WriteBuffer(const WriteBuffer&); | ||
2581 | 84 | WriteBuffer &operator=(const WriteBuffer&); | ||
2582 | 85 | |||
2583 | 86 | std::vector<uint8_t> buffer; ///< Raw memory buffer managed by the log | ||
2584 | 87 | pthread_mutex_t latch; ///< Lock around the synchronized parts of the log (the write buffer) | ||
2585 | 88 | }; | ||
2586 | 89 | |||
2587 | 90 | #endif /* PLUGIN_TRANSACTION_LOG_WRITE_BUFFER_H */ |
It's missing an update to the sun studio atomic trait... but other than that looks good.