Advertisement
Guest User

Untitled

a guest
Jun 29th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.57 KB | None | 0 0
  1. diff --git a/sql/log.cc b/sql/log.cc
  2. index a938dcb..953990f 100644
  3. --- a/sql/log.cc
  4. +++ b/sql/log.cc
  5. @@ -3690,7 +3690,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
  6. new_xid_list_entry->binlog_id= current_binlog_id;
  7. /* Remove any initial entries with no pending XIDs. */
  8. while ((b= binlog_xid_count_list.head()) && b->xid_count == 0)
  9. + {
  10. my_free(binlog_xid_count_list.get());
  11. + }
  12. + mysql_cond_broadcast(&COND_xid_list);
  13. binlog_xid_count_list.push_back(new_xid_list_entry);
  14. mysql_mutex_unlock(&LOCK_xid_list);
  15.  
  16. @@ -4227,6 +4230,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
  17. DBUG_ASSERT(b->xid_count == 0);
  18. my_free(binlog_xid_count_list.get());
  19. }
  20. + mysql_cond_broadcast(&COND_xid_list);
  21. reset_master_pending--;
  22. mysql_mutex_unlock(&LOCK_xid_list);
  23. }
  24. @@ -4237,6 +4241,19 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log,
  25. }
  26.  
  27.  
  28. +void MYSQL_BIN_LOG::wait_for_last_checkpoint_event()
  29. +{
  30. + mysql_mutex_lock(&LOCK_xid_list);
  31. + for (;;)
  32. + {
  33. + if (binlog_xid_count_list.is_last(binlog_xid_count_list.head()))
  34. + break;
  35. + mysql_cond_wait(&COND_xid_list, &LOCK_xid_list);
  36. + }
  37. + mysql_mutex_unlock(&LOCK_xid_list);
  38. +}
  39. +
  40. +
  41. /**
  42. Delete relay log files prior to rli->group_relay_log_name
  43. (i.e. all logs which are not involved in a non-finished group
  44. @@ -9394,7 +9411,7 @@ void TC_LOG_BINLOG::close()
  45. */
  46. if (unlikely(reset_master_pending))
  47. {
  48. - mysql_cond_signal(&COND_xid_list);
  49. + mysql_cond_broadcast(&COND_xid_list);
  50. mysql_mutex_unlock(&LOCK_xid_list);
  51. DBUG_VOID_RETURN;
  52. }
  53. @@ -9432,8 +9449,7 @@ void TC_LOG_BINLOG::close()
  54. mysql_mutex_lock(&LOCK_log);
  55. mysql_mutex_lock(&LOCK_xid_list);
  56. --mark_xid_done_waiting;
  57. - if (unlikely(reset_master_pending))
  58. - mysql_cond_signal(&COND_xid_list);
  59. + mysql_cond_broadcast(&COND_xid_list);
  60. /* We need to reload current_binlog_id due to release/re-take of lock. */
  61. current= current_binlog_id;
  62.  
  63. diff --git a/sql/log.h b/sql/log.h
  64. index 9bf80d6..d81c4b0 100644
  65. --- a/sql/log.h
  66. +++ b/sql/log.h
  67. @@ -788,6 +788,7 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
  68. bool reset_logs(THD* thd, bool create_new_log,
  69. rpl_gtid *init_state, uint32 init_state_len,
  70. ulong next_log_number);
  71. + void wait_for_last_checkpoint_event();
  72. void close(uint exiting);
  73. void clear_inuse_flag_when_closing(File file);
  74.  
  75. diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
  76. index c2a1ab5..ade4414 100644
  77. --- a/sql/wsrep_sst.cc
  78. +++ b/sql/wsrep_sst.cc
  79. @@ -949,36 +949,54 @@ static int sst_create_file(const char *name, const char *content)
  80.  
  81. static int run_sql_command(THD *thd, const char *query)
  82. {
  83. + int err= 0;
  84. + CHARSET_INFO *current_charset= thd->variables.character_set_client;
  85. +
  86. + if (!is_supported_parser_charset(current_charset))
  87. + {
  88. + /* Do not use non-supported parser character sets */
  89. + WSREP_WARN("Current client character set is non-supported parser "
  90. + "character set: %s", current_charset->csname);
  91. +
  92. + thd->variables.character_set_client= &my_charset_latin1;
  93. +
  94. + WSREP_WARN("For SST temporally setting character set to : %s",
  95. + my_charset_latin1.csname);
  96. + }
  97. +
  98. thd->set_query((char *)query, strlen(query));
  99.  
  100. Parser_state ps;
  101. if (ps.init(thd, thd->query(), thd->query_length()))
  102. {
  103. WSREP_ERROR("SST query: %s failed", query);
  104. - return -1;
  105. + err= -1;
  106. + goto end;
  107. }
  108.  
  109. mysql_parse(thd, thd->query(), thd->query_length(), &ps);
  110. +
  111. if (thd->is_error())
  112. {
  113. - int const err= thd->get_stmt_da()->sql_errno();
  114. + int const sql_errno= thd->get_stmt_da()->sql_errno();
  115. WSREP_WARN ("Error executing '%s': %d (%s)%s",
  116. - query, err, thd->get_stmt_da()->message(),
  117. - err == ER_UNKNOWN_SYSTEM_VARIABLE ?
  118. + query, sql_errno, thd->get_stmt_da()->message(),
  119. + sql_errno == ER_UNKNOWN_SYSTEM_VARIABLE ?
  120. ". Was mysqld built with --with-innodb-disallow-writes ?" : "");
  121. thd->clear_error();
  122. - return -1;
  123. + err= -1;
  124. }
  125. - return 0;
  126. +
  127. +end:
  128. + /* Restore the local character_set_client. */
  129. + thd->variables.character_set_client= current_charset;
  130. +
  131. + return err;
  132. }
  133.  
  134.  
  135. static int sst_flush_tables(THD* thd)
  136. {
  137. - WSREP_INFO("Flushing tables for SST...");
  138. -
  139. - int err= 0;
  140. - int not_used;
  141. /*
  142. Files created to notify the SST script about the outcome of table flush
  143. operation.
  144. @@ -986,95 +1004,92 @@ static int sst_flush_tables(THD* thd)
  145. const char *flush_success= "tables_flushed";
  146. const char *flush_error= "sst_error";
  147.  
  148. - CHARSET_INFO *current_charset= thd->variables.character_set_client;
  149. + int err= -1;
  150. + int not_used;
  151.  
  152. - if (!is_supported_parser_charset(current_charset))
  153. - {
  154. - /* Do not use non-supported parser character sets */
  155. - WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
  156. - thd->variables.character_set_client = &my_charset_latin1;
  157. - WSREP_WARN("For SST temporally setting character set to : %s",
  158. - my_charset_latin1.csname);
  159. - }
  160. + WSREP_INFO("Flushing tables for SST...");
  161.  
  162. if (run_sql_command(thd, "FLUSH TABLES WITH READ LOCK"))
  163. {
  164. - err= -1;
  165. + goto err1;
  166. }
  167. - else
  168. +
  169. + /*
  170. + Make sure logs are flushed after global read lock acquired. In case
  171. + reload fails, we must also release the acquired FTWRL.
  172. + */
  173. + if (reload_acl_and_cache(thd, REFRESH_ENGINE_LOG, (TABLE_LIST *) 0,
  174. + &not_used))
  175. {
  176. - /*
  177. - Make sure logs are flushed after global read lock acquired. In case
  178. - reload fails, we must also release the acquired FTWRL.
  179. - */
  180. - if (reload_acl_and_cache(thd, REFRESH_ENGINE_LOG | REFRESH_BINARY_LOG,
  181. - (TABLE_LIST*) 0, &not_used))
  182. - {
  183. - thd->global_read_lock.unlock_global_read_lock(thd);
  184. - err= -1;
  185. - }
  186. + goto err2;
  187. }
  188.  
  189. - thd->variables.character_set_client = current_charset;
  190. -
  191. - if (err)
  192. + if (run_sql_command(thd, "SET GLOBAL innodb_disallow_writes=1"))
  193. {
  194. - WSREP_ERROR("Failed to flush and lock tables");
  195. -
  196. - /*
  197. - The SST must be aborted as the flush tables failed. Notify this to SST
  198. - script by creating the error file.
  199. - */
  200. - int tmp;
  201. - if ((tmp= sst_create_file(flush_error, NULL))) {
  202. - err= tmp;
  203. - }
  204. + WSREP_ERROR("Failed to disallow InnoDB writes.");
  205. + goto err2;
  206. }
  207. - else
  208. +
  209. + if (mysql_bin_log.is_open())
  210. {
  211. - WSREP_INFO("Tables flushed.");
  212. + if (reload_acl_and_cache(thd, REFRESH_BINARY_LOG, (TABLE_LIST *) 0,
  213. + &not_used))
  214. + goto err3;
  215.  
  216. /*
  217. - Tables have been flushed. Create a file with cluster state ID and
  218. - wsrep_gtid_domain_id.
  219. + Wait for binlog checkpoint event for current binary log file.
  220. + LOCK_xid_list and LOCK_log are chained, so the LOCK_log will only be
  221. + obtained after mark_xid_done() has written the last checkpoint
  222. + event. We keep LOCK_log for the duration of file transfer to prevent
  223. + statements that modify binary logs (like RESET LOGS, RESET MASTER) from
  224. + proceeding until the files have been transferred to the joiner node.
  225. */
  226. - char content[100];
  227. - snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid,
  228. - (long long)wsrep_locked_seqno, wsrep_gtid_domain_id);
  229. - err= sst_create_file(flush_success, content);
  230. + mysql_bin_log.wait_for_last_checkpoint_event();
  231. + mysql_mutex_lock(mysql_bin_log.get_log_lock());
  232. }
  233.  
  234. - return err;
  235. -}
  236. + WSREP_INFO("Tables flushed.");
  237.  
  238. + /*
  239. + Tables have been flushed. Create a file with cluster state ID and
  240. + wsrep_gtid_domain_id.
  241. + */
  242. + char content[100];
  243. + snprintf(content, sizeof(content), "%s:%lld %d\n", wsrep_cluster_state_uuid,
  244. + (long long)wsrep_locked_seqno, wsrep_gtid_domain_id);
  245. + err= sst_create_file(flush_success, content);
  246. + if (err == 0)
  247. + {
  248. + return 0;
  249. + }
  250.  
  251. -static void sst_disallow_writes (THD* thd, bool yes)
  252. -{
  253. - char query_str[64] = { 0, };
  254. - ssize_t const query_max = sizeof(query_str) - 1;
  255. - CHARSET_INFO *current_charset;
  256. +err3:
  257. + /* Switch innodb_disallow_writes back to 0. */
  258. + run_sql_command(thd, "SET GLOBAL innodb_disallow_writes=0");
  259.  
  260. - current_charset = thd->variables.character_set_client;
  261. +err2:
  262. + /* Release the acquired FTWRL. */
  263. + thd->global_read_lock.unlock_global_read_lock(thd);
  264.  
  265. - if (!is_supported_parser_charset(current_charset))
  266. - {
  267. - /* Do not use non-supported parser character sets */
  268. - WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
  269. - thd->variables.character_set_client = &my_charset_latin1;
  270. - WSREP_WARN("For SST temporally setting character set to : %s",
  271. - my_charset_latin1.csname);
  272. - }
  273. +err1:
  274. + WSREP_ERROR("Failed to flush and lock tables");
  275.  
  276. - snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
  277. - yes ? 1 : 0);
  278. + err= -1;
  279.  
  280. - if (run_sql_command(thd, query_str))
  281. + /*
  282. + The SST must be aborted as the flush tables failed. Notify this to SST
  283. + script by creating the error file.
  284. + */
  285. + int tmp;
  286. + if ((tmp= sst_create_file(flush_error, NULL)))
  287. {
  288. - WSREP_ERROR("Failed to disallow InnoDB writes");
  289. + err= tmp;
  290. }
  291. - thd->variables.character_set_client = current_charset;
  292. +
  293. + return err;
  294. }
  295.  
  296. +
  297. static void* sst_donor_thread (void* a)
  298. {
  299. sst_thread_arg* arg= (sst_thread_arg*)a;
  300. @@ -1119,7 +1134,6 @@ static void* sst_donor_thread (void* a)
  301. err= sst_flush_tables (thd.ptr);
  302. if (!err)
  303. {
  304. - sst_disallow_writes (thd.ptr, true);
  305. locked= true;
  306. goto wait_signal;
  307. }
  308. @@ -1128,7 +1142,12 @@ static void* sst_donor_thread (void* a)
  309. {
  310. if (locked)
  311. {
  312. - sst_disallow_writes (thd.ptr, false);
  313. + if (mysql_bin_log.is_open())
  314. + {
  315. + mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
  316. + mysql_mutex_unlock(mysql_bin_log.get_log_lock());
  317. + }
  318. + run_sql_command(thd.ptr, "SET GLOBAL innodb_disallow_writes=0");
  319. thd.ptr->global_read_lock.unlock_global_read_lock (thd.ptr);
  320. locked= false;
  321. }
  322. @@ -1160,7 +1179,13 @@ static void* sst_donor_thread (void* a)
  323.  
  324. if (locked) // don't forget to unlock server before return
  325. {
  326. - sst_disallow_writes (thd.ptr, false);
  327. + if (mysql_bin_log.is_open())
  328. + {
  329. + mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
  330. + mysql_mutex_unlock(mysql_bin_log.get_log_lock());
  331. + }
  332. +
  333. + run_sql_command(thd.ptr, "SET GLOBAL innodb_disallow_writes=0");
  334. thd.ptr->global_read_lock.unlock_global_read_lock (thd.ptr);
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement