Skip to content

Commit 421b732

Browse files
committed
WL#8159 Include Sys Schema in MySQL 5.7
1 parent 9f73961 commit 421b732

File tree

270 files changed

+5111
-90
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

270 files changed

+5111
-90
lines changed

client/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ MYSQL_ADD_EXECUTABLE(mysql_upgrade
4949
../sql-common/sql_string.cc
5050
)
5151
TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient client_base mysqlcheck_core)
52-
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
52+
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs GenSysSchema)
5353

5454
MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test)
5555
SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
@@ -101,7 +101,7 @@ IF(UNIX)
101101
auth_utils.cc mysql_install_db.cc
102102
COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/sql/auth"
103103
)
104-
ADD_DEPENDENCIES(mysql_install_db GenBootstrapPriv)
104+
ADD_DEPENDENCIES(mysql_install_db GenBootstrapPriv GenSysSchema)
105105
ENDIF(UNIX)
106106

107107
MYSQL_ADD_EXECUTABLE(mysql_ssl_rsa_setup mysql_ssl_rsa_setup.cc path.cc logger.cc)

client/mysql_install_db.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ using namespace std;
5555
#include "../scripts/sql_commands_system_tables.h"
5656
#include "../scripts/sql_commands_system_data.h"
5757
#include "../scripts/sql_commands_help_data.h"
58+
#include "../scripts/sql_commands_sys_schema.h"
5859

5960
#define PROGRAM_NAME "mysql_install_db"
6061
#define MYSQLD_EXECUTABLE "mysqld"
@@ -95,6 +96,7 @@ my_bool opt_no_defaults= FALSE;
9596
my_bool opt_insecure= FALSE;
9697
my_bool opt_verbose= FALSE;
9798
my_bool opt_ssl= FALSE;
99+
my_bool opt_skipsys= FALSE;
98100

99101
/**
100102
Connection options.
@@ -163,6 +165,8 @@ static struct my_option my_connection_options[]=
163165
&opt_langpath, 0, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
164166
{"lc-messages", 0, "Specifies the language to use.", &opt_lang,
165167
0, 0, GET_STR_ALLOC, REQUIRED_ARG, (longlong)&default_lang, 0, 0, 0, 0, 0},
168+
{"skip-sys-schema", 0, "Skip installation of the sys schema.",
169+
&opt_skipsys, 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
166170
/* End token */
167171
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
168172
};
@@ -1054,6 +1058,24 @@ class Process_writer
10541058
if (w1 != create_proxy_cmd.length() || errno != 0)
10551059
return false;
10561060

1061+
if (!opt_skipsys)
1062+
{
1063+
info << "Creating sys schema" << endl;
1064+
s= sizeof(mysql_sys_schema)/sizeof(*mysql_sys_schema);
1065+
for(unsigned i=0, n= 1; i< s && errno != EPIPE && n != 0 &&
1066+
mysql_sys_schema[i] != NULL; ++i)
1067+
{
1068+
n= write(fh, mysql_sys_schema[i],
1069+
strlen(mysql_sys_schema[i]));
1070+
}
1071+
if (errno != 0)
1072+
{
1073+
info << "failed." << endl;
1074+
return false;
1075+
}
1076+
else
1077+
info << "done." << endl;
1078+
}
10571079

10581080
/* Execute optional SQL from a file */
10591081
if (m_opt_sqlfile.length() > 0)

client/upgrade/program.cc

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "../client_priv.h"
1919
#include <string>
20+
#include <sstream>
2021
#include <vector>
2122
#include <algorithm>
2223
#include <memory>
@@ -26,16 +27,24 @@
2627
#include "my_default.h"
2728
#include "check/mysqlcheck.h"
2829
#include "../scripts/mysql_fix_privilege_tables_sql.c"
30+
#include "../scripts/sql_commands_sys_schema.h"
2931

3032
#include "base/abstract_connection_program.h"
3133
#include "base/abstract_options_provider.h"
3234
#include "show_variable_query_extractor.h"
3335

3436
using std::string;
3537
using std::vector;
38+
using std::stringstream;
3639

3740
int mysql_check_errors;
3841

42+
const int SYS_TABLE_COUNT = 1;
43+
const int SYS_VIEW_COUNT = 91;
44+
const int SYS_TRIGGER_COUNT = 2;
45+
const int SYS_FUNCTION_COUNT = 14;
46+
const int SYS_PROCEDURE_COUNT = 22;
47+
3948
/**
4049
Error callback to be called from mysql_check functionality.
4150
*/
@@ -57,6 +66,7 @@ namespace Upgrade{
5766

5867
using std::vector;
5968
using std::string;
69+
using std::stringstream;
6070

6171
enum exit_codes
6272
{
@@ -184,6 +194,226 @@ class Program : public Base::Abstract_connection_program
184194
}
185195
}
186196

