You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
10 KiB

WL#3984 (Revise locking of mysql.general_log and mysql.slow_log) Bug#25422 (Hang with log tables) Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the thread) Bug 23044 (Warnings on flush of a log table) Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes a deadlock) Prior to this fix, the server would hang when performing concurrent ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES, which are mysql.general_log and mysql.slow_log. The root cause traces to the following code: in sql_base.cc, open_table() if (table->in_use != thd) { /* wait_for_condition will unlock LOCK_open for us */ wait_for_condition(thd, &LOCK_open, &COND_refresh); } The problem with this code is that the current implementation of the LOGGER creates 'fake' THD objects, like - Log_to_csv_event_handler::general_log_thd - Log_to_csv_event_handler::slow_log_thd which are not associated to a real thread running in the server, so that waiting for these non-existing threads to release table locks cause the dead lock. In general, the design of Log_to_csv_event_handler does not fit into the general architecture of the server, so that the concept of general_log_thd and slow_log_thd has to be abandoned: - this implementation does not work with table locking - it will not work with commands like SHOW PROCESSLIST - having the log tables always opened does not integrate well with DDL operations / FLUSH TABLES / SET GLOBAL READ_ONLY With this patch, the fundamental design of the LOGGER has been changed to: - always open and close a log table when writing a log - remove totally the usage of fake THD objects - clarify how locking of log tables is implemented in general. See WL#3984 for details related to the new locking design. Additional changes (misc bugs exposed and fixed): 1) mysqldump which would ignore some tables in dump_all_tables_in_db(), but forget to ignore the same in dump_all_views_in_db(). 2) mysqldump would also issue an empty "LOCK TABLE" command when all the tables to lock are to be ignored (numrows == 0), instead of not issuing the query. 3) Internal errors handlers could intercept errors but not warnings (see sql_error.cc). 4) Implementing a nested call to open tables, for the performance schema tables, exposed an existing bug in remove_table_from_cache(), which would perform: in_use->some_tables_deleted=1; against another thread, without any consideration about thread locking. This call inside remove_table_from_cache() was not required anyway, since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads that might hold a lock on a table. This line (in_use->some_tables_deleted=1) has been removed.
19 years ago
WL#3984 (Revise locking of mysql.general_log and mysql.slow_log) Bug#25422 (Hang with log tables) Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the thread) Bug 23044 (Warnings on flush of a log table) Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes a deadlock) Prior to this fix, the server would hang when performing concurrent ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES, which are mysql.general_log and mysql.slow_log. The root cause traces to the following code: in sql_base.cc, open_table() if (table->in_use != thd) { /* wait_for_condition will unlock LOCK_open for us */ wait_for_condition(thd, &LOCK_open, &COND_refresh); } The problem with this code is that the current implementation of the LOGGER creates 'fake' THD objects, like - Log_to_csv_event_handler::general_log_thd - Log_to_csv_event_handler::slow_log_thd which are not associated to a real thread running in the server, so that waiting for these non-existing threads to release table locks cause the dead lock. In general, the design of Log_to_csv_event_handler does not fit into the general architecture of the server, so that the concept of general_log_thd and slow_log_thd has to be abandoned: - this implementation does not work with table locking - it will not work with commands like SHOW PROCESSLIST - having the log tables always opened does not integrate well with DDL operations / FLUSH TABLES / SET GLOBAL READ_ONLY With this patch, the fundamental design of the LOGGER has been changed to: - always open and close a log table when writing a log - remove totally the usage of fake THD objects - clarify how locking of log tables is implemented in general. See WL#3984 for details related to the new locking design. Additional changes (misc bugs exposed and fixed): 1) mysqldump which would ignore some tables in dump_all_tables_in_db(), but forget to ignore the same in dump_all_views_in_db(). 2) mysqldump would also issue an empty "LOCK TABLE" command when all the tables to lock are to be ignored (numrows == 0), instead of not issuing the query. 3) Internal errors handlers could intercept errors but not warnings (see sql_error.cc). 4) Implementing a nested call to open tables, for the performance schema tables, exposed an existing bug in remove_table_from_cache(), which would perform: in_use->some_tables_deleted=1; against another thread, without any consideration about thread locking. This call inside remove_table_from_cache() was not required anyway, since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads that might hold a lock on a table. This line (in_use->some_tables_deleted=1) has been removed.
19 years ago
  1. set global general_log= OFF;
  2. truncate table mysql.general_log;
  3. truncate table mysql.slow_log;
  4. show global variables
  5. where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
  6. Variable_name = 'general_log' or Variable_name = 'slow_query_log';
  7. Variable_name Value
  8. general_log OFF
  9. log OFF
  10. log_slow_queries OFF
  11. slow_query_log OFF
  12. flush logs;
  13. set global general_log= ON;
  14. create table t1(f1 int);
  15. select * from mysql.general_log;
  16. event_time user_host thread_id server_id command_type argument
  17. TIMESTAMP USER_HOST # 1 Query create table t1(f1 int)
  18. TIMESTAMP USER_HOST # 1 Query select * from mysql.general_log
  19. set global general_log= OFF;
  20. drop table t1;
  21. select * from mysql.general_log;
  22. event_time user_host thread_id server_id command_type argument
  23. TIMESTAMP USER_HOST # 1 Query create table t1(f1 int)
  24. TIMESTAMP USER_HOST # 1 Query select * from mysql.general_log
  25. TIMESTAMP USER_HOST # 1 Query set global general_log= OFF
  26. set global general_log= ON;
  27. flush logs;
  28. show global variables
  29. where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
  30. Variable_name = 'general_log' or Variable_name = 'slow_query_log';
  31. Variable_name Value
  32. general_log ON
  33. log ON
  34. log_slow_queries OFF
  35. slow_query_log OFF
  36. set session long_query_time=1;
  37. select sleep(2);
  38. sleep(2)
  39. 0
  40. select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
  41. start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
  42. set global slow_query_log= ON;
  43. set session long_query_time=1;
  44. select sleep(2);
  45. sleep(2)
  46. 0
  47. select * from mysql.slow_log where sql_text NOT LIKE '%slow_log%';
  48. start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
  49. TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2)
  50. show global variables
  51. where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
  52. Variable_name = 'general_log' or Variable_name = 'slow_query_log';
  53. Variable_name Value
  54. general_log ON
  55. log ON
  56. log_slow_queries ON
  57. slow_query_log ON
  58. set global general_log= ON;
  59. set global general_log= OFF;
  60. set global general_log= OFF;
  61. set global slow_query_log= ON;
  62. set global slow_query_log= OFF;
  63. set global slow_query_log= OFF;
  64. set global general_log= ON;
  65. truncate table mysql.general_log;
  66. create table t1(f1 int);
  67. drop table t1;
  68. select * from mysql.general_log;
  69. event_time user_host thread_id server_id command_type argument
  70. TIMESTAMP USER_HOST # 1 Query create table t1(f1 int)
  71. TIMESTAMP USER_HOST # 1 Query drop table t1
  72. TIMESTAMP USER_HOST # 1 Query select * from mysql.general_log
  73. set global general_log= OFF;
  74. truncate table mysql.general_log;
  75. select * from mysql.general_log;
  76. event_time user_host thread_id server_id command_type argument
  77. set global general_log= ON;
  78. show global variables
  79. where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
  80. Variable_name = 'general_log' or Variable_name = 'slow_query_log';
  81. Variable_name Value
  82. general_log ON
  83. log ON
  84. log_slow_queries OFF
  85. slow_query_log OFF
  86. show variables like 'general_log_file';
  87. Variable_name Value
  88. general_log_file #
  89. show variables like 'slow_query_log_file';
  90. Variable_name Value
  91. slow_query_log_file #
  92. show variables like 'log_output';
  93. Variable_name Value
  94. log_output FILE,TABLE
  95. set global general_log_file='/not exiting path/log.master';
  96. ERROR 42000: Variable 'general_log_file' can't be set to the value of '/not exiting path/log.master'
  97. set global general_log_file='MYSQLTEST_VARDIR';
  98. ERROR 42000: Variable 'general_log_file' can't be set to the value of 'MYSQLTEST_VARDIR'
  99. set global general_log_file='';
  100. ERROR 42000: Variable 'general_log_file' can't be set to the value of ''
  101. show variables like 'general_log_file';
  102. Variable_name Value
  103. general_log_file #
  104. set global general_log= OFF;
  105. set global general_log_file='MYSQLTEST_VARDIR/tmp/log.master';
  106. set global general_log= ON;
  107. create table t1(f1 int);
  108. drop table t1;
  109. set global general_log= OFF;
  110. set global general_log_file=default;
  111. set global general_log= ON;
  112. create table t1(f1 int);
  113. drop table t1;
  114. show variables like 'general_log_file';
  115. Variable_name Value
  116. general_log_file #
  117. show variables like 'slow_query_log_file';
  118. Variable_name Value
  119. slow_query_log_file #
  120. set global general_log= default;
  121. set global slow_query_log= default;
  122. set global general_log_file= default;
  123. set global slow_query_log_file= default;
  124. show variables like 'general_log';
  125. Variable_name Value
  126. general_log OFF
  127. show variables like 'slow_query_log';
  128. Variable_name Value
  129. slow_query_log OFF
  130. set global general_log=ON;
  131. set global log_output=default;
  132. show variables like 'log_output';
  133. Variable_name Value
  134. log_output FILE
  135. set global general_log=OFF;
  136. set global log_output=FILE;
  137. truncate table mysql.general_log;
  138. show variables like 'log_output';
  139. Variable_name Value
  140. log_output FILE
  141. set global general_log=ON;
  142. create table t1(f1 int);
  143. select * from mysql.general_log;
  144. event_time user_host thread_id server_id command_type argument
  145. set global general_log=OFF;
  146. set global log_output="FILE,TABLE";
  147. show variables like 'log_output';
  148. Variable_name Value
  149. log_output FILE,TABLE
  150. set global general_log=ON;
  151. drop table t1;
  152. select * from mysql.general_log;
  153. event_time user_host thread_id server_id command_type argument
  154. TIMESTAMP USER_HOST # 1 Query drop table t1
  155. TIMESTAMP USER_HOST # 1 Query select * from mysql.general_log
  156. SET @old_general_log_state = @@global.general_log;
  157. SET @old_slow_log_state = @@global.slow_query_log;
  158. SET GLOBAL general_log = ON;
  159. SET GLOBAL slow_query_log = ON;
  160. FLUSH TABLES WITH READ LOCK;
  161. SET GLOBAL general_log = OFF;
  162. SET GLOBAL slow_query_log = OFF;
  163. UNLOCK TABLES;
  164. FLUSH TABLES WITH READ LOCK;
  165. SET GLOBAL general_log = ON;
  166. SET GLOBAL slow_query_log = ON;
  167. UNLOCK TABLES;
  168. SET GLOBAL READ_ONLY = ON;
  169. SET GLOBAL general_log = OFF;
  170. SET GLOBAL slow_query_log = OFF;
  171. SET GLOBAL READ_ONLY = OFF;
  172. SET GLOBAL READ_ONLY = ON;
  173. SET GLOBAL general_log = ON;
  174. SET GLOBAL slow_query_log = ON;
  175. SET GLOBAL READ_ONLY = OFF;
  176. SET GLOBAL general_log = @old_general_log_state;
  177. SET GLOBAL slow_query_log = @old_slow_log_state;
  178. SET @old_general_log_state = @@global.general_log;
  179. SET @old_slow_log_state = @@global.slow_query_log;
  180. SHOW VARIABLES LIKE 'general_log';
  181. Variable_name Value
  182. general_log ON
  183. SHOW VARIABLES LIKE 'log';
  184. Variable_name Value
  185. log ON
  186. SELECT @@general_log, @@log;
  187. @@general_log @@log
  188. 1 1
  189. SET GLOBAL log = 0;
  190. Warnings:
  191. Warning 1287 The syntax '@@log' is deprecated and will be removed in MySQL 7.0. Please use '@@general_log' instead
  192. SHOW VARIABLES LIKE 'general_log';
  193. Variable_name Value
  194. general_log OFF
  195. SHOW VARIABLES LIKE 'log';
  196. Variable_name Value
  197. log OFF
  198. SELECT @@general_log, @@log;
  199. @@general_log @@log
  200. 0 0
  201. SET GLOBAL general_log = 1;
  202. SHOW VARIABLES LIKE 'general_log';
  203. Variable_name Value
  204. general_log ON
  205. SHOW VARIABLES LIKE 'log';
  206. Variable_name Value
  207. log ON
  208. SELECT @@general_log, @@log;
  209. @@general_log @@log
  210. 1 1
  211. SHOW VARIABLES LIKE 'slow_query_log';
  212. Variable_name Value
  213. slow_query_log OFF
  214. SHOW VARIABLES LIKE 'log_slow_queries';
  215. Variable_name Value
  216. log_slow_queries OFF
  217. SELECT @@slow_query_log, @@log_slow_queries;
  218. @@slow_query_log @@log_slow_queries
  219. 0 0
  220. SET GLOBAL log_slow_queries = 0;
  221. Warnings:
  222. Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MySQL 7.0. Please use '@@slow_query_log' instead
  223. SHOW VARIABLES LIKE 'slow_query_log';
  224. Variable_name Value
  225. slow_query_log OFF
  226. SHOW VARIABLES LIKE 'log_slow_queries';
  227. Variable_name Value
  228. log_slow_queries OFF
  229. SELECT @@slow_query_log, @@log_slow_queries;
  230. @@slow_query_log @@log_slow_queries
  231. 0 0
  232. SET GLOBAL slow_query_log = 1;
  233. SHOW VARIABLES LIKE 'slow_query_log';
  234. Variable_name Value
  235. slow_query_log ON
  236. SHOW VARIABLES LIKE 'log_slow_queries';
  237. Variable_name Value
  238. log_slow_queries ON
  239. SELECT @@slow_query_log, @@log_slow_queries;
  240. @@slow_query_log @@log_slow_queries
  241. 1 1
  242. SET GLOBAL general_log = @old_general_log_state;
  243. SET GLOBAL slow_query_log = @old_slow_log_state;
  244. set @old_general_log_file= @@global.general_log_file;
  245. set @old_slow_query_log_file= @@global.slow_query_log_file;
  246. set global general_log_file= concat('/not exiting path/log.maste', 'r');
  247. ERROR 42000: Variable 'general_log_file' can't be set to the value of '/not exiting path/log.master'
  248. set global general_log_file= NULL;
  249. ERROR 42000: Variable 'general_log_file' can't be set to the value of 'NULL'
  250. set global slow_query_log_file= concat('/not exiting path/log.maste', 'r');
  251. ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of '/not exiting path/log.master'
  252. set global slow_query_log_file= NULL;
  253. ERROR 42000: Variable 'slow_query_log_file' can't be set to the value of 'NULL'
  254. set global general_log_file= @old_general_log_file;
  255. set global slow_query_log_file= @old_slow_query_log_file;
  256. # --
  257. # -- Bug#32748: Inconsistent handling of assignments to
  258. # -- general_log_file/slow_query_log_file.
  259. # --
  260. SET @general_log_file_saved = @@global.general_log_file;
  261. SET @slow_query_log_file_saved = @@global.slow_query_log_file;
  262. SET GLOBAL general_log_file = 'bug32748.query.log';
  263. SET GLOBAL slow_query_log_file = 'bug32748.slow.log';
  264. SHOW VARIABLES LIKE '%log_file';
  265. Variable_name Value
  266. general_log_file bug32748.query.log
  267. slow_query_log_file bug32748.slow.log
  268. SET GLOBAL general_log_file = @general_log_file_saved;
  269. SET GLOBAL slow_query_log_file = @slow_query_log_file_saved;
  270. # -- End of Bug#32748.
  271. deprecated:
  272. SET GLOBAL log = 0;
  273. Warnings:
  274. Warning 1287 The syntax '@@log' is deprecated and will be removed in MySQL 7.0. Please use '@@general_log' instead
  275. SET GLOBAL log_slow_queries = 0;
  276. Warnings:
  277. Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MySQL 7.0. Please use '@@slow_query_log' instead
  278. SET GLOBAL log = DEFAULT;
  279. Warnings:
  280. Warning 1287 The syntax '@@log' is deprecated and will be removed in MySQL 7.0. Please use '@@general_log' instead
  281. SET GLOBAL log_slow_queries = DEFAULT;
  282. Warnings:
  283. Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MySQL 7.0. Please use '@@slow_query_log' instead
  284. not deprecated:
  285. SELECT @@global.general_log_file INTO @my_glf;
  286. SELECT @@global.slow_query_log_file INTO @my_sqlf;
  287. SET GLOBAL general_log = 0;
  288. SET GLOBAL slow_query_log = 0;
  289. SET GLOBAL general_log_file = 'WL4403_G.log';
  290. SET GLOBAL slow_query_log_file = 'WL4403_SQ.log';
  291. SET GLOBAL general_log_file = @my_glf;
  292. SET GLOBAL slow_query_log_file = @my_sqlf;
  293. SET GLOBAL general_log = DEFAULT;
  294. SET GLOBAL slow_query_log = DEFAULT;
  295. End of 5.1 tests