From 4b4a0532456fa05dc04c63d3e202e44573abaa4c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 9 Nov 2015 15:25:01 +0100 Subject: [PATCH 001/127] Raise version number after cloning 5.5.47 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b85da230659..4bf30e8600e 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=47 +MYSQL_VERSION_PATCH=48 MYSQL_VERSION_EXTRA= From 15de3c6275ad8898aed5cd466762030df0fef015 Mon Sep 17 00:00:00 2001 From: Ajo Robert Date: Fri, 13 Nov 2015 17:51:18 +0530 Subject: [PATCH 002/127] Bug#19817021 CRASH IN TABLE_LIST::PREPARE_SECURITY WHEN DOING BAD DDL IN PREPARED STATEMENT Analysis ======== A repeat execution of the prepared statement 'ALTER TABLE v1 CHECK PARTITION' where v1 is a view leads to server exit. ALTER TABLE ... CHECK PARTITION is not applicable for views and check for the same check is missing. This leads to further execution and creation of derived table for the view (Allocated under temp_table mem_root). Any reference to open view or related pointers from second execution leads to server exit as the same was freed at previous execution closure. Fix: ====== Added check for view in mysql_admin_table() on PARTITION operation. This will prevent mysql_admin_table() from going ahead and creating temp table and related issues. Changed message on admin table view operation error to be more appropriate. --- mysql-test/r/sp.result | 18 +++++++++--------- mysql-test/r/view.result | 12 ++++++------ sql/sql_admin.cc | 14 +++++++++++--- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 4d93ce202fe..638f54a93ce 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -4414,57 +4414,57 @@ test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK test.v1 repair Error 'test.v1' is not BASE TABLE -test.v1 repair error Corrupt +test.v1 repair status Operation failed Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK test.v1 optimize Error 'test.v1' is not BASE TABLE -test.v1 optimize error Corrupt +test.v1 optimize status Operation failed Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date test.v1 analyze Error 'test.v1' is not BASE TABLE -test.v1 analyze error Corrupt +test.v1 analyze status Operation failed call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK test.v1 repair Error 'test.v1' is not BASE TABLE -test.v1 repair error Corrupt +test.v1 repair status Operation failed Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK test.v1 optimize Error 'test.v1' is not BASE TABLE -test.v1 optimize error Corrupt +test.v1 optimize status Operation failed Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date test.v1 analyze Error 'test.v1' is not BASE TABLE -test.v1 analyze error Corrupt +test.v1 analyze status Operation failed call bug13012()| Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK test.v1 repair Error 'test.v1' is not BASE TABLE -test.v1 repair error Corrupt +test.v1 repair status Operation failed Table Op Msg_type Msg_text test.t1 optimize status OK test.t2 optimize status OK test.t3 optimize status OK test.v1 optimize Error 'test.v1' is not BASE TABLE -test.v1 optimize error Corrupt +test.v1 optimize status Operation failed Table Op Msg_type Msg_text test.t1 analyze status Table is already up to date test.t2 analyze status Table is already up to date test.t3 analyze status Table is already up to date test.v1 analyze Error 'test.v1' is not BASE TABLE -test.v1 analyze error Corrupt +test.v1 analyze status Operation failed drop procedure bug13012| drop view v1| select * from t1 order by data| diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index a3adf80c096..1842de91ef9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2402,28 +2402,28 @@ CREATE VIEW v1 AS SELECT id FROM t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text test.v1 optimize Error 'test.v1' is not BASE TABLE -test.v1 optimize error Corrupt +test.v1 optimize status Operation failed ANALYZE TABLE v1; Table Op Msg_type Msg_text test.v1 analyze Error 'test.v1' is not BASE TABLE -test.v1 analyze error Corrupt +test.v1 analyze status Operation failed REPAIR TABLE v1; Table Op Msg_type Msg_text test.v1 repair Error 'test.v1' is not BASE TABLE -test.v1 repair error Corrupt +test.v1 repair status Operation failed DROP TABLE t1; OPTIMIZE TABLE v1; Table Op Msg_type Msg_text test.v1 optimize Error 'test.v1' is not BASE TABLE -test.v1 optimize error Corrupt +test.v1 optimize status Operation failed ANALYZE TABLE v1; Table Op Msg_type Msg_text test.v1 analyze Error 'test.v1' is not BASE TABLE -test.v1 analyze error Corrupt +test.v1 analyze status Operation failed REPAIR TABLE v1; Table Op Msg_type Msg_text test.v1 repair Error 'test.v1' is not BASE TABLE -test.v1 repair error Corrupt +test.v1 repair status Operation failed DROP VIEW v1; create definer = current_user() sql security invoker view v1 as select 1; show create view v1; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index f07a8089853..efdb67d01c4 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights + reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -248,7 +249,8 @@ static inline bool table_not_corrupt_error(uint sql_errno) sql_errno == ER_LOCK_WAIT_TIMEOUT || sql_errno == ER_LOCK_DEADLOCK || sql_errno == ER_CANT_LOCK_LOG_TABLE || - sql_errno == ER_OPEN_AS_READONLY); + sql_errno == ER_OPEN_AS_READONLY || + sql_errno == ER_WRONG_OBJECT); } @@ -333,7 +335,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, lex->query_tables_last= &table->next_global; lex->query_tables_own_last= 0; - if (view_operator_func == NULL) + /* + CHECK TABLE command is allowed for views as well. Check on alter flags + to differentiate from ALTER TABLE...CHECK PARTITION on which view is not + allowed. + */ + if (lex->alter_info.flags & ALTER_ADMIN_PARTITION || + view_operator_func == NULL) table->required_type=FRMTYPE_TABLE; if (!thd->locked_tables_mode && repair_table_use_frm) From 6d1e2fbca805cb9dde94def5f579b0ee45444f5b Mon Sep 17 00:00:00 2001 From: Ajo Robert Date: Fri, 13 Nov 2015 18:04:31 +0530 Subject: [PATCH 003/127] Bug#20691429 ASSERTION `CHILD_L' FAILED IN STORAGE/MYISAMMRG/ HA_MYISAMMRG.CC:631 Analysis ======== Any attempt to open a temporary MyISAM merge table consisting of a view in its list of tables (not the last table in the list) under LOCK TABLES causes the server to exit. Current implementation doesn't perform sanity checks during merge table creation. This allows merge table to be created with incompatible tables (table with non-myisam engine), views or even with table doesn't exist in the system. During view open, check to verify whether requested view is part of a merge table is missing under LOCK TABLES path in open_table(). This leads to opening of underlying table with parent_l having NULL value. Later when attaching child tables to parent, this hits an ASSERT as all child tables should have parent_l pointing to merge parent. If the operation does not happen under LOCK TABLES mode, open_table() checks for view's parent_l and returns error. Fix: ====== Check added before opening view Under LOCK TABLES in open_table() to verify whether it is part of merge table. Error is returned if the view is part of a merge table. --- sql/sql_base.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 61a0d1ae909..172987cc1c6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2828,6 +2828,16 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, */ if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) { + /* + If parent_l of the table_list is non null then a merge table + has this view as child table, which is not supported. + */ + if (table_list->parent_l) + { + my_error(ER_WRONG_MRG_TABLE, MYF(0)); + DBUG_RETURN(true); + } + if (!tdc_open_view(thd, table_list, alias, key, key_length, mem_root, 0)) { From 63dc9c3f42858e0f855abb875f37cb096cf3ae27 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Wed, 18 Nov 2015 08:04:04 +0530 Subject: [PATCH 004/127] Bug #22214852: MYSQL 5.5 AND 5.6: MAIN.KEY AND OTHER FAILURE WITH VALGRIND FOR RELEASE BUILD Issue: ------ Initialization of variable with UNINIT_VAR is flagged by valgrind 3.11. SOLUTION: --------- Initialize the variable to 0. This is a backport of Bug# 14580121. --- storage/myisam/mi_check.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 5f326d0e45f..ba1f975549a 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -138,7 +138,7 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag) { reg2 ha_rows i; uint delete_link_length; - my_off_t empty,next_link,UNINIT_VAR(old_link); + my_off_t empty, next_link, old_link= 0; char buff[22],buff2[22]; DBUG_ENTER("chk_del"); From bb56c30ad750465ab140477a1042cb34e714dcc5 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Thu, 19 Nov 2015 13:59:27 +0530 Subject: [PATCH 005/127] Bug#17047208 REPLICATION DIFFERENCE FOR MULTIPLE TRIGGERS Problem & Analysis: If DML invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column, that DML has to be marked as 'unsafe' statement. If the tables are locked in the transaction prior to DML statement (using LOCK TABLES), then the same statement is not marked as 'unsafe' statement. The logic of checking whether unsafeness is protected with if (!thd->locked_tables_mode). Hence if we lock the tables prior to DML statement, it is *not* entering into this if condition. Hence the statement is not marked as unsafe statement. Fix: Irrespective of locked_tables_mode value, the unsafeness check should be done. Now with this patch, the code is moved out to 'decide_logging_format()' function where all these checks are happening and also with out 'if(!thd->locked_tables_mode)'. Along with the specified test case in the bug scenario (BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS), we also identified that other cases BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST, BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT, BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS are also protected with thd->locked_tables_mode which is not right. All of those checks also moved to 'decide_logging_format()' function. --- .../suite/rpl/r/rpl_unsafe_statements.result | 53 ++++++ .../suite/rpl/t/rpl_unsafe_statements.test | 175 ++++++++++++++++++ sql/sql_base.cc | 154 --------------- sql/sql_class.cc | 131 +++++++++++++ sql/sql_lex.h | 7 +- 5 files changed, 365 insertions(+), 155 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_unsafe_statements.result create mode 100644 mysql-test/suite/rpl/t/rpl_unsafe_statements.test diff --git a/mysql-test/suite/rpl/r/rpl_unsafe_statements.result b/mysql-test/suite/rpl/r/rpl_unsafe_statements.result new file mode 100644 index 00000000000..2efb3eba2b1 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_unsafe_statements.result @@ -0,0 +1,53 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TRIGGER trig1 AFTER INSERT ON t1 +FOR EACH ROW +INSERT INTO t2(i) VALUES(new.i); +START TRANSACTION; +INSERT INTO t2(i) VALUES (1); +ROLLBACK; +INSERT INTO t1(i) VALUES(2); +START TRANSACTION; +LOCK TABLES t1 WRITE, t2 WRITE; +INSERT INTO t1(i) VALUES(3); +UNLOCK TABLES; +COMMIT; +include/diff_tables.inc [master:t1, slave:t1] +include/diff_tables.inc [master:t2, slave:t2] +DROP TABLE t1,t2; +CREATE TABLE t1(i INT) ENGINE=INNODB; +CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; +INSERT INTO t1 values (1), (2), (3); +START TRANSACTION; +INSERT INTO t2(i) VALUES (1); +ROLLBACK; +INSERT INTO t2(i) SELECT i FROM t1; +START TRANSACTION; +LOCK TABLES t2 WRITE, t1 READ; +INSERT INTO t2(i) SELECT i FROM t1; +UNLOCK TABLES; +COMMIT; +include/diff_tables.inc [master:t1, slave:t1] +include/diff_tables.inc [master:t2, slave:t2] +DROP TABLE t1,t2; +CREATE TABLE t1(i int, id INT AUTO_INCREMENT, PRIMARY KEY (i, id)) ENGINE=MYISAM; +INSERT INTO t1 (i) values (1); +START TRANSACTION; +LOCK TABLES t1 WRITE; +INSERT INTO t1 (i) values (2); +UNLOCK TABLES; +COMMIT; +include/diff_tables.inc [master:t1, slave:t1] +DROP TABLE t1; +CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB; +INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; +START TRANSACTION; +LOCK TABLES t1 WRITE; +INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; +UNLOCK TABLES; +COMMIT; +include/diff_tables.inc [master:t1, slave:t1] +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_unsafe_statements.test b/mysql-test/suite/rpl/t/rpl_unsafe_statements.test new file mode 100644 index 00000000000..def8e8f50ec --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_unsafe_statements.test @@ -0,0 +1,175 @@ +################################################################################ +# Bug#17047208 REPLICATION DIFFERENCE FOR MULTIPLE TRIGGERS +# Problem: If DML invokes a trigger or a stored function that inserts into an +# AUTO_INCREMENT column, that DML has to be marked as 'unsafe' statement. If the +# tables are locked in the transaction prior to DML statement (using LOCK +# TABLES), then the DML statement is not marked as 'unsafe' statement. + +# Steps to reproduce the reported test case (BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS) +# Case-1: +# > Create a trigger on a table and do a insert in the trigger that updates +# auto increment column +# > A DML that executes the trigger in step.1 and check that DML is marked +# as unsafe and DML is written into binlog using row format (in MBR) +# > Execute the step 2 by locking the required tables prior to DML and check +# that DML is marked as unsafe and DML is written into binlog using row +# format (in MBR) +# +# This test script also adds test cases to cover few other unsafe statements. +# Case-2: BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT +# Case-3: BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST +# Case-4: BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS +################################################################################ + +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +# Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS +# Statement is unsafe because it invokes a trigger or a +# stored function that inserts into an AUTO_INCREMENT column. + +# Step-1.1: Create two tables, one with AUTO_INCREMENT column. +CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; + +# Step-1.2: Create a trigger that inserts into an AUTO_INCREMENT column. +CREATE TRIGGER trig1 AFTER INSERT ON t1 +FOR EACH ROW + INSERT INTO t2(i) VALUES(new.i); + +# Step-1.3: Create some gap in auto increment value on master's t2 table +# but not on slave (by doing rollback). Just in case if the unsafe statements +# are written in statement format, diff tables will fail. +START TRANSACTION; +INSERT INTO t2(i) VALUES (1); +ROLLBACK; + +# Step-1.4: Insert a tuple into table t1 that triggers trig1 which inserts +# into an AUTO_INCREMENT column. +INSERT INTO t1(i) VALUES(2); + +# Step-1.5: Repeat step 1.4 but using 'LOCK TABLES' logic. +START TRANSACTION; +LOCK TABLES t1 WRITE, t2 WRITE; +INSERT INTO t1(i) VALUES(3); +UNLOCK TABLES; +COMMIT; + +# Step-1.6: Sync slave with master +--sync_slave_with_master + +# Step-1.7: Diff master-slave tables to make sure everything is in sync. +--let $diff_tables=master:t1, slave:t1 +--source include/diff_tables.inc + +--let $diff_tables=master:t2, slave:t2 +--source include/diff_tables.inc + +# Step-1.8: Cleanup +--connection master +DROP TABLE t1,t2; + +# Case-2: BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT +# Statements writing to a table with an auto-increment column after selecting +# from another table are unsafe because the order in which rows are retrieved +# determines what (if any) rows will be written. This order cannot be +# predicted and may differ on master and the slave. + +# Step-2.1: Create two tables, one with AUTO_INCREMENT column. +CREATE TABLE t1(i INT) ENGINE=INNODB; +CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; + +# Step-2.2: Create some tuples in table t1. +INSERT INTO t1 values (1), (2), (3); + +# Step-2.3: Create some gap in auto increment value on master's t2 table +# but not on slave (by doing rollback). Just in case if the unsafe statements +# are written in statement format, diff tables will fail. +START TRANSACTION; +INSERT INTO t2(i) VALUES (1); +ROLLBACK; + +# Step-2.4: Insert into t2 (table with an auto-increment) by selecting tuples +# from table t1. +INSERT INTO t2(i) SELECT i FROM t1; + +# Step-2.5: Repeat step 2.4 but now with 'LOCK TABLES' logic. +START TRANSACTION; +LOCK TABLES t2 WRITE, t1 READ; +INSERT INTO t2(i) SELECT i FROM t1; +UNLOCK TABLES; +COMMIT; + +# Step-2.6: Sync slave with master +--sync_slave_with_master + +# Step-2.7: Diff master-slave tables to make sure everything is in sync. +--let $diff_tables=master:t1, slave:t1 +--source include/diff_tables.inc + +--let $diff_tables=master:t2, slave:t2 +--source include/diff_tables.inc + +# Step-2.8: Cleanup +--connection master +DROP TABLE t1,t2; + +# Case-3: BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST +# INSERT into autoincrement field which is not the first part in the +# composed primary key is unsafe +# +# Step-3.1: Create a table with auto increment column and a composed primary key +# (second column is auto increment column). Such a definition is allowed only +# with 'myisam' engine. +CREATE TABLE t1(i int, id INT AUTO_INCREMENT, PRIMARY KEY (i, id)) ENGINE=MYISAM; + +# Step-3.2: Inserting into such a table is unsafe. +INSERT INTO t1 (i) values (1); + +# Step-3.3: Repeat step 3.2, now with 'LOCK TABLES' logic. +START TRANSACTION; +LOCK TABLES t1 WRITE; +INSERT INTO t1 (i) values (2); +UNLOCK TABLES; +COMMIT; + +# Step-3.4: Sync slave with master +--sync_slave_with_master + +# Step-3.5: Diff master-slave tables to make sure everything is in sync. +--let $diff_tables=master:t1, slave:t1 +--source include/diff_tables.inc + +# Step-3.6: Cleanup +--connection master +DROP TABLE t1; + +# Case-4: BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS +# INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY +# is unsafe Statement + +# Step-4.1: Create a table with two unique keys +CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB; + +# Step-4.2: Inserting into such a table is unsafe. +INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; + +# Step-4.3: Repeat step 3.2, now with 'LOCK TABLES' logic. +START TRANSACTION; +LOCK TABLES t1 WRITE; +INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; +UNLOCK TABLES; +COMMIT; + +# Step-4.4: Sync slave with master +--sync_slave_with_master + +# Step-4.5: Diff master-slave tables to make sure everything is in sync. +--let $diff_tables=master:t1, slave:t1 +--source include/diff_tables.inc + +# Step-4.6: Cleanup +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 172987cc1c6..f559974c86b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -212,11 +212,6 @@ static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables, static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry); static bool auto_repair_table(THD *thd, TABLE_LIST *table_list); static void free_cache_entry(TABLE *entry); -static bool -has_write_table_with_auto_increment(TABLE_LIST *tables); -static bool -has_write_table_with_auto_increment_and_select(TABLE_LIST *tables); -static bool has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables); uint cached_open_tables(void) { @@ -5744,63 +5739,6 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, *(ptr++)= table->table; } - /* - DML statements that modify a table with an auto_increment column based on - rows selected from a table are unsafe as the order in which the rows are - fetched fron the select tables cannot be determined and may differ on - master and slave. - */ - if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables && - has_write_table_with_auto_increment_and_select(tables)) - thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT); - /* Todo: merge all has_write_table_auto_inc with decide_logging_format */ - if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables) - { - if (has_write_table_auto_increment_not_first_in_pk(tables)) - thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST); - } - - /* - INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys - can be unsafe. - */ - uint unique_keys= 0; - for (TABLE_LIST *query_table= tables; query_table && unique_keys <= 1; - query_table= query_table->next_global) - if(query_table->table) - { - uint keys= query_table->table->s->keys, i= 0; - unique_keys= 0; - for (KEY* keyinfo= query_table->table->s->key_info; - i < keys && unique_keys <= 1; i++, keyinfo++) - { - if (keyinfo->flags & HA_NOSAME) - unique_keys++; - } - if (!query_table->placeholder() && - query_table->lock_type >= TL_WRITE_ALLOW_WRITE && - unique_keys > 1 && thd->lex->sql_command == SQLCOM_INSERT && - /* Duplicate key update is not supported by INSERT DELAYED */ - thd->command != COM_DELAYED_INSERT && - thd->lex->duplicates == DUP_UPDATE) - thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS); - } - - /* We have to emulate LOCK TABLES if we are statement needs prelocking. */ - if (thd->lex->requires_prelocking()) - { - - /* - A query that modifies autoinc column in sub-statement can make the - master and slave inconsistent. - We can solve these problems in mixed mode by switching to binlogging - if at least one updated table is used by sub-statement - */ - if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables && - has_write_table_with_auto_increment(thd->lex->first_not_own_table())) - thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS); - } - DEBUG_SYNC(thd, "before_lock_tables_takes_lock"); if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), @@ -9170,98 +9108,6 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b) return a->length == b->length && !strncmp(a->str, b->str, a->length); } - -/* - Tells if two (or more) tables have auto_increment columns and we want to - lock those tables with a write lock. - - SYNOPSIS - has_two_write_locked_tables_with_auto_increment - tables Table list - - NOTES: - Call this function only when you have established the list of all tables - which you'll want to update (including stored functions, triggers, views - inside your statement). -*/ - -static bool -has_write_table_with_auto_increment(TABLE_LIST *tables) -{ - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - /* we must do preliminary checks as table->table may be NULL */ - if (!table->placeholder() && - table->table->found_next_number_field && - (table->lock_type >= TL_WRITE_ALLOW_WRITE)) - return 1; - } - - return 0; -} - -/* - checks if we have select tables in the table list and write tables - with auto-increment column. - - SYNOPSIS - has_two_write_locked_tables_with_auto_increment_and_select - tables Table list - - RETURN VALUES - - -true if the table list has atleast one table with auto-increment column - - - and atleast one table to select from. - -false otherwise -*/ - -static bool -has_write_table_with_auto_increment_and_select(TABLE_LIST *tables) -{ - bool has_select= false; - bool has_auto_increment_tables = has_write_table_with_auto_increment(tables); - for(TABLE_LIST *table= tables; table; table= table->next_global) - { - if (!table->placeholder() && - (table->lock_type <= TL_READ_NO_INSERT)) - { - has_select= true; - break; - } - } - return(has_select && has_auto_increment_tables); -} - -/* - Tells if there is a table whose auto_increment column is a part - of a compound primary key while is not the first column in - the table definition. - - @param tables Table list - - @return true if the table exists, fais if does not. -*/ - -static bool -has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables) -{ - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - /* we must do preliminary checks as table->table may be NULL */ - if (!table->placeholder() && - table->table->found_next_number_field && - (table->lock_type >= TL_WRITE_ALLOW_WRITE) - && table->table->s->next_number_keypart != 0) - return 1; - } - - return 0; -} - - - /* Open and lock system tables for read. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c3d2a092fd6..05bb38d8358 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4142,6 +4142,94 @@ void xid_cache_delete(XID_STATE *xid_state) mysql_mutex_unlock(&LOCK_xid_cache); } +/* + Tells if two (or more) tables have auto_increment columns and we want to + lock those tables with a write lock. + + SYNOPSIS + has_two_write_locked_tables_with_auto_increment + tables Table list + + NOTES: + Call this function only when you have established the list of all tables + which you'll want to update (including stored functions, triggers, views + inside your statement). +*/ + +static bool +has_write_table_with_auto_increment(TABLE_LIST *tables) +{ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + /* we must do preliminary checks as table->table may be NULL */ + if (!table->placeholder() && + table->table->found_next_number_field && + (table->lock_type >= TL_WRITE_ALLOW_WRITE)) + return 1; + } + + return 0; +} + +/* + checks if we have select tables in the table list and write tables + with auto-increment column. + + SYNOPSIS + has_two_write_locked_tables_with_auto_increment_and_select + tables Table list + + RETURN VALUES + + -true if the table list has atleast one table with auto-increment column + + + and atleast one table to select from. + -false otherwise +*/ + +static bool +has_write_table_with_auto_increment_and_select(TABLE_LIST *tables) +{ + bool has_select= false; + bool has_auto_increment_tables = has_write_table_with_auto_increment(tables); + for(TABLE_LIST *table= tables; table; table= table->next_global) + { + if (!table->placeholder() && + (table->lock_type <= TL_READ_NO_INSERT)) + { + has_select= true; + break; + } + } + return(has_select && has_auto_increment_tables); +} + +/* + Tells if there is a table whose auto_increment column is a part + of a compound primary key while is not the first column in + the table definition. + + @param tables Table list + + @return true if the table exists, fais if does not. +*/ + +static bool +has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables) +{ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + /* we must do preliminary checks as table->table may be NULL */ + if (!table->placeholder() && + table->table->found_next_number_field && + (table->lock_type >= TL_WRITE_ALLOW_WRITE) + && table->table->s->next_number_keypart != 0) + return 1; + } + + return 0; +} /** Decide on logging format to use for the statement and issue errors @@ -4305,6 +4393,31 @@ int THD::decide_logging_format(TABLE_LIST *tables) } #endif + if (variables.binlog_format != BINLOG_FORMAT_ROW && tables) + { + /* + DML statements that modify a table with an auto_increment column based on + rows selected from a table are unsafe as the order in which the rows are + fetched fron the select tables cannot be determined and may differ on + master and slave. + */ + if (has_write_table_with_auto_increment_and_select(tables)) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT); + + if (has_write_table_auto_increment_not_first_in_pk(tables)) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST); + + /* + A query that modifies autoinc column in sub-statement can make the + master and slave inconsistent. + We can solve these problems in mixed mode by switching to binlogging + if at least one updated table is used by sub-statement + */ + if (lex->requires_prelocking() && + has_write_table_with_auto_increment(lex->first_not_own_table())) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS); + } + /* Get the capabilities vector for all involved storage engines and mask out the flags for the binary log. @@ -4343,6 +4456,24 @@ int THD::decide_logging_format(TABLE_LIST *tables) prev_write_table= table->table; + /* + INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys + can be unsafe. Check for it if the flag is already not marked for the + given statement. + */ + if (!lex->is_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS) && + lex->sql_command == SQLCOM_INSERT && lex->duplicates == DUP_UPDATE) + { + uint keys= table->table->s->keys, i= 0, unique_keys= 0; + for (KEY* keyinfo= table->table->s->key_info; + i < keys && unique_keys <= 1; i++, keyinfo++) + { + if (keyinfo->flags & HA_NOSAME) + unique_keys++; + } + if (unique_keys > 1 ) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS); + } } flags_access_some_set |= flags; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c5886b3c142..867997feb39 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1362,6 +1362,11 @@ public: return get_stmt_unsafe_flags() != 0; } + inline bool is_stmt_unsafe(enum_binlog_stmt_unsafe unsafe) + { + return binlog_stmt_flags & (1 << unsafe); + } + /** Flag the current (top-level) statement as unsafe. The flag will be reset after the statement has finished. From f3554bf148710c73df2a1ca5547ea7ff7c21a969 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 20 Nov 2015 05:40:39 +0530 Subject: [PATCH 006/127] Bug #22214867: MYSQL 5.5: MAIN.SUBSELECT AND OTHERS FAIL WITH NEW VALGRIND Issue: ------ Function signature in valgrind.supp requires a change with valgrind 3.11. Static function is replaced with wild card. --- mysql-test/valgrind.supp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 52b59da58cd..72fcd3ef787 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -1,4 +1,4 @@ -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -881,8 +881,8 @@ # write_keys() and find_all_keys(). # They both return ha_rows, which is platform dependent. # -# The '...' wildcards are for 'fun:inline_mysql_file_write' which *may* -# be inlined. +# The '...' wildcards are for 'fun:inline_mysql_file_write' and +# 'fun:find_all_keys' which *may* be inlined. { Bug#12856915 VALGRIND FAILURE IN FILESORT/CREATE_SORT_INDEX / one Memcheck:Param @@ -893,7 +893,7 @@ fun:my_b_flush_io_cache fun:_my_b_write fun:_Z*10write_keysP13st_sort_paramPPhjP11st_io_cacheS4_ - fun:_Z*13find_all_keysP13st_sort_paramP10SQL_SELECTPPhP11st_io_cacheS6_ + ... fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPy } From a7fb5aecfd527c6b9274db02dcec69daf06c97a3 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Fri, 20 Nov 2015 12:30:15 +0530 Subject: [PATCH 007/127] Bug#19941403: FATAL_SIGNAL(SIG 6) IN BUILD_EQUAL_ITEMS_FOR_COND | IN SQL/SQL_OPTIMIZER.CC:1657 Problem: At the end of first execution select_lex->prep_where is pointing to a runtime created object (temporary table field). As a result server exits trying to access a invalid pointer during second execution. Analysis: While optimizing the join conditions for the query, after the permanent transformation, optimizer makes a copy of the new where conditions in select_lex->prep_where. "prep_where" is what is used as the "where condition" for the query at the start of execution. W.r.t the query in question, "where" condition is actually pointing to a field in the temporary table. As a result, for the second execution the pointer is no more valid resulting in server exit. Fix: At the end of the first execution, select_lex->where will have the original item of the where condition. Make prep_where the new place where the original item of select->where has to be rolled back. Fixed in 5.7 with the wl#7082 - Move permanent transformations from JOIN::optimize to JOIN::prepare Patch for 5.5 includes the following backports from 5.6: Bugfix for Bug12603141 - This makes the first execute statement in the testcase pass in 5.5 However it was noted later in in Bug16163596 that the above bugfix needed to be modified. Although Bug16163596 is reproducible only with changes done for Bug12582849, we have decided include the fix. Considering that Bug12582849 is related to Bug12603141, the fix is also included here. However this results in Bug16317817, Bug16317685, Bug16739050. So fix for the above three bugs is also part of this patch. --- sql/item.cc | 2 +- sql/item.h | 8 +++++++- sql/item_cmpfunc.cc | 5 +++-- sql/item_cmpfunc.h | 10 +++++----- sql/sql_class.cc | 15 +++++++++++++++ sql/sql_class.h | 16 ++++++++++++++++ sql/sql_lex.cc | 23 +++++++++++++++++++++-- sql/sql_select.cc | 19 +++++++++++++++++-- 8 files changed, 85 insertions(+), 13 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index fd590574e56..beb68c5d321 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4684,7 +4684,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) It's not an Item_field in the select list so we must make a new Item_ref to point to the Item in the select list and replace the Item_field created by the parser with the new Item_ref. - + Ex: SELECT func1(col) as c ... ORDER BY func2(c); NOTE: If we are fixing an alias reference inside ORDER/GROUP BY item tree, then we use new Item_ref as an intermediate value to resolve referenced item only. diff --git a/sql/item.h b/sql/item.h index 629f9afa241..831343de7ad 100644 --- a/sql/item.h +++ b/sql/item.h @@ -960,7 +960,13 @@ public: */ virtual void no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } - virtual Item *copy_andor_structure(THD *thd) { return this; } + /** + @param real_items True <=> in the copy, replace any Item_ref with its + real_item() + @todo this argument should be always false and removed in WL#7082. + */ + virtual Item *copy_andor_structure(THD *thd, bool real_items= false) + { return real_items ? real_item() : this; } virtual Item *real_item() { return this; } virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e6cc3272ceb..b302440272e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4303,11 +4303,12 @@ Item_cond::Item_cond(THD *thd, Item_cond *item) } -void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item) +void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item, bool real_items) { List_iterator_fast li(item->list); while (Item *it= li++) - list.push_back(it->copy_andor_structure(thd)); + list.push_back((real_items ? it->real_item() : it)-> + copy_andor_structure(thd, real_items)); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 115d6db300d..00c7bccbfb8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1514,7 +1514,7 @@ public: friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds); void top_level_item() { abort_on_null=1; } - void copy_andor_arguments(THD *thd, Item_cond *item); + void copy_andor_arguments(THD *thd, Item_cond *item, bool real_items= false); bool walk(Item_processor processor, bool walk_subquery, uchar *arg); Item *transform(Item_transformer transformer, uchar *arg); void traverse_cond(Cond_traverser, void *arg, traverse_order order); @@ -1689,11 +1689,11 @@ public: const char *func_name() const { return "and"; } table_map not_null_tables() const { return abort_on_null ? not_null_tables_cache: and_tables_cache; } - Item* copy_andor_structure(THD *thd) + Item* copy_andor_structure(THD *thd, bool real_items) { Item_cond_and *item; if ((item= new Item_cond_and(thd, this))) - item->copy_andor_arguments(thd, this); + item->copy_andor_arguments(thd, this, real_items); return item; } Item *neg_transformer(THD *thd); @@ -1719,11 +1719,11 @@ public: longlong val_int(); const char *func_name() const { return "or"; } table_map not_null_tables() const { return and_tables_cache; } - Item* copy_andor_structure(THD *thd) + Item* copy_andor_structure(THD *thd, bool real_items) { Item_cond_or *item; if ((item= new Item_cond_or(thd, this))) - item->copy_andor_arguments(thd, this); + item->copy_andor_arguments(thd, this, real_items); return item; } Item *neg_transformer(THD *thd); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 05bb38d8358..629088dd862 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2064,6 +2064,21 @@ struct Item_change_record: public ilink static void operator delete(void *ptr, void *mem) { /* never called */ } }; +void THD::change_item_tree_place(Item **old_ref, Item **new_ref) +{ + I_List_iterator it(change_list); + Item_change_record *change; + while ((change= it++)) + { + if (change->place == old_ref) + { + DBUG_PRINT("info", ("change_item_tree_place old_ref %p new_ref %p", + old_ref, new_ref)); + change->place= new_ref; + break; + } + } +} /* Register an item tree tree transformation, performed by the query diff --git a/sql/sql_class.h b/sql/sql_class.h index 5a5e8b48754..c9900231615 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2515,6 +2515,22 @@ public: nocheck_register_item_tree_change(place, *place, mem_root); *place= new_value; } + + /* + Find and update change record of an underlying item. + + @param old_ref The old place of moved expression. @param new_ref The + new place of moved expression. @details During permanent + transformations, e.g. join flattening in simplify_joins, a condition + could be moved from one place to another, e.g. from on_expr to WHERE + condition. If the moved condition has replaced some other with + change_item_tree() function, the change record will restore old value to + the wrong place during rollback_item_tree_changes. This function goes + through the list of change records, and replaces + Item_change_record::place. + */ + void change_item_tree_place(Item **old_ref, Item **new_ref); + void nocheck_register_item_tree_change(Item **place, Item *old_value, MEM_ROOT *runtime_memroot); void rollback_item_tree_changes(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 17446778034..50cdabe341a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3158,7 +3158,26 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds, } if (*conds) { - prep_where= *conds; + /* + In "WHERE outer_field", *conds may be an Item_outer_ref allocated in + the execution memroot. + @todo change this line in WL#7082. Currently, when we execute a SP, + containing "SELECT (SELECT ... WHERE t1.col) FROM t1", + resolution may make *conds equal to an Item_outer_ref, then below + *conds becomes Item_field, which then goes straight on to execution, + undoing the effects of putting Item_outer_ref in the first place... + With a PS the problem is not as severe, as after the code below we + don't go to execution: a next execution will do a new name resolution + which will create Item_outer_ref again. + + To reviewers: in WL#7082, + prep_where= (*conds)->real_item(); + becomes: + prep_where= *conds; + thd->change_item_tree_place(conds, &prep_where); + and same for HAVING. + */ + prep_where= (*conds)->real_item(); *conds= where= prep_where->copy_andor_structure(thd); } if (*having_conds) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 96f60d46651..96271f26b0f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -915,7 +915,22 @@ JOIN::optimize() conds= simplify_joins(this, join_list, conds, TRUE); build_bitmap_for_nested_joins(join_list, 0); - sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; + /* + After permanent transformations above, prep_where created in + st_select_lex::fix_prepare_information() is out-of-date, we need to + refresh it. + For that We must copy "conds" because it contains AND/OR items in a + non-permanent memroot. And this copy must contain real items only, + because the new AND/OR items will not have their argument pointers + restored by rollback_item_tree_changes(). + @see st_select_lex::fix_prepare_information() for problems with this. + @todo in WL#7082 move transformations above to before + st_select_lex::fix_prepare_information(), and remove this second copy + below. + */ + sel->prep_where= conds ? conds->copy_andor_structure(thd, true) : NULL; + if (conds) + thd->change_item_tree_place(&conds, &select_lex->prep_where); if (arena) thd->restore_active_arena(arena, &backup); @@ -9061,7 +9076,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) DBUG_ASSERT(expr); table->on_expr= expr; - table->prep_on_expr= expr->copy_andor_structure(join->thd); + table->prep_on_expr= expr->copy_andor_structure(join->thd, true); } } nested_join->used_tables= (table_map) 0; From 08e929388b2cea170f6a44e9c8669f9c0f636808 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Sat, 21 Nov 2015 11:08:44 +0530 Subject: [PATCH 008/127] Bug #17047208 REPLICATION DIFFERENCE FOR MULTIPLE TRIGGERS Fixing pb2 valgrind failure Missed a 'if condition' check while moving the logic from one place to another place. --- sql/sql_class.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 629088dd862..4711009d7cd 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4477,7 +4477,9 @@ int THD::decide_logging_format(TABLE_LIST *tables) given statement. */ if (!lex->is_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS) && - lex->sql_command == SQLCOM_INSERT && lex->duplicates == DUP_UPDATE) + lex->sql_command == SQLCOM_INSERT && + /* Duplicate key update is not supported by INSERT DELAYED */ + command != COM_DELAYED_INSERT && lex->duplicates == DUP_UPDATE) { uint keys= table->table->s->keys, i= 0, unique_keys= 0; for (KEY* keyinfo= table->table->s->key_info; From 2735f0b92020c8ac4bd07d7ea843a0946b19e8ad Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Tue, 1 Dec 2015 15:38:11 +0530 Subject: [PATCH 009/127] Bug#21205695 DROP TABLE MAY CAUSE SLAVES TO BREAK Problem: ======== 1) Drop table queries are re-generated by server before writing the events(queries) into binlog for various reasons. If table name/db name contains a non regular characters (like latin characters), the generated query is wrong. Hence it breaks the replication. 2) In the edge case, when table name/db name contains 64 characters, server is throwing an assert assert(M_TBLLEN < 128) 3) In the edge case, when db name contains 64 latin characters, binlog content is interpreted badly which is leading replication failure. Analysis & Fix : ================ 1) Parser reads the table name from the query and converts it to standard charset(utf8) and stores it in table_name variable. When drop table query is regenerated with the same table_name variable, it should be converted back to the original charset from standard charset(utf8). 2) Latin character takes two bytes for each character. Limit of the identifier is 64. SYSTEM_CHARSET_MBMAXLEN is set to '3'. So there is a possiblity that tablename/dbname contains 3 * 64. Hence assert is changed to (M_TBLLEN <= NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) 3) db_len in the binlog event header is taking 1 byte. db_len is ranged from 0 to 192 bytes (3 * 64). While reading the db_len from the event, server is casting to uint instead of uchar which is leading to bad db_len. This problem is fixed by changing the cast type to uchar. --- .../rpl_autogen_query_multi_byte_char.result | 29 +++++++ .../t/rpl_autogen_query_multi_byte_char.test | 87 +++++++++++++++++++ sql/log_event.cc | 10 +-- sql/sql_show.cc | 57 +++++++----- sql/sql_show.h | 10 ++- sql/sql_table.cc | 12 ++- 6 files changed, 173 insertions(+), 32 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_autogen_query_multi_byte_char.result create mode 100644 mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test diff --git a/mysql-test/suite/rpl/r/rpl_autogen_query_multi_byte_char.result b/mysql-test/suite/rpl/r/rpl_autogen_query_multi_byte_char.result new file mode 100644 index 00000000000..b03c0057a69 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_autogen_query_multi_byte_char.result @@ -0,0 +1,29 @@ +include/master-slave.inc +[connection master] +Test case 1:- table name with one character latin name. +SET @s:=CONCAT("CREATE TABLE `",REPEAT(CHAR(131),1),"` (a INT)"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("INSERT INTO `",REPEAT(CHAR(131),1),"` VALUES (1)"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("DROP TABLE `",REPEAT(CHAR(131),1), "`"); +PREPARE STMT FROM @s; +EXECUTE stmt; +Test case 2:- table name and database names with one character latin name. +SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(131),1),"`"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("CREATE TABLE `",REPEAT(CHAR(131),1),"`.`",REPEAT(CHAR(131),1),"` (a INT)"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("INSERT INTO `",REPEAT(CHAR(131),1),"`.`",REPEAT(CHAR(131),1),"` VALUES (1)"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("DROP TABLE `",REPEAT(CHAR(131),1),"`.`",REPEAT(CHAR(131),1), "`"); +PREPARE STMT FROM @s; +EXECUTE stmt; +SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(131),1),"`"); +PREPARE STMT FROM @s; +EXECUTE stmt; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test b/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test new file mode 100644 index 00000000000..a93fcbac82f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test @@ -0,0 +1,87 @@ +############################################################################### +# Bug#21205695 DROP TABLE MAY CAUSE SLAVES TO BREAK +# +# Problem: +# ======== +# 1) Drop table queries are re-generated by server +# before writing the events(queries) into binlog +# for various reasons. If table name/db name contains +# a non regular characters (like latin characters), +# the generated query is wrong. Hence it breaks the +# replication. +# 2) In the edge case, when table name contains +# 64 latin characters (latin takes 2 bytes), server is +# throwing an assert (M_TBLLEN < 128) +# +# 3) In the edge case, when db name contains 64 latin +# characters, binlog contents are interpreted wrongly +# which is leading to replication issues. +# +############################################################################### + +--source include/not_windows.inc +--source include/master-slave.inc + +--let iter=1 +# Change iteration to 4 after fixing Bug #22280214 +while ($iter <= 2) +{ + --connection master + if ($iter == 1) + { + --echo Test case 1:- table name with one character latin name. + --let $tblname= REPEAT(CHAR(131),1) + } + if ($iter == 2) + { + --echo Test case 2:- table name and database names with one character latin name. + --let $tblname= REPEAT(CHAR(131),1),"`.`",REPEAT(CHAR(131),1) + --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(131),1),"`") + PREPARE STMT FROM @s; EXECUTE stmt; + } + # After fixing Bug #22280214 DATADIR LOCATION IS LIMITING + # IDENTIFIER MAX LENGTH, the following two tests (iter 3 and 4) can be + # uncommented. + #if ($iter == 3) + #{ + # --echo Test case 3:- table name and database names with 64 latin characters name. + # --let $tblname= REPEAT(CHAR(131),64),"`.`", REPEAT(CHAR(131),64) + # --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(131),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + #if ($iter == 4) + #{ + # --echo Test case 4:- table name and database names with 64 Euro(€) characters. + # --let $tblname= REPEAT(CHAR(226,130,172),64),"`.`", REPEAT(CHAR(226,130,172),64) + # --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(226,130,172),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + --eval SET @s:=CONCAT("CREATE TABLE `",$tblname,"` (a INT)") + PREPARE STMT FROM @s; EXECUTE stmt; + --eval SET @s:=CONCAT("INSERT INTO `",$tblname,"` VALUES (1)") + PREPARE STMT FROM @s; EXECUTE stmt; + --eval SET @s:=CONCAT("DROP TABLE `",$tblname, "`") + PREPARE STMT FROM @s; EXECUTE stmt; + if ($iter == 2) + { + --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(131),1),"`") + PREPARE STMT FROM @s; EXECUTE stmt; + } + # After fixing Bug #22280214 DATADIR LOCATION IS LIMITING + # IDENTIFIER MAX LENGTH, the following two tests (iter 3 and 4) can be + # uncommented. + #if ($iter == 3) + #{ + # --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(131),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + #if ($iter == 4) + #{ + # --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(226,130,172),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + --sync_slave_with_master + --inc $iter +} + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 38efb2a9c6b..accb6a28dbd 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2792,7 +2792,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET); exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET); - db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars + db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars error_code = uint2korr(buf + Q_ERR_CODE_OFFSET); /* @@ -8960,9 +8960,9 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) { DBUG_ASSERT(m_dbnam != NULL); DBUG_ASSERT(m_tblnam != NULL); - /* We use only one byte per length for storage in event: */ - DBUG_ASSERT(m_dblen < 128); - DBUG_ASSERT(m_tbllen < 128); + + DBUG_ASSERT(m_dblen <= NAME_LEN); + DBUG_ASSERT(m_tbllen <= NAME_LEN); uchar const dbuf[]= { (uchar) m_dblen }; uchar const tbuf[]= { (uchar) m_tbllen }; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5da9f43d793..c936ea69a97 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -949,29 +949,44 @@ static const char *require_quotes(const char *name, uint name_length) } -/* - Quote the given identifier if needed and append it to the target string. - If the given identifier is empty, it will be quoted. - - SYNOPSIS - append_identifier() - thd thread handler - packet target string - name the identifier to be appended - name_length length of the appending identifier +/** + Convert and quote the given identifier if needed and append it to the + target string. If the given identifier is empty, it will be quoted. + @thd thread handler + @packet target string + @name the identifier to be appended + @length length of the appending identifier + @param from_cs Charset information about the input string + @param to_cs Charset information about the target string */ void -append_identifier(THD *thd, String *packet, const char *name, uint length) +append_identifier(THD *thd, String *packet, const char *name, uint length, + CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) { const char *name_end; char quote_char; int q; - q= thd ? get_quote_char_for_identifier(thd, name, length) : '`'; + CHARSET_INFO *cs_info= system_charset_info; + const char *to_name= name; + size_t to_length= length; + String to_string(name,length, from_cs); + + if (from_cs != NULL && to_cs != NULL && from_cs != to_cs) + thd->convert_string(&to_string, from_cs, to_cs); + + if (to_cs != NULL) + { + to_name= to_string.c_ptr(); + to_length= to_string.length(); + cs_info= to_cs; + } + + q= thd ? get_quote_char_for_identifier(thd, to_name, to_length) : '`'; if (q == EOF) { - packet->append(name, length, packet->charset()); + packet->append(to_name, to_length, packet->charset()); return; } @@ -980,14 +995,14 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) it's a keyword */ - (void) packet->reserve(length*2 + 2); + (void) packet->reserve(to_length*2 + 2); quote_char= (char) q; packet->append("e_char, 1, system_charset_info); - for (name_end= name+length ; name < name_end ; name+= length) + for (name_end= to_name+to_length ; to_name < name_end ; to_name+= to_length) { - uchar chr= (uchar) *name; - length= my_mbcharlen(system_charset_info, chr); + uchar chr= (uchar) *to_name; + to_length= my_mbcharlen(cs_info, chr); /* my_mbcharlen can return 0 on a wrong multibyte sequence. It is possible when upgrading from 4.0, @@ -995,11 +1010,11 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) The manual says it does not work. So we'll just change length to 1 not to hang in the endless loop. */ - if (!length) - length= 1; - if (length == 1 && chr == (uchar) quote_char) + if (!to_length) + to_length= 1; + if (to_length == 1 && chr == (uchar) quote_char) packet->append("e_char, 1, system_charset_info); - packet->append(name, length, system_charset_info); + packet->append(to_name, to_length, system_charset_info); } packet->append("e_char, 1, system_charset_info); } diff --git a/sql/sql_show.h b/sql/sql_show.h index 16bfc5cdb69..ad6494fd7d4 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -92,8 +92,14 @@ int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); int get_quote_char_for_identifier(THD *thd, const char *name, uint length); -void append_identifier(THD *thd, String *packet, const char *name, - uint length); +void append_identifier(THD *thd, String *packet, const char *name, uint length, + CHARSET_INFO *from_cs, CHARSET_INFO *to_cs); +inline void append_identifier(THD *thd, String *packet, const char *name, + uint length) +{ + append_identifier(thd, packet, name, length, NULL, NULL); +} + void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd); bool mysqld_show_create(THD *thd, TABLE_LIST *table_list); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0a58d9ade5b..3f64de7eac2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2138,11 +2138,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (thd->db == NULL || strcmp(db,thd->db) != 0 || is_drop_tmp_if_exists_added ) { - append_identifier(thd, built_ptr_query, db, db_len); + append_identifier(thd, built_ptr_query, db, db_len, + system_charset_info, thd->charset()); built_ptr_query->append("."); } append_identifier(thd, built_ptr_query, table->table_name, - strlen(table->table_name)); + strlen(table->table_name), system_charset_info, + thd->charset()); built_ptr_query->append(","); } /* @@ -2204,12 +2206,14 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, */ if (thd->db == NULL || strcmp(db,thd->db) != 0) { - append_identifier(thd, &built_query, db, db_len); + append_identifier(thd, &built_query, db, db_len, + system_charset_info, thd->charset()); built_query.append("."); } append_identifier(thd, &built_query, table->table_name, - strlen(table->table_name)); + strlen(table->table_name), system_charset_info, + thd->charset()); built_query.append(","); } } From 11c339f4327c9ff88bfb62e342f45550d3c6140c Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 14 Dec 2015 23:45:23 +0100 Subject: [PATCH 010/127] - Fix MDEV-9279. Replacing exit(1) in yy_fatal_error by a longjmp. modified: storage/connect/fmdlex.c modified: storage/connect/plgdbutl.cpp --- storage/connect/fmdlex.c | 9 +++++++-- storage/connect/plgdbutl.cpp | 10 ++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c index 22c3a1e79ad..548a7ae5b7e 100644 --- a/storage/connect/fmdlex.c +++ b/storage/connect/fmdlex.c @@ -1,3 +1,5 @@ +#include + #define yyFlexLexer fmdfFlexLexer #define yy_create_buffer fmdf_create_buffer #define yy_delete_buffer fmdf_delete_buffer @@ -506,13 +508,16 @@ YY_MALLOC_DECL #define YY_BREAK break; #endif +static jmp_buf env; + YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; - + if (setjmp(env)) + return -1; /*************************************************************************/ /* Flex parser to analyze date format and produce input and/or output */ @@ -1316,7 +1321,7 @@ char msg[]; #endif { (void) fprintf( stderr, "%s\n", msg ); - exit( 1 ); + longjmp(env, 1 ); } diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 9e236da2d93..1ec1108c639 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -679,7 +679,8 @@ void PlugConvertConstant(PGLOBAL g, void* & value, short& type) /* non quoted blanks are not included in the output format. */ /***********************************************************************/ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag) - { +{ + int rc; PDTP pdp = (PDTP)PlugSubAlloc(g, NULL, sizeof(DATPAR)); if (trace) @@ -708,7 +709,7 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag) pthread_mutex_lock(&parmut); #endif // !__WIN__ #endif // THREAD - /*int rc =*/ fmdflex(pdp); + rc = fmdflex(pdp); #if defined(THREAD) #if defined(__WIN__) LeaveCriticalSection((LPCRITICAL_SECTION)&parsec); @@ -718,9 +719,10 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag) #endif // THREAD if (trace) - htrc("Done: in=%s out=%s\n", SVP(pdp->InFmt), SVP(pdp->OutFmt)); + htrc("Done: in=%s out=%s rc=%d\n", SVP(pdp->InFmt), SVP(pdp->OutFmt), rc); + return pdp; - } // end of MakeDateFormat +} // end of MakeDateFormat /***********************************************************************/ /* Extract the date from a formatted string according to format. */ From c5ba706791910f7ab5d83056abc9e9266891fa46 Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Wed, 16 Dec 2015 10:48:57 +0530 Subject: [PATCH 011/127] Bug#22278455: MYSQL 5.5:RPL_BINLOG_INDEX FAILS IN VALGRIND. Problem: ======= rpl_binlog_index.test fails with following valgrind error. line Conditional jump or move depends on uninitialised value(s) at 0x4C2F842: __memcmp_sse4_1 (in /usr/lib64/valgrind/ vgpreload_memcheck-amd64-linux.so) 0x739E39: find_uniq_filename(char*) (log.cc:2212) 0x73A11B: MYSQL_LOG::generate_new_name(char*, char const*) (log.cc:2492) 0x73A1ED: MYSQL_LOG::init_and_set_log_file_name(char const*, char const*, enum_log_type, cache_type) (log.cc:2289) 0x73B6F5: MYSQL_BIN_LOG::open(char const*, enum_log_type, Analysis and fix: ================= This issue was fixed as part of Bug#20459363 fix in 5.6 and above. Hence backporting the fix to MySQL-5.5. --- sql/log.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index d322abcd742..9e34532f1ac 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2209,7 +2209,7 @@ static int find_uniq_filename(char *name) file_info= dir_info->dir_entry; for (i= dir_info->number_off_files ; i-- ; file_info++) { - if (memcmp(file_info->name, start, length) == 0 && + if (strncmp(file_info->name, start, length) == 0 && test_if_number(file_info->name+length, &number,0)) { set_if_bigger(max_found,(ulong) number); From 3c9ba967af3e8d2c47e7849760f018dcfc9d4d16 Mon Sep 17 00:00:00 2001 From: Balasubramanian Kandasamy Date: Wed, 16 Dec 2015 12:03:04 +0530 Subject: [PATCH 012/127] Bug#22361702 - /USR/BIN/MYSQL-SYSTEMD-START DOES NOT RETURN CONTROL TO COMMAND LINE If the configuration files contains multiple datadir lines, use the last datadir entry in the RPM installation scripts --- packaging/rpm-oel/mysql-systemd-start | 2 +- packaging/rpm-oel/mysql.spec.in | 2 +- packaging/rpm-sles/mysql-systemd-start | 2 +- packaging/rpm-sles/mysql.spec.in | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/rpm-oel/mysql-systemd-start b/packaging/rpm-oel/mysql-systemd-start index 12a1b16db80..fab7b3627b3 100644 --- a/packaging/rpm-oel/mysql-systemd-start +++ b/packaging/rpm-oel/mysql-systemd-start @@ -12,7 +12,7 @@ get_option () { local section=$1 local option=$2 local default=$3 - ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2-) + ret=$(/usr/bin/my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2- | tail -n 1) [ -z "$ret" ] && ret=$default echo $ret } diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index a76eaa114f8..8a020b05ae6 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -626,7 +626,7 @@ rm -r $(readlink var) var -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || : %post server -datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p') +datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p' | tail -n 1) /bin/chmod 0755 "$datadir" /bin/touch /var/log/mysqld.log %if 0%{?systemd} diff --git a/packaging/rpm-sles/mysql-systemd-start b/packaging/rpm-sles/mysql-systemd-start index dc151e0322c..28472249eda 100644 --- a/packaging/rpm-sles/mysql-systemd-start +++ b/packaging/rpm-sles/mysql-systemd-start @@ -10,7 +10,7 @@ install_db () { # Note: something different than datadir=/var/lib/mysql requires SELinux policy changes (in enforcing mode) - datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p') + datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p' | tail -n 1) # Restore log, dir, perms and SELinux contexts [ -d "$datadir" ] || install -d -m 0755 -omysql -gmysql "$datadir" || exit 1 diff --git a/packaging/rpm-sles/mysql.spec.in b/packaging/rpm-sles/mysql.spec.in index cb42dfacf71..91c708a583d 100644 --- a/packaging/rpm-sles/mysql.spec.in +++ b/packaging/rpm-sles/mysql.spec.in @@ -489,7 +489,7 @@ rm -r $(readlink var) var -c "MySQL Server" -u 60 mysql >/dev/null 2>&1 || : %post server -datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p') +datadir=$(/usr/bin/my_print_defaults server mysqld | grep '^--datadir=' | sed -n 's/--datadir=//p' | tail -n 1) /bin/chmod 0755 "$datadir" /bin/touch /var/log/mysql/mysqld.log %if 0%{?systemd} From 3402f7a85364e26fe85dfff3b5d803a8497042aa Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 18 Dec 2015 16:31:05 +0400 Subject: [PATCH 013/127] Fixed auth_socket static compilation --- plugin/auth_socket/CMakeLists.txt | 2 +- plugin/auth_socket/auth_socket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/auth_socket/CMakeLists.txt b/plugin/auth_socket/CMakeLists.txt index 8137c6b4529..e4a8d1d6efd 100644 --- a/plugin/auth_socket/CMakeLists.txt +++ b/plugin/auth_socket/CMakeLists.txt @@ -65,6 +65,6 @@ ENDIF() ENDIF() IF(ok) - MYSQL_ADD_PLUGIN(auth_socket auth_socket.c MODULE_ONLY) + MYSQL_ADD_PLUGIN(auth_socket auth_socket.c) ENDIF() diff --git a/plugin/auth_socket/auth_socket.c b/plugin/auth_socket/auth_socket.c index 601b76b6b5c..f04b1d9d2a1 100644 --- a/plugin/auth_socket/auth_socket.c +++ b/plugin/auth_socket/auth_socket.c @@ -105,7 +105,7 @@ static struct st_mysql_auth socket_auth_handler= socket_auth }; -maria_declare_plugin(socket_auth) +maria_declare_plugin(auth_socket) { MYSQL_AUTHENTICATION_PLUGIN, &socket_auth_handler, From 5efb8f1677f680e6d6ab2304630495c522475dc3 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 18 Dec 2015 22:51:12 +0400 Subject: [PATCH 014/127] Filter out unix-socket from unrelated test cases --- mysql-test/suite/plugins/r/auth_v0100.result | 5 ++--- mysql-test/suite/plugins/t/auth_v0100.test | 3 ++- mysql-test/t/mysqld--help.test | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/plugins/r/auth_v0100.result b/mysql-test/suite/plugins/r/auth_v0100.result index 53affc94947..a72b8e209b0 100644 --- a/mysql-test/suite/plugins/r/auth_v0100.result +++ b/mysql-test/suite/plugins/r/auth_v0100.result @@ -1,9 +1,8 @@ install soname 'auth_0x0100'; -select plugin_name, plugin_type_version from information_schema.plugins where plugin_type='authentication' order by plugin_name; +select plugin_name, plugin_type_version from information_schema.plugins where +plugin_type='authentication' and plugin_library is not null order by plugin_name; plugin_name plugin_type_version auth_0x0100 1.0 -mysql_native_password 2.0 -mysql_old_password 2.0 create user tt identified via auth_0x0100; grant select on test.* to zzzzzzzzzzzzzzzz; connect(localhost,tt,,test,MASTER_MYPORT,MASTER_MYSOCK); diff --git a/mysql-test/suite/plugins/t/auth_v0100.test b/mysql-test/suite/plugins/t/auth_v0100.test index 3cf93ba67f2..c4333d376d3 100644 --- a/mysql-test/suite/plugins/t/auth_v0100.test +++ b/mysql-test/suite/plugins/t/auth_v0100.test @@ -6,7 +6,8 @@ if (!$AUTH_0X0100_SO) { install soname 'auth_0x0100'; -select plugin_name, plugin_type_version from information_schema.plugins where plugin_type='authentication' order by plugin_name; +select plugin_name, plugin_type_version from information_schema.plugins where +plugin_type='authentication' and plugin_library is not null order by plugin_name; create user tt identified via auth_0x0100; grant select on test.* to zzzzzzzzzzzzzzzz; diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index c27fa58f935..fabc2e21f18 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -30,7 +30,7 @@ perl; thread-concurrency super-large-pages mutex-deadlock-detector connect null-audit aria oqgraph sphinx thread-handling test-sql-discovery rpl-semi-sync query-cache-info - query-response-time metadata-lock-info locales/; + query-response-time metadata-lock-info locales unix-socket/; # And substitute the content some environment variables with their # names: From 3b9423fda2612a463e9f3af5750234ccf2667545 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Mar 2015 04:49:31 +1100 Subject: [PATCH 015/127] MDEV-7384: Add --persistent option for mysqlcheck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 10.0 has an "analyze table .. persistent for all" syntax. This adds --persistent to mysqlcheck(mysqlanalyize) to perform this extended analyze table option. Signed-off-by: Vicențiu Ciorbaru --- client/mysqlcheck.c | 7 ++++++- man/mysqlcheck.1 | 18 +++++++++++++++++- mysql-test/r/mysqlcheck.result | 19 +++++++++++++++++++ mysql-test/t/mysqlcheck.test | 22 ++++++++++++++++------ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ead4127dad6..9b6934d204f 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -43,7 +43,7 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, - opt_do_tables= 1; + opt_persistent_all= 0, opt_do_tables= 1; static my_bool opt_write_binlog= 1, opt_flush_tables= 0; static uint verbose = 0, opt_mysql_port=0; static int my_end_arg; @@ -160,6 +160,10 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given, it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"persistent", 'Z', + "When using ANALYZE TABLE use the PERSISTENT FOR ALL option.", + &opt_persistent_all, &opt_persistent_all, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -909,6 +913,7 @@ static int handle_request_for_tables(char *tables, size_t length, my_bool view) case DO_ANALYZE: DBUG_ASSERT(!view); op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG"; + if (opt_persistent_all) end = strmov(end, " PERSISTENT FOR ALL"); break; case DO_OPTIMIZE: DBUG_ASSERT(!view); diff --git a/man/mysqlcheck.1 b/man/mysqlcheck.1 index c175483347c..e05bbf8a519 100644 --- a/man/mysqlcheck.1 +++ b/man/mysqlcheck.1 @@ -1,6 +1,6 @@ '\" t .\" -.TH "\FBMYSQLCHECK\FR" "1" "04/08/2015" "MariaDB 10\&.0" "MariaDB Database System" +.TH "\FBMYSQLCHECK\FR" "1" "27/12/2015" "MariaDB 10\&.0" "MariaDB Database System" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -677,6 +677,22 @@ Specifying a password on the command line should be considered insecure\&. You c .sp -1 .IP \(bu 2.3 .\} +.\" mysqlcheck: persisent option +.\" persistent option: mysql +\fB\-\-persistent\fR, +\fB\-Z\fR +.sp +Used with ANALYZE TABLE to append the option PERSISENT FOR ALL. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} .\" mysqlcheck: pipe option .\" pipe option: mysql \fB\-\-pipe\fR, diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index b4bcdc495ae..66e23c18355 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -347,6 +347,9 @@ CREATE TABLE test.`t.1` (id int); mysqlcheck test t.1 test.t.1 OK drop table test.`t.1`; +# +# MDEV-8123 mysqlcheck: new --process-views option conflicts with --quick, --extended and such +# create view v1 as select 1; mysqlcheck --process-views test test.v1 OK @@ -361,6 +364,9 @@ test.v1 OK mysqlcheck --process-views --check-upgrade test test.v1 OK drop view v1; +# +# MDEV-8124 mysqlcheck: --auto-repair runs REPAIR TABLE instead of REPAIR VIEW on views +# create table t1(a int); mysqlcheck --process-views --check-upgrade --auto-repair test test.t1 OK @@ -370,3 +376,16 @@ Repairing views test.v1 OK drop view v1; drop table t1; +# +#MDEV-7384 [PATCH] add PERSISENT FOR ALL option to mysqlanalyze/mysqlcheck +# +create table t1(a int); +insert into t1 (a) values (1), (2), (3); +select * from mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test.t1 Engine-independent statistics collected +status : OK +select * from mysql.column_stats where db_name = 'test' and table_name = 't1'; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 a 1 3 0.0000 4.0000 1.0000 0 NULL NULL +drop table t1; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 6cd0265f89a..88f0d034bf0 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -319,9 +319,9 @@ CREATE TABLE test.`t.1` (id int); drop table test.`t.1`; -# -# MDEV-8123 mysqlcheck: new --process-views option conflicts with --quick, --extended and such -# +--echo # +--echo # MDEV-8123 mysqlcheck: new --process-views option conflicts with --quick, --extended and such +--echo # create view v1 as select 1; --echo mysqlcheck --process-views test --exec $MYSQL_CHECK --process-views test @@ -340,12 +340,22 @@ create view v1 as select 1; drop view v1; -# -# MDEV-8124 mysqlcheck: --auto-repair runs REPAIR TABLE instead of REPAIR VIEW on views -# +--echo # +--echo # MDEV-8124 mysqlcheck: --auto-repair runs REPAIR TABLE instead of REPAIR VIEW on views +--echo # create table t1(a int); --copy_file $MYSQL_TEST_DIR/std_data/mysql_upgrade/v1.frm $MYSQLD_DATADIR/test/v1.frm --echo mysqlcheck --process-views --check-upgrade --auto-repair test --exec $MYSQL_CHECK --process-views --check-upgrade --auto-repair test drop view v1; drop table t1; + +--echo # +--echo #MDEV-7384 [PATCH] add PERSISENT FOR ALL option to mysqlanalyze/mysqlcheck +--echo # +create table t1(a int); +insert into t1 (a) values (1), (2), (3); +select * from mysql.column_stats; +--exec $MYSQL_CHECK --analyze test t1 --persistent +select * from mysql.column_stats where db_name = 'test' and table_name = 't1'; +drop table t1; From f89c9fc4b7b5d82c79775cb848225900b45a6b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sat, 19 Dec 2015 13:25:55 +0200 Subject: [PATCH 016/127] MDEV-7526: TokuDB doesn't build on OS X This patch fixes one compilation error related to __db_lsn struct. The struct can not be defined as empty according to the main C standard. In C++, this is handled by forcing a size of 1. To eliminate the error we add a dummy char field of size 1. This has no effect on the C++ compiled code, but also removes the compiler error. --- storage/tokudb/ft-index/buildheader/make_tdb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/tokudb/ft-index/buildheader/make_tdb.cc b/storage/tokudb/ft-index/buildheader/make_tdb.cc index 53706649231..610ce670db5 100644 --- a/storage/tokudb/ft-index/buildheader/make_tdb.cc +++ b/storage/tokudb/ft-index/buildheader/make_tdb.cc @@ -481,7 +481,9 @@ static void print_db_key_range_struct (void) { static void print_db_lsn_struct (void) { field_counter=0; - sort_and_dump_fields("db_lsn", false, NULL); + /* A dummy field to make sizeof(DB_LSN) equal in C and C++ */ + const char *extra[] = { "char dummy", NULL }; + sort_and_dump_fields("db_lsn", false, extra); } static void print_dbt_struct (void) { From 64149590c47d1cf6b1b227d8c90bdc23d20a8956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sat, 19 Dec 2015 13:31:44 +0200 Subject: [PATCH 017/127] MDEV-7526: TokuDB doesn't build on OS X This patch fixes another compilation error caused by specifying attribute nonnull for all the parameters of the copyout function. This is incorrect as the function actually gets called with null parameters indirectly and thus only the output parameter should be nonnull. --- storage/tokudb/ft-index/util/dmt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/ft-index/util/dmt.h b/storage/tokudb/ft-index/util/dmt.h index d4b032f5d6f..43e44df6a70 100644 --- a/storage/tokudb/ft-index/util/dmt.h +++ b/storage/tokudb/ft-index/util/dmt.h @@ -679,16 +679,16 @@ private: __attribute__((nonnull)) void rebalance(subtree *const subtree); - __attribute__((nonnull)) + __attribute__((nonnull(3))) static void copyout(uint32_t *const outlen, dmtdata_t *const out, const dmt_node *const n); - __attribute__((nonnull)) + __attribute__((nonnull(3))) static void copyout(uint32_t *const outlen, dmtdata_t **const out, dmt_node *const n); - __attribute__((nonnull)) + __attribute__((nonnull(4))) static void copyout(uint32_t *const outlen, dmtdata_t *const out, const uint32_t len, const dmtdata_t *const stored_value_ptr); - __attribute__((nonnull)) + __attribute__((nonnull(4))) static void copyout(uint32_t *const outlen, dmtdata_t **const out, const uint32_t len, dmtdata_t *const stored_value_ptr); template Date: Sat, 19 Dec 2015 13:52:27 +0200 Subject: [PATCH 018/127] MDEV-7526: TokuDB doesn't build on OS X Removed unused functions from tokudb_dump.cc. --- storage/tokudb/ft-index/tools/tokudb_dump.cc | 70 -------------------- 1 file changed, 70 deletions(-) diff --git a/storage/tokudb/ft-index/tools/tokudb_dump.cc b/storage/tokudb/ft-index/tools/tokudb_dump.cc index 2da50bb793a..b162c5caece 100644 --- a/storage/tokudb/ft-index/tools/tokudb_dump.cc +++ b/storage/tokudb/ft-index/tools/tokudb_dump.cc @@ -247,76 +247,6 @@ outputplaintextstring(char* str) g.plaintext = old_plaintext; } -static inline int -hextoint(int ch) -{ - if (ch >= '0' && ch <= '9') { - return ch - '0'; - } - if (ch >= 'a' && ch <= 'z') { - return ch - 'a' + 10; - } - if (ch >= 'A' && ch <= 'Z') { - return ch - 'A' + 10; - } - return EOF; -} - -static inline int -printabletocstring(char* inputstr, char** poutputstr) -{ - char highch; - char lowch; - char nextch; - char* cstring; - - assert(inputstr); - assert(poutputstr); - assert(*poutputstr == NULL); - - cstring = (char*)toku_malloc((strlen(inputstr) + 1) * sizeof(char)); - if (cstring == NULL) { - PRINT_ERROR(errno, "printabletocstring"); - goto error; - } - - for (*poutputstr = cstring; *inputstr != '\0'; inputstr++) { - if (*inputstr == '\\') { - if ((highch = *++inputstr) == '\\') { - *cstring++ = '\\'; - continue; - } - if (highch == '\0' || (lowch = *++inputstr) == '\0') { - PRINT_ERROR(0, "unexpected end of input data or key/data pair"); - goto error; - } - if (!isxdigit(highch)) { - PRINT_ERROR(0, "Unexpected '%c' (non-hex) input.\n", highch); - goto error; - } - if (!isxdigit(lowch)) { - PRINT_ERROR(0, "Unexpected '%c' (non-hex) input.\n", lowch); - goto error; - } - nextch = (char)((hextoint(highch) << 4) | hextoint(lowch)); - if (nextch == '\0') { - /* Database names are c strings, and cannot have extra NULL terminators. */ - PRINT_ERROR(0, "Unexpected '\\00' in input.\n"); - goto error; - } - *cstring++ = nextch; - } - else *cstring++ = *inputstr; - } - /* Terminate the string. */ - *cstring = '\0'; - return EXIT_SUCCESS; - -error: - PRINT_ERROR(0, "Quitting out due to errors.\n"); - return EXIT_FAILURE; -} - static inline int verify_library_version(void) { From e386523a41245d8b03f1338934c1aa965530e4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sat, 19 Dec 2015 13:53:43 +0200 Subject: [PATCH 019/127] MDEV-7526: TokuDB doesn't build on OS X Fixed compile warning related to if statement always being true. The if statement can not be false, as the address of a member field is always true. --- storage/tokudb/ft-index/ft/txn/rollback.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/storage/tokudb/ft-index/ft/txn/rollback.cc b/storage/tokudb/ft-index/ft/txn/rollback.cc index 62048039c26..ea2f2a07c50 100644 --- a/storage/tokudb/ft-index/ft/txn/rollback.cc +++ b/storage/tokudb/ft-index/ft/txn/rollback.cc @@ -147,9 +147,7 @@ static inline PAIR_ATTR make_rollback_pair_attr(long size) { PAIR_ATTR rollback_memory_size(ROLLBACK_LOG_NODE log) { size_t size = sizeof(*log); - if (&log->rollentry_arena) { - size += log->rollentry_arena.total_footprint(); - } + size += log->rollentry_arena.total_footprint(); return make_rollback_pair_attr(size); } From 591e74c7e8f682f2eada7496f50aa73f38bd168d Mon Sep 17 00:00:00 2001 From: DevilSatan <2530212445@qq.com> Date: Sat, 20 Jun 2015 16:59:22 +0800 Subject: [PATCH 020/127] MDEV-7526: TokuDB doesn't build on OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A string definition is inconsistent and thus causes a compilation error. Signed-off-by: Vicențiu Ciorbaru --- storage/tokudb/ha_tokudb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index b4e2c1a311e..2eb8004a296 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -379,7 +379,7 @@ static int free_share(TOKUDB_SHARE * share) { } const char *ha_tokudb::table_type() const { - extern const char * const tokudb_hton_name; + extern const char *tokudb_hton_name; return tokudb_hton_name; } From 865548fc8d0574e6418b66def39b6d36bbc0205a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 18 Dec 2015 09:50:39 +0100 Subject: [PATCH 021/127] MDEV-9088 Server crashes on shutdown after the second post of feedback report On shutdown feedback was sending a short report without creating a THD. At that point current_thd was pointing to the already destroyed THD from the previous full report. backport from 10.1: commit bfe703a Author: Sergei Golubchik Date: Tue Feb 3 18:19:56 2015 +0100 don't let current_thd to point to a destroyed THD --- sql/events.cc | 3 --- sql/mysqld.cc | 2 -- sql/sql_acl.cc | 4 ---- sql/sql_base.cc | 1 - sql/sql_class.cc | 2 +- sql/sql_plugin.cc | 2 -- sql/sql_reload.cc | 2 -- sql/sql_servers.cc | 2 -- sql/sql_table.cc | 2 -- sql/sql_udf.cc | 2 -- sql/tztime.cc | 4 ---- storage/spider/spd_conn.cc | 30 ------------------------------ 12 files changed, 1 insertion(+), 55 deletions(-) diff --git a/sql/events.cc b/sql/events.cc index 32d194e3bac..75780cd94c5 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -907,10 +907,7 @@ end: if (res) deinit(); if (!had_thd) - { delete thd; - set_current_thd(0); - } DBUG_RETURN(res); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e52a35bcc8f..e3e331932d0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6334,7 +6334,6 @@ void handle_connections_sockets() (void) mysql_socket_close(new_sock); } delete thd; - set_current_thd(0); statistic_increment(connection_errors_internal, &LOCK_status); continue; } @@ -6449,7 +6448,6 @@ pthread_handler_t handle_connections_namedpipes(void *arg) { close_connection(thd, ER_OUT_OF_RESOURCES); delete thd; - set_current_thd(0); continue; } /* Host is unknown */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3647520ed4b..63d7d7a0399 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -959,8 +959,6 @@ my_bool acl_init(bool dont_read_acl_tables) */ return_val= acl_reload(thd); delete thd; - /* Remember that we don't have a THD */ - set_current_thd(0); DBUG_RETURN(return_val); } @@ -6371,8 +6369,6 @@ my_bool grant_init() thd->store_globals(); return_val= grant_reload(thd); delete thd; - /* Remember that we don't have a THD */ - set_current_thd(0); DBUG_RETURN(return_val); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 807ec93f4cb..52d5928ea1d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9045,7 +9045,6 @@ my_bool mysql_rm_tmp_tables(void) my_dirend(dirp); } delete thd; - set_current_thd(0); DBUG_RETURN(0); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 583abee360f..7a9cdad84f6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1645,7 +1645,7 @@ THD::~THD() DBUG_ASSERT(status_var.memory_used == 0); // Ensure everything is freed } - set_current_thd(orig_thd); + set_current_thd(orig_thd == this ? 0 : orig_thd); DBUG_VOID_RETURN; } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index dea224398ea..5977cfb8618 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1791,9 +1791,7 @@ static void plugin_load(MEM_ROOT *tmp_root) table->m_needs_reopen= TRUE; // Force close to free memory close_mysql_tables(new_thd); end: - /* Remember that we don't have a THD */ delete new_thd; - set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 4d22dae1c47..86d1e27a4ef 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -98,8 +98,6 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, if (tmp_thd) { delete tmp_thd; - /* Remember that we don't have a THD */ - set_current_thd(0); thd= 0; } reset_mqh((LEX_USER *)NULL, TRUE); diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 8d5bb2b596d..78d11a6bebf 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -177,8 +177,6 @@ bool servers_init(bool dont_read_servers_table) */ return_val= servers_reload(thd); delete thd; - /* Remember that we don't have a THD */ - set_current_thd(0); end: DBUG_RETURN(return_val); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ff5c385626a..1e7d4f5e3c6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1674,8 +1674,6 @@ void execute_ddl_log_recovery() mysql_mutex_unlock(&LOCK_gdl); thd->reset_query(); delete thd; - /* Remember that we don't have a THD */ - set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 0f9043a77df..74d2f6bc252 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -258,8 +258,6 @@ void udf_init() end: close_mysql_tables(new_thd); delete new_thd; - /* Remember that we don't have a THD */ - set_current_thd(0); DBUG_VOID_RETURN; } diff --git a/sql/tztime.cc b/sql/tztime.cc index 6486e9b2018..9791e218108 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1803,11 +1803,7 @@ end: if (org_thd) org_thd->store_globals(); /* purecov: inspected */ else - { - /* Remember that we don't have a THD */ - set_current_thd(0); my_pthread_setspecific_ptr(THR_MALLOC, 0); - } default_tz= default_tz_name ? global_system_variables.time_zone : my_tz_SYSTEM; diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index 293a209ac68..c5c47064403 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -2280,9 +2280,6 @@ void *spider_bg_conn_action( if (!(trx = spider_get_trx(thd, FALSE, &error_num))) { delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif pthread_mutex_lock(&conn->bg_conn_sync_mutex); pthread_cond_signal(&conn->bg_conn_sync_cond); pthread_mutex_unlock(&conn->bg_conn_sync_mutex); @@ -2346,9 +2343,6 @@ void *spider_bg_conn_action( spider_free_trx(trx, TRUE); /* lex_end(thd->lex); */ delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif pthread_mutex_lock(&conn->bg_conn_sync_mutex); pthread_cond_signal(&conn->bg_conn_sync_cond); pthread_mutex_unlock(&conn->bg_conn_mutex); @@ -2799,9 +2793,6 @@ void *spider_bg_sts_action( if (!(trx = spider_get_trx(thd, FALSE, &error_num))) { delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif share->bg_sts_thd_wait = FALSE; share->bg_sts_kill = FALSE; share->bg_sts_init = FALSE; @@ -2867,9 +2858,6 @@ void *spider_bg_sts_action( } spider_free_trx(trx, TRUE); delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif share->bg_sts_thd_wait = FALSE; share->bg_sts_kill = FALSE; share->bg_sts_init = FALSE; @@ -2903,9 +2891,6 @@ void *spider_bg_sts_action( } spider_free_trx(trx, TRUE); delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif pthread_cond_signal(&share->bg_sts_sync_cond); pthread_mutex_unlock(&share->sts_mutex); #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) @@ -3190,9 +3175,6 @@ void *spider_bg_crd_action( if (!(trx = spider_get_trx(thd, FALSE, &error_num))) { delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif share->bg_crd_thd_wait = FALSE; share->bg_crd_kill = FALSE; share->bg_crd_init = FALSE; @@ -3262,9 +3244,6 @@ void *spider_bg_crd_action( } spider_free_trx(trx, TRUE); delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif share->bg_crd_thd_wait = FALSE; share->bg_crd_kill = FALSE; share->bg_crd_init = FALSE; @@ -3298,9 +3277,6 @@ void *spider_bg_crd_action( } spider_free_trx(trx, TRUE); delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif pthread_cond_signal(&share->bg_crd_sync_cond); pthread_mutex_unlock(&share->crd_mutex); #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) @@ -3688,9 +3664,6 @@ void *spider_bg_mon_action( if (!(trx = spider_get_trx(thd, FALSE, &error_num))) { delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif share->bg_mon_kill = FALSE; share->bg_mon_init = FALSE; pthread_cond_signal(&share->bg_mon_conds[link_idx]); @@ -3734,9 +3707,6 @@ void *spider_bg_mon_action( pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]); spider_free_trx(trx, TRUE); delete thd; -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 - set_current_thd(NULL); -#endif #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32) my_pthread_setspecific_ptr(THR_THD, NULL); #endif From e126baafbc78f15c794082f0a93740d81041d038 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 21 Dec 2015 10:19:02 +0100 Subject: [PATCH 022/127] =?UTF-8?q?MDEV-9249=20MariaDB=20un-buildable=20on?= =?UTF-8?q?=20linux64:=20fails=20@=20"error:=20=E2=80=98ERR=5Fremove=5Fsta?= =?UTF-8?q?te=E2=80=99=20was=20not=20declared=20in=20this=20scope"=20when?= =?UTF-8?q?=20linking=20against=20OpenSSL=201.0.2e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ERR_remove_state is deprecated, use ERR_remove_thread_state if possible --- cmake/ssl.cmake | 5 +++++ config.h.cmake | 2 +- include/violite.h | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index ca950229129..43665d04a88 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -26,6 +26,7 @@ MACRO (MYSQL_USE_BUNDLED_SSL) SET(SSL_INCLUDE_DIRS ${INC_DIRS}) SET(SSL_INTERNAL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL) SET(SSL_DEFINES "-DHAVE_YASSL -DYASSL_PURE_C -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED") + SET(HAVE_ERR_remove_thread_state OFF CACHE INTERNAL "yassl doesn't have ERR_remove_thread_state") CHANGE_SSL_SETTINGS("bundled") #Remove -fno-implicit-templates #(yassl sources cannot be compiled with it) @@ -70,9 +71,13 @@ MACRO (MYSQL_CHECK_SSL) MARK_AS_ADVANCED(CRYPTO_LIBRARY) INCLUDE(CheckSymbolExists) SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) CHECK_SYMBOL_EXISTS(SHA512_DIGEST_LENGTH "openssl/sha.h" HAVE_SHA512_DIGEST_LENGTH) + CHECK_SYMBOL_EXISTS(ERR_remove_thread_state "openssl/err.h" + HAVE_ERR_remove_thread_state) SET(CMAKE_REQUIRED_INCLUDES) + SET(CMAKE_REQUIRED_LIBRARIES) IF(OPENSSL_FOUND AND CRYPTO_LIBRARY AND HAVE_SHA512_DIGEST_LENGTH) SET(SSL_SOURCES "") SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARY}) diff --git a/config.h.cmake b/config.h.cmake index 73dc918bc3c..02952f6f395 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -465,7 +465,7 @@ #cmakedefine HAVE_BSD_SIGNALS 1 #cmakedefine HAVE_SVR3_SIGNALS 1 #cmakedefine HAVE_V7_SIGNALS 1 - +#cmakedefine HAVE_ERR_remove_thread_state 1 #cmakedefine HAVE_SOLARIS_STYLE_GETHOST 1 diff --git a/include/violite.h b/include/violite.h index 14c99e8d8fe..ea7e3d7897c 100644 --- a/include/violite.h +++ b/include/violite.h @@ -123,6 +123,10 @@ typedef my_socket YASSL_SOCKET_T; #include #include +#ifdef HAVE_ERR_remove_thread_state +#define ERR_remove_state(X) ERR_remove_thread_state(NULL) +#endif + enum enum_ssl_init_error { SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY, From 4fdf25afa8188905653a83e08fc387243e584600 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 21 Dec 2015 16:37:59 +0100 Subject: [PATCH 023/127] after-merge: 10.0 part of MDEV-9249 (ERR_remove_state) --- mysys_ssl/my_aes.cc | 4 ++++ storage/perfschema/CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysys_ssl/my_aes.cc b/mysys_ssl/my_aes.cc index 05dbfdb4f0b..2bc54d68848 100644 --- a/mysys_ssl/my_aes.cc +++ b/mysys_ssl/my_aes.cc @@ -26,6 +26,10 @@ #include #include +#ifdef HAVE_ERR_remove_thread_state +#define ERR_remove_state(X) ERR_remove_thread_state(NULL) +#endif + // Wrap C struct, to ensure resources are released. struct MyCipherCtx { diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt index 3b3ffae6357..fe3b5ec985a 100644 --- a/storage/perfschema/CMakeLists.txt +++ b/storage/perfschema/CMakeLists.txt @@ -17,7 +17,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql ${PCRE_INCLUDES} - ${CMAKE_SOURCE_DIR}/extra/yassl/include) + ${SSL_INCLUDE_DIRS}) ADD_DEFINITIONS(-DMYSQL_SERVER) From 6883e5c4c40d1411dcc7c43bbb7cbb3f2d0ab251 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 27 Dec 2015 19:45:51 +0100 Subject: [PATCH 024/127] - Fix MDEV-9322. modified: storage/connect/json.cpp --- storage/connect/json.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index fc7edb84c0f..75bf277b25b 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -594,8 +594,8 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty) if (fs) { fputs(EL, fs); fclose(fs); - str = (err) ? NULL : "Ok"; - } else if (!err) { + str = (err) ? NULL : strcpy(g->Message, "Ok"); + } else if (!err) { str = ((JOUTSTR*)jp)->Strp; jp->WriteChr('\0'); PlugSubAlloc(g, NULL, ((JOUTSTR*)jp)->N); From e1b9be5417668b184893148adea5f1f0e3a8d00f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 29 Dec 2015 14:17:31 +0400 Subject: [PATCH 025/127] MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data --- mysql-test/r/ctype_utf8.result | 16 +++++++++++++++ mysql-test/r/ctype_utf8mb4.result | 16 +++++++++++++++ mysql-test/r/myisam-blob.result | 4 +++- mysql-test/r/type_blob.result | 33 +++++++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 11 +++++++++++ mysql-test/t/ctype_utf8mb4.test | 12 +++++++++++ mysql-test/t/type_blob.test | 25 +++++++++++++++++++++++ sql/field.cc | 29 +++++++++++++++++++++++++++ sql/field.h | 11 ++++++----- sql/field_conv.cc | 9 +-------- 10 files changed, 152 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 91dbe853a38..dfc872cc734 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -5804,5 +5804,21 @@ c0 c1 c2 c3 c4 2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 2012-06-11 15:18:24 DROP TABLE t2, t1; # +# MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +# +SET NAMES utf8; +CREATE TABLE t1 (a TEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES (REPEAT('A',100)); +SELECT OCTET_LENGTH(a) FROM t1; +OCTET_LENGTH(a) +300 +ALTER TABLE t1 MODIFY a TINYTEXT CHARACTER SET utf8; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT OCTET_LENGTH(a),a FROM t1; +OCTET_LENGTH(a) a +255 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +DROP TABLE t1; +# # End of 5.5 tests # diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index 64556308de2..29749d3f07b 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -2606,6 +2606,22 @@ Warning 1292 Truncated incorrect INTEGER value: 'a' DROP TABLE t1; # End of test for Bug#13581962,Bug#14096619 # +# MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +# +SET NAMES utf8mb4; +CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4); +INSERT INTO t1 VALUES (REPEAT('😎',100)); +SELECT OCTET_LENGTH(a) FROM t1; +OCTET_LENGTH(a) +400 +ALTER TABLE t1 MODIFY a TINYTEXT CHARACTER SET utf8mb4; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT OCTET_LENGTH(a),a FROM t1; +OCTET_LENGTH(a) a +252 😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎 +DROP TABLE t1; +# # End of 5.5 tests # # diff --git a/mysql-test/r/myisam-blob.result b/mysql-test/r/myisam-blob.result index 43db7c8badd..6b41a244621 100644 --- a/mysql-test/r/myisam-blob.result +++ b/mysql-test/r/myisam-blob.result @@ -29,9 +29,11 @@ select length(data) from t1; length(data) 18874368 alter table t1 modify data blob; +Warnings: +Warning 1265 Data truncated for column 'data' at row 1 select length(data) from t1; length(data) -0 +65535 drop table t1; CREATE TABLE t1 (data BLOB) ENGINE=myisam; INSERT INTO t1 (data) VALUES (NULL); diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 723efbdcb23..f49b2a7d5ef 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -1000,9 +1000,42 @@ COUNT(*) DROP FUNCTION f1; DROP TABLE t1; End of 5.1 tests +# +# Start of 5.5 tests +# CREATE TABLE t1 ( f1 blob, f2 blob ); INSERT INTO t1 VALUES ('',''); SELECT f1,f2,"found row" FROM t1 WHERE f1 = f2 ; f1 f2 found row found row DROP TABLE t1; +# +# MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +# +CREATE TABLE t1 (a MEDIUMBLOB); +INSERT INTO t1 VALUES (REPEAT(0x61,128000)); +SELECT LENGTH(a) FROM t1; +LENGTH(a) +128000 +ALTER TABLE t1 MODIFY a BLOB; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT LENGTH(a) FROM t1; +LENGTH(a) +65535 +DROP TABLE t1; +CREATE TABLE t1 (a BLOB); +INSERT INTO t1 VALUES (REPEAT(0x61,65000)); +SELECT LENGTH(a) FROM t1; +LENGTH(a) +65000 +ALTER TABLE t1 MODIFY a TINYBLOB; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT LENGTH(a) FROM t1; +LENGTH(a) +255 +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8cd70e9261a..fd70292c6c8 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1648,6 +1648,17 @@ SHOW CREATE TABLE t2; SELECT * FROM t2; DROP TABLE t2, t1; +--echo # +--echo # MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +--echo # +SET NAMES utf8; +CREATE TABLE t1 (a TEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES (REPEAT('A',100)); +SELECT OCTET_LENGTH(a) FROM t1; +ALTER TABLE t1 MODIFY a TINYTEXT CHARACTER SET utf8; +SELECT OCTET_LENGTH(a),a FROM t1; +DROP TABLE t1; + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index fda20ca0ec5..66f5a3ba5ac 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1826,6 +1826,18 @@ DROP TABLE t1; --echo # End of test for Bug#13581962,Bug#14096619 +--echo # +--echo # MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +--echo # +SET NAMES utf8mb4; +CREATE TABLE t1 (a TEXT CHARACTER SET utf8mb4); +INSERT INTO t1 VALUES (REPEAT('😎',100)); +SELECT OCTET_LENGTH(a) FROM t1; +ALTER TABLE t1 MODIFY a TINYTEXT CHARACTER SET utf8mb4; +SELECT OCTET_LENGTH(a),a FROM t1; +DROP TABLE t1; + + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 66dd71d2305..d5f6fc6ed32 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -643,6 +643,10 @@ DROP TABLE t1; --echo End of 5.1 tests +--echo # +--echo # Start of 5.5 tests +--echo # + # # Problem when comparing blobs #778901 # @@ -651,3 +655,24 @@ CREATE TABLE t1 ( f1 blob, f2 blob ); INSERT INTO t1 VALUES ('',''); SELECT f1,f2,"found row" FROM t1 WHERE f1 = f2 ; DROP TABLE t1; + +--echo # +--echo # MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data +--echo # +CREATE TABLE t1 (a MEDIUMBLOB); +INSERT INTO t1 VALUES (REPEAT(0x61,128000)); +SELECT LENGTH(a) FROM t1; +ALTER TABLE t1 MODIFY a BLOB; +SELECT LENGTH(a) FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a BLOB); +INSERT INTO t1 VALUES (REPEAT(0x61,65000)); +SELECT LENGTH(a) FROM t1; +ALTER TABLE t1 MODIFY a TINYBLOB; +SELECT LENGTH(a) FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/field.cc b/sql/field.cc index aeeacf7f88d..ceea0893a3f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7068,6 +7068,35 @@ uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg) } +/** + Copy a value from another BLOB field of the same character set. + This method is used by Copy_field, e.g. during ALTER TABLE. +*/ +int Field_blob::copy_value(Field_blob *from) +{ + DBUG_ASSERT(field_charset == from->charset()); + int rc= 0; + uint32 length= from->get_length(); + uchar *data; + from->get_ptr(&data); + if (packlength < from->packlength) + { + int well_formed_errors; + set_if_smaller(length, Field_blob::max_data_length()); + length= field_charset->cset->well_formed_len(field_charset, + (const char *) data, + (const char *) data + length, + length, &well_formed_errors); + rc= report_if_important_data((const char *) data + length, + (const char *) data + from->get_length(), + true); + } + store_length(length); + bmove(ptr + packlength, (uchar*) &data, sizeof(char*)); + return rc; +} + + int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; diff --git a/sql/field.h b/sql/field.h index 4c79847228e..49f94179a92 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1830,6 +1830,11 @@ protected: */ String value; + void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number); + inline void store_length(uint32 number) + { + store_length(ptr, packlength, number); + } public: Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, @@ -1902,11 +1907,6 @@ public: int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; } void reset_fields() { bzero((uchar*) &value,sizeof(value)); } uint32 get_field_buffer_size(void) { return value.alloced_length(); } - void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number); - inline void store_length(uint32 number) - { - store_length(ptr, packlength, number); - } inline uint32 get_length(uint row_offset= 0) { return get_length(ptr+row_offset, this->packlength); } uint32 get_length(const uchar *ptr, uint packlength); @@ -1935,6 +1935,7 @@ public: { set_ptr_offset(0, length, data); } + int copy_value(Field_blob *from); uint get_key_image(uchar *buff,uint length, imagetype type); void set_key_image(const uchar *buff,uint length); void sql_type(String &str) const; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index d24f31e4fa1..3fdc1639266 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -332,9 +332,7 @@ static void do_copy_next_number(Copy_field *copy) static void do_copy_blob(Copy_field *copy) { - ulong length=((Field_blob*) copy->from_field)->get_length(); - ((Field_blob*) copy->to_field)->store_length(length); - memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*)); + ((Field_blob*) copy->to_field)->copy_value(((Field_blob*) copy->from_field)); } static void do_conv_blob(Copy_field *copy) @@ -709,12 +707,7 @@ Copy_field::get_copy_func(Field *to,Field *from) if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) return do_conv_blob; if (from_length != to_length) - { - // Correct pointer to point at char pointer - to_ptr+= to_length - to->table->s->blob_ptr_size; - from_ptr+= from_length- from->table->s->blob_ptr_size; return do_copy_blob; - } } else { From 93b078cc85f4ff11a0dca661d0089b1200d94981 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Sun, 27 Dec 2015 15:40:34 +0400 Subject: [PATCH 026/127] MDEV-9128 - Compiling on IBM System Z fails Provided IBM System Z have outdated compiler version, which supports gcc sync builtins but not gcc atomic builtins. It also has weak memory model. InnoDB attempted to verify if __sync_lock_test_and_set() is available by checking IB_STRONG_MEMORY_MODEL. This macro has nothing to do with availability of __sync_lock_test_and_set(), the right one is HAVE_ATOMIC_BUILTINS. --- storage/xtradb/include/os0sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 56c094547b1..db996b096bb 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -488,7 +488,7 @@ os_atomic_clear(volatile lock_word_t* ptr) __atomic_clear(ptr, __ATOMIC_RELEASE); } -# elif defined(IB_STRONG_MEMORY_MODEL) +# elif defined(HAVE_ATOMIC_BUILTINS) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero From f31a89191f6b1679d9f8b584aa95fe006182ee7d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 18 Nov 2015 15:51:20 +0400 Subject: [PATCH 027/127] MDEV-9128 - Compiling on IBM System Z fails Provided IBM System Z have outdated compiler version, which supports gcc sync builtins but not gcc atomic builtins. It also has weak memory model. InnoDB attempted to verify if __sync_lock_test_and_set() is available by checking IB_STRONG_MEMORY_MODEL. This macro has nothing to do with availability of __sync_lock_test_and_set(), the right one is HAVE_ATOMIC_BUILTINS. --- storage/innobase/include/os0sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 8e4b4f41aae..e192a3a6c94 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -487,7 +487,7 @@ os_atomic_clear(volatile lock_word_t* ptr) __atomic_clear(ptr, __ATOMIC_RELEASE); } -# elif defined(IB_STRONG_MEMORY_MODEL) +# elif defined(HAVE_ATOMIC_BUILTINS) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero From 1ec594dd60aa3b58e7d1c686016695b5b0bc1aa1 Mon Sep 17 00:00:00 2001 From: Karthik Kamath Date: Tue, 29 Dec 2015 15:58:44 +0530 Subject: [PATCH 028/127] BUG#21902059: "CREATE TEMPORARY TABLE SELECT ..." AND BIT(1) COLUMNS ANALYSIS: ========= A valgrind error is reported when CREATE TABLE .. SELECT involving BIT columns triggers a column type redefinition. In general the pack_flag is set for BIT columns in 'mysql_prepare_create_table()'. However, during the above operation, redefined column types was handled after the special handling for BIT columns and thus pack_flag ended up not being set correctly triggering the valgrind error. FIX: ==== The patch fixes this problem by setting pack_flag correctly for BIT columns in the case of column type redefinition. --- sql/sql_table.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3f64de7eac2..7b4d08613cf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3081,8 +3081,31 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, else { /* Field redefined */ + + /* + If we are replacing a BIT field, revert the increment + of total_uneven_bit_length that was done above. + */ + if (sql_field->sql_type == MYSQL_TYPE_BIT && + file->ha_table_flags() & HA_CAN_BIT_FIELD) + total_uneven_bit_length-= sql_field->length & 7; + sql_field->def= dup_field->def; sql_field->sql_type= dup_field->sql_type; + + /* + If we are replacing a field with a BIT field, we need + to initialize pack_flag. Note that we do not need to + increment total_uneven_bit_length here as this dup_field + has already been processed. + */ + if (sql_field->sql_type == MYSQL_TYPE_BIT) + { + sql_field->pack_flag= FIELDFLAG_NUMBER; + if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD)) + sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR; + } + sql_field->charset= (dup_field->charset ? dup_field->charset : create_info->default_table_charset); From 61d3621ea3ce8171ca6d48f1d3ddbb6adefbbad7 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 29 Dec 2015 18:40:41 +0400 Subject: [PATCH 029/127] Moving Field_blob::store_length() back from protected to public, as it's needed for Cassandra in 10.0. --- sql/field.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/field.h b/sql/field.h index 49f94179a92..f761aa8d3ea 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1830,11 +1830,6 @@ protected: */ String value; - void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number); - inline void store_length(uint32 number) - { - store_length(ptr, packlength, number); - } public: Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, @@ -1907,6 +1902,11 @@ public: int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; } void reset_fields() { bzero((uchar*) &value,sizeof(value)); } uint32 get_field_buffer_size(void) { return value.alloced_length(); } + void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number); + inline void store_length(uint32 number) + { + store_length(ptr, packlength, number); + } inline uint32 get_length(uint row_offset= 0) { return get_length(ptr+row_offset, this->packlength); } uint32 get_length(const uchar *ptr, uint packlength); From ff2482026996d007689f41d522fb4d8289143a6b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 30 Dec 2015 19:39:31 +0100 Subject: [PATCH 030/127] Fix process handle leak in buildbot. GenerateConsoleCtrlEvent sent to non-existing process will add a process handle to this non-existing process to console host process conhost.exe --- mysql-test/lib/My/SafeProcess/safe_process_win.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 87a14481e25..dca2faded71 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -357,14 +357,14 @@ int main(int argc, const char** argv ) CloseHandle(job_handle); message("Job terminated and closed"); - if (!jobobject_assigned) - { - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, process_info.dwProcessId); - TerminateProcess(process_info.hProcess, 202); - } + if (wait_res != WAIT_OBJECT_0 + CHILD) { + if (!jobobject_assigned) + { + TerminateProcess(process_info.hProcess, 202); + } /* The child has not yet returned, wait for it */ message("waiting for child to exit"); if ((wait_res= WaitForSingleObject(wait_handles[CHILD], INFINITE)) From cb15cce746db6c32cb62c70bd356b2db61267fd9 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Thu, 31 Dec 2015 07:31:12 +0530 Subject: [PATCH 031/127] Bug #21564557: INCONSISTENT OUTPUT FROM 5.5 AND 5.6 UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%M" Issue: ----- When an invalid date is supplied to the UNIX_TIMESTAMP function from STR_TO_DATE, no check is performed before converting it to a timestamp value. SOLUTION: --------- Add the check_date function and only if it succeeds, proceed to the timestamp conversion. No warning will be returned for dates having zero in month/date, since partial dates are allowed. UNIX_TIMESTAMP will return only a zero for such values. The problem has been handled in 5.6+ with WL#946. --- mysql-test/r/func_time.result | 31 +++++++++++++++++++++++++++++++ mysql-test/t/func_time.test | 18 ++++++++++++++++++ sql/item_timefunc.cc | 13 +++++++++---- sql/sql_time.h | 7 ++++++- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 7f3ecc0d602..2db5711a4b9 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1672,3 +1672,34 @@ insert into t1 values ('00:00:00'),('00:01:00'); select 1 from t1 where 1 < some (select cast(a as datetime) from t1); 1 drop table t1; +# +# Bug #21564557: INCONSISTENT OUTPUT FROM 5.5 AND 5.6 +# UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%M" +# +SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); +UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")) +0 +SELECT UNIX_TIMESTAMP('2015-06-00'); +UNIX_TIMESTAMP('2015-06-00') +0 +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); +UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) +0 +set sql_mode= 'TRADITIONAL'; +SELECT @@sql_mode; +@@sql_mode +STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION +SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); +UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")) +NULL +Warnings: +Warning 1411 Incorrect datetime value: '201506' for function str_to_date +SELECT UNIX_TIMESTAMP('2015-06-00'); +UNIX_TIMESTAMP('2015-06-00') +0 +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); +UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')) +NULL +Warnings: +Warning 1411 Incorrect datetime value: '0000-00-00 10:30:30' for function str_to_date +set sql_mode= default; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index b6c70485dbc..3abfdc616ff 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1026,3 +1026,21 @@ create table t1(a time); insert into t1 values ('00:00:00'),('00:01:00'); select 1 from t1 where 1 < some (select cast(a as datetime) from t1); drop table t1; + +--echo # +--echo # Bug #21564557: INCONSISTENT OUTPUT FROM 5.5 AND 5.6 +--echo # UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%M" +--echo # + +SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); +SELECT UNIX_TIMESTAMP('2015-06-00'); +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); + +set sql_mode= 'TRADITIONAL'; +SELECT @@sql_mode; + +SELECT UNIX_TIMESTAMP(STR_TO_DATE('201506', "%Y%m")); +SELECT UNIX_TIMESTAMP('2015-06-00'); +SELECT UNIX_TIMESTAMP(STR_TO_DATE('0000-00-00 10:30:30', '%Y-%m-%d %h:%i:%s')); + +set sql_mode= default; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 840c8e55efe..00145540e6d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1378,7 +1378,7 @@ longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp) longlong Item_func_unix_timestamp::val_int() { MYSQL_TIME ltime; - my_bool not_used; + my_bool not_used= 0; DBUG_ASSERT(fixed == 1); if (arg_count == 0) @@ -1390,7 +1390,7 @@ longlong Item_func_unix_timestamp::val_int() return ((Field_timestamp*) field)->get_timestamp(&null_value); } - if (get_arg0_date(<ime, 0)) + if (get_arg0_date(<ime, TIME_FUZZY_DATE)) { /* We have to set null_value again because get_arg0_date will also set it @@ -1400,7 +1400,11 @@ longlong Item_func_unix_timestamp::val_int() null_value= args[0]->null_value; return 0; } - + + int dummy= 0; + if (check_date(<ime, non_zero_date(<ime), TIME_NO_ZERO_IN_DATE, &dummy)) + return 0; + return (longlong) TIME_to_timestamp(current_thd, <ime, ¬_used); } @@ -3482,6 +3486,7 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date) String val_string(val_buff, sizeof(val_buff), &my_charset_bin), *val; String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format; + fuzzy_date|= sql_mode; val= args[0]->val_str(&val_string); format= args[1]->val_str(&format_str); if (args[0]->null_value || args[1]->null_value) diff --git a/sql/sql_time.h b/sql/sql_time.h index 0418a0e9621..3e3cd693613 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -91,6 +91,11 @@ inline bool parse_date_time_format(timestamp_type format_type, date_time_format); } +static inline bool +non_zero_date(const MYSQL_TIME *ltime) +{ + return ltime->year || ltime->month || ltime->day; +} extern DATE_TIME_FORMAT global_date_format; extern DATE_TIME_FORMAT global_datetime_format; From 4b4777ab63522b2bdd1f98ad03558a5b1da53dc0 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 3 Jan 2016 12:48:55 +0200 Subject: [PATCH 032/127] Backported fix for ccache Fixed compiler warnings Added --big-test to tokudb change_column_char & change_column_bin --- BUILD/SETUP.sh | 15 +++++++++++++-- storage/connect/json.cpp | 2 +- storage/connect/jsonudf.cpp | 2 +- .../mysql-test/tokudb/t/change_column_bin.py | 1 + .../mysql-test/tokudb/t/change_column_bin.test | 1 + .../mysql-test/tokudb/t/change_column_char.py | 1 + .../mysql-test/tokudb/t/change_column_char.test | 1 + 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index bde095b0aa8..858f42320b8 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -31,6 +31,7 @@ Usage: $0 [-h|-n] [configure-options] -h, --help Show this help message. -n, --just-print Don't actually run any commands; just print them. -c, --just-configure Stop after running configure. + Combined with --just-print shows configure options. --extra-configs=xxx Add this to configure options --extra-flags=xxx Add this C and CXX flags --extra-cflags=xxx Add this to C flags @@ -257,6 +258,10 @@ fi # (http://samba.org/ccache) is installed, use it. # We use 'grep' and hope 'grep' will work as expected # (returns 0 if finds lines) + +# As cmake doesn't like CC and CXX with a space, use symlinks from +# /usr/lib64/ccache if they exits. + if test "$USING_GCOV" != "1" then # Not using gcov; Safe to use ccache @@ -265,8 +270,14 @@ fi if ccache -V > /dev/null 2>&1 && test "$CCACHE_GCOV_VERSION_ENABLED" = "1" then - echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC" - echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX" + if test -x /usr/lib64/ccache/gcc + then + CC=/usr/lib64/ccache/gcc + fi + if test -x /usr/lib64/ccache/g++ + then + CXX=/usr/lib64/ccache/g++ + fi fi # gcov diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index fc7edb84c0f..aa677342fac 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -594,7 +594,7 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, char *fn, int pretty) if (fs) { fputs(EL, fs); fclose(fs); - str = (err) ? NULL : "Ok"; + str = (err) ? NULL : (char*) "Ok"; } else if (!err) { str = ((JOUTSTR*)jp)->Strp; jp->WriteChr('\0'); diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 40685ae0f0e..215562af46e 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3365,7 +3365,7 @@ my_bool jsoncontains_init(UDF_INIT *initid, UDF_ARGS *args, char *message) long long jsoncontains(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) { - char *p, res[256]; + char *p __attribute__((unused)), res[256]; long long n; unsigned long reslen; diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py index 0ddee301d1b..b94a80ec7be 100644 --- a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py +++ b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py @@ -24,6 +24,7 @@ def gen_test(n): def main(): print "# this test is generated by change_bin.py" print "# test binary expansion is hot" + print "--source include/big_test.inc" print "--disable_warnings" print "DROP TABLE IF EXISTS t,ti;" print "--enable_warnings" diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.test index 0365c155302..6053a263cf0 100644 --- a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.test +++ b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.test @@ -1,6 +1,7 @@ source include/have_tokudb.inc; # this test is generated by change_bin.py # test binary expansion is hot +--source include/big_test.inc --disable_warnings DROP TABLE IF EXISTS t,ti; --enable_warnings diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char.py index 99d99d1c017..7481d9092f2 100644 --- a/storage/tokudb/mysql-test/tokudb/t/change_column_char.py +++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char.py @@ -24,6 +24,7 @@ def gen_test(n): def main(): print "# this test is generated by change_char.py" print "# test char expansion" + print "--source include/big_test.inc" print "--disable_warnings" print "DROP TABLE IF EXISTS t,ti;" print "--enable_warnings" diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char.test index 8a0b0a9abd8..977420ad07e 100644 --- a/storage/tokudb/mysql-test/tokudb/t/change_column_char.test +++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char.test @@ -1,6 +1,7 @@ source include/have_tokudb.inc; # this test is generated by change_char.py # test char expansion +--source include/big_test.inc --disable_warnings DROP TABLE IF EXISTS t,ti; --enable_warnings From 661a6d89065390ca1e9b4be05219b75f850ed290 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 3 Jan 2016 13:20:07 +0200 Subject: [PATCH 033/127] Cleanup of slave code: - Added testing if connection is killed to shortcut reading of connection data This will allow us later in 10.2 to do a cleaner shutdown of slaves (less errors in the log) - Add new status variables: Slaves_connected, Slaves_running and Slave_connections. - Use MYSQL_SLAVE_NOT_RUN instead of 0 with slave_running. - Don't print obvious extra warnings to the error log when slave is shut down normally. --- sql/mysqld.cc | 35 +++++++++++++++++++++++++++++++++++ sql/net_serv.cc | 20 +++++++++++++++----- sql/rpl_mi.cc | 16 +++++++++------- sql/rpl_mi.h | 2 +- sql/rpl_rli.cc | 2 +- sql/slave.cc | 13 ++++++------- sql/sql_class.cc | 9 ++++++++- sql/sql_class.h | 1 + sql/sql_parse.cc | 1 + 9 files changed, 77 insertions(+), 22 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e3e331932d0..c6ac3f7a4a2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7299,6 +7299,38 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) } +/* How many slaves are connected to this master */ + +static int show_slaves_connected(THD *thd, SHOW_VAR *var, char *buff) +{ + + var->type= SHOW_LONGLONG; + var->value= buff; + mysql_mutex_lock(&LOCK_slave_list); + + *((longlong *)buff)= slave_list.records; + + mysql_mutex_unlock(&LOCK_slave_list); + return 0; +} + + +/* How many masters this slave is connected to */ + + +static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff) +{ + var->type= SHOW_LONGLONG; + var->value= buff; + mysql_mutex_lock(&LOCK_active_mi); + + *((longlong *)buff)= master_info_index->any_slave_sql_running(); + + mysql_mutex_unlock(&LOCK_active_mi); + return 0; +} + + static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff) { Master_info *mi= NULL; @@ -7950,6 +7982,9 @@ SHOW_VAR status_vars[]= { {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count_), SHOW_LONG_STATUS}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_INT}, #ifdef HAVE_REPLICATION + {"Slaves_connected", (char*) &show_slaves_connected, SHOW_SIMPLE_FUNC }, + {"Slaves_running", (char*) &show_slaves_running, SHOW_SIMPLE_FUNC }, + {"Slave_connections", (char*) offsetof(STATUS_VAR, com_register_slave), SHOW_LONG_STATUS}, {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC}, {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC}, {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG}, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 0ce0fa93f99..91a17606d68 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -34,6 +34,7 @@ HFTODO this must be hidden if we don't want client capabilities in embedded library */ + #include #include #include @@ -107,13 +108,12 @@ extern void query_cache_insert(const char *packet, ulong length, unsigned pkt_nr); #endif // HAVE_QUERY_CACHE #define update_statistics(A) A -#else -#define update_statistics(A) -#endif - -#ifdef MYSQL_SERVER +extern my_bool thd_net_is_killed(); /* Additional instrumentation hooks for the server */ #include "mysql_com_server.h" +#else +#define update_statistics(A) +#define thd_net_is_killed() 0 #endif #define TEST_BLOCKING 8 @@ -875,6 +875,16 @@ my_real_read(NET *net, size_t *complen, DBUG_PRINT("info",("vio_read returned %ld errno: %d", (long) length, vio_errno(net->vio))); + + if (i== 0 && thd_net_is_killed()) + { + len= packet_error; + net->error= 0; + net->last_errno= ER_CONNECTION_KILLED; + MYSQL_SERVER_my_error(net->last_errno, MYF(0)); + goto end; + } + #if !defined(__WIN__) && defined(MYSQL_SERVER) /* We got an error that there was no data on the socket. We now set up diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index ae6cc1ac0a2..a7ee3f3f45e 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -35,7 +35,8 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, rli(is_slave_recovery), port(MYSQL_PORT), checksum_alg_before_fd(BINLOG_CHECKSUM_ALG_UNDEF), connect_retry(DEFAULT_CONNECT_RETRY), inited(0), abort_slave(0), - slave_running(0), slave_run_id(0), clock_diff_with_master(0), + slave_running(MYSQL_SLAVE_NOT_RUN), slave_run_id(0), + clock_diff_with_master(0), sync_counter(0), heartbeat_period(0), received_heartbeats(0), master_id(0), prev_master_id(0), using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0), @@ -1273,23 +1274,24 @@ bool Master_info_index::give_error_if_slave_running() The LOCK_active_mi must be held while calling this function. @return - TRUE If some slave SQL thread is running. - FALSE No slave SQL thread is running + 0 No Slave SQL thread is running + # Number of slave SQL thread running */ -bool Master_info_index::any_slave_sql_running() +uint Master_info_index::any_slave_sql_running() { + uint count= 0; DBUG_ENTER("any_slave_sql_running"); if (!this) // master_info_index is set to NULL on server shutdown - DBUG_RETURN(TRUE); + DBUG_RETURN(count); for (uint i= 0; i< master_info_hash.records; ++i) { Master_info *mi= (Master_info *)my_hash_element(&master_info_hash, i); if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) - DBUG_RETURN(TRUE); + count++; } - DBUG_RETURN(FALSE); + DBUG_RETURN(count); } diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 2b0b40feb3d..a27672e4c90 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -218,7 +218,7 @@ public: Master_info *get_master_info(LEX_STRING *connection_name, Sql_condition::enum_warning_level warning); bool give_error_if_slave_running(); - bool any_slave_sql_running(); + uint any_slave_sql_running(); bool start_all_slaves(THD *thd); bool stop_all_slaves(THD *thd); }; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 8c7724d88a3..422c38209b5 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -63,7 +63,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) last_master_timestamp(0), sql_thread_caught_up(true), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_driver_thd(), gtid_skip_flag(GTID_SKIP_NOT), inited(0), abort_slave(0), stop_for_until(0), - slave_running(0), until_condition(UNTIL_NONE), + slave_running(MYSQL_SLAVE_NOT_RUN), until_condition(UNTIL_NONE), until_log_pos(0), retried_trans(0), executed_entries(0), m_flags(0) { diff --git a/sql/slave.cc b/sql/slave.cc index 3f8bc066378..6b2a88a2953 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -112,7 +112,7 @@ static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]= { { "Waiting to reconnect after a failed registration on master", - "Slave I/O thread killed while waitnig to reconnect after a failed \ + "Slave I/O thread killed while waiting to reconnect after a failed \ registration on master", "Reconnecting after a failed registration on master", "failed registering on master, reconnecting to try again, \ @@ -4040,10 +4040,9 @@ connected: if (request_dump(thd, mysql, mi, &suppress_warnings)) { sql_print_error("Failed on request_dump()"); - if (check_io_slave_killed(mi, "Slave I/O thread killed while \ -requesting master dump") || - try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings, - reconnect_messages[SLAVE_RECON_ACT_DUMP])) + if (check_io_slave_killed(mi, NullS) || + try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings, + reconnect_messages[SLAVE_RECON_ACT_DUMP])) goto err; goto connected; } @@ -4059,6 +4058,7 @@ requesting master dump") || }); const char *event_buf; + mi->slave_running= MYSQL_SLAVE_RUN_READING; DBUG_ASSERT(mi->last_error().number == 0); while (!io_slave_killed(mi)) { @@ -4071,8 +4071,7 @@ requesting master dump") || */ THD_STAGE_INFO(thd, stage_waiting_for_master_to_send_event); event_len= read_event(mysql, mi, &suppress_warnings); - if (check_io_slave_killed(mi, "Slave I/O thread killed while \ -reading event")) + if (check_io_slave_killed(mi, NullS)) goto err; DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT", if (!retry_count_event) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7a9cdad84f6..3d0d99bcfa2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1743,7 +1743,8 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, void THD::awake(killed_state state_to_set) { DBUG_ENTER("THD::awake"); - DBUG_PRINT("enter", ("this: %p current_thd: %p", this, current_thd)); + DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d", + this, current_thd, (int) state_to_set)); THD_CHECK_SENTRY(this); mysql_mutex_assert_owner(&LOCK_thd_data); @@ -3799,6 +3800,12 @@ void thd_increment_bytes_sent(ulong length) } } +my_bool thd_net_is_killed() +{ + THD *thd= current_thd; + return thd && thd->killed ? 1 : 0; +} + void thd_increment_bytes_received(ulong length) { diff --git a/sql/sql_class.h b/sql/sql_class.h index a94236aec0b..8264921cabd 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -656,6 +656,7 @@ typedef struct system_status_var { ulong com_other; ulong com_stat[(uint) SQLCOM_END]; + ulong com_register_slave; ulong created_tmp_disk_tables_; ulong created_tmp_tables_; ulong ha_commit_count; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 23629ff3ec4..8373ddabe3c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1177,6 +1177,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifdef HAVE_REPLICATION case COM_REGISTER_SLAVE: { + status_var_increment(thd->status_var.com_register_slave); if (!register_slave(thd, (uchar*)packet, packet_length)) my_ok(thd); break; From 8fcc0bfefadcb4e9f7acb13d11661daeea5097f9 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 3 Jan 2016 13:27:59 +0200 Subject: [PATCH 034/127] Fixed bug in semi_sync replication tests. The problem was that wait_for_slave_io_to_start reported that the io thread was ready, when it was still initializing. This caused test suite to continue too early, for example before the semi sync plugin was properly enabled. Fixed by introducing a new internal stage: "Preparing". Slave_IO_Running is now set to "Yes" only when all initializing is done and the IO thread is ready to read things from the master. The only test affected by this change is rpl_flsh_tbls, which got stuck in the preparing phase while trying to read the GTID position from a table. Fixed by having this test waiting for Preparing instead of Yes. --- mysql-test/extra/rpl_tests/rpl_flsh_tbls.test | 8 +++++++- mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result | 3 ++- .../suite/rpl/r/rpl_semi_sync_uninstall_plugin.result | 8 ++++++++ mysql-test/suite/rpl/r/rpl_stm_flsh_tbls.result | 3 ++- .../suite/rpl/t/rpl_semi_sync_uninstall_plugin.test | 6 ++++++ sql/mysqld.cc | 4 ++-- sql/rpl_mi.cc | 2 +- sql/slave.cc | 8 ++++---- sql/slave.h | 9 +++++---- 9 files changed, 37 insertions(+), 14 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test index 5cbda2d591f..a8cec3d2a1a 100644 --- a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test +++ b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test @@ -45,7 +45,13 @@ drop table t1; connection slave; flush tables with read lock; start slave; -source include/wait_for_slave_to_start.inc; + +# The IO thread will not be able to read the GTID because of flush tables +let $slave_param= Slave_IO_Running; +let $slave_param_value= Preparing; +source include/wait_for_slave_param.inc; + +--source include/wait_for_slave_sql_to_start.inc --error 1192 stop slave; diff --git a/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result b/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result index 6aca4282ccd..27b23739831 100644 --- a/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result +++ b/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result @@ -22,7 +22,8 @@ include/wait_for_slave_to_stop.inc drop table t1; flush tables with read lock; start slave; -include/wait_for_slave_to_start.inc +include/wait_for_slave_param.inc [Slave_IO_Running] +include/wait_for_slave_sql_to_start.inc stop slave; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result index 0809af5f943..36d862dedce 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_uninstall_plugin.result @@ -14,6 +14,10 @@ DROP TABLE t1; [connection slave] include/install_semisync.inc [connection slave] +show global status like "Slave%_running"; +Variable_name Value +Slave_running ON +Slaves_running 1 UNINSTALL PLUGIN rpl_semi_sync_slave; Warnings: Warning 1620 Plugin is busy and will be uninstalled on shutdown @@ -21,6 +25,10 @@ select plugin_name,plugin_status from information_schema.plugins where plugin_na plugin_name plugin_status rpl_semi_sync_slave DELETED [connection master] +show global status like "Slave%_connect%"; +Variable_name Value +Slave_connections 2 +Slaves_connected 1 UNINSTALL PLUGIN rpl_semi_sync_master; Warnings: Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/mysql-test/suite/rpl/r/rpl_stm_flsh_tbls.result b/mysql-test/suite/rpl/r/rpl_stm_flsh_tbls.result index 6aca4282ccd..27b23739831 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_flsh_tbls.result +++ b/mysql-test/suite/rpl/r/rpl_stm_flsh_tbls.result @@ -22,7 +22,8 @@ include/wait_for_slave_to_stop.inc drop table t1; flush tables with read lock; start slave; -include/wait_for_slave_to_start.inc +include/wait_for_slave_param.inc [Slave_IO_Running] +include/wait_for_slave_sql_to_start.inc stop slave; ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction unlock tables; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test index 4ee345e54ba..0f86789cced 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_uninstall_plugin.test @@ -57,6 +57,8 @@ DROP TABLE t1; # possible at this state --connection slave --echo [connection slave] +show global status like "Slave%_running"; + UNINSTALL PLUGIN rpl_semi_sync_slave; select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%'; @@ -64,6 +66,10 @@ select plugin_name,plugin_status from information_schema.plugins where plugin_na # possible at this state --connection master --echo [connection master] + +# The following is to catch errors if the next uninstall plugin would succeed +show global status like "Slave%_connect%"; + UNINSTALL PLUGIN rpl_semi_sync_master; select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'rpl_%'; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c6ac3f7a4a2..416193ff1e0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7287,8 +7287,8 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) get_master_info(&thd->variables.default_master_connection, Sql_condition::WARN_LEVEL_NOTE); if (mi) - tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT && - mi->rli.slave_running); + tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING && + mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN); } mysql_mutex_unlock(&LOCK_active_mi); if (mi) diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index a7ee3f3f45e..9c6f4639717 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1321,7 +1321,7 @@ bool Master_info_index::start_all_slaves(THD *thd) Try to start all slaves that are configured (host is defined) and are not already running */ - if ((mi->slave_running != MYSQL_SLAVE_RUN_CONNECT || + if ((mi->slave_running == MYSQL_SLAVE_NOT_RUN || !mi->rli.slave_running) && *mi->host) { if ((error= start_slave(thd, mi, 1))) diff --git a/sql/slave.cc b/sql/slave.cc index 6b2a88a2953..7474aec38ca 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2615,6 +2615,8 @@ static bool send_show_master_info_header(THD *thd, bool full, DBUG_RETURN(FALSE); } +/* Text for Slave_IO_Running */ +static const char *slave_running[]= { "No", "Connecting", "Preparing", "Yes" }; static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, String *gtid_pos) @@ -2668,9 +2670,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, &my_charset_bin); protocol->store((ulonglong) mi->rli.group_relay_log_pos); protocol->store(mi->rli.group_master_log_name, &my_charset_bin); - protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ? - "Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ? - "Connecting" : "No"), &my_charset_bin); + protocol->store(slave_running[mi->slave_running], &my_charset_bin); protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin); protocol->store(rpl_filter->get_do_db()); protocol->store(rpl_filter->get_ignore_db()); @@ -2713,7 +2713,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, Seconds_Behind_Master: if SQL thread is running and I/O thread is connected, we can compute it otherwise show NULL (i.e. unknown). */ - if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) && + if ((mi->slave_running == MYSQL_SLAVE_RUN_READING) && mi->rli.slave_running) { long time_diff; diff --git a/sql/slave.h b/sql/slave.h index e16f801b577..5cc02c8a10b 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -132,11 +132,11 @@ extern my_bool opt_replicate_annotate_row_events; extern ulonglong relay_log_space_limit; /* - 3 possible values for Master_info::slave_running and + 4 possible values for Master_info::slave_running and Relay_log_info::slave_running. - The values 0,1,2 are very important: to keep the diff small, I didn't - substitute places where we use 0/1 with the newly defined symbols. So don't change - these values. + The values 0,1,2,3 are very important: to keep the diff small, I didn't + substitute places where we use 0/1 with the newly defined symbols. + So don't change these values. The same way, code is assuming that in Relay_log_info we use only values 0/1. I started with using an enum, but @@ -145,6 +145,7 @@ extern ulonglong relay_log_space_limit; #define MYSQL_SLAVE_NOT_RUN 0 #define MYSQL_SLAVE_RUN_NOT_CONNECT 1 #define MYSQL_SLAVE_RUN_CONNECT 2 +#define MYSQL_SLAVE_RUN_READING 3 #define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\ "FIRST") From 8c65e082f397a34cf393cfc6019daaa303ef5151 Mon Sep 17 00:00:00 2001 From: V S Murthy Sidagam Date: Mon, 4 Jan 2016 15:31:45 +0530 Subject: [PATCH 035/127] Description: yaSSL was only handling the cases of zero or one leading zeros for the key agreement instead of potentially any number. There is about 1 in 50,000 connections to fail when using DHE cipher suites. The second problem was the case where a server would send a public value shorter than the prime value, causing about 1 in 128 client connections to fail, and also caused the yaSSL client to read off the end of memory. All client side DHE cipher suite users should update. Note: The patch is received from YaSSL people --- extra/yassl/README | 11 +++++++++++ extra/yassl/include/crypto_wrapper.hpp | 1 + extra/yassl/include/openssl/ssl.h | 2 +- extra/yassl/src/crypto_wrapper.cpp | 11 ++++++++--- extra/yassl/src/yassl_imp.cpp | 15 ++++----------- extra/yassl/src/yassl_int.cpp | 15 +++++++++++++++ 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/extra/yassl/README b/extra/yassl/README index bf0e1c9f40f..81d573d0b20 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,6 +12,17 @@ before calling SSL_new(); *** end Note *** +yaSSL Release notes, version 2.3.9 (12/01/2015) + This release of yaSSL fixes two client side Diffie-Hellman problems. + yaSSL was only handling the cases of zero or one leading zeros for the key + agreement instead of potentially any number. This caused about 1 in 50,000 + connections to fail when using DHE cipher suites. The second problem was + the case where a server would send a public value shorter than the prime + value, causing about 1 in 128 client connections to fail, and also + caused the yaSSL client to read off the end of memory. All client side + DHE cipher suite users should update. + Thanks to Adam Langely (agl@imperialviolet.org) for the detailed report! + yaSSL Release notes, version 2.3.8 (9/17/2015) This release of yaSSL fixes a high security vulnerability. All users SHOULD update. If using yaSSL for TLS on the server side with private diff --git a/extra/yassl/include/crypto_wrapper.hpp b/extra/yassl/include/crypto_wrapper.hpp index b09b662c88c..0472b304679 100644 --- a/extra/yassl/include/crypto_wrapper.hpp +++ b/extra/yassl/include/crypto_wrapper.hpp @@ -378,6 +378,7 @@ public: uint get_agreedKeyLength() const; const byte* get_agreedKey() const; + uint get_publicKeyLength() const; const byte* get_publicKey() const; void makeAgreement(const byte*, unsigned int); diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index b0a7592f870..095b3c6aa80 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -35,7 +35,7 @@ #include "rsa.h" -#define YASSL_VERSION "2.3.8" +#define YASSL_VERSION "2.3.9" #if defined(__cplusplus) diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 3f819ee2349..95065932c5f 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -751,9 +751,10 @@ struct DiffieHellman::DHImpl { byte* publicKey_; byte* privateKey_; byte* agreedKey_; + uint pubKeyLength_; DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0), - privateKey_(0), agreedKey_(0) {} + privateKey_(0), agreedKey_(0), pubKeyLength_(0) {} ~DHImpl() { ysArrayDelete(agreedKey_); @@ -762,7 +763,7 @@ struct DiffieHellman::DHImpl { } DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_), - publicKey_(0), privateKey_(0), agreedKey_(0) + publicKey_(0), privateKey_(0), agreedKey_(0), pubKeyLength_(0) { uint length = dh_.GetByteLength(); AllocKeys(length, length, length); @@ -810,7 +811,7 @@ DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g, using TaoCrypt::Integer; pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref()); - pimpl_->publicKey_ = NEW_YS opaque[pubSz]; + pimpl_->publicKey_ = NEW_YS opaque[pimpl_->pubKeyLength_ = pubSz]; memcpy(pimpl_->publicKey_, pub, pubSz); } @@ -869,6 +870,10 @@ const byte* DiffieHellman::get_agreedKey() const return pimpl_->agreedKey_; } +uint DiffieHellman::get_publicKeyLength() const +{ + return pimpl_->pubKeyLength_; +} const byte* DiffieHellman::get_publicKey() const { diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 1baa5adedf8..f190761604d 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -109,15 +109,12 @@ void ClientDiffieHellmanPublic::build(SSL& ssl) uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same alloc(keyLength, true); - dhClient.makeAgreement(dhServer.get_publicKey(), keyLength); + dhClient.makeAgreement(dhServer.get_publicKey(), + dhServer.get_publicKeyLength()); c16toa(keyLength, Yc_); memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength); - // because of encoding first byte might be zero, don't use it for preMaster - if (*dhClient.get_agreedKey() == 0) - ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1); - else - ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); + ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); } @@ -321,11 +318,7 @@ void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input) } dh.makeAgreement(Yc_, keyLength); - // because of encoding, first byte might be 0, don't use for preMaster - if (*dh.get_agreedKey() == 0) - ssl.set_preMaster(dh.get_agreedKey() + 1, dh.get_agreedKeyLength() - 1); - else - ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength()); + ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength()); ssl.makeMasterSecret(); } diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index c04c5a53352..19ba6386efd 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -807,6 +807,19 @@ void SSL::set_random(const opaque* random, ConnectionEnd sender) // store client pre master secret void SSL::set_preMaster(const opaque* pre, uint sz) { + uint i(0); // trim leading zeros + uint fullSz(sz); + + while (i++ < fullSz && *pre == 0) { + sz--; + pre++; + } + + if (sz == 0) { + SetError(bad_input); + return; + } + secure_.use_connection().AllocPreSecret(sz); memcpy(secure_.use_connection().pre_master_secret_, pre, sz); } @@ -924,6 +937,8 @@ void SSL::order_error() // Create and store the master secret see page 32, 6.1 void SSL::makeMasterSecret() { + if (GetError()) return; + if (isTLS()) makeTLSMasterSecret(); else { From 3d1306f7b74077cfa197c8fa23baeb96c535af67 Mon Sep 17 00:00:00 2001 From: Ajo Robert Date: Thu, 7 Jan 2016 14:36:19 +0530 Subject: [PATCH 036/127] Bug#21770366 backport bug#21657078 to 5.5 and 5.6 Problem Statement ========= Fix various issues when building MySQL with Visual Studio 2015. Fix: ======= - Visual Studio 2015 adds support for timespec. Add check and related code to use this and only use our replacement if timespec is not defined. - Rename lfind/lsearch to my* to avoid redefinition problems. - Set default value for TMPDIR to "" on Windows as P_tmpdir no longer exists. - using VS definition of snprintf if available - tzname are now renamed to _tzname. --- CMakeLists.txt | 15 +++++++++++---- cmake/os/Windows.cmake | 4 +++- cmake/os/WindowsCache.cmake | 5 ++--- config.h.cmake | 4 +++- configure.cmake | 5 +++-- include/my_pthread.h | 12 ++++-------- mysys/lf_hash.c | 22 +++++++++++----------- mysys/my_wincond.c | 14 +++++++++++++- plugin/semisync/semisync_master.cc | 7 +++---- 9 files changed, 53 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 586119b2ffb..1abfa95f8b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -328,9 +328,16 @@ IF(SYSCONFDIR) SET(DEFAULT_SYSCONFDIR "${SYSCONFDIR}") ENDIF() -SET(TMPDIR "P_tmpdir" - CACHE PATH - "PATH to MySQL TMP dir. Defaults to the P_tmpdir macro in ") +IF(WIN32) # P_tmpdir is not defined on Windows as of VS2015. + SET(TMPDIR "" # So we use empty path as default. In practice TMP/TEMP is used + CACHE PATH + "PATH to MySQL TMP dir") +ELSE() + SET(TMPDIR "P_tmpdir" + CACHE PATH + "PATH to MySQL TMP dir. Defaults to the P_tmpdir macro in ") +ENDIF() + IF(TMPDIR STREQUAL "P_tmpdir") # Do not quote it, to refer to the P_tmpdir macro. SET(DEFAULT_TMPDIR "P_tmpdir") diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake index 98158ca806b..1b79970a830 100644 --- a/cmake/os/Windows.cmake +++ b/cmake/os/Windows.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -185,6 +185,8 @@ CHECK_SYMBOL_REPLACEMENT(SIGQUIT SIGTERM signal.h) CHECK_SYMBOL_REPLACEMENT(SIGPIPE SIGINT signal.h) CHECK_SYMBOL_REPLACEMENT(isnan _isnan float.h) CHECK_SYMBOL_REPLACEMENT(finite _finite float.h) +CHECK_SYMBOL_REPLACEMENT(tzname _tzname time.h) +CHECK_SYMBOL_REPLACEMENT(snprintf _snprintf stdio.h) CHECK_FUNCTION_REPLACEMENT(popen _popen) CHECK_FUNCTION_REPLACEMENT(pclose _pclose) CHECK_FUNCTION_REPLACEMENT(access _access) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index bbed14556b9..1b5a2cedfd5 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -227,7 +227,6 @@ SET(HAVE_SIZEOF_ULONG FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_U_INT32_T FALSE CACHE INTERNAL "") SET(HAVE_SIZE_OF_SSIZE_T FALSE CACHE INTERNAL "") SET(HAVE_SLEEP CACHE INTERNAL "") -SET(HAVE_SNPRINTF CACHE INTERNAL "") SET(HAVE_SOCKADDR_STORAGE_SS_FAMILY 1 CACHE INTERNAL "") SET(HAVE_SOLARIS_STYLE_GETHOST CACHE INTERNAL "") SET(STACK_DIRECTION -1 CACHE INTERNAL "") @@ -301,7 +300,7 @@ SET(HAVE_TIME 1 CACHE INTERNAL "") SET(HAVE_TIMES CACHE INTERNAL "") SET(HAVE_TIMESPEC_TS_SEC CACHE INTERNAL "") SET(HAVE_TIME_H 1 CACHE INTERNAL "") -SET(HAVE_TZNAME 1 CACHE INTERNAL "") +SET(HAVE__tzname 1 CACHE INTERNAL "") SET(HAVE_UNISTD_H CACHE INTERNAL "") SET(HAVE_UTIME_H CACHE INTERNAL "") SET(HAVE_VALLOC CACHE INTERNAL "") diff --git a/config.h.cmake b/config.h.cmake index 8c93da072fb..4548d0a221f 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -376,6 +376,7 @@ #cmakedefine HAVE_UINT64 1 #cmakedefine SIZEOF_BOOL @SIZEOF_BOOL@ #cmakedefine HAVE_BOOL 1 +#cmakedefine HAVE_STRUCT_TIMESPEC #cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@ @@ -497,6 +498,7 @@ #cmakedefine strtok_r @strtok_r@ #cmakedefine strtoll @strtoll@ #cmakedefine strtoull @strtoull@ +#cmakedefine tzname @tzname@ #cmakedefine vsnprintf @vsnprintf@ #if (_MSC_VER > 1310) # define HAVE_SETENV diff --git a/configure.cmake b/configure.cmake index 28974a84c49..f90d36a01e4 100644 --- a/configure.cmake +++ b/configure.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -561,7 +561,7 @@ MY_CHECK_TYPE_SIZE(char CHAR) MY_CHECK_TYPE_SIZE(short SHORT) MY_CHECK_TYPE_SIZE(int INT) MY_CHECK_TYPE_SIZE("long long" LONG_LONG) -SET(CMAKE_EXTRA_INCLUDE_FILES stdio.h sys/types.h) +SET(CMAKE_EXTRA_INCLUDE_FILES stdio.h sys/types.h time.h) MY_CHECK_TYPE_SIZE(off_t OFF_T) MY_CHECK_TYPE_SIZE(uchar UCHAR) MY_CHECK_TYPE_SIZE(uint UINT) @@ -576,6 +576,7 @@ MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T) MY_CHECK_TYPE_SIZE(int64 INT64) MY_CHECK_TYPE_SIZE(uint64 UINT64) MY_CHECK_TYPE_SIZE(time_t TIME_T) +MY_CHECK_TYPE_SIZE("struct timespec" STRUCT_TIMESPEC) SET (CMAKE_EXTRA_INCLUDE_FILES sys/types.h) MY_CHECK_TYPE_SIZE(bool BOOL) SET(CMAKE_EXTRA_INCLUDE_FILES) diff --git a/include/my_pthread.h b/include/my_pthread.h index 92676bd727c..6ff198ac6f3 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -90,6 +90,7 @@ typedef volatile LONG my_pthread_once_t; windows implementation of pthread_cond_timedwait */ +#ifndef HAVE_STRUCT_TIMESPEC /* Declare a union to make sure FILETIME is properly aligned so it can be used directly as a 64 bit value. The value @@ -128,6 +129,7 @@ struct timespec { ((TS1.tv.i64 > TS2.tv.i64) ? 1 : \ ((TS1.tv.i64 < TS2.tv.i64) ? -1 : 0)) +#endif int win_pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *); @@ -433,13 +435,7 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #endif /* !set_timespec_nsec */ #else #ifndef set_timespec -#define set_timespec(ABSTIME,SEC) \ -{\ - struct timeval tv;\ - gettimeofday(&tv,0);\ - (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\ - (ABSTIME).tv_nsec=tv.tv_usec*1000;\ -} +#define set_timespec(ABSTIME,SEC) set_timespec_nsec((ABSTIME),(SEC)*1000000000ULL) #endif /* !set_timespec */ #ifndef set_timespec_nsec #define set_timespec_nsec(ABSTIME,NSEC) \ diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 4f0a3a32d86..dc019b07bd9 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,7 +43,7 @@ typedef struct { /* a structure to pass the context (pointers two the three successive elements - in a list) from lfind to linsert/ldelete + in a list) from my_lfind to linsert/ldelete */ typedef struct { intptr volatile *prev; @@ -70,7 +70,7 @@ typedef struct { cursor is positioned in either case pins[0..2] are used, they are NOT removed on return */ -static int lfind(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, +static int my_lfind(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, const uchar *key, uint keylen, CURSOR *cursor, LF_PINS *pins) { uint32 cur_hashnr; @@ -138,7 +138,7 @@ retry: /* DESCRIPTION insert a 'node' in the list that starts from 'head' in the correct - position (as found by lfind) + position (as found by my_lfind) RETURN 0 - inserted @@ -156,7 +156,7 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, for (;;) { - if (lfind(head, cs, node->hashnr, node->key, node->keylen, + if (my_lfind(head, cs, node->hashnr, node->key, node->keylen, &cursor, pins) && (flags & LF_HASH_UNIQUE)) { @@ -207,7 +207,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, for (;;) { - if (!lfind(head, cs, hashnr, key, keylen, &cursor, pins)) + if (!my_lfind(head, cs, hashnr, key, keylen, &cursor, pins)) { res= 1; /* not found */ break; @@ -231,7 +231,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, (to ensure the number of "set DELETED flag" actions is equal to the number of "remove from the list" actions) */ - lfind(head, cs, hashnr, key, keylen, &cursor, pins); + my_lfind(head, cs, hashnr, key, keylen, &cursor, pins); } res= 0; break; @@ -257,12 +257,12 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, it uses pins[0..2], on return the pin[2] keeps the node found all other pins are removed. */ -static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs, +static LF_SLIST *my_lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, const uchar *key, uint keylen, LF_PINS *pins) { CURSOR cursor; - int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins); + int res= my_lfind(head, cs, hashnr, key, keylen, &cursor, pins); if (res) _lf_pin(pins, 2, cursor.curr); _lf_unpin(pins, 0); @@ -443,7 +443,7 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) MY_ERRPTR if OOM NOTE - see lsearch() for pin usage notes + see my_lsearch() for pin usage notes */ void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) { @@ -457,7 +457,7 @@ void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) return MY_ERRPTR; if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) return MY_ERRPTR; - found= lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1, + found= my_lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1, (uchar *)key, keylen, pins); lf_rwunlock_by_pins(pins); return found ? found+1 : 0; diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c index ac0166c87b8..567721baf27 100644 --- a/mysys/my_wincond.c +++ b/mysys/my_wincond.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -88,6 +88,7 @@ static void check_native_cond_availability(void) static DWORD get_milliseconds(const struct timespec *abstime) { +#ifndef HAVE_STRUCT_TIMESPEC long long millis; union ft64 now; @@ -118,6 +119,17 @@ static DWORD get_milliseconds(const struct timespec *abstime) millis= UINT_MAX; return (DWORD)millis; +#else + /* + Convert timespec to millis and subtract current time. + my_getsystime() returns time in 100 ns units. + */ + if (abstime == NULL) + return INFINITE; + + return (DWORD)(abstime->tv_sec * 1000 + abstime->tv_nsec / 1000000 - + my_getsystime() / 10000); +#endif } diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index 2e40fc8b5c5..40d577e4372 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -1,6 +1,5 @@ /* Copyright (C) 2007 Google Inc. - Copyright (c) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. - Use is subject to license terms. + Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,7 +47,7 @@ static int getWaitTime(const struct timespec& start_ts); static unsigned long long timespec_to_usec(const struct timespec *ts) { -#ifndef __WIN__ +#ifdef HAVE_STRUCT_TIMESPEC return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND; #else return ts->tv.i64 / 10; @@ -683,7 +682,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, } /* Calcuate the waiting period. */ -#ifdef __WIN__ +#ifndef HAVE_STRUCT_TIMESPEC abstime.tv.i64 = start_ts.tv.i64 + (__int64)wait_timeout_ * TIME_THOUSAND * 10; abstime.max_timeout_msec= (long)wait_timeout_; #else From 5f48b61509e4bc0fcb4e679abe51a6fc2dbb6359 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 7 Jan 2016 14:45:40 +0100 Subject: [PATCH 037/127] MDEV-9298 : Build failure when linking libmysql. If GCC or CLang compile with link time optimization (-flto), they throw an error during link , when lto sees a function (e.g mysql_real_connect) is redeclared as "external void *" in libmysql_exports.cc The fix disables -flto for generated libmysql_exports.cc --- cmake/libutils.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index cca0032962d..41b7d9d1d86 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -87,6 +87,11 @@ MACRO(CREATE_EXPORT_FILE VAR TARGET API_FUNCTIONS) ENDFOREACH() SET(CONTENT "${CONTENT} (void *)0\n}\;") CONFIGURE_FILE_CONTENT(${CONTENT} ${EXPORTS}) + # Avoid "function redeclared as variable" error + # when using gcc/clang option -flto(link time optimization) + IF(" ${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} " MATCHES " -flto") + SET_SOURCE_FILES_PROPERTIES(${EXPORTS} PROPERTIES COMPILE_FLAGS "-fno-lto") + ENDIF() SET(${VAR} ${EXPORTS}) ENDIF() ENDMACRO() From 1236333333c351b93593b12c0e20b06313e4ac29 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 24 Dec 2015 21:46:38 +0100 Subject: [PATCH 038/127] Fix annoying repetitive tokudb build warning, if MariaDB is build on non-Linux x64 system --- storage/tokudb/CMakeLists.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index d1f43d71f57..1b256ff100b 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -9,10 +9,9 @@ struct a d = { .b=1, .c=2 }; int main() { return 0; } " TOKUDB_OK) ELSE() - IF(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - MESSAGE(WARNING "Not Intel 64 bit CPU") - ELSE() - MESSAGE(WARNING "Too old CMAKE VERSION. 2.8.9 or higher is required by TokuDB") + IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND + CMAKE_VERSION VERSION_LESS "2.8.9") + MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB") ENDIF() ENDIF() From 3730d8a225fe33a0157e0aaa85121ef7cecf288d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 Jan 2016 22:48:50 +0100 Subject: [PATCH 039/127] MDEV-9366 : do_shutdown_server fails to detect server shutdown on Windows. Fix test whether process is alive in mysqltest. Also fix SHUT_RD definition on Windows to be SD_RECEIVE. SD_BOTH was used instead prior to this patch, and this would occasionally make mysql_shutdown() fail - when the socket for the current connection is not able send the COM_SHUTDOWN response anymore. --- client/mysqltest.cc | 5 +++-- include/violite.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c601fb57f2f..026934a2feb 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5121,12 +5121,13 @@ static int my_kill(int pid, int sig) { #ifdef __WIN__ HANDLE proc; - if ((proc= OpenProcess(PROCESS_TERMINATE, FALSE, pid)) == NULL) + if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) return -1; if (sig == 0) { + DWORD wait_result= WaitForSingleObject(proc, 0); CloseHandle(proc); - return 0; + return wait_result == WAIT_OBJECT_0?-1:0; } (void)TerminateProcess(proc, 201); CloseHandle(proc); diff --git a/include/violite.h b/include/violite.h index d5ce66c3061..a7165ca91a9 100644 --- a/include/violite.h +++ b/include/violite.h @@ -208,7 +208,7 @@ void vio_end(void); /* shutdown(2) flags */ #ifndef SHUT_RD -#define SHUT_RD SD_BOTH +#define SHUT_RD SD_RECEIVE #endif /* From 863f7cebd79e76f90bd8f1e3e0c1a1de5fe77d07 Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Fri, 8 Jan 2016 06:46:59 +0530 Subject: [PATCH 040/127] Bug #22232332: SAVING TEXT FIELD TO TEXT VARIABLE IN A PROCEDURE RESULTS IN GARBAGE BYTES Issue: ----- This problem occurs under the following conditions: a) Stored procedure has a variable is declared as TEXT/BLOB. b) Data is copied into the the variable using the SELECT...INTO syntax from a TEXT/BLOB column. Data corruption can occur in such cases. SOLUTION: --------- The blob type does not allocate space for the string to be stored. Instead it contains a pointer to the source string. Since the source is deallocated immediately after the select statement, this can cause data corruption. As part of the fix for Bug #21143080, when the source was part of the table's write-set, blob would allocate the neccessary space. But this fix missed the possibility that, as in the above case, the target might be a variable. The fix will add the copy_blobs check that was removed by the earlier fix. --- sql/field_conv.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 7eb49b9dd92..d98f19c3e01 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -826,7 +826,12 @@ int field_conv(Field *to,Field *from) Field_blob *blob=(Field_blob*) to; from->val_str(&blob->value); - if (!blob->value.is_alloced() && from->is_updatable()) + /* + Copy value if copy_blobs is set, or source is part of the table's + writeset. + */ + if (to->table->copy_blobs || + (!blob->value.is_alloced() && from->is_updatable())) blob->value.copy(); return blob->store(blob->value.ptr(),blob->value.length(),from->charset()); From 0891ae2fbb77c96a7fbeeb2ce9973d22da596f2a Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 9 Jan 2016 20:52:17 +0100 Subject: [PATCH 041/127] - Fix MDEV-9239. Meanwhile, make all references to the database in XTAB Schema (was sometimes in XTAB Catalog) modified: storage/connect/mycat.cc modified: storage/connect/mycat.h modified: storage/connect/reldef.cpp modified: storage/connect/reldef.h modified: storage/connect/tabmysql.cpp modified: storage/connect/tabpivot.cpp modified: storage/connect/tabtbl.cpp modified: storage/connect/tabutil.cpp --- storage/connect/mycat.cc | 31 +++++++++++++++++-------------- storage/connect/mycat.h | 10 ++++++---- storage/connect/reldef.cpp | 13 ++++++++----- storage/connect/reldef.h | 12 +++++++----- storage/connect/tabmysql.cpp | 2 +- storage/connect/tabpivot.cpp | 4 ++-- storage/connect/tabtbl.cpp | 6 +++--- storage/connect/tabutil.cpp | 25 +++++++++++++++++-------- 8 files changed, 61 insertions(+), 42 deletions(-) diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 2e9085b4c87..97ad980dd6a 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -1,4 +1,4 @@ -/* Copyright (C) Olivier Bertrand 2004 - 2015 +/* Copyright (C) Olivier Bertrand 2004 - 2016 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ /* ------------- */ /* Version 1.4 */ /* */ -/* Author: Olivier Bertrand 2012 - 2015 */ +/* Author: Olivier Bertrand 2012 - 2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -509,30 +509,33 @@ void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path) /* GetTableDesc: retrieve a table descriptor. */ /* Look for a table descriptor matching the name and type. */ /***********************************************************************/ -PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name, +PRELDEF MYCAT::GetTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR type, PRELDEF *) { if (trace) - printf("GetTableDesc: name=%s am=%s\n", name, SVP(type)); + printf("GetTableDesc: name=%s am=%s\n", tablep->GetName(), SVP(type)); // If not specified get the type of this table if (!type) type= Hc->GetStringOption("Type","*"); - return MakeTableDesc(g, name, type); + return MakeTableDesc(g, tablep, type); } // end of GetTableDesc /***********************************************************************/ /* MakeTableDesc: make a table/view description. */ /* Note: caller must check if name already exists before calling it. */ /***********************************************************************/ -PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) +PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) { TABTYPE tc; + LPCSTR name = (PSZ)PlugDup(g, tablep->GetName()); + LPCSTR schema = (PSZ)PlugDup(g, tablep->GetSchema()); PRELDEF tdp= NULL; if (trace) - printf("MakeTableDesc: name=%s am=%s\n", name, SVP(am)); + printf("MakeTableDesc: name=%s schema=%s am=%s\n", + name, SVP(schema), SVP(am)); /*********************************************************************/ /* Get a unique enum identifier for types. */ @@ -571,11 +574,11 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) case TAB_VIR: tdp= new(g) VIRDEF; break; case TAB_JSON: tdp= new(g) JSONDEF; break; default: - sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name); + sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name); } // endswitch // Do make the table/view definition - if (tdp && tdp->Define(g, this, name, am)) + if (tdp && tdp->Define(g, this, name, schema, am)) tdp= NULL; return tdp; @@ -588,20 +591,20 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type) { PRELDEF tdp; PTDB tdbp= NULL; - LPCSTR name= tablep->GetName(); +// LPCSTR name= tablep->GetName(); if (trace) - printf("GetTableDB: name=%s\n", name); + printf("GetTableDB: name=%s\n", tablep->GetName()); // Look for the description of the requested table - tdp= GetTableDesc(g, name, type); + tdp= GetTableDesc(g, tablep, type); if (tdp) { if (trace) printf("tdb=%p type=%s\n", tdp, tdp->GetType()); - if (tablep->GetQualifier()) - tdp->Database = SetPath(g, tablep->GetQualifier()); + if (tablep->GetSchema()) + tdp->Database = SetPath(g, tablep->GetSchema()); tdbp= tdp->GetTable(g, mode); } // endif tdp diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h index dfcbb2f6766..05163f08f1b 100644 --- a/storage/connect/mycat.h +++ b/storage/connect/mycat.h @@ -100,15 +100,17 @@ class MYCAT : public CATALOG { //void SetDataPath(PGLOBAL g, const char *path) // {SetPath(g, &DataPath, path);} bool StoreIndex(PGLOBAL, PTABDEF) {return false;} // Temporary - PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, - LPCSTR type, PRELDEF *prp = NULL); +// PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, + PRELDEF GetTableDesc(PGLOBAL g, PTABLE tablep, + LPCSTR type, PRELDEF *prp = NULL); PTDB GetTable(PGLOBAL g, PTABLE tablep, MODE mode = MODE_READ, LPCSTR type = NULL); void ClearDB(PGLOBAL g); protected: - PRELDEF MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am); -//void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path); +// PRELDEF MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am); + PRELDEF MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am); + //void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path); // Members ha_connect *Hc; // The Connect handler diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index 8f9328c0b2f..e455bc8f1a5 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -1,11 +1,11 @@ /************* RelDef CPP Program Source Code File (.CPP) **************/ /* PROGRAM NAME: RELDEF */ /* ------------- */ -/* Version 1.4 */ +/* Version 1.5 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2004-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -37,6 +37,7 @@ #include "plgdbsem.h" #include "reldef.h" #include "colblk.h" +#include "tabcol.h" #include "filamap.h" #include "filamfix.h" #include "filamvct.h" @@ -217,11 +218,13 @@ TABDEF::TABDEF(void) /***********************************************************************/ /* Define: initialize the table definition block from XDB file. */ /***********************************************************************/ -bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) +bool TABDEF::Define(PGLOBAL g, PCATLG cat, + LPCSTR name, LPCSTR schema, LPCSTR am) { int poff = 0; - Name = (PSZ)PlugDup(g, name); + Name = (PSZ)name; + Schema = (PSZ)schema; Cat = cat; Hc = ((MYCAT*)cat)->GetHandler(); Catfunc = GetFuncID(GetStringCatInfo(g, "Catfunc", NULL)); @@ -569,7 +572,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) } // endif Cbuf // Here "OEM" should be replace by a more useful value - if (xdefp->Define(g, cat, Name, "OEM")) + if (xdefp->Define(g, cat, Name, Schema, "OEM")) return NULL; // Ok, return external block diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index dada5716dbe..bc1bd2ddd74 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -1,7 +1,7 @@ /*************** RelDef H Declares Source Code File (.H) ***************/ -/* Name: RELDEF.H Version 1.5 */ +/* Name: RELDEF.H Version 1.6 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2004-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */ /* */ /* This file contains the DEF classes definitions. */ /***********************************************************************/ @@ -50,7 +50,8 @@ class DllExport RELDEF : public BLOCK { // Relation definition block int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size); char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef); virtual int Indexable(void) {return 0;} - virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0; + virtual bool Define(PGLOBAL g, PCATLG cat, + LPCSTR name, LPCSTR schema, LPCSTR am) = 0; virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0; protected: @@ -97,8 +98,9 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ int GetColCatInfo(PGLOBAL g); void SetIndexInfo(void); bool DropTable(PGLOBAL g, PSZ name); - virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am); - virtual bool DefineAM(PGLOBAL, LPCSTR, int) = 0; + virtual bool Define(PGLOBAL g, PCATLG cat, + LPCSTR name, LPCSTR schema, LPCSTR am); + virtual bool DefineAM(PGLOBAL, LPCSTR, int) = 0; protected: // Members diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 658f3513b07..b9cede52a21 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -334,7 +334,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) Delayed = !!GetIntCatInfo("Delayed", 0); } else { // MYSQL access from a PROXY table - Database = GetStringCatInfo(g, "Database", "*"); + Database = GetStringCatInfo(g, "Database", Schema ? Schema : "*"); Isview = GetBoolCatInfo("View", false); // We must get other connection parms from the calling table diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index b628e26d3c7..256b454741c 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -348,7 +348,7 @@ bool PIVOTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) return TRUE; Tabname = (char*)Tablep->GetName(); - DB = (char*)Tablep->GetQualifier(); + DB = (char*)Tablep->GetSchema(); Tabsrc = (char*)Tablep->GetSrc(); Host = GetStringCatInfo(g, "Host", "localhost"); @@ -529,7 +529,7 @@ bool TDBPIVOT::GetSourceTable(PGLOBAL g) // Get the new table description block of this source table PTABLE tablep = new(g) XTAB("whatever", Tabsrc); - tablep->SetQualifier(Database); + tablep->SetSchema(Database); if (!(Tdbp = GetSubTable(g, tablep, true))) return true; diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 7f979eaf4be..6b72c715517 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to PlugDB Software Development 2008-2015 */ +/* (C) Copyright to PlugDB Software Development 2008-2016 */ /* Author: Olivier BERTRAND */ /* */ /* WHAT THIS PROGRAM DOES: */ @@ -130,10 +130,10 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR, int) // Allocate the TBLIST block for that table tbl = new(g) XTAB(pn, def); - tbl->SetQualifier(pdb); + tbl->SetSchema(pdb); if (trace) - htrc("TBL: Name=%s db=%s\n", tbl->GetName(), tbl->GetQualifier()); + htrc("TBL: Name=%s db=%s\n", tbl->GetName(), tbl->GetSchema()); // Link the blocks if (Tablep) diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index 331a7f45d4d..4069cdbed2a 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -1,7 +1,7 @@ /************* Tabutil cpp Declares Source Code File (.CPP) ************/ /* Name: TABUTIL.CPP Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2013 - 2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2013 - 2016 */ /* */ /* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */ /***********************************************************************/ @@ -118,7 +118,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM, FLD_NO, FLD_CHARSET}; unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32}; - char *fld, *colname, *chset, *fmt, v; + char *pn, *tn, *fld, *colname, *chset, *fmt, v; int i, n, ncol = sizeof(buftyp) / sizeof(int); int prec, len, type, scale; int zconv = GetConvSize(); @@ -130,7 +130,16 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db, PCOLRES crp; if (!info) { - if (!(s = GetTableShare(g, thd, db, name, mysql))) { + // Analyze the table name, it may have the format: [dbname.]tabname + if (strchr((char*)name, '.')) { + tn = (char*)PlugDup(g, name); + pn = strchr(tn, '.'); + *pn++ = 0; + db = tn; + name = pn; + } // endif pn + + if (!(s = GetTableShare(g, thd, db, name, mysql))) { return NULL; } else if (s->is_view) { strcpy(g->Message, "Use MYSQL type to see columns from a view"); @@ -315,7 +324,7 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR, int) } // endif pn Tablep = new(g) XTAB(tab, def); - Tablep->SetQualifier(db); + Tablep->SetSchema(db); return false; } // end of DefineAM @@ -379,12 +388,12 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) LPCSTR cdb, curdb = hc->GetDBName(NULL); THD *thd = (hc->GetTable())->in_use; - db = (char*)tabp->GetQualifier(); + db = (char*)(tabp->GetSchema() ? tabp->GetSchema() : curdb); name = (char*)tabp->GetName(); // Check for eventual loop for (PTABLE tp = To_Table; tp; tp = tp->Next) { - cdb = (tp->Qualifier) ? tp->Qualifier : curdb; + cdb = (tp->Schema) ? tp->Schema : curdb; if (!stricmp(name, tp->Name) && !stricmp(db, cdb)) { sprintf(g->Message, "Table %s.%s pointing on itself", db, name); @@ -423,7 +432,7 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) } // endif Define if (db) - ((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier()); + ((PTDBMY)tdbp)->SetDatabase(tabp->GetSchema()); if (Mode == MODE_UPDATE || Mode == MODE_DELETE) tdbp->SetName(Name); // For Make_Command @@ -757,7 +766,7 @@ void PRXCOL::WriteColumn(PGLOBAL g) /***********************************************************************/ TDBTBC::TDBTBC(PPRXDEF tdp) : TDBCAT(tdp) { - Db = (PSZ)tdp->Tablep->GetQualifier(); + Db = (PSZ)tdp->Tablep->GetSchema(); Tab = (PSZ)tdp->Tablep->GetName(); } // end of TDBTBC constructor From 13380bf81f6bc20d39549f531f9acebdfb5a8c37 Mon Sep 17 00:00:00 2001 From: Yashwant Sahu Date: Mon, 11 Jan 2016 07:09:13 +0530 Subject: [PATCH 042/127] Bug #22295186: CERTIFICATE VALIDATION BUG IN MYSQL MAY ALLOW MITM --- mysql-test/std_data/ca-cert-verify.pem | 20 +++++ .../std_data/server-cert-verify-fail.pem | 19 ++++ .../std_data/server-cert-verify-pass.pem | 19 ++++ .../std_data/server-key-verify-fail.pem | 27 ++++++ .../std_data/server-key-verify-pass.pem | 27 ++++++ .../suite/auth_sec/r/cert_verify.result | 5 ++ mysql-test/suite/auth_sec/t/cert_verify.test | 49 ++++++++++ sql-common/client.c | 90 +++++++++++++------ 8 files changed, 230 insertions(+), 26 deletions(-) create mode 100644 mysql-test/std_data/ca-cert-verify.pem create mode 100644 mysql-test/std_data/server-cert-verify-fail.pem create mode 100644 mysql-test/std_data/server-cert-verify-pass.pem create mode 100644 mysql-test/std_data/server-key-verify-fail.pem create mode 100644 mysql-test/std_data/server-key-verify-pass.pem create mode 100644 mysql-test/suite/auth_sec/r/cert_verify.result create mode 100644 mysql-test/suite/auth_sec/t/cert_verify.test diff --git a/mysql-test/std_data/ca-cert-verify.pem b/mysql-test/std_data/ca-cert-verify.pem new file mode 100644 index 00000000000..21d6264a0ad --- /dev/null +++ b/mysql-test/std_data/ca-cert-verify.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWzCCAkOgAwIBAgIJAO/QdKLEDQdXMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNV +BAYTAklOMREwDwYDVQQIDAhLYXJuYXRrYTESMBAGA1UEBwwJQmFuZ2Fsb3JlMQ4w +DAYDVQQKDAVNeVNRTDAeFw0xNjAxMDUxMDA1MDhaFw0yNTExMTMxMDA1MDhaMEQx +CzAJBgNVBAYTAklOMREwDwYDVQQIDAhLYXJuYXRrYTESMBAGA1UEBwwJQmFuZ2Fs +b3JlMQ4wDAYDVQQKDAVNeVNRTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKdOCuS2CzfBTJ2x8SAzY0J7cYJfNJvMDF1cvANnhkIhtnkWt/HZ5DJ9NxeX +q5h7FJLAi4gddqdk/tvQJw0V6gZepJr/mKVnMPivF5+oHPc9ZJQMX6B3FBNwWylm +ACd5GKx8I/H/MXyuhQTcoV//Ab+2pI8RHeYbBsm3lHH+tX7bRU6mUFjneqMpiCkb +JHt6BWZiWR10O6pMuGQ9+dDdsLhEV1fj3CctEPwW6rs4IZzD8xl5n+8cy7qu6eYH +Wt/snwsTzkrufeMRqTtqelxON9eoQwYOR1oH3vNEVlcbuoJAvaWOqBROUBdf12SP +TYSdP9nlRh7lTKQOywN4kYt6LqUCAwEAAaNQME4wHQYDVR0OBBYEFJ4c9tKaUU0P +EjBq5G207jjXI7RAMB8GA1UdIwQYMBaAFJ4c9tKaUU0PEjBq5G207jjXI7RAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABRnUyj21oFi0SGJg/K5+8Lc +4n6OwVU/NgLOysIB0baIP/Rqeaze59xG/v9FPQgBlWcJK3RabOywx5bxAxdcus+1 +yp5j4h37Qq1/qkgqmevvdSAPa0OBQbLb+58/naV+ywUpCYZ6flLdCMH3fXuDSlSq +qrCznextjojtWbnzrBmCmJmXWGd2gSaJDvb90ZZp/Elt3vN1sgjW0M/JEkb4MJ1r +6nfD/FHr2lUwBHm2yk7Blovx7x4d/Ip3pglk63cNO/Rn0SBTdoVDS2LB9du3Phq2 +TZiL3NrRMGUNwmdaavyrJxaPq5D+Sfa4LYP3MMYD4KhLogNzIl299n5joyizlJw= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-cert-verify-fail.pem b/mysql-test/std_data/server-cert-verify-fail.pem new file mode 100644 index 00000000000..4203425a344 --- /dev/null +++ b/mysql-test/std_data/server-cert-verify-fail.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJzCCAg8CAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCSU4xETAPBgNV +BAgMCEthcm5hdGthMRIwEAYDVQQHDAlCYW5nYWxvcmUxDjAMBgNVBAoMBU15U1FM +MB4XDTE2MDEwNTEwMDgyN1oXDTI1MTExMzEwMDgyN1owbzELMAkGA1UEBhMCSU4x +EjAQBgNVBAgMCTpLYXJuYXRrYTETMBEGA1UEBwwKOkJhbmdhbG9yZTEPMA0GA1UE +CgwGOk15U1FMMRcwFQYDVQQLDA4vQ049bG9jYWxob3N0LzENMAsGA1UEAwwEZmFp +bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3wnWuJodzZYq9TAJRm +HU7995FA3TEWdUinYTgGP79aTVQ4M9aeINlB6whWXOI8seh9Ja7C6kMzqOgYbgCl +WlDPAVJWktFYeWXOLxbpzh1KWkS6jBkWT02t7H7JcYbil7xjlJUxLz4UOOUDUDIP +6yqdA9VE3osESttjzj57Zm2xPqzbIHVJfORn7EexH4pryS7439p6i4XtfL31NJ8V +07M3j3a8GqbcEqXYvcUCrLnywDQ1igP817b6ta52nbgYWiqdn0mJs535UJ/p/rSl +D4Ae/6G3BSEY7whir6xY6vsd4KJ6w+wRCHnY0ky6OdDJVJLH1iqh7si7P3RBGkxw +Y7MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAggbw1jj2b7H5KDdeGJGIoOGkQAcs +GNSJussCfdk7qnzYXKmjyNppC86jjaOrXona5f+SNCuujdu86Tv8V69EH57k4lUc +DW7J4AD3vUb/tBzB0tsI/76Z4gm1XoCsnCGGpWd8GQAg/QNn/ZfJB2Vb/9ObN6rH +0HV7ouB6OGZSsb71+grKiN6mDyB1lZynCGvqBxOCKFISfcRbCNFHo/pONlHaNGPE +vjDH1bPZbEHj8owYgkdcQe0a8EbJYeQfm6fH8V8bmUcG7N60DrCnq4l1qwwVkh1S +7RpIDgrWkU+esIIdYZIIbtDxQP1Sm7kUh++7b+bcHnyw3KtDVSCw7MIedA== +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-cert-verify-pass.pem b/mysql-test/std_data/server-cert-verify-pass.pem new file mode 100644 index 00000000000..f8780f1f94e --- /dev/null +++ b/mysql-test/std_data/server-cert-verify-pass.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfsCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCSU4xETAPBgNV +BAgMCEthcm5hdGthMRIwEAYDVQQHDAlCYW5nYWxvcmUxDjAMBgNVBAoMBU15U1FM +MB4XDTE2MDEwNTEwMDU1OVoXDTI1MTExMzEwMDU1OVowWzELMAkGA1UEBhMCSU4x +EjAQBgNVBAgMCTpLYXJuYXRrYTETMBEGA1UEBwwKOkJhbmdhbG9yZTEPMA0GA1UE +CgwGOk15U1FMMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAmkbUwDe+nrqL8A8uwlIZk74HHCDjUAWrskKF9leEIQsB +5exFZ8JEo1u6mdR4laQWsxizGdTPqIEidkDyyEMh4+joHgyQEPD/G3rFVW8yEFHb +42O04O96BEPFXNPDRuX3MxI+lGbYDjxTS/WhVub4/3SqLjC28FJmEUXIHA0/A+c5 +hlYXK0u+aPAqXxHIjBgB4BxxHXZKqecmvR3LhXoVmhJmndsVfKajB27nDKc8/OTI +H2SXb6h3nRPDXRfwB/C5i+004tEsVeIgkYshcCgLSyDdeVieUP2pm3EAmDSjmtLF +6CgY/EBSfH+JCKFUk75bA4k8CCGzBfIeOcsKHwgFAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAInDuHtDkeT6dkWmRJCP56c4xiQqib2QuYUuMSrAhf07xlLHc6iHnD2X +hCWCrja6uwF90DnPjeouKMAUe5txq/uKA8/Y/NfXN6nPiAeHLI0qnTv7Mr9TQ8zU +DNDwRz6onlI2cS4GhrwAnlpiaxu7AjMUWHtfBFGFrgn3PawjDQpsBZNcxw1QsLc0 +E0hFrWLOd0vDETEhoRge88N7a0jqK0Rd9cvRWnvjI+IsjQMLZzKufivIHPzI9K+9 +Wtp8iRHcaBr5DpsBjgsO7dqVRbsNyaWsdHdLt+CQSGXpv7P6fq3K6nJFTBeIgSfS +gflrHVKYZRkKDDDpX4yHNdnIqrvy4RU= +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-key-verify-fail.pem b/mysql-test/std_data/server-key-verify-fail.pem new file mode 100644 index 00000000000..af1ae1e3ae1 --- /dev/null +++ b/mysql-test/std_data/server-key-verify-fail.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAvfCda4mh3Nlir1MAlGYdTv33kUDdMRZ1SKdhOAY/v1pNVDgz +1p4g2UHrCFZc4jyx6H0lrsLqQzOo6BhuAKVaUM8BUlaS0Vh5Zc4vFunOHUpaRLqM +GRZPTa3sfslxhuKXvGOUlTEvPhQ45QNQMg/rKp0D1UTeiwRK22POPntmbbE+rNsg +dUl85GfsR7EfimvJLvjf2nqLhe18vfU0nxXTszePdrwaptwSpdi9xQKsufLANDWK +A/zXtvq1rnaduBhaKp2fSYmznflQn+n+tKUPgB7/obcFIRjvCGKvrFjq+x3gonrD +7BEIedjSTLo50MlUksfWKqHuyLs/dEEaTHBjswIDAQABAoIBAQCSUyNzDPydXvsf +hhoUOParPAvU4tuETYDdD9Vdi7Lgf3jDQOjulbNIq/ec3KuBvrBwIrk9APvn+YxO +AUP9S2Vgi5jBDeDdVgNv4n90b3pSJk2UVQJI8V72wN5Ibnf/KeErSKvWo6V5daq/ +AuZtKsZIdd3WFtA62HuyuBjTGc23Alj1C0EKnN0Rx1uBwDvx/OVQ266Us/x8jJqW +ZxIOfcvfNzBQEa5hAzbQCReVaC+rBLRAcMM2yGP7aDa+8cRkwuVlSqpX8CXBdLoU +PqmU49etcW72Rb1AFt9WgEu1Oh9UYbHFSB+FEbO8IGcGBsuYHf9zkxQyjpy/iKyT +H5dTu7YBAoGBAOWqEGepZVrfB+P6X18n3vbJhgYmF0sa0mCmwkFYgk36yNqsZ8at +lQjm5mbn4wjEKHIcQ/T1taq73W471M+PxMnn0WTwoG5jsyarZGgy6/95YXiyZtQe +qgA4P3aKkCteRP22DjG7uxmm9Hoqx8Z31vfRTLAHN1IEHPHHkg/J3gPTAoGBANO4 +aqKeY4vcDvVkvxVbADrw++tZGwA+RuxfO4HKKru59VdA2PsAxhXwb3Dfejwj7hYW +yE9edHjGpMr1+dpf8YJYs7qjajHe1HxBOYqQGHycIdw+Gv56R4HpaS9eW3x8l/Pi +b4xnAodv2qIriACOe7br+rll4wKX46Wt64zdvpShAoGAT0r3HQM0Vjp4u/J+qRjX +9za+yjKuiiS5i9snaG5JlujGHhG2Rrc5pHgsBk17alRnbnZp1BJdZZQ1MFEB+aO2 +mssp1YLqsRJFEU3NfdhO+MaMq6JUtFnd8fN5ndDbU83ZXgtUPUGGqKWm9OL+VHyd +wLQHmSL0q6F16Ngxirf0qjcCgYEAtSmiJVA+gdhk/FmeoBlkEwtNpM50Kjsf2PaM +Jrzk4Al5A5Y7lFvPI8q+sOio4XklKsWH1VJPe2EOdZUQnGlocE6SS+u03MN9Mm1l +XUl7inTXDGwgEQx0z5b4KE4nHlhGdauWI5+pLFbrz8RL9Z32AkneGnIyU2/AnW46 +lijQAMECgYEAmgp/88ndIw49RCtMhYhtXQ87AsEAP6kzXQyKppDkn0os+xI5igIL +i/UDxB33hx3yjrUZwoGDV9MwlMhZNX5Tf5bwjPmmh1NR6KdEpPt5AkklX4s6uil2 +Bxl1P5l1jl/PbEYtv5LDZKIPANWRzViMSIWqjUWlbdqE7/vjx+Oo+cc= +-----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-key-verify-pass.pem b/mysql-test/std_data/server-key-verify-pass.pem new file mode 100644 index 00000000000..7ecc44f6d48 --- /dev/null +++ b/mysql-test/std_data/server-key-verify-pass.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAwJpG1MA3vp66i/APLsJSGZO+Bxwg41AFq7JChfZXhCELAeXs +RWfCRKNbupnUeJWkFrMYsxnUz6iBInZA8shDIePo6B4MkBDw/xt6xVVvMhBR2+Nj +tODvegRDxVzTw0bl9zMSPpRm2A48U0v1oVbm+P90qi4wtvBSZhFFyBwNPwPnOYZW +FytLvmjwKl8RyIwYAeAccR12SqnnJr0dy4V6FZoSZp3bFXymowdu5wynPPzkyB9k +l2+od50Tw10X8AfwuYvtNOLRLFXiIJGLIXAoC0sg3XlYnlD9qZtxAJg0o5rSxego +GPxAUnx/iQihVJO+WwOJPAghswXyHjnLCh8IBQIDAQABAoIBAHPQUSc9LkgBSks7 +XuXPE28t1+aOk3gcdkx4NGg5aQaal/PcPea+LaL4WAAs4AZidPjxWLjZn43+1SfT +09opcbS/Rx3Mc+FtTn0YGQrwBJ0mExMV+K6bU2Ubi2TyHKQfzciHfUEEG5Nve/ba +hikuCFVRxuVOQRzABcw6NqvNsmlg892lfw6/+RDwMBcz7ocwzmiOUoIxgjyFo9G4 +aJvRmHLij5892H6qveik+A/Xr+8leGQHiQET2wW/F9MFP5ypIT7aeE6remeZH7fG +f4/Zfei/TE4xK2ElNR/91byzeKIVY4vjtTndAiBuqpfYuICb40MC02LNW5Oe6VN2 +3mQ6EgECgYEA7O4ndBnbs/00gyTGyNg6I+3wRTibhNH4R8RZFJiLfKRKOlUiLhUo ++bQeO4bCQ6YY++TYDvMEXTlA3jow9R9Mj2AWc6bNmQmJd/065QyFHftywT66I+V4 +rz1ohSJyHXcv4DxqNk3o3Vb4N8GFjZKcodSgTv2Lk+9ipDYFcQiZop0CgYEA0BrF +SIyLTnjoVht/7RbIGEqhMQUiz5mx7qQ1TPB+YTG77G2xXJNg5d6S7WT4LN+cqbxN +YdndIbW4NdV7bH7FlG9q7jfkuZ+AY2BPU047tcDeyO0HYYEhVY+EyZqHci/26mvt +JrawdqS5HQS1y/rKfytm7YBGTvqoNZHvOHc6aokCgYEAxcjlbJkte+pyzMuFmiJP +HrFBczeXM+BoJ9j0GCpjvvAS+vEYsGl/pDvFRSHwx7I/hv/5kTkzOnNSAHGJbwbq +zYGEHJVxakC43k6pvI2gDnBa0pD/qHmmLnvP5dvkcU6Oy90DOUP+kc9JNJo7V/y8 +/qdWD7q+qwcaTETAdCSexE0CgYA/DN1Y7bwHOnqqHArWOmDFe1b7EyNI4rgWJYpA +lVy09eyJ5XInKj/hZV3+rujCL723b2XCj89/tx7osJWEeaRDJL6xDh4uXzT25uch +xkIw/w6Asc/aqtT+p00EB92hqwaUX76qTA+K4r1zHUo3UvSnMu8sZgDnTOpJ0L05 +zmXUgQKBgDT+IFrAzOty4B0mJncTCC/TulpW704bEZwNJfQSdtiBQr/vqoXygBQc +bHfpncpSfhzHB5lhRUv02TqXgl53D70nM7JD5nx98WYTTBxsbvxPlt4gBRZkfgq5 +tHKclAArc1SbfW5Z8oYyl7h33LQJK116QSyiIIGieH5VXNPwnqUs +-----END RSA PRIVATE KEY----- diff --git a/mysql-test/suite/auth_sec/r/cert_verify.result b/mysql-test/suite/auth_sec/r/cert_verify.result new file mode 100644 index 00000000000..1da77329509 --- /dev/null +++ b/mysql-test/suite/auth_sec/r/cert_verify.result @@ -0,0 +1,5 @@ +#T1: Host name (/CN=localhost/) as OU name in the server certificate, server certificate verification should fail. +#T2: Host name (localhost) as common name in the server certificate, server certificate verification should pass. +Variable_name Value +Ssl_version TLS_VERSION +# restart server using restart diff --git a/mysql-test/suite/auth_sec/t/cert_verify.test b/mysql-test/suite/auth_sec/t/cert_verify.test new file mode 100644 index 00000000000..7250d4db67e --- /dev/null +++ b/mysql-test/suite/auth_sec/t/cert_verify.test @@ -0,0 +1,49 @@ +# Want to skip this test from Valgrind execution +--source include/no_valgrind_without_big.inc +# This test should work in embedded server after we fix mysqltest +-- source include/not_embedded.inc +-- source include/have_ssl_communication.inc +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +let $ssl_verify_fail_path = --ssl --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-key=$MYSQL_TEST_DIR/std_data/server-key-verify-fail.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert-verify-fail.pem; +let $ssl_verify_pass_path = --ssl --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-key=$MYSQL_TEST_DIR/std_data/server-key-verify-pass.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert-verify-pass.pem; + +let $tls_default= TLSv1.1; +let $openssl= query_get_value("SHOW STATUS LIKE 'Rsa_public_key'", Variable_name, 1); +if ($openssl == 'Rsa_public_key'){ + let $tls_default= TLSv1.2; +} + +--echo #T1: Host name (/CN=localhost/) as OU name in the server certificate, server certificate verification should fail. +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--exec echo "restart:" $ssl_verify_fail_path > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error 1 +--exec $MYSQL --protocol=tcp --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" + +--echo #T2: Host name (localhost) as common name in the server certificate, server certificate verification should pass. +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--exec echo "restart:" $ssl_verify_pass_path > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--replace_result $tls_default TLS_VERSION +--exec $MYSQL --protocol=tcp --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" + +--echo # restart server using restart +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--exec echo "restart: " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc diff --git a/sql-common/client.c b/sql-common/client.c index c874086fc9c..0ef70eb7f56 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1885,35 +1885,39 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr) { SSL *ssl; - X509 *server_cert; - char *cp1, *cp2; - char buf[256]; + X509 *server_cert= NULL; + char *cn= NULL; + int cn_loc= -1; + ASN1_STRING *cn_asn1= NULL; + X509_NAME_ENTRY *cn_entry= NULL; + X509_NAME *subject= NULL; + int ret_validation= 1; + DBUG_ENTER("ssl_verify_server_cert"); DBUG_PRINT("enter", ("server_hostname: %s", server_hostname)); if (!(ssl= (SSL*)vio->ssl_arg)) { *errptr= "No SSL pointer found"; - DBUG_RETURN(1); + goto error; } if (!server_hostname) { *errptr= "No server hostname supplied"; - DBUG_RETURN(1); + goto error; } if (!(server_cert= SSL_get_peer_certificate(ssl))) { *errptr= "Could not get server certificate"; - DBUG_RETURN(1); + goto error; } if (X509_V_OK != SSL_get_verify_result(ssl)) { *errptr= "Failed to verify the server certificate"; - X509_free(server_cert); - DBUG_RETURN(1); + goto error; } /* We already know that the certificate exchanged was valid; the SSL library @@ -1921,27 +1925,61 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c are what we expect. */ - X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf)); - X509_free (server_cert); + /* + Some notes for future development + We should check host name in alternative name first and then if needed check in common name. + Currently yssl doesn't support alternative name. + openssl 1.0.2 support X509_check_host method for host name validation, we may need to start using + X509_check_host in the future. + */ - DBUG_PRINT("info", ("hostname in cert: %s", buf)); - cp1= strstr(buf, "/CN="); - if (cp1) + subject= X509_get_subject_name((X509 *) server_cert); + // Find the CN location in the subject + cn_loc= X509_NAME_get_index_by_NID(subject, NID_commonName, -1); + if (cn_loc < 0) { - cp1+= 4; /* Skip the "/CN=" that we found */ - /* Search for next / which might be the delimiter for email */ - cp2= strchr(cp1, '/'); - if (cp2) - *cp2= '\0'; - DBUG_PRINT("info", ("Server hostname in cert: %s", cp1)); - if (!strcmp(cp1, server_hostname)) - { - /* Success */ - DBUG_RETURN(0); - } + *errptr= "Failed to get CN location in the certificate subject"; + goto error; } + + // Get the CN entry for given location + cn_entry= X509_NAME_get_entry(subject, cn_loc); + if (cn_entry == NULL) + { + *errptr= "Failed to get CN entry using CN location"; + goto error; + } + + // Get CN from common name entry + cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry); + if (cn_asn1 == NULL) + { + *errptr= "Failed to get CN from CN entry"; + goto error; + } + + cn= (char *) ASN1_STRING_data(cn_asn1); + + // There should not be any NULL embedded in the CN + if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn)) + { + *errptr= "NULL embedded in the certificate CN"; + goto error; + } + + DBUG_PRINT("info", ("Server hostname in cert: %s", cn)); + if (!strcmp(cn, server_hostname)) + { + /* Success */ + ret_validation= 0; + } + *errptr= "SSL certificate validation failure"; - DBUG_RETURN(1); + +error: + if (server_cert != NULL) + X509_free (server_cert); + DBUG_RETURN(ret_validation); } #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ From 70f1aa4223fd6631736b73fb0ccc17aeaece84e7 Mon Sep 17 00:00:00 2001 From: Yashwant Sahu Date: Mon, 11 Jan 2016 09:23:31 +0530 Subject: [PATCH 043/127] Bug #22295186: CERTIFICATE VALIDATION BUG IN MYSQL MAY ALLOW MITM. Test Fix --- mysql-test/suite/auth_sec/t/cert_verify.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/auth_sec/t/cert_verify.test b/mysql-test/suite/auth_sec/t/cert_verify.test index 7250d4db67e..20918349963 100644 --- a/mysql-test/suite/auth_sec/t/cert_verify.test +++ b/mysql-test/suite/auth_sec/t/cert_verify.test @@ -25,7 +25,7 @@ if ($openssl == 'Rsa_public_key'){ --source include/wait_until_connected_again.inc --error 1 ---exec $MYSQL --protocol=tcp --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" +--exec $MYSQL --protocol=tcp --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" --echo #T2: Host name (localhost) as common name in the server certificate, server certificate verification should pass. --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect @@ -37,7 +37,7 @@ if ($openssl == 'Rsa_public_key'){ --source include/wait_until_connected_again.inc --replace_result $tls_default TLS_VERSION ---exec $MYSQL --protocol=tcp --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" +--exec $MYSQL --protocol=tcp --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-verify-server-cert -e "SHOW STATUS like 'Ssl_version'" --echo # restart server using restart --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect From 2a9f84b9a6e72f2d4facfaf49226736cdfe38d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Mon, 11 Jan 2016 10:28:00 +0200 Subject: [PATCH 044/127] MDEV-9354: Debian: unmask the mysql.service on installation Unmask the systemd mysql.service if left behind by mysql-server-5.6 Without this a simple 'apt-get install mariadb-server' would end up with a system where mysqld is not running despite it was running OK with mysql-server-5.6 installed, and users might wrongly think mariadb-server package is broken when the real cause was the removal of mysql-server-5.6 that left a /etc/systemd/system/ file behind pointing to /dev/null. --- debian/dist/Debian/mariadb-server-10.0.postinst | 5 +++++ debian/dist/Ubuntu/mariadb-server-10.0.postinst | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/debian/dist/Debian/mariadb-server-10.0.postinst b/debian/dist/Debian/mariadb-server-10.0.postinst index 19594fb910e..19a69ed00cb 100644 --- a/debian/dist/Debian/mariadb-server-10.0.postinst +++ b/debian/dist/Debian/mariadb-server-10.0.postinst @@ -264,6 +264,11 @@ fi db_stop # in case invoke failes +# If we upgrade from MySQL mysql.service may be masked, which also +# means init.d script is disabled. Unmask mysql service explicitely. +# Ignore exit code as command is not available everywhere. +deb-systemd-helper unmask mysql.service > /dev/null || true + #DEBHELPER# exit 0 diff --git a/debian/dist/Ubuntu/mariadb-server-10.0.postinst b/debian/dist/Ubuntu/mariadb-server-10.0.postinst index 1acfbc80970..2486a09a5af 100644 --- a/debian/dist/Ubuntu/mariadb-server-10.0.postinst +++ b/debian/dist/Ubuntu/mariadb-server-10.0.postinst @@ -280,6 +280,11 @@ fi db_stop # in case invoke failes +# If we upgrade from MySQL mysql.service may be masked, which also +# means init.d script is disabled. Unmask mysql service explicitely. +# Ignore exit code as command is not available everywhere. +deb-systemd-helper unmask mysql.service > /dev/null || true + #DEBHELPER# exit 0 From d9f89fff16671ba2623e7673e4a306ce90223aba Mon Sep 17 00:00:00 2001 From: Yashwant Sahu Date: Mon, 11 Jan 2016 14:44:49 +0530 Subject: [PATCH 045/127] Bug #22295186: CERTIFICATE VALIDATION BUG IN MYSQL MAY ALLOW MITM Test fix for 5.5 and 5.6 --- mysql-test/suite/auth_sec/t/cert_verify.test | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mysql-test/suite/auth_sec/t/cert_verify.test b/mysql-test/suite/auth_sec/t/cert_verify.test index 20918349963..1515fc62340 100644 --- a/mysql-test/suite/auth_sec/t/cert_verify.test +++ b/mysql-test/suite/auth_sec/t/cert_verify.test @@ -9,11 +9,7 @@ let $ssl_verify_fail_path = --ssl --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-key=$MYSQL_TEST_DIR/std_data/server-key-verify-fail.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert-verify-fail.pem; let $ssl_verify_pass_path = --ssl --ssl-ca=$MYSQL_TEST_DIR/std_data/ca-cert-verify.pem --ssl-key=$MYSQL_TEST_DIR/std_data/server-key-verify-pass.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert-verify-pass.pem; -let $tls_default= TLSv1.1; -let $openssl= query_get_value("SHOW STATUS LIKE 'Rsa_public_key'", Variable_name, 1); -if ($openssl == 'Rsa_public_key'){ - let $tls_default= TLSv1.2; -} +let $tls_default= TLSv1; --echo #T1: Host name (/CN=localhost/) as OU name in the server certificate, server certificate verification should fail. --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect From 0aab0e7a3d9afa5475d5a515142a19c6a09ae44c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 11 Jan 2016 14:10:58 +0100 Subject: [PATCH 046/127] Updated copyright year in user visible text --- README | 2 +- include/welcome_copyright_notice.h | 4 ++-- packaging/WiX/custom_ui.wxs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 47b38689038..72cc70bbd16 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software is released under the version 2 of the GNU General Public License. MySQL is brought to you by Oracle. -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. License information can be found in the COPYING file. diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h index eb2bf260af3..7b6c28c2f56 100644 --- a/include/welcome_copyright_notice.h +++ b/include/welcome_copyright_notice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ #ifndef _welcome_copyright_notice_h_ #define _welcome_copyright_notice_h_ -#define COPYRIGHT_NOTICE_CURRENT_YEAR "2015" +#define COPYRIGHT_NOTICE_CURRENT_YEAR "2016" /* This define specifies copyright notice which is displayed by every MySQL diff --git a/packaging/WiX/custom_ui.wxs b/packaging/WiX/custom_ui.wxs index a28c3c9b8a1..e96ab0fe505 100644 --- a/packaging/WiX/custom_ui.wxs +++ b/packaging/WiX/custom_ui.wxs @@ -2,7 +2,7 @@ xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">