197+
if (this->m_skip_sys_schema == false)
198+
{
199+
/*
200+
If the sys schema does not exist, then create it
201+
Otherwise, try to select from sys.version, if this does not
202+
exist but the schema does, then raise an error rather than
203+
overwriting/adding to the existing schema
204+
*/
205+
if (mysql_query(this->m_mysql_connection, "USE sys") != 0)
206+
{
207+
if (this->run_sys_schema_upgrade() != 0)
208+
{
209+
return EXIT_UPGRADING_QUERIES_ERROR;
210+
}
211+
} else {
212+
/* If the version is smaller, upgrade */
213+
if (mysql_query(this->m_mysql_connection, "SELECT * FROM sys.version") != 0)
214+
{
215+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
216+
"A sys schema exists with no sys.version view. "
217+
"If you have a user created sys schema, this must be "
218+
"renamed for the upgrade to succeed.");
219+
} else {
220+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
221+
if (result)
222+
{
223+
MYSQL_ROW row;
224+
225+
while ((row = mysql_fetch_row(result)))
226+
{
227+
ulong sys_version = calc_server_version(row[0]);
228+
if (sys_version >= calc_server_version(SYS_SCHEMA_VERSION))
229+
{
230+
stringstream ss;
231+
ss << "The sys schema is already up to date (version " << row[0] << ").";
232+
this->print_verbose_message(ss.str());
233+
} else {
234+
stringstream ss;
235+
ss << "Found outdated sys schema version " << row[0] << ".";
236+
this->print_verbose_message(ss.str());
237+
if (this->run_sys_schema_upgrade() != 0)
238+
{
239+
return EXIT_UPGRADING_QUERIES_ERROR;
240+
}
241+
}
242+
}
243+
mysql_free_result(result);
244+
} else {
245+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
246+
"A sys schema exists with a sys.version view, but it returns no results.");
247+
}
248+
}
249+
/*
250+
The version may be the same, but in some upgrade scenarios
251+
such as importing a 5.6 dump in to a fresh 5.7 install that
252+
includes the mysql schema, and then running mysql_upgrade,
253+
the functions/procedures will be removed.
254+
255+
In this case, we check for the expected counts of objects,
256+
and if those do not match, we just re-install the schema.
257+
*/
258+
if (mysql_query(this->m_mysql_connection,
259+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'sys' AND TABLE_TYPE = 'BASE TABLE'") != 0)
260+
{
261+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
262+
"Query against INFORMATION_SCHEMA.TABLES failed when checking the sys schema.");
263+
} else {
264+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
265+
if (result)
266+
{
267+
MYSQL_ROW row;
268+
269+
while ((row = mysql_fetch_row(result)))
270+
{
271+
if (SYS_TABLE_COUNT != atoi(row[0]))
272+
{
273+
stringstream ss;
274+
ss << "Found " << row[0] << " sys tables, but expected " << SYS_TABLE_COUNT << "."
275+
" Re-installing the sys schema.";
276+
this->print_verbose_message(ss.str());
277+
if (this->run_sys_schema_upgrade() != 0)
278+
{
279+
return EXIT_UPGRADING_QUERIES_ERROR;
280+
}
281+
}
282+
}
283+
284+
mysql_free_result(result);
285+
}
286+
}
287+
288+
if (mysql_query(this->m_mysql_connection,
289+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'sys' AND TABLE_TYPE = 'VIEW'") != 0)
290+
{
291+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
292+
"Query against INFORMATION_SCHEMA.TABLES failed when checking the sys schema.");
293+
} else {
294+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
295+
if (result)
296+
{
297+
MYSQL_ROW row;
298+
299+
while ((row = mysql_fetch_row(result)))
300+
{
301+
if (SYS_VIEW_COUNT != atoi(row[0]))
302+
{
303+
stringstream ss;
304+
ss << "Found " << row[0] << " sys views, but expected " << SYS_VIEW_COUNT << "."
305+
" Re-installing the sys schema.";
306+
this->print_verbose_message(ss.str());
307+
if (this->run_sys_schema_upgrade() != 0)
308+
{
309+
return EXIT_UPGRADING_QUERIES_ERROR;
310+
}
311+
}
312+
}
313+
314+
mysql_free_result(result);
315+
}
316+
}
317+
318+
if (mysql_query(this->m_mysql_connection,
319+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA = 'sys'") != 0)
320+
{
321+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
322+
"Query against INFORMATION_SCHEMA.TABLES failed when checking the sys schema.");
323+
} else {
324+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
325+
if (result)
326+
{
327+
MYSQL_ROW row;
328+
329+
while ((row = mysql_fetch_row(result)))
330+
{
331+
if (SYS_TRIGGER_COUNT != atoi(row[0]))
332+
{
333+
stringstream ss;
334+
ss << "Found " << row[0] << " sys triggers, but expected " << SYS_TRIGGER_COUNT << "."
335+
" Re-installing the sys schema.";
336+
this->print_verbose_message(ss.str());
337+
if (this->run_sys_schema_upgrade() != 0)
338+
{
339+
return EXIT_UPGRADING_QUERIES_ERROR;
340+
}
341+
}
342+
}
343+
344+
mysql_free_result(result);
345+
}
346+
}
347+
348+
if (mysql_query(this->m_mysql_connection,
349+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'sys' AND ROUTINE_TYPE = 'FUNCTION'") != 0)
350+
{
351+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
352+
"Query against INFORMATION_SCHEMA.TABLES failed when checking the sys schema.");
353+
} else {
354+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
355+
if (result)
356+
{
357+
MYSQL_ROW row;
358+
359+
while ((row = mysql_fetch_row(result)))
360+
{
361+
if (SYS_FUNCTION_COUNT != atoi(row[0]))
362+
{
363+
stringstream ss;
364+
ss << "Found " << row[0] << " sys functions, but expected " << SYS_FUNCTION_COUNT << "."
365+
" Re-installing the sys schema.";
366+
this->print_verbose_message(ss.str());
367+
if (this->run_sys_schema_upgrade() != 0)
368+
{
369+
return EXIT_UPGRADING_QUERIES_ERROR;
370+
}
371+
}
372+
}
373+
374+
mysql_free_result(result);
375+
}
376+
}
377+
378+
if (mysql_query(this->m_mysql_connection,
379+
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'sys' AND ROUTINE_TYPE = 'PROCEDURE'") != 0)
380+
{
381+
return this->print_error(EXIT_UPGRADING_QUERIES_ERROR,
382+
"Query against INFORMATION_SCHEMA.TABLES failed when checking the sys schema.");
383+
} else {
384+
MYSQL_RES *result = mysql_store_result(this->m_mysql_connection);
385+
if (result)
386+
{
387+
MYSQL_ROW row;
388+
389+
while ((row = mysql_fetch_row(result)))
390+
{
391+
if (SYS_PROCEDURE_COUNT != atoi(row[0]))
392+
{
393+
stringstream ss;
394+
ss << "Found " << row[0] << " sys procedures, but expected " << SYS_PROCEDURE_COUNT << "."
395+
" Re-installing the sys schema.";
396+
this->print_verbose_message(ss.str());
397+
if (this->run_sys_schema_upgrade() != 0)
398+
{
399+
return EXIT_UPGRADING_QUERIES_ERROR;
400+
}
401+
}
402+
}
403+
404+
mysql_free_result(result);
405+
}
406+
}
407+
408+
}
409+
if (mysql_query(this->m_mysql_connection, "USE mysql") != 0)
410+
{
411+
return this->print_error(1, "Cannot select mysql database.");
412+
}
413+
} else {
414+
this->print_verbose_message("Skipping installation/upgrade of the sys schema.");
415+
}
416+
187417
if (!this->m_upgrade_systables_only)
188418
{
189419
this->print_verbose_message("Checking databases.");
@@ -236,6 +466,10 @@ class Program : public Base::Abstract_connection_program
236466
"Force execution of SQL statements even if mysql_upgrade has already "
237467
"been executed for the current version of MySQL.")
238468
->set_short_character('f');
469+
470+
this->create_new_option(&this->m_skip_sys_schema, "skip-sys-schema",
471+
"Do not upgrade/install the sys schema.")
472+
->set_value(false);
239473
}
240474

241475
void error(int error_code)
@@ -322,6 +556,39 @@ class Program : public Base::Abstract_connection_program
322556
return 0;
323557
}
324558

559+
/**
560+
Update the sys schema
561+
*/
562+
int run_sys_schema_upgrade()
563+
{
564+
const char **query_ptr;
565+
int result;
566+
567+
Mysql_query_runner runner(*this->m_query_runner);
568+
runner.add_result_callback(
569+
new Instance_callback<int, vector<string>, Program>(
570+
this, &Program::result_callback));
571+
runner.add_message_callback(
572+
new Instance_callback<int, Mysql_message, Program>(
573+
this, &Program::fix_privilage_tables_error));
574+
575+
this->print_verbose_message("Upgrading the sys schema.");
576+
577+
for ( query_ptr= &mysql_sys_schema[0];
578+
*query_ptr != NULL;
579+
query_ptr++
580+
)
581+
{
582+
result= runner.run_query(*query_ptr);
583+
if (!this->m_ignore_errors && result != 0)
584+
{
585+
return result;
586+
}
587+
}
588+
589+
return 0;
590+
}
591+
325592
/**
326593
Gets path to file to write upgrade info into. Path is based on datadir of
327594
server.
@@ -637,6 +904,7 @@ class Program : public Base::Abstract_connection_program
637904
Mysql_query_runner* m_query_runner;
638905
bool m_write_binlog;
639906
bool m_upgrade_systables_only;
907+
bool m_skip_sys_schema;
640908
bool m_check_version;
641909
bool m_ignore_errors;
642910
bool m_verbose;

0 commit comments

Comments
 (0)