From 88eee63d8c02e5a4b3ac39c0ed31794dcf243a29 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sat, 3 Dec 2005 18:13:06 +0200 Subject: [PATCH 01/49] Set thread_stack after return from end_thread() Fixes core dump when reusing thread when running debug binary --- sql-bench/bench-init.pl.sh | 2 +- sql-bench/server-cfg.sh | 10 +++++----- sql/mysqld.cc | 1 + sql/sql_parse.cc | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh index d61551ffb3b..31282d06abf 100644 --- a/sql-bench/bench-init.pl.sh +++ b/sql-bench/bench-init.pl.sh @@ -447,7 +447,7 @@ All benchmarks takes the following options: --create-options=# Extra argument to all create statements. If you for example want to create all MySQL tables as BDB tables use: - --create-options=TYPE=BDB + --create-options=ENGINE=BDB --database (Default $opt_database) In which database the test tables are created. diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh index b0c40102a6b..75528b24b77 100644 --- a/sql-bench/server-cfg.sh +++ b/sql-bench/server-cfg.sh @@ -174,29 +174,29 @@ sub new # Some fixes that depends on the environment if (defined($main::opt_create_options) && - $main::opt_create_options =~ /type=heap/i) + $main::opt_create_options =~ /engine=heap/i) { $limits{'working_blobs'} = 0; # HEAP tables can't handle BLOB's } if (defined($main::opt_create_options) && - $main::opt_create_options =~ /type=innodb/i) + $main::opt_create_options =~ /engine=innodb/i) { $self->{'transactions'} = 1; # Transactions enabled } if (defined($main::opt_create_options) && - $main::opt_create_options =~ /type=ndb/i) + $main::opt_create_options =~ /engine=ndb/i) { $self->{'transactions'} = 1; # Transactions enabled $limits{'max_columns'} = 90; # Max number of columns in table $limits{'max_tables'} = 32; # No comments } if (defined($main::opt_create_options) && - $main::opt_create_options =~ /type=bdb/i) + $main::opt_create_options =~ /engine=bdb/i) { $self->{'transactions'} = 1; # Transactions enabled } if (defined($main::opt_create_options) && - $main::opt_create_options =~ /type=gemini/i) + $main::opt_create_options =~ /engine=gemini/i) { $limits{'working_blobs'} = 0; # Blobs not implemented yet $limits{'max_tables'} = 500; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b5b95e48889..857658207ba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1589,6 +1589,7 @@ void end_thread(THD *thd, bool put_in_cache) wake_thread--; thd=thread_cache.get(); thd->real_id=pthread_self(); + thd->thread_stack= (char*) &thd; // For store_globals (void) thd->store_globals(); thd->thr_create_time= time(NULL); threads.append(thd); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 00124225719..1a9b4ef4db7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1182,6 +1182,7 @@ end_thread: or this thread has been schedule to handle the next query */ thd= current_thd; + thd->thread_stack= (char*) &thd; } while (!(test_flags & TEST_NO_THREADS)); /* The following is only executed if we are not using --one-thread */ return(0); /* purecov: deadcode */ From d07a57c03ae13cbbf7fe68cd4eebc8b7266eaa69 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Fri, 9 Dec 2005 15:00:33 -0800 Subject: [PATCH 02/49] Fix crash in BDB from improper cleanup of transactions, and avoid problem in NDB that the fix would cause due to improper registration of a transaction that isn't meant to be seen by the handler layer. (Bug #14212) Thanks to Sergei Golubchik for helping with this. --- mysql-test/r/bdb.result | 5 +++++ mysql-test/t/bdb.test | 11 +++++++++++ sql/ha_ndbcluster.cc | 14 ++++++++------ sql/handler.cc | 3 ++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 2bba44d36e9..dd251eed0f0 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1895,3 +1895,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1 drop table t1; set storage_engine=MyISAM; +set autocommit=0; +create table t1 (a int) engine=bdb; +commit; +alter table t1 add primary key(a); +drop table t1; diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 3167682f816..bf72a4555b8 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -973,3 +973,14 @@ drop table t1; # End varchar test eval set storage_engine=$default; + +# +# Bug #14212: Server crash after COMMIT + ALTER TABLE +# +set autocommit=0; +create table t1 (a int) engine=bdb; +commit; +alter table t1 add primary key(a); +drop table t1; + +# End of 5.0 tests diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index a0efcd2c4f9..b3d5d86dc52 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3221,6 +3221,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) if (lock_type != F_UNLCK) { DBUG_PRINT("info", ("lock_type != F_UNLCK")); + if (!thd->transaction.on) + m_transaction_on= FALSE; + else + m_transaction_on= thd->variables.ndb_use_transactions; if (!thd_ndb->lock_count++) { PRINT_OPTION_FLAGS(thd); @@ -3235,7 +3239,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->stmt= trans; - trans_register_ha(thd, FALSE, &ndbcluster_hton); + if (m_transaction_on) + trans_register_ha(thd, FALSE, &ndbcluster_hton); } else { @@ -3250,7 +3255,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->all= trans; - trans_register_ha(thd, TRUE, &ndbcluster_hton); + if (m_transaction_on) + trans_register_ha(thd, TRUE, &ndbcluster_hton); /* If this is the start of a LOCK TABLE, a table look @@ -3284,10 +3290,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) m_ha_not_exact_count= !thd->variables.ndb_use_exact_count; m_autoincrement_prefetch= (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz; - if (!thd->transaction.on) - m_transaction_on= FALSE; - else - m_transaction_on= thd->variables.ndb_use_transactions; m_active_trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt; DBUG_ASSERT(m_active_trans); diff --git a/sql/handler.cc b/sql/handler.cc index 81e94af5dc7..416455c9bb9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1910,7 +1910,8 @@ int ha_enable_transaction(THD *thd, bool on) is an optimization hint that storage engine is free to ignore. So, let's commit an open transaction (if any) now. */ - error= end_trans(thd, COMMIT); + if (!(error= ha_commit_stmt(thd))) + error= end_trans(thd, COMMIT); } DBUG_RETURN(error); } From 5bb966a9b61eeaac9677cfe09d21fd9bb5435f4c Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Wed, 14 Dec 2005 15:01:02 -0800 Subject: [PATCH 03/49] Fix crash when trying to open table using a disabled storage engine. (Bug #15185) --- sql/handler.cc | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 47010de3002..5a0e0d27b40 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -300,39 +300,56 @@ handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type) case DB_TYPE_HASH: return new (alloc) ha_hash(table); #endif + case DB_TYPE_MRG_MYISAM: case DB_TYPE_MRG_ISAM: return new (alloc) ha_myisammrg(table); #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: - return new (alloc) ha_berkeley(table); + if (have_berkeley_db == SHOW_OPTION_YES) + return new (alloc) ha_berkeley(table); + return NULL; #endif #ifdef HAVE_INNOBASE_DB case DB_TYPE_INNODB: - return new (alloc) ha_innobase(table); + if (have_innodb == SHOW_OPTION_YES) + return new (alloc) ha_innobase(table); + return NULL; #endif #ifdef HAVE_EXAMPLE_DB case DB_TYPE_EXAMPLE_DB: - return new (alloc) ha_example(table); + if (have_example_db == SHOW_OPTION_YES) + return new (alloc) ha_example(table); + return NULL; #endif #if defined(HAVE_ARCHIVE_DB) && !defined(__NETWARE__) case DB_TYPE_ARCHIVE_DB: - return new (alloc) ha_archive(table); + if (have_archive_db == SHOW_OPTION_YES) + return new (alloc) ha_archive(table); + return NULL; #endif #ifdef HAVE_BLACKHOLE_DB case DB_TYPE_BLACKHOLE_DB: - return new (alloc) ha_blackhole(table); + if (have_blackhole_db == SHOW_OPTION_YES) + return new (alloc) ha_blackhole(table); + return NULL; #endif #ifdef HAVE_FEDERATED_DB case DB_TYPE_FEDERATED_DB: - return new (alloc) ha_federated(table); + if (have_federated_db == SHOW_OPTION_YES) + return new (alloc) ha_federated(table); + return NULL; #endif #ifdef HAVE_CSV_DB case DB_TYPE_CSV_DB: - return new (alloc) ha_tina(table); + if (have_csv_db == SHOW_OPTION_YES) + return new (alloc) ha_tina(table); + return NULL; #endif #ifdef HAVE_NDBCLUSTER_DB case DB_TYPE_NDBCLUSTER: - return new (alloc) ha_ndbcluster(table); + if (have_ndbcluster == SHOW_OPTION_YES) + return new (alloc) ha_ndbcluster(table); + return NULL; #endif case DB_TYPE_HEAP: return new (alloc) ha_heap(table); @@ -346,8 +363,6 @@ handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type) /* Fall back to MyISAM */ case DB_TYPE_MYISAM: return new (alloc) ha_myisam(table); - case DB_TYPE_MRG_MYISAM: - return new (alloc) ha_myisammrg(table); } } From 400bc0ca33275711375a43e2a08628534e880dfe Mon Sep 17 00:00:00 2001 From: "jmiller@mysql.com" <> Date: Fri, 23 Dec 2005 14:45:02 +0100 Subject: [PATCH 04/49] Updated tests from Lars Review --- .../extra/rpl_tests/rpl_loaddata_m.test | 28 - .../r/{rpl_row_ddl.result => rpl_ddl.result} | 0 mysql-test/r/rpl_err_ignoredtable.result | 42 + mysql-test/r/rpl_loaddata_m.result | 38 + ...ow_rewrt_db.result => rpl_rewrt_db.result} | 0 mysql-test/r/rpl_stm_ddl.result | 1693 ----------------- mysql-test/r/rpl_stm_err_ignoredtable.result | 39 - mysql-test/r/rpl_stm_loaddata_m.result | 20 - mysql-test/r/rpl_stm_rewrt_db.result | 93 - mysql-test/r/rpl_stm_timezone.result | 127 -- mysql-test/r/rpl_stm_user_variables.result | 82 - mysql-test/r/rpl_stm_view.result | 56 - ...ow_timezone.result => rpl_timezone.result} | 26 +- ...ables.result => rpl_user_variables.result} | 0 .../{rpl_row_view.result => rpl_view.result} | 1 + mysql-test/t/disabled.def | 2 + .../t/{rpl_row_ddl.test => rpl_ddl.test} | 1 - ...ave.opt => rpl_err_ignoredtable-slave.opt} | 0 .../rpl_tests => t}/rpl_err_ignoredtable.test | 20 +- ...m-master.opt => rpl_loaddata_m-master.opt} | 0 mysql-test/t/rpl_loaddata_m.test | 49 + ...rt_db-slave.opt => rpl_rewrt_db-slave.opt} | 0 ...pl_stm_rewrt_db.test => rpl_rewrt_db.test} | 0 mysql-test/t/rpl_row_log.test | 2 +- mysql-test/t/rpl_row_rewrt_db.test | 83 - mysql-test/t/rpl_row_timezone-slave.opt | 2 - mysql-test/t/rpl_row_user_variables.test | 4 - mysql-test/t/rpl_row_view.test | 47 - mysql-test/t/rpl_stm_ddl.test | 35 - mysql-test/t/rpl_stm_err_ignoredtable.test | 8 - mysql-test/t/rpl_stm_rewrt_db-slave.opt | 1 - mysql-test/t/rpl_stm_timezone-master.opt | 1 - mysql-test/t/rpl_stm_timezone.test | 129 -- mysql-test/t/rpl_stm_user_variables.test | 5 - ...one-master.opt => rpl_timezone-master.opt} | 0 ...ezone-slave.opt => rpl_timezone-slave.opt} | 0 ...pl_row_timezone.test => rpl_timezone.test} | 13 +- .../rpl_tests => t}/rpl_user_variables.test | 1 - .../t/{rpl_stm_view.test => rpl_view.test} | 10 +- 39 files changed, 162 insertions(+), 2496 deletions(-) delete mode 100644 mysql-test/extra/rpl_tests/rpl_loaddata_m.test rename mysql-test/r/{rpl_row_ddl.result => rpl_ddl.result} (100%) create mode 100644 mysql-test/r/rpl_err_ignoredtable.result create mode 100644 mysql-test/r/rpl_loaddata_m.result rename mysql-test/r/{rpl_row_rewrt_db.result => rpl_rewrt_db.result} (100%) delete mode 100644 mysql-test/r/rpl_stm_ddl.result delete mode 100644 mysql-test/r/rpl_stm_err_ignoredtable.result delete mode 100644 mysql-test/r/rpl_stm_loaddata_m.result delete mode 100644 mysql-test/r/rpl_stm_rewrt_db.result delete mode 100644 mysql-test/r/rpl_stm_timezone.result delete mode 100644 mysql-test/r/rpl_stm_user_variables.result delete mode 100644 mysql-test/r/rpl_stm_view.result rename mysql-test/r/{rpl_row_timezone.result => rpl_timezone.result} (76%) rename mysql-test/r/{rpl_row_user_variables.result => rpl_user_variables.result} (100%) rename mysql-test/r/{rpl_row_view.result => rpl_view.result} (98%) rename mysql-test/t/{rpl_row_ddl.test => rpl_ddl.test} (97%) rename mysql-test/t/{rpl_stm_err_ignoredtable-slave.opt => rpl_err_ignoredtable-slave.opt} (100%) rename mysql-test/{extra/rpl_tests => t}/rpl_err_ignoredtable.test (77%) rename mysql-test/t/{rpl_stm_loaddata_m-master.opt => rpl_loaddata_m-master.opt} (100%) create mode 100644 mysql-test/t/rpl_loaddata_m.test rename mysql-test/t/{rpl_row_rewrt_db-slave.opt => rpl_rewrt_db-slave.opt} (100%) rename mysql-test/t/{rpl_stm_rewrt_db.test => rpl_rewrt_db.test} (100%) delete mode 100644 mysql-test/t/rpl_row_rewrt_db.test delete mode 100644 mysql-test/t/rpl_row_timezone-slave.opt delete mode 100644 mysql-test/t/rpl_row_user_variables.test delete mode 100644 mysql-test/t/rpl_row_view.test delete mode 100644 mysql-test/t/rpl_stm_ddl.test delete mode 100644 mysql-test/t/rpl_stm_err_ignoredtable.test delete mode 100644 mysql-test/t/rpl_stm_rewrt_db-slave.opt delete mode 100644 mysql-test/t/rpl_stm_timezone-master.opt delete mode 100644 mysql-test/t/rpl_stm_timezone.test delete mode 100644 mysql-test/t/rpl_stm_user_variables.test rename mysql-test/t/{rpl_row_timezone-master.opt => rpl_timezone-master.opt} (100%) rename mysql-test/t/{rpl_stm_timezone-slave.opt => rpl_timezone-slave.opt} (100%) rename mysql-test/t/{rpl_row_timezone.test => rpl_timezone.test} (93%) rename mysql-test/{extra/rpl_tests => t}/rpl_user_variables.test (96%) rename mysql-test/t/{rpl_stm_view.test => rpl_view.test} (82%) diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata_m.test b/mysql-test/extra/rpl_tests/rpl_loaddata_m.test deleted file mode 100644 index ef90283f80e..00000000000 --- a/mysql-test/extra/rpl_tests/rpl_loaddata_m.test +++ /dev/null @@ -1,28 +0,0 @@ -# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules -# exist. -# This is for BUG#1100 (LOAD DATA INFILE was half-logged). - - --- source include/master-slave.inc - ---disable_warnings -drop database if exists mysqltest; ---enable_warnings - -connection slave; -stop slave; # don't need slave for this test - -# Test logging on master - -connection master; -# 'test' is the current database -create database mysqltest; -use mysqltest; -create table t1(a int, b int, unique(b)); -load data infile '../../std_data/rpl_loaddata.dat' into table t1; -# Starting from 5.0.3 LOAD DATA is replicated much in the same way as ordinary -# query so "show binlog ..." should show two events (before 5.0.3 no events -# were returned). ---replace_column 2 # 5 # -show binlog events from 102; -drop database mysqltest; diff --git a/mysql-test/r/rpl_row_ddl.result b/mysql-test/r/rpl_ddl.result similarity index 100% rename from mysql-test/r/rpl_row_ddl.result rename to mysql-test/r/rpl_ddl.result diff --git a/mysql-test/r/rpl_err_ignoredtable.result b/mysql-test/r/rpl_err_ignoredtable.result new file mode 100644 index 00000000000..84072be7d44 --- /dev/null +++ b/mysql-test/r/rpl_err_ignoredtable.result @@ -0,0 +1,42 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +create table t1 (a int primary key); +create table t4 (a int primary key); +insert into t1 values (1),(1); +ERROR 23000: Duplicate entry '1' for key 1 +insert into t4 values (1),(2); +show tables like 't1'; +Tables_in_test (t1) +show tables like 't4'; +Tables_in_test (t4) +t4 +SELECT * FROM test.t4; +a +1 +2 +drop table t1; +select get_lock('crash_lock%20C', 10); +get_lock('crash_lock%20C', 10) +1 +create table t2 (a int primary key); +insert into t2 values(1); +create table t3 (id int); +insert into t3 values(connection_id()); + update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); +select (@id := id) - id from t3; +(@id := id) - id +0 +kill @id; +drop table t2,t3; +insert into t4 values (3),(4); +SELECT * FROM test.t4; +a +1 +2 +3 +4 +DROP TABLE test.t4; diff --git a/mysql-test/r/rpl_loaddata_m.result b/mysql-test/r/rpl_loaddata_m.result new file mode 100644 index 00000000000..1d263a41e1b --- /dev/null +++ b/mysql-test/r/rpl_loaddata_m.result @@ -0,0 +1,38 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +drop database if exists mysqltest; +USE test; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE test.t1; +SELECT COUNT(*) FROM test.t1; +COUNT(*) +2 +CREATE DATABASE mysqltest; +USE mysqltest; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE mysqltest.t1; +SELECT COUNT(*) FROM mysqltest.t1; +COUNT(*) +2 +SHOW DATABASES; +Database +information_schema +mysql +mysqltest +test +USE test; +SHOW TABLES; +Tables_in_test +USE mysqltest; +SHOW TABLES; +Tables_in_mysqltest +t1 +SELECT COUNT(*) FROM mysqltest.t1; +COUNT(*) +2 +DROP DATABASE mysqltest; +DROP TABLE test.t1; diff --git a/mysql-test/r/rpl_row_rewrt_db.result b/mysql-test/r/rpl_rewrt_db.result similarity index 100% rename from mysql-test/r/rpl_row_rewrt_db.result rename to mysql-test/r/rpl_rewrt_db.result diff --git a/mysql-test/r/rpl_stm_ddl.result b/mysql-test/r/rpl_stm_ddl.result deleted file mode 100644 index 91163f1fe29..00000000000 --- a/mysql-test/r/rpl_stm_ddl.result +++ /dev/null @@ -1,1693 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -SET AUTOCOMMIT = 1; -DROP DATABASE IF EXISTS mysqltest1; -DROP DATABASE IF EXISTS mysqltest2; -DROP DATABASE IF EXISTS mysqltest3; -CREATE DATABASE mysqltest1; -CREATE DATABASE mysqltest2; -CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB"; -INSERT INTO mysqltest1.t1 SET f1= 0; -CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE="InnoDB"; -CREATE INDEX my_idx6 ON mysqltest1.t6(f1); -CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE="InnoDB"; -INSERT INTO mysqltest1.t7 SET f1= 0; -CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE="InnoDB"; -CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT); -SET AUTOCOMMIT = 0; -use mysqltest1; - --------- switch to slave -------- -SET AUTOCOMMIT = 0; -use mysqltest1; - --------- switch to master ------- - -######## COMMIT ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 0 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -0 - --------- switch to master ------- -COMMIT; -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## ROLLBACK ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 1 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - -TEST-INFO: MASTER: The INSERT is not committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - -TEST-INFO: SLAVE: The INSERT is not committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## SET AUTOCOMMIT=1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 1 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -1 - --------- switch to master ------- -SET AUTOCOMMIT=1; -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SET AUTOCOMMIT=0; - -######## START TRANSACTION ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 2 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -2 - --------- switch to master ------- -START TRANSACTION; -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## BEGIN ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 3 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -3 - --------- switch to master ------- -BEGIN; -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## DROP TABLE mysqltest1.t2 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 4 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -4 - --------- switch to master ------- -DROP TABLE mysqltest1.t2; -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW TABLES LIKE 't2'; -Tables_in_mysqltest1 (t2) - --------- switch to slave -------- -SHOW TABLES LIKE 't2'; -Tables_in_mysqltest1 (t2) - --------- switch to master ------- - -######## DROP TEMPORARY TABLE mysqltest1.t23 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 5 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - --------- switch to master ------- -DROP TEMPORARY TABLE mysqltest1.t23; -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - --------- switch to master ------- -ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back -SELECT MAX(f1) FROM t1; -MAX(f1) -5 - -TEST-INFO: MASTER: The INSERT is not committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW TABLES LIKE 't23'; -Tables_in_mysqltest1 (t23) - --------- switch to slave -------- -SHOW TABLES LIKE 't23'; -Tables_in_mysqltest1 (t23) - --------- switch to master ------- - -######## RENAME TABLE mysqltest1.t3 to mysqltest1.t20 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 5 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to master ------- -RENAME TABLE mysqltest1.t3 to mysqltest1.t20; -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW TABLES LIKE 't20'; -Tables_in_mysqltest1 (t20) -t20 - --------- switch to slave -------- -SHOW TABLES LIKE 't20'; -Tables_in_mysqltest1 (t20) -t20 - --------- switch to master ------- - -######## ALTER TABLE mysqltest1.t4 ADD column f2 BIGINT ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 6 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -6 - --------- switch to master ------- -ALTER TABLE mysqltest1.t4 ADD column f2 BIGINT; -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -describe mysqltest1.t4; -Field Type Null Key Default Extra -f1 bigint(20) YES NULL -f2 bigint(20) YES NULL - --------- switch to slave -------- -describe mysqltest1.t4; -Field Type Null Key Default Extra -f1 bigint(20) YES NULL -f2 bigint(20) YES NULL - --------- switch to master ------- - -######## CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= "InnoDB" ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 7 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -7 - --------- switch to master ------- -CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= "InnoDB"; -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT) ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 8 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - --------- switch to master ------- -CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT); -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - --------- switch to master ------- -ROLLBACK; -Warnings: -Warning 1196 Some non-transactional changed tables couldn't be rolled back -SELECT MAX(f1) FROM t1; -MAX(f1) -8 - -TEST-INFO: MASTER: The INSERT is not committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## TRUNCATE TABLE mysqltest1.t7 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 8 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to master ------- -TRUNCATE TABLE mysqltest1.t7; -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SELECT * FROM mysqltest1.t7; -f1 - --------- switch to slave -------- -SELECT * FROM mysqltest1.t7; -f1 - --------- switch to master ------- - -######## LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 9 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -9 - --------- switch to master ------- -LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -UNLOCK TABLES; - -######## UNLOCK TABLES ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 10 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -UNLOCK TABLES; -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: MASTER: The INSERT is not committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: SLAVE: The INSERT is not committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -LOCK TABLES mysqltest1.t1 READ; - -######## UNLOCK TABLES ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 10 + 1; -ERROR HY000: Table 't1' was locked with a READ lock and can't be updated -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -UNLOCK TABLES; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: MASTER: The INSERT is not committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - -TEST-INFO: SLAVE: The INSERT is not committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ; - -######## UNLOCK TABLES ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 10 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -10 - --------- switch to master ------- -UNLOCK TABLES; -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- - -######## DROP INDEX my_idx6 ON mysqltest1.t6 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 11 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -11 - --------- switch to master ------- -DROP INDEX my_idx6 ON mysqltest1.t6; -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW INDEX FROM mysqltest1.t6; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment - --------- switch to slave -------- -SHOW INDEX FROM mysqltest1.t6; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment - --------- switch to master ------- - -######## CREATE INDEX my_idx5 ON mysqltest1.t5(f1) ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 12 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -12 - --------- switch to master ------- -CREATE INDEX my_idx5 ON mysqltest1.t5(f1); -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW INDEX FROM mysqltest1.t5; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t5 1 my_idx5 1 f1 A 0 NULL NULL YES BTREE - --------- switch to slave -------- -SHOW INDEX FROM mysqltest1.t5; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t5 1 my_idx5 1 f1 A NULL NULL NULL YES BTREE - --------- switch to master ------- - -######## DROP DATABASE mysqltest2 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 13 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -13 - --------- switch to master ------- -DROP DATABASE mysqltest2; -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW DATABASES LIKE "mysqltest2"; -Database (mysqltest2) - --------- switch to slave -------- -SHOW DATABASES LIKE "mysqltest2"; -Database (mysqltest2) - --------- switch to master ------- - -######## CREATE DATABASE mysqltest3 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 14 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -14 - --------- switch to master ------- -CREATE DATABASE mysqltest3; -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW DATABASES LIKE "mysqltest3"; -Database (mysqltest3) -mysqltest3 - --------- switch to slave -------- -SHOW DATABASES LIKE "mysqltest3"; -Database (mysqltest3) -mysqltest3 - --------- switch to master ------- - -######## CREATE PROCEDURE p1() READS SQL DATA SELECT "this is p1" ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 15 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -15 - --------- switch to master ------- -CREATE PROCEDURE p1() READS SQL DATA SELECT "this is p1"; -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW PROCEDURE STATUS LIKE 'p1'; -Db mysqltest1 -Name p1 -Type PROCEDURE -Definer root@localhost -Modified # -Created # -Security_type DEFINER -Comment - -------- switch to slave ------- -SHOW PROCEDURE STATUS LIKE 'p1'; -Db mysqltest1 -Name p1 -Type PROCEDURE -Definer @ -Modified # -Created # -Security_type DEFINER -Comment - -######## ALTER PROCEDURE p1 COMMENT "I have been altered" ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 16 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -16 - --------- switch to master ------- -ALTER PROCEDURE p1 COMMENT "I have been altered"; -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW PROCEDURE STATUS LIKE 'p1'; -Db mysqltest1 -Name p1 -Type PROCEDURE -Definer root@localhost -Modified # -Created # -Security_type DEFINER -Comment I have been altered - -------- switch to slave ------- -SHOW PROCEDURE STATUS LIKE 'p1'; -Db mysqltest1 -Name p1 -Type PROCEDURE -Definer @ -Modified # -Created # -Security_type DEFINER -Comment I have been altered - -######## DROP PROCEDURE p1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 17 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -17 - --------- switch to master ------- -DROP PROCEDURE p1; -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW PROCEDURE STATUS LIKE 'p1'; - -------- switch to slave ------- -SHOW PROCEDURE STATUS LIKE 'p1'; - -######## CREATE OR REPLACE VIEW v1 as select * from t1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 18 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -18 - --------- switch to master ------- -CREATE OR REPLACE VIEW v1 as select * from t1; -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` - --------- switch to slave ------- -SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` - -######## ALTER VIEW v1 AS select f1 from t1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 19 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -19 - --------- switch to master ------- -ALTER VIEW v1 AS select f1 from t1; -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` - --------- switch to slave ------- -SHOW CREATE VIEW v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` - -######## DROP VIEW IF EXISTS v1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 20 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -20 - --------- switch to master ------- -DROP VIEW IF EXISTS v1; -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW CREATE VIEW v1; -ERROR 42S02: Table 'mysqltest1.v1' doesn't exist - --------- switch to slave ------- -SHOW CREATE VIEW v1; -ERROR 42S02: Table 'mysqltest1.v1' doesn't exist - -######## CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 21 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -21 - --------- switch to master ------- -CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost - --------- switch to slave ------- -SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost - -######## DROP TRIGGER trg1 ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 22 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -22 - --------- switch to master ------- -DROP TRIGGER trg1; -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer - --------- switch to slave ------- -SHOW TRIGGERS; -Trigger Event Table Statement Timing Created sql_mode Definer - -######## CREATE USER user1@localhost ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 23 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -23 - --------- switch to master ------- -CREATE USER user1@localhost; -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SELECT user FROM mysql.user WHERE user = 'user1'; -user -user1 - --------- switch to slave ------- -SELECT user FROM mysql.user WHERE user = 'user1'; -user -user1 - -######## RENAME USER user1@localhost TO rename1@localhost ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 24 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -24 - --------- switch to master ------- -RENAME USER user1@localhost TO rename1@localhost; -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SELECT user FROM mysql.user WHERE user = 'rename1'; -user -rename1 - --------- switch to slave ------- -SELECT user FROM mysql.user WHERE user = 'rename1'; -user -rename1 - -######## DROP USER rename1@localhost ######## - --------- switch to master ------- -INSERT INTO t1 SET f1= 25 + 1; -SELECT MAX(f1) FROM t1; -MAX(f1) -26 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -25 - --------- switch to master ------- -DROP USER rename1@localhost; -SELECT MAX(f1) FROM t1; -MAX(f1) -26 - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -26 - --------- switch to master ------- -ROLLBACK; -SELECT MAX(f1) FROM t1; -MAX(f1) -26 - -TEST-INFO: MASTER: The INSERT is committed (Succeeded) - --------- switch to slave -------- -SELECT MAX(f1) FROM t1; -MAX(f1) -26 - -TEST-INFO: SLAVE: The INSERT is committed (Succeeded) - --------- switch to master ------- -flush logs; - --------- switch to slave -------- -flush logs; - --------- switch to master ------- -SELECT user FROM mysql.user WHERE user = 'rename1'; -user - --------- switch to slave ------- -SELECT user FROM mysql.user WHERE user = 'rename1'; -user -DROP DATABASE IF EXISTS mysqltest1; -DROP DATABASE IF EXISTS mysqltest2; -DROP DATABASE IF EXISTS mysqltest3; diff --git a/mysql-test/r/rpl_stm_err_ignoredtable.result b/mysql-test/r/rpl_stm_err_ignoredtable.result deleted file mode 100644 index 42abb2c3c44..00000000000 --- a/mysql-test/r/rpl_stm_err_ignoredtable.result +++ /dev/null @@ -1,39 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -create table t1 (a int primary key); -insert into t1 values (1),(1); -ERROR 23000: Duplicate entry '1' for key 1 -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 292 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 292 # None 0 No # -show tables like 't1'; -Tables_in_test (t1) -drop table t1; -select get_lock('crash_lock%20C', 10); -get_lock('crash_lock%20C', 10) -1 -create table t2 (a int primary key); -insert into t2 values(1); -create table t3 (id int); -insert into t3 values(connection_id()); - update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); -select (@id := id) - id from t3; -(@id := id) - id -0 -kill @id; -drop table t2,t3; -show binlog events from 102; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query 1 # use `test`; create table t1 (a int primary key) -master-bin.000001 # Query 1 # use `test`; insert into t1 values (1),(1) -master-bin.000001 # Query 1 # use `test`; drop table t1 -master-bin.000001 # Query 1 # use `test`; create table t2 (a int primary key) -master-bin.000001 # Query 1 # use `test`; insert into t2 values(1) -master-bin.000001 # Query 1 # use `test`; create table t3 (id int) -master-bin.000001 # Query 1 # use `test`; insert into t3 values(connection_id()) -master-bin.000001 # Query 1 # use `test`; update t2 set a = a + 1 + get_lock('crash_lock%20C', 10) -master-bin.000001 # Query 1 # use `test`; drop table t2,t3 diff --git a/mysql-test/r/rpl_stm_loaddata_m.result b/mysql-test/r/rpl_stm_loaddata_m.result deleted file mode 100644 index 9c7dba0e711..00000000000 --- a/mysql-test/r/rpl_stm_loaddata_m.result +++ /dev/null @@ -1,20 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -drop database if exists mysqltest; -stop slave; -create database mysqltest; -use mysqltest; -create table t1(a int, b int, unique(b)); -load data infile '../../std_data/rpl_loaddata.dat' into table t1; -show binlog events from 102; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query 1 # drop database if exists mysqltest -master-bin.000001 # Query 1 # create database mysqltest -master-bin.000001 # Query 1 # use `mysqltest`; create table t1(a int, b int, unique(b)) -master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=12 -master-bin.000001 # Execute_load_query 1 # use `mysqltest`; load data infile '../../std_data/rpl_loaddata.dat' into table t1 ;file_id=1 -drop database mysqltest; diff --git a/mysql-test/r/rpl_stm_rewrt_db.result b/mysql-test/r/rpl_stm_rewrt_db.result deleted file mode 100644 index 6c72e982e3e..00000000000 --- a/mysql-test/r/rpl_stm_rewrt_db.result +++ /dev/null @@ -1,93 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -drop database if exists mysqltest1; -create database mysqltest1; -use mysqltest1; -create table t1 (a int); -insert into t1 values(9); -select * from mysqltest1.t1; -a -9 -show databases like 'mysqltest1'; -Database (mysqltest1) -mysqltest1 -select * from test.t1; -a -9 -drop table t1; -drop database mysqltest1; -drop database if exists rewrite; -create database rewrite; -use test; -create table t1 (a date, b date, c date not null, d date); -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ','; -Warnings: -Warning 1265 Data truncated for column 'a' at row 1 -Warning 1265 Data truncated for column 'c' at row 1 -Warning 1265 Data truncated for column 'd' at row 1 -Warning 1265 Data truncated for column 'a' at row 2 -Warning 1265 Data truncated for column 'b' at row 2 -Warning 1265 Data truncated for column 'd' at row 2 -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES; -select * from rewrite.t1; -a b c d -0000-00-00 NULL 0000-00-00 0000-00-00 -0000-00-00 0000-00-00 0000-00-00 0000-00-00 -2003-03-03 2003-03-03 2003-03-03 NULL -2003-03-03 2003-03-03 2003-03-03 NULL -truncate table t1; -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d); -Warnings: -Warning 1265 Data truncated for column 'c' at row 1 -Warning 1265 Data truncated for column 'd' at row 1 -Warning 1265 Data truncated for column 'b' at row 2 -Warning 1265 Data truncated for column 'd' at row 2 -select * from rewrite.t1; -a b c d -NULL NULL 0000-00-00 0000-00-00 -NULL 0000-00-00 0000-00-00 0000-00-00 -NULL 2003-03-03 2003-03-03 NULL -drop table t1; -create table t1 (a text, b text); -load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; -Warnings: -Warning 1261 Row 3 doesn't contain data for all columns -select concat('|',a,'|'), concat('|',b,'|') from rewrite.t1; -concat('|',a,'|') concat('|',b,'|') -|Field A| |Field B| -|Field 1| |Field 2' -Field 3,'Field 4| -|Field 5' ,'Field 6| NULL -|Field 6| | 'Field 7'| -drop table t1; -create table t1 (a int, b char(10)); -load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines; -Warnings: -Warning 1264 Out of range value for column 'a' at row 3 -Warning 1262 Row 3 was truncated; it contained more data than there were input columns -Warning 1264 Out of range value for column 'a' at row 5 -Warning 1262 Row 5 was truncated; it contained more data than there were input columns -select * from rewrite.t1; -a b -1 row 1 -2 row 2 -0 1234567890 -3 row 3 -0 1234567890 -truncate table t1; -load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines; -Warnings: -Warning 1264 Out of range value for column 'a' at row 4 -Warning 1261 Row 4 doesn't contain data for all columns -select * from rewrite.t1; -a b -1 row 1 -2 row 2 -3 row 3 -0 -drop database rewrite; -drop table t1; diff --git a/mysql-test/r/rpl_stm_timezone.result b/mysql-test/r/rpl_stm_timezone.result deleted file mode 100644 index 64d05aa787e..00000000000 --- a/mysql-test/r/rpl_stm_timezone.result +++ /dev/null @@ -1,127 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -set timestamp=100000000; -create table t1 (t timestamp); -create table t2 (t char(32)); -select @@time_zone; -@@time_zone -Japan -select @@time_zone; -@@time_zone -Europe/Moscow -insert into t1 values ('20050101000000'), ('20050611093902'); -set time_zone='UTC'; -insert into t1 values ('20040101000000'), ('20040611093902'); -select * from t1; -t -2004-12-31 21:00:00 -2005-06-11 05:39:02 -2004-01-01 00:00:00 -2004-06-11 09:39:02 -set time_zone='UTC'; -select * from t1; -t -2004-12-31 21:00:00 -2005-06-11 05:39:02 -2004-01-01 00:00:00 -2004-06-11 09:39:02 -delete from t1; -set time_zone='Europe/Moscow'; -insert into t1 values ('20040101000000'), ('20040611093902'); -select * from t1; -t -2004-01-01 00:00:00 -2004-06-11 09:39:02 -set time_zone='Europe/Moscow'; -select * from t1; -t -2004-01-01 00:00:00 -2004-06-11 09:39:02 -/*!40019 SET @@session.max_insert_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -ROLLBACK; -use test; -SET TIMESTAMP=100000000; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; -SET @@session.sql_mode=0; -SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; -create table t1 (t timestamp); -SET TIMESTAMP=100000000; -create table t2 (t char(32)); -SET TIMESTAMP=100000000; -SET @@session.time_zone='Europe/Moscow'; -insert into t1 values ('20050101000000'), ('20050611093902'); -SET TIMESTAMP=100000000; -SET @@session.time_zone='UTC'; -insert into t1 values ('20040101000000'), ('20040611093902'); -SET TIMESTAMP=100000000; -delete from t1; -SET TIMESTAMP=100000000; -SET @@session.time_zone='Europe/Moscow'; -insert into t1 values ('20040101000000'), ('20040611093902'); -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -delete from t1; -set time_zone='UTC'; -load data infile '../../std_data/rpl_timezone.dat' into table t1; -select * from t1; -t -2004-01-01 00:00:00 -2004-06-11 09:39:02 -set time_zone='UTC'; -select * from t1; -t -2004-01-01 00:00:00 -2004-06-11 09:39:02 -set time_zone='Europe/Moscow'; -set time_zone='Europe/Moscow'; -delete from t1; -insert into t1 values ('20040101000000'), ('20040611093902'); -set time_zone='MET'; -insert into t2 (select t from t1); -select * from t1; -t -2003-12-31 22:00:00 -2004-06-11 07:39:02 -select * from t2; -t -2003-12-31 22:00:00 -2004-06-11 07:39:02 -delete from t2; -set timestamp=1000072000; -insert into t2 values (current_timestamp), (current_date), (current_time); -select * from t2; -t -2001-09-09 23:46:40 -2001-09-09 -23:46:40 -delete from t2; -insert into t2 values (from_unixtime(1000000000)), -(unix_timestamp('2001-09-09 03:46:40')); -select * from t2; -t -2001-09-09 03:46:40 -1000000000 -select * from t2; -t -2001-09-09 03:46:40 -1000000000 -set global time_zone='MET'; -delete from t2; -set time_zone='UTC'; -insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone)); -insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan')); -select * from t2; -t -2003-12-31 23:00:00 -2005-01-01 08:00:00 -select * from t2; -t -2003-12-31 23:00:00 -2005-01-01 08:00:00 -drop table t1, t2; diff --git a/mysql-test/r/rpl_stm_user_variables.result b/mysql-test/r/rpl_stm_user_variables.result deleted file mode 100644 index 3e2efcbe9da..00000000000 --- a/mysql-test/r/rpl_stm_user_variables.result +++ /dev/null @@ -1,82 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -reset master; -create table t1(n char(30)); -set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1; -set @s1:='This is a test', @r1:=12.5, @r2:=-12.5; -set @n1:=null; -set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def'; -insert into t1 values (@i1), (@i2), (@i3), (@i4); -insert into t1 values (@r1), (@r2); -insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5); -insert into t1 values (@n1); -insert into t1 values (@n2); -insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1); -insert into t1 values (@a+(@b:=@a+1)); -set @q:='abc'; -insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')); -set @a:=5; -insert into t1 values (@a),(@a); -select * from t1 where n = ''; -n -insert into t1 values (@a),(@a),(@a*5); -select * from t1; -n -12345678901234 --12345678901234 -0 --1 -12.5 --12.5 -This is a test - -abc'def -abc\def -abc'def -NULL -NULL -0 -1 -2 -5 -abc -abcn1 -abcn1n2 -5 -5 -NULL -NULL -NULL -select * from t1; -n -12345678901234 --12345678901234 -0 --1 -12.5 --12.5 -This is a test - -abc'def -abc\def -abc'def -NULL -NULL -0 -1 -2 -5 -abc -abcn1 -abcn1n2 -5 -5 -NULL -NULL -NULL -drop table t1; -stop slave; diff --git a/mysql-test/r/rpl_stm_view.result b/mysql-test/r/rpl_stm_view.result deleted file mode 100644 index cf4c161b296..00000000000 --- a/mysql-test/r/rpl_stm_view.result +++ /dev/null @@ -1,56 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -drop table if exists t1,v1; -drop view if exists t1,v1; -reset master; -create table t1 (a int); -insert into t1 values (1); -create view v1 as select a from t1; -insert into v1 values (2); -select * from v1 order by a; -a -1 -2 -select * from v1 order by a; -a -1 -2 -update v1 set a=3 where a=1; -select * from v1 order by a; -a -2 -3 -select * from v1 order by a; -a -2 -3 -delete from v1 where a=2; -select * from v1 order by a; -a -3 -select * from v1 order by a; -a -3 -alter view v1 as select a as b from t1; -select * from v1 order by 1; -b -3 -drop view v1; -select * from v1 order by a; -ERROR 42S02: Table 'test.v1' doesn't exist -drop table t1; -show binlog events limit 1,100; -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000001 # Query 1 # use `test`; create table t1 (a int) -slave-bin.000001 # Query 1 # use `test`; insert into t1 values (1) -slave-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a from t1 -slave-bin.000001 # Query 1 # use `test`; insert into v1 values (2) -slave-bin.000001 # Query 1 # use `test`; update v1 set a=3 where a=1 -slave-bin.000001 # Query 1 # use `test`; delete from v1 where a=2 -slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a as b from t1 -slave-bin.000001 # Query 1 # use `test`; drop view v1 -slave-bin.000001 # Query 1 # use `test`; drop table t1 diff --git a/mysql-test/r/rpl_row_timezone.result b/mysql-test/r/rpl_timezone.result similarity index 76% rename from mysql-test/r/rpl_row_timezone.result rename to mysql-test/r/rpl_timezone.result index 26c10648ffb..9c45997cbf6 100644 --- a/mysql-test/r/rpl_row_timezone.result +++ b/mysql-test/r/rpl_timezone.result @@ -9,7 +9,7 @@ create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n)); create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n)); select @@time_zone; @@time_zone -Europe/Moscow +Japan select @@time_zone; @@time_zone Europe/Moscow @@ -23,10 +23,10 @@ t n 2004-06-11 09:39:02 4 select * from t1; t n -2005-01-01 00:00:00 1 -2005-06-11 09:39:02 2 -2004-01-01 00:00:00 3 -2004-06-11 09:39:02 4 +2005-01-01 06:00:00 1 +2005-06-11 14:39:02 2 +2004-01-01 06:00:00 3 +2004-06-11 14:39:02 4 delete from t1; set time_zone='Europe/Moscow'; insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL); @@ -39,22 +39,6 @@ select * from t1; t n 2004-01-01 00:00:00 5 2004-06-11 09:39:02 6 -/*!40019 SET @@session.max_insert_delayed_threads=0*/; -/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; -ROLLBACK; -use test; -SET TIMESTAMP=100000000; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; -SET @@session.sql_mode=0; -SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; -create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n)); -SET TIMESTAMP=100000000; -create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n)); -SET TIMESTAMP=100000000; -delete from t1; -# End of log file -ROLLBACK /* added by mysqlbinlog */; -/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; delete from t1; set time_zone='UTC'; load data infile '../../std_data/rpl_timezone2.dat' into table t1; diff --git a/mysql-test/r/rpl_row_user_variables.result b/mysql-test/r/rpl_user_variables.result similarity index 100% rename from mysql-test/r/rpl_row_user_variables.result rename to mysql-test/r/rpl_user_variables.result diff --git a/mysql-test/r/rpl_row_view.result b/mysql-test/r/rpl_view.result similarity index 98% rename from mysql-test/r/rpl_row_view.result rename to mysql-test/r/rpl_view.result index ce807a361ba..f038f4d00cb 100644 --- a/mysql-test/r/rpl_row_view.result +++ b/mysql-test/r/rpl_view.result @@ -6,6 +6,7 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; drop table if exists t1,v1; drop view if exists t1,v1; +reset master; create table t1 (a int); insert into t1 values (1); create view v1 as select a from t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f32ed667864..683cd4558ea 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -25,3 +25,5 @@ type_time : Bug#15805 rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite sp_trans : Bug#15924 Code dump in RBR mode when executing test suite +rpl_loaddata_m : Bug#15942 RBR ignores --binlog_ignore_db +rpl_ddl : Bug#15963 SBR does not show "Definer" correctly diff --git a/mysql-test/t/rpl_row_ddl.test b/mysql-test/t/rpl_ddl.test similarity index 97% rename from mysql-test/t/rpl_row_ddl.test rename to mysql-test/t/rpl_ddl.test index 2433d6a83a7..d08406334d1 100644 --- a/mysql-test/t/rpl_row_ddl.test +++ b/mysql-test/t/rpl_ddl.test @@ -29,7 +29,6 @@ # --source include/have_innodb.inc ---source include/have_binlog_format_row.inc --source include/master-slave.inc let $engine_type= "InnoDB"; -- source extra/rpl_tests/rpl_ddl.test diff --git a/mysql-test/t/rpl_stm_err_ignoredtable-slave.opt b/mysql-test/t/rpl_err_ignoredtable-slave.opt similarity index 100% rename from mysql-test/t/rpl_stm_err_ignoredtable-slave.opt rename to mysql-test/t/rpl_err_ignoredtable-slave.opt diff --git a/mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test b/mysql-test/t/rpl_err_ignoredtable.test similarity index 77% rename from mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test rename to mysql-test/t/rpl_err_ignoredtable.test index e439dbdc388..81aa76225be 100644 --- a/mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test +++ b/mysql-test/t/rpl_err_ignoredtable.test @@ -7,20 +7,19 @@ connection master; create table t1 (a int primary key); +create table t4 (a int primary key); # generate an error that goes to the binlog --error 1062 insert into t1 values (1),(1); +insert into t4 values (1),(2); save_master_pos; connection slave; # as the t1 table is ignored on the slave, the slave should be able to sync sync_with_master; -# The port number is different when doing the release build with -# Do-compile, hence we have to replace the port number here accordingly ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # -show slave status; # check that the table has been ignored, because otherwise the test is nonsense show tables like 't1'; +show tables like 't4'; +SELECT * FROM test.t4; connection master; drop table t1; save_master_pos; @@ -46,17 +45,20 @@ real_sleep 2; select (@id := id) - id from t3; kill @id; drop table t2,t3; +insert into t4 values (3),(4); connection master; --error 0,1053,2013 reap; connection master1; ---replace_column 2 # 5 # -show binlog events from 102; save_master_pos; connection slave; -# SQL slave thread should not have stopped (because table of the killed -# query is in the ignore list). sync_with_master; +SELECT * FROM test.t4; +connection master1; +DROP TABLE test.t4; +save_master_pos; +connection slave; +sync_with_master; # End of 4.1 tests # Adding comment for force manual merge 5.0 -> wl1012. delete me if needed diff --git a/mysql-test/t/rpl_stm_loaddata_m-master.opt b/mysql-test/t/rpl_loaddata_m-master.opt similarity index 100% rename from mysql-test/t/rpl_stm_loaddata_m-master.opt rename to mysql-test/t/rpl_loaddata_m-master.opt diff --git a/mysql-test/t/rpl_loaddata_m.test b/mysql-test/t/rpl_loaddata_m.test new file mode 100644 index 00000000000..01ef89d4efc --- /dev/null +++ b/mysql-test/t/rpl_loaddata_m.test @@ -0,0 +1,49 @@ +# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules +# exist. +# This is for BUG#1100 (LOAD DATA INFILE was half-logged). +###################################################### +# Change Author: JBM +# Change Date: 2005-12-22 +# Change: Test rewritten to remove show binlog events +# and to test the option better + Cleanup +###################################################### +-- source include/master-slave.inc + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings + +connection master; +# 'test' database should be ignored by the slave +USE test; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE test.t1; +SELECT COUNT(*) FROM test.t1; + +# 'mysqltest' database should NOT be ignored by the slave +CREATE DATABASE mysqltest; +USE mysqltest; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE mysqltest.t1; +SELECT COUNT(*) FROM mysqltest.t1; + +# Now lets check the slave to see what we have :-) +save_master_pos; +connection slave; +sync_with_master; + +SHOW DATABASES; + +USE test; +SHOW TABLES; + +USE mysqltest; +SHOW TABLES; +SELECT COUNT(*) FROM mysqltest.t1; + +#show binlog events; +connection master; +DROP DATABASE mysqltest; +DROP TABLE test.t1; + +# End of test diff --git a/mysql-test/t/rpl_row_rewrt_db-slave.opt b/mysql-test/t/rpl_rewrt_db-slave.opt similarity index 100% rename from mysql-test/t/rpl_row_rewrt_db-slave.opt rename to mysql-test/t/rpl_rewrt_db-slave.opt diff --git a/mysql-test/t/rpl_stm_rewrt_db.test b/mysql-test/t/rpl_rewrt_db.test similarity index 100% rename from mysql-test/t/rpl_stm_rewrt_db.test rename to mysql-test/t/rpl_rewrt_db.test diff --git a/mysql-test/t/rpl_row_log.test b/mysql-test/t/rpl_row_log.test index 290a08ff75a..29abf5bb93e 100644 --- a/mysql-test/t/rpl_row_log.test +++ b/mysql-test/t/rpl_row_log.test @@ -1,4 +1,4 @@ -# Requires statement logging +# Requires row base logging -- source include/have_binlog_format_row.inc -- source extra/rpl_tests/rpl_log.test diff --git a/mysql-test/t/rpl_row_rewrt_db.test b/mysql-test/t/rpl_row_rewrt_db.test deleted file mode 100644 index 8781b361d87..00000000000 --- a/mysql-test/t/rpl_row_rewrt_db.test +++ /dev/null @@ -1,83 +0,0 @@ -# TBF - difference in row level logging --- source include/have_binlog_format_row.inc --- source include/master-slave.inc - ---disable_warnings -drop database if exists mysqltest1; ---enable_warnings -create database mysqltest1; - -use mysqltest1; -create table t1 (a int); -insert into t1 values(9); -select * from mysqltest1.t1; -sync_slave_with_master; -show databases like 'mysqltest1'; # should be empty -select * from test.t1; -# cleanup -connection master; -drop table t1; -drop database mysqltest1; -sync_slave_with_master; - -# -# BUG#6353: -# Option --replicate-rewrite-db should work together with LOAD DATA INFILE -# - -connection slave; ---disable_warnings -drop database if exists rewrite; ---enable_warnings -create database rewrite; - -connection master; -use test; -create table t1 (a date, b date, c date not null, d date); -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ','; -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES; -sync_slave_with_master; - -connection slave; -select * from rewrite.t1; - -connection master; -truncate table t1; -load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d); -sync_slave_with_master; - -connection slave; -select * from rewrite.t1; - -connection master; -drop table t1; -create table t1 (a text, b text); -load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; -sync_slave_with_master; - -connection slave; -select concat('|',a,'|'), concat('|',b,'|') from rewrite.t1; - -connection master; -drop table t1; -create table t1 (a int, b char(10)); -load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines; -sync_slave_with_master; - -connection slave; -select * from rewrite.t1; - -connection master; -truncate table t1; -load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines; -sync_slave_with_master; - -connection slave; -# The empty line last comes from the end line field in the file -select * from rewrite.t1; - -drop database rewrite; - -connection master; -drop table t1; - diff --git a/mysql-test/t/rpl_row_timezone-slave.opt b/mysql-test/t/rpl_row_timezone-slave.opt deleted file mode 100644 index c383fd9f17d..00000000000 --- a/mysql-test/t/rpl_row_timezone-slave.opt +++ /dev/null @@ -1,2 +0,0 @@ ---default-time-zone=Europe/Moscow - diff --git a/mysql-test/t/rpl_row_user_variables.test b/mysql-test/t/rpl_row_user_variables.test deleted file mode 100644 index 2ebb668b1a8..00000000000 --- a/mysql-test/t/rpl_row_user_variables.test +++ /dev/null @@ -1,4 +0,0 @@ -# row-based and statement binlog difference in result files --- source include/have_binlog_format_row.inc --- source extra/rpl_tests/rpl_user_variables.test - diff --git a/mysql-test/t/rpl_row_view.test b/mysql-test/t/rpl_row_view.test deleted file mode 100644 index 6d460d58df6..00000000000 --- a/mysql-test/t/rpl_row_view.test +++ /dev/null @@ -1,47 +0,0 @@ -# NYI - row-based cannot use CREATE ... SELECT ---source include/have_binlog_format_row.inc - -source include/master-slave.inc; ---disable_warnings -drop table if exists t1,v1; -drop view if exists t1,v1; -sync_slave_with_master; ---enable_warnings - -# -# Check that createion drop of view is replicated, also check replication of -# updating of view -# -connection master; -create table t1 (a int); -insert into t1 values (1); -create view v1 as select a from t1; -insert into v1 values (2); -select * from v1 order by a; -sync_slave_with_master; -# view already have to be on slave -select * from v1 order by a; -connection master; -update v1 set a=3 where a=1; -select * from v1 order by a; -sync_slave_with_master; -select * from v1 order by a; -connection master; -delete from v1 where a=2; -select * from v1 order by a; -sync_slave_with_master; -select * from v1 order by a; -connection master; -# 'alter view' internally maped to creation, but still check that it works -alter view v1 as select a as b from t1; -sync_slave_with_master; -select * from v1 order by 1; -connection master; -drop view v1; -sync_slave_with_master; -#error, because view have to be removed from slave --- error 1146 -select * from v1 order by a; -connection master; -drop table t1; -sync_slave_with_master; diff --git a/mysql-test/t/rpl_stm_ddl.test b/mysql-test/t/rpl_stm_ddl.test deleted file mode 100644 index 54548114f86..00000000000 --- a/mysql-test/t/rpl_stm_ddl.test +++ /dev/null @@ -1,35 +0,0 @@ -######################## rpl_ddl.test ######################## -# # -# DDL statements (sometimes with implicit COMMIT) executed # -# by the master and it's propagation into the slave # -# # -############################################################## - -# -# NOTE, PLEASE BE CAREFUL, WHEN MODIFYING THE TESTS !! -# -# 1. !All! objects to be dropped, renamed, altered ... must be created -# in AUTOCOMMIT= 1 mode before AUTOCOMMIT is set to 0 and the test -# sequences start. -# -# 2. Never use a test object, which was direct or indirect affected by a -# preceeding test sequence again. -# Except table d1.t1 where ONLY DML is allowed. -# -# If one preceeding test sequence hits a (sometimes not good visible, -# because the sql error code of the statement might be 0) bug -# and these rules are ignored, a following test sequence might earn ugly -# effects like failing 'sync_slave_with_master', crashes of the slave or -# abort of the test case etc.. -# -# 3. The assignment of the DDL command to be tested to $my_stmt can -# be a bit difficult. "'" must be avoided, because the test -# routine "include/rpl_stmt_seq.inc" performs a -# eval SELECT CONCAT('######## ','$my_stmt',' ########') as ""; -# - ---source include/have_innodb.inc ---source include/have_binlog_format_statement.inc ---source include/master-slave.inc -let $engine_type= "InnoDB"; --- source extra/rpl_tests/rpl_ddl.test diff --git a/mysql-test/t/rpl_stm_err_ignoredtable.test b/mysql-test/t/rpl_stm_err_ignoredtable.test deleted file mode 100644 index a426be27b59..00000000000 --- a/mysql-test/t/rpl_stm_err_ignoredtable.test +++ /dev/null @@ -1,8 +0,0 @@ -# Test for -# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave -# still checks that it has the same error as on the master. - -# Requires statement logging --- source include/have_binlog_format_statement.inc --- source extra/rpl_tests/rpl_err_ignoredtable.test - diff --git a/mysql-test/t/rpl_stm_rewrt_db-slave.opt b/mysql-test/t/rpl_stm_rewrt_db-slave.opt deleted file mode 100644 index a462ad19ba0..00000000000 --- a/mysql-test/t/rpl_stm_rewrt_db-slave.opt +++ /dev/null @@ -1 +0,0 @@ -"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test" diff --git a/mysql-test/t/rpl_stm_timezone-master.opt b/mysql-test/t/rpl_stm_timezone-master.opt deleted file mode 100644 index 8e43bfbbb7e..00000000000 --- a/mysql-test/t/rpl_stm_timezone-master.opt +++ /dev/null @@ -1 +0,0 @@ ---default-time-zone=Europe/Moscow diff --git a/mysql-test/t/rpl_stm_timezone.test b/mysql-test/t/rpl_stm_timezone.test deleted file mode 100644 index 0cd6dbf5d89..00000000000 --- a/mysql-test/t/rpl_stm_timezone.test +++ /dev/null @@ -1,129 +0,0 @@ -# TBF - difference in row level logging --- source include/have_binlog_format_statement.inc - -# Test of replication of time zones. - -# There is currently some bug possibly in prepared statements (this -# test fails with --ps-protocol): sys_var_thd_time_zone::value_ptr() -# is called only at prepare time, not at execution time. So, -# thd->time_zone_used is not equal to 1 (it is back to 0, because of -# reset_thd_for_next_command called at execution time), so the -# timezone used in CONVERT_TZ is not binlogged. To debug (by Guilhem -# and possibly Konstantin). - ---disable_ps_protocol - -source include/master-slave.inc; - -# Some preparations -let $VERSION=`select version()`; -set timestamp=100000000; # for fixed output of mysqlbinlog -create table t1 (t timestamp); -create table t2 (t char(32)); - -connection slave; -select @@time_zone; - -# -# Let us check how well replication works when we are saving datetime -# value in TIMESTAMP field. -# -connection master; -select @@time_zone; -insert into t1 values ('20050101000000'), ('20050611093902'); -set time_zone='UTC'; -insert into t1 values ('20040101000000'), ('20040611093902'); -select * from t1; -sync_slave_with_master; -set time_zone='UTC'; -select * from t1; - -# Let us check also that setting of time_zone back to default also works -# well -connection master; -delete from t1; -set time_zone='Europe/Moscow'; -insert into t1 values ('20040101000000'), ('20040611093902'); -select * from t1; -sync_slave_with_master; -set time_zone='Europe/Moscow'; -select * from t1; -connection master; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 - -# Let us check with LOAD DATA INFILE -# (we do it after mysqlbinlog because the temp files names are not constant) -connection master; -delete from t1; -set time_zone='UTC'; -load data infile '../../std_data/rpl_timezone.dat' into table t1; -select * from t1; -sync_slave_with_master; -set time_zone='UTC'; -select * from t1; -set time_zone='Europe/Moscow'; - -# Put back values of before the LOAD -connection master; -set time_zone='Europe/Moscow'; -delete from t1; -insert into t1 values ('20040101000000'), ('20040611093902'); - -# -# Now let us check how well we replicate statments reading TIMESTAMP fields -# (We should see the same data on master and on slave but it should differ -# from originally inserted) -# -set time_zone='MET'; -insert into t2 (select t from t1); -select * from t1; -sync_slave_with_master; -select * from t2; - -# -# Now let us check how well we replicate various CURRENT_* functions -# -connection master; -delete from t2; -set timestamp=1000072000; -insert into t2 values (current_timestamp), (current_date), (current_time); -sync_slave_with_master; -select * from t2; - -# -# At last let us check replication of FROM_UNIXTIME/UNIX_TIMESTAMP functions. -# -connection master; -delete from t2; -insert into t2 values (from_unixtime(1000000000)), - (unix_timestamp('2001-09-09 03:46:40')); -select * from t2; -sync_slave_with_master; -# We should get same result on slave as on master -select * from t2; - -# -# Let us check that we are allowing to set global time_zone with -# replication -# -connection master; -set global time_zone='MET'; - -# -# Let us see if CONVERT_TZ(@@time_zone) replicates -# -delete from t2; -set time_zone='UTC'; -insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone)); -insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan')); -select * from t2; -sync_slave_with_master; -select * from t2; - -# Clean up -connection master; -drop table t1, t2; -sync_slave_with_master; - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_stm_user_variables.test b/mysql-test/t/rpl_stm_user_variables.test deleted file mode 100644 index af4e46cdace..00000000000 --- a/mysql-test/t/rpl_stm_user_variables.test +++ /dev/null @@ -1,5 +0,0 @@ -# row-based and statement binlog difference in result files --- source include/have_binlog_format_statement.inc --- source extra/rpl_tests/rpl_user_variables.test - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_row_timezone-master.opt b/mysql-test/t/rpl_timezone-master.opt similarity index 100% rename from mysql-test/t/rpl_row_timezone-master.opt rename to mysql-test/t/rpl_timezone-master.opt diff --git a/mysql-test/t/rpl_stm_timezone-slave.opt b/mysql-test/t/rpl_timezone-slave.opt similarity index 100% rename from mysql-test/t/rpl_stm_timezone-slave.opt rename to mysql-test/t/rpl_timezone-slave.opt diff --git a/mysql-test/t/rpl_row_timezone.test b/mysql-test/t/rpl_timezone.test similarity index 93% rename from mysql-test/t/rpl_row_timezone.test rename to mysql-test/t/rpl_timezone.test index 047a458f09f..e78f1e1899e 100644 --- a/mysql-test/t/rpl_row_timezone.test +++ b/mysql-test/t/rpl_timezone.test @@ -1,6 +1,3 @@ -# TBF - difference in row level logging --- source include/have_binlog_format_row.inc - # Test of replication of time zones. # There is currently some bug possibly in prepared statements (this @@ -51,8 +48,11 @@ sync_slave_with_master; set time_zone='Europe/Moscow'; select * from t1; connection master; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 +# Change Author: JBM +# Change Date: 2005-12-22 +# Change: Comment out the exec of the binlog so test works for both SBR and RBR +#--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +#--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001 # Let us check with LOAD DATA INFILE # (we do it after mysqlbinlog because the temp files names are not constant) @@ -74,7 +74,7 @@ insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL); # # Now let us check how well we replicate statments reading TIMESTAMP fields -# (We should see the same data on master and on slave but it should differ +# (We should see the same data on master and on slave but it should differ # from originally inserted) # set time_zone='MET'; @@ -127,3 +127,4 @@ select * from t2; connection master; drop table t1, t2; sync_slave_with_master; + diff --git a/mysql-test/extra/rpl_tests/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test similarity index 96% rename from mysql-test/extra/rpl_tests/rpl_user_variables.test rename to mysql-test/t/rpl_user_variables.test index 256c244d4eb..b46a0fad02e 100644 --- a/mysql-test/extra/rpl_tests/rpl_user_variables.test +++ b/mysql-test/t/rpl_user_variables.test @@ -1,4 +1,3 @@ -# row-based and statement binlog difference in result files # # Test of replicating user variables # diff --git a/mysql-test/t/rpl_stm_view.test b/mysql-test/t/rpl_view.test similarity index 82% rename from mysql-test/t/rpl_stm_view.test rename to mysql-test/t/rpl_view.test index 39f39705f77..0e8c7514488 100644 --- a/mysql-test/t/rpl_stm_view.test +++ b/mysql-test/t/rpl_view.test @@ -1,5 +1,4 @@ # NYI - row-based cannot use CREATE ... SELECT ---source include/have_binlog_format_statement.inc source include/master-slave.inc; --disable_warnings @@ -10,7 +9,7 @@ reset master; --enable_warnings # -# Check that createion drop of view is replicated, also check replication of +# Check that creation drop of view is replicated, also check replication of # updating of view # connection master; @@ -46,5 +45,8 @@ select * from v1 order by a; connection master; drop table t1; sync_slave_with_master; ---replace_column 2 # 5 # -show binlog events limit 1,100; +# Change Author: JBM +# Change Date: 2005-12-22 +# Change: Commented out binlog events to work with SBR and RBR +#--replace_column 2 # 5 # +# show binlog events limit 1,100; From 56db7a6b6e0f8f6955e6eec76e5de5a28af442cd Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Sat, 24 Dec 2005 12:07:07 +0100 Subject: [PATCH 05/49] Bug#15924 (Core dump in sp_trans): Added code for pending event flush just before executing the function or trigger. --- mysql-test/t/disabled.def | 2 +- sql/log.cc | 18 +++++++++++------- sql/sql_class.cc | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f32ed667864..5fdc6f6f3dc 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,4 +24,4 @@ subselect : Bug#15706 type_time : Bug#15805 rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite -sp_trans : Bug#15924 Code dump in RBR mode when executing test suite +#sp_trans : Bug#15924 Code dump in RBR mode when executing test suite diff --git a/sql/log.cc b/sql/log.cc index 44d3869e9d5..dd08ca7b9b5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -241,13 +241,15 @@ static int binlog_savepoint_set(THD *thd, void *sv) DBUG_ENTER("binlog_savepoint_set"); binlog_trx_data *const trx_data= (binlog_trx_data*) thd->ha_data[binlog_hton.slot]; - IO_CACHE *trans_log= &trx_data->trans_log; - DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log)); + DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(&trx_data->trans_log)); - *(my_off_t *)sv= my_b_tell(trans_log); + *(my_off_t *)sv= my_b_tell(&trx_data->trans_log); /* Write it to the binary log */ - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } static int binlog_savepoint_rollback(THD *thd, void *sv) @@ -265,8 +267,10 @@ static int binlog_savepoint_rollback(THD *thd, void *sv) */ if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE)) { - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); - DBUG_RETURN(mysql_bin_log.write(&qinfo)); + int const error= + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, TRUE, FALSE); + DBUG_RETURN(error); } reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0); DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 08d89228a72..2bc0d8d59ab 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1969,6 +1969,23 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, backup->client_capabilities= client_capabilities; backup->savepoints= transaction.savepoints; + /* + For row-based replication and before executing a function/trigger, + the pending rows event has to be flushed. The function/trigger + might execute statement that require the pending event to be + flushed. A simple example: + + CREATE FUNCTION foo() RETURNS INT + BEGIN + SAVEPOINT x; + RETURN 0; + END + + INSERT INTO t1 VALUES (1), (foo()), (2); + */ + if (binlog_row_based) + thd->binlog_flush_pending_rows_event(false); + if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !binlog_row_based) options&= ~OPTION_BIN_LOG; From 344017061847a8244a5973bd02fc07a0d4721011 Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Tue, 27 Dec 2005 12:06:48 +0100 Subject: [PATCH 06/49] Bug#15942 (RBR ignored --binlog_ignore_db and tries to map table on slave for writes): Added code to do the filtering (seems to have gone away). --- mysql-test/r/rpl_row_basic_11bugs.result | 45 ++++++++++++++++++++ mysql-test/t/rpl_row_basic_11bugs-master.opt | 1 + mysql-test/t/rpl_row_basic_11bugs.test | 31 ++++++++++++++ sql/handler.cc | 5 ++- 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/rpl_row_basic_11bugs.result create mode 100644 mysql-test/t/rpl_row_basic_11bugs-master.opt create mode 100644 mysql-test/t/rpl_row_basic_11bugs.test diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result new file mode 100644 index 00000000000..9249405ac26 --- /dev/null +++ b/mysql-test/r/rpl_row_basic_11bugs.result @@ -0,0 +1,45 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +CREATE DATABASE test_ignore; +**** On Master **** +SHOW DATABASES; +Database +information_schema +mysql +test +test_ignore +USE test; +CREATE TABLE t1 (a INT, b INT); +SHOW TABLES; +Tables_in_test +t1 +INSERT INTO t1 VALUES (1,1), (2,2); +USE test_ignore; +CREATE TABLE t2 (a INT, b INT); +SHOW TABLES; +Tables_in_test_ignore +t2 +INSERT INTO t2 VALUES (3,3), (4,4); +SHOW BINLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 102 Server ver: 5.1.5-alpha-debug-log, Binlog ver: 4 +master-bin.000001 102 Query 1 195 use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 195 Table_map 1 235 test.t1 +master-bin.000001 235 Write_rows 1 282 +**** On Slave **** +SHOW DATABASES; +Database +information_schema +mysql +test +USE test; +SHOW TABLES; +Tables_in_test +t1 +USE test_ignore; +ERROR 42000: Unknown database 'test_ignore' +DROP DATABASE test_ignore; diff --git a/mysql-test/t/rpl_row_basic_11bugs-master.opt b/mysql-test/t/rpl_row_basic_11bugs-master.opt new file mode 100644 index 00000000000..d5ae999b180 --- /dev/null +++ b/mysql-test/t/rpl_row_basic_11bugs-master.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test_ignore; diff --git a/mysql-test/t/rpl_row_basic_11bugs.test b/mysql-test/t/rpl_row_basic_11bugs.test new file mode 100644 index 00000000000..76ff5a581c9 --- /dev/null +++ b/mysql-test/t/rpl_row_basic_11bugs.test @@ -0,0 +1,31 @@ +--source include/have_row_based.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# Bug#15942 (RBR ignores --binlog_ignore_db and tries to map to table +# on slave for writes) + +CREATE DATABASE test_ignore; # --binlog_ignore_db=mysqltest_ignore + +--echo **** On Master **** +SHOW DATABASES; +USE test; +CREATE TABLE t1 (a INT, b INT); +SHOW TABLES; +INSERT INTO t1 VALUES (1,1), (2,2); +USE test_ignore; +CREATE TABLE t2 (a INT, b INT); +SHOW TABLES; +INSERT INTO t2 VALUES (3,3), (4,4); +SHOW BINLOG EVENTS; +sync_slave_with_master; +--echo **** On Slave **** +SHOW DATABASES; +USE test; +SHOW TABLES; +--error 1049 +USE test_ignore; + +connection master; +DROP DATABASE test_ignore; +sync_slave_with_master; diff --git a/sql/handler.cc b/sql/handler.cc index 59445a1b2f1..70e445dd321 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2797,7 +2797,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) - Row-based replication is on - It is not a temporary table - The binlog is enabled - - The table shall be binlogged (binlog_*_db rules) [Seems disabled /Matz] + - The table shall be binlogged (binlog_*_db rules) */ #ifdef HAVE_ROW_BASED_REPLICATION @@ -2806,7 +2806,8 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table) return binlog_row_based && thd && (thd->options & OPTION_BIN_LOG) && - (table->s->tmp_table == NO_TMP_TABLE); + (table->s->tmp_table == NO_TMP_TABLE) && + binlog_filter->db_ok(table->s->db.str); } template int binlog_log_row(TABLE* table, From eaffb7eb73b13f2275fe0fc2af490df2ac521fa8 Mon Sep 17 00:00:00 2001 From: "kent@mysql.com" <> Date: Wed, 28 Dec 2005 18:35:22 +0100 Subject: [PATCH 07/49] config-win.h: Backported Windows MAX_INDEXES handling from 5.1 --- include/config-win.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 528bc8a8cdd..b825d34f1ee 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -61,6 +61,10 @@ functions */ #define __WIN__ /* To make it easier in VC++ */ #endif +#ifndef MAX_INDEXES +#define MAX_INDEXES 64 +#endif + /* File and lock constants */ #define O_SHARE 0x1000 /* Open file in sharing mode */ #ifdef __BORLANDC__ From ec753efd43b5a41fee179a430662431e93dd0a58 Mon Sep 17 00:00:00 2001 From: "pekka@mysql.com" <> Date: Sat, 31 Dec 2005 10:54:36 +0100 Subject: [PATCH 08/49] ndb - wl#2972 (4.1) copy detached trigger fix from 5.0 --- ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp index 470b98fd04c..e16d3df6d8d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp @@ -445,6 +445,7 @@ Dbtup::commitRecord(Signal* signal, befOpPtr.p->changeMask.bitOR(attributeMask); befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; checkDetachedTriggers(signal, befOpPtr.p, @@ -483,6 +484,7 @@ Dbtup::commitRecord(Signal* signal, befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC; befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; checkDetachedTriggers(signal, befOpPtr.p, From 70d13a7cb791f64c8ceec8ab64279098b8e6d876 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sun, 1 Jan 2006 16:43:34 +0100 Subject: [PATCH 09/49] plugin versioning: we cannot assume that sizeof(st_mysql_plugin) is the same in the plugin and in the mysqld. store the size in the plugin. To simplify access to plugin's st_mysql_plugin, copy it on open and convert to the latest version, so that the rest of the code would not need to care about versions. --- include/plugin.h | 1 + sql/sql_plugin.cc | 92 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/include/plugin.h b/include/plugin.h index 7677db3ace2..3faa02cb079 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -39,6 +39,7 @@ #define mysql_declare_plugin \ int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \ +int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \ struct st_mysql_plugin _mysql_plugin_declarations_[]= { #define mysql_declare_plugin_end ,{0,0,0,0,0,0,0}} diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 51e53252d84..9c3d19369c8 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -29,6 +29,8 @@ LEX_STRING plugin_type_names[]= }; static const char *plugin_interface_version_sym= "_mysql_plugin_interface_version_"; +static const char *sizeof_st_plugin_sym= + "_mysql_sizeof_struct_st_plugin_"; static const char *plugin_declarations_sym= "_mysql_plugin_declarations_"; static int min_plugin_interface_version= 0x0000; /* Note that 'int version' must be the first field of every plugin @@ -90,6 +92,13 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) struct st_plugin_dl *)); } +static inline void free_plugin_mem(struct st_plugin_dl *p) +{ + dlclose(p->handle); + my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR)); + if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION) + my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR)); +} static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) { @@ -121,6 +130,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) tmp->ref_count++; DBUG_RETURN(tmp); } + bzero(&plugin_dl, sizeof(plugin_dl)); /* Compile dll path */ strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", dl->str, NullS); plugin_dl.ref_count= 1; @@ -136,7 +146,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) /* Determine interface version */ if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym))) { - dlclose(plugin_dl.handle); + free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym); if (report & REPORT_TO_LOG) @@ -148,7 +158,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) if (plugin_dl.version < min_plugin_interface_version || (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8)) { - dlclose(plugin_dl.handle); + free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0, "plugin interface version mismatch"); @@ -160,19 +170,84 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) /* Find plugin declarations */ if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym))) { - dlclose(plugin_dl.handle); + free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym); if (report & REPORT_TO_LOG) sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym); DBUG_RETURN(0); } + + if (plugin_dl.version != MYSQL_PLUGIN_INTERFACE_VERSION) + { + int i, sizeof_st_plugin; + struct st_mysql_plugin *old, *cur; + char *ptr=(char *)sym; + + if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym))) + sizeof_st_plugin= *(int *)sym; + else + { +#ifdef ERROR_ON_NO_SIZEOF_PLUGIN_SYMBOL + free_plugin_mem(&plugin_dl); + if (report & REPORT_TO_USER) + my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), sizeof_st_plugin_sym); + if (report & REPORT_TO_LOG) + sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym); + DBUG_RETURN(0); +#else + DBUG_ASSERT(min_plugin_interface_version == 0); + sizeof_st_plugin=(int)offsetof(struct st_mysql_plugin, version); +#endif + } + + for (i= 0; + ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info; + i++) + /* no op */; + + cur= (struct st_mysql_plugin*) + my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME)); + if (!cur) + { + free_plugin_mem(&plugin_dl); + if (report & REPORT_TO_USER) + my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length); + if (report & REPORT_TO_LOG) + sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length); + DBUG_RETURN(0); + } + for (i=0; + (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info; + i++) + { + switch (plugin_dl.version) { + default: /* version > MYSQL_PLUGIN_INTERFACE_VERSION */ + /* fall through */ + case 0x0001: + cur[i].version=old->version; + // cur[i].status_vars=old->status_vars; + /* fall through */ + case 0x0000: + cur[i].type=old->type; + cur[i].info=old->info; + cur[i].name=old->name; + cur[i].author=old->author; + cur[i].descr=old->descr; + cur[i].init=old->init; + cur[i].deinit=old->deinit; + } + } + + sym=cur; + } plugin_dl.plugins= (struct st_mysql_plugin *)sym; + /* Duplicate and convert dll name */ plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1; if (! (plugin_dl.dl.str= my_malloc(plugin_dl.dl.length, MYF(0)))) { - dlclose(plugin_dl.handle); + free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length); if (report & REPORT_TO_LOG) @@ -186,8 +261,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) /* Add this dll to array */ if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl))) { - dlclose(plugin_dl.handle); - my_free(plugin_dl.dl.str, MYF(0)); + free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl)); if (report & REPORT_TO_LOG) @@ -223,8 +297,7 @@ static void plugin_dl_del(LEX_STRING *dl) /* Do not remove this element, unless no other plugin uses this dll. */ if (! --tmp->ref_count) { - dlclose(tmp->handle); - my_free(tmp->dl.str, MYF(0)); + free_plugin_mem(tmp); bzero(tmp, sizeof(struct st_plugin_dl)); } break; @@ -646,8 +719,7 @@ void plugin_free(void) #ifdef HAVE_DLOPEN if (tmp->handle) { - dlclose(tmp->handle); - my_free(tmp->dl.str, MYF(0)); + free_plugin_mem(tmp); } #endif } From 533b18c8f9eab8a6bb6cc5c605aa6014fdd2c52c Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 2 Jan 2006 15:41:13 +0100 Subject: [PATCH 10/49] cleanup of SHOW STATUS code, as a preparation for WL#2935 (MySQL plugin interface: status variables) adding SHOW_FUNC, removing SHOW_some_specific_value, only generic SHOW_LONG/SHOW_CHAR/etc are recognized. changing to use SHOW_FUNC instead of ha_update_statistics --- sql/ha_innodb.h | 1 - sql/handler.cc | 9 -- sql/handler.h | 3 +- sql/mysqld.cc | 413 +++++++++++++++++++++++++++++++++++++++++++----- sql/set_var.cc | 41 ++++- sql/sql_show.cc | 293 +++------------------------------- sql/structs.h | 27 +--- 7 files changed, 443 insertions(+), 344 deletions(-) diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index fd0d3aa7e8c..8db7f00ffa9 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -277,7 +277,6 @@ void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offse void innobase_drop_database(char *path); bool innobase_show_status(THD* thd, stat_print_fn*, enum ha_stat_type); -int innodb_export_status(void); int innobase_release_temporary_latches(THD *thd); diff --git a/sql/handler.cc b/sql/handler.cc index db97b14da2a..17ee2f3b819 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1180,15 +1180,6 @@ int ha_release_temporary_latches(THD *thd) #endif } - -int ha_update_statistics() -{ -#ifdef WITH_INNOBASE_STORAGE_ENGINE - innodb_export_status(); -#endif - return 0; -} - int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv) { int error=0; diff --git a/sql/handler.h b/sql/handler.h index eff4ecdc4d2..b03b7654c9e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1538,7 +1538,7 @@ inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag) inline bool ha_storage_engine_is_enabled(const handlerton *db_type) { - return (db_type && db_type->create) ? + return (db_type && db_type->create) ? (db_type->state == SHOW_OPTION_YES) : FALSE; } @@ -1549,7 +1549,6 @@ int ha_initialize_handlerton(handlerton *hton); TYPELIB *ha_known_exts(void); int ha_panic(enum ha_panic_function flag); -int ha_update_statistics(); void ha_close_connection(THD* thd); bool ha_flush_logs(handlerton *db_type); void ha_drop_database(char* path); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d6d54d180db..59c317d724e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6186,6 +6186,335 @@ The minimum value for this variable is 4096.", {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; +static int show_question(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONGLONG; + var->value= (char *)&thd->query_id; + return 0; +} + +static int show_net_compression(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_MY_BOOL; + var->value= (char *)&thd->net.compress; + return 0; +} + +static int show_starttime(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long) (thd->query_start() - start_time); + return 0; +} + +#ifdef HAVE_REPLICATION +static int show_rpl_status(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + var->value= const_cast(rpl_status_type[(int)rpl_status]); + return 0; +} + +static int show_slave_running(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + pthread_mutex_lock(&LOCK_active_mi); + var->value= const_cast((active_mi && active_mi->slave_running && + active_mi->rli.slave_running) ? "ON" : "OFF"); + pthread_mutex_unlock(&LOCK_active_mi); + return 0; +} + +static int show_slave_retried_trans(THD *thd, show_var_st *var, char *buff) +{ + /* + TODO: with multimaster, have one such counter per line in + SHOW SLAVE STATUS, and have the sum over all lines here. + */ + pthread_mutex_lock(&LOCK_active_mi); + if (active_mi) + { + var->type=SHOW_LONG; + var->value= buff; + pthread_mutex_lock(&active_mi->rli.data_lock); + *((long *)buff)= (long)active_mi->rli.retried_trans; + pthread_mutex_unlock(&active_mi->rli.data_lock); + } + else + var->type=SHOW_UNDEF; + pthread_mutex_unlock(&LOCK_active_mi); + return 0; +} +#endif /* HAVE_REPLICATION */ + +static int show_open_tables(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)cached_open_tables(); + return 0; +} + +static int show_table_definitions(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)cached_table_definitions(); + return 0; +} + +#ifdef HAVE_OPENSSL +/* Functions relying on CTX */ +static int show_ssl_ctx_sess_accept(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_accept_good(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_connect_good(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_cb_hits(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_hits(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_cache_full(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_misses(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_timeouts(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_number(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_connect(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_sess_get_cache_size(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_get_verify_mode(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_get_verify_depth(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (!ssl_acceptor_fd ? 0 : + SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)); + return 0; +} + +static int show_ssl_ctx_get_session_cache_mode(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + if (!ssl_acceptor_fd) + var->value= "NONE"; + else + switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context)) + { + case SSL_SESS_CACHE_OFF: + var->value= "OFF"; break; + case SSL_SESS_CACHE_CLIENT: + var->value= "CLIENT"; break; + case SSL_SESS_CACHE_SERVER: + var->value= "SERVER"; break; + case SSL_SESS_CACHE_BOTH: + var->value= "BOTH"; break; + case SSL_SESS_CACHE_NO_AUTO_CLEAR: + var->value= "NO_AUTO_CLEAR"; break; + case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: + var->value= "NO_INTERNAL_LOOKUP"; break; + default: + var->value= "Unknown"; break; + } + return 0; +} + +/* Functions relying on SSL */ +static int show_ssl_get_version(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + var->value= const_cast(thd->net.vio->ssl_arg ? + SSL_get_version((SSL*) thd->net.vio->ssl_arg) : ""); + return 0; +} + +static int show_ssl_session_reused(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)thd->net.vio->ssl_arg ? + SSL_session_reused((SSL*) thd->net.vio->ssl_arg) : + 0; +} + +static int show_ssl_get_default_timeout(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)thd->net.vio->ssl_arg ? + SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg) : + 0; + return 0; +} + +static int show_ssl_get_verify_mode(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)thd->net.vio->ssl_arg ? + SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg) : + 0; + return 0; +} + +static int show_ssl_get_verify_depth(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_LONG; + var->value= buff; + *((long *)buff)= (long)thd->net.vio->ssl_arg ? + SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg) : + 0; + return 0; +} + +static int show_ssl_get_cipher(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + var->value= const_cast(thd->net.vio->ssl_arg ? + SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : ""); + return 0; +} + +static int show_ssl_get_cipher_list(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + var->value= buff; + if (thd->net.vio->ssl_arg) + { + int i; + const char *p; + for (i=0 ; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)); i++) + { + buff= strmov(buff, p); + *buff++= ':'; + } + if (i) + buff--; + } + *buff=0; + return 0; +} + +#endif /* HAVE_OPENSSL */ + +#ifdef WITH_INNOBASE_STORAGE_ENGINE +int innodb_export_status(void); +static int show_innodb_vars(THD *thd, show_var_st *var, char *buff) +{ + innodb_export_status(); + var->type= SHOW_ARRAY; + var->value= (char *) &innodb_status_variables; + return 0; +} +#endif struct show_var_st status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, @@ -6296,7 +6625,7 @@ struct show_var_st status_vars[]= { {"Com_xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS}, {"Com_xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS}, {"Com_xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS}, - {"Compression", (char*) 0, SHOW_NET_COMPRESSION}, + {"Compression", (char*) &show_net_compression, SHOW_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_CONST}, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, @@ -6321,25 +6650,25 @@ struct show_var_st status_vars[]= { {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, #ifdef WITH_INNOBASE_STORAGE_ENGINE - {"Innodb_", (char*) &innodb_status_variables, SHOW_VARS}, + {"Innodb_", (char*) &show_innodb_vars, SHOW_FUNC}, #endif /* WITH_INNOBASE_STORAGE_ENGINE */ - {"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed, SHOW_KEY_CACHE_LONG}, - {"Key_blocks_unused", (char*) &dflt_key_cache_var.blocks_unused, SHOW_KEY_CACHE_CONST_LONG}, - {"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, SHOW_KEY_CACHE_CONST_LONG}, - {"Key_read_requests", (char*) &dflt_key_cache_var.global_cache_r_requests, SHOW_KEY_CACHE_LONGLONG}, - {"Key_reads", (char*) &dflt_key_cache_var.global_cache_read, SHOW_KEY_CACHE_LONGLONG}, - {"Key_write_requests", (char*) &dflt_key_cache_var.global_cache_w_requests, SHOW_KEY_CACHE_LONGLONG}, - {"Key_writes", (char*) &dflt_key_cache_var.global_cache_write, SHOW_KEY_CACHE_LONGLONG}, + {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG}, + {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_CONST_LONG}, + {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_CONST_LONG}, + {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG}, + {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG}, + {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG}, + {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE - {"Ndb_", (char*) &ndb_status_variables, SHOW_VARS}, + {"Ndb_", (char*) &ndb_status_variables, SHOW_ARRAY}, #endif /* WITH_NDBCLUSTER_STORAGE_ENGINE */ {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST}, {"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST}, {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST}, - {"Open_table_definitions", (char*) 0, SHOW_TABLE_DEFINITIONS}, - {"Open_tables", (char*) 0, SHOW_OPEN_TABLES}, + {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC}, + {"Open_tables", (char*) &show_open_tables, SHOW_FUNC}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_CONST}, @@ -6351,16 +6680,20 @@ struct show_var_st status_vars[]= { {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST}, {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST}, #endif /*HAVE_QUERY_CACHE*/ - {"Questions", (char*) 0, SHOW_QUESTION}, - {"Rpl_status", (char*) 0, SHOW_RPL_STATUS}, + {"Questions", (char*) &show_question, SHOW_FUNC}, +#ifdef HAVE_REPLICATION + {"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC}, +#endif {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS}, {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS}, {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS}, {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS}, {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, - {"Slave_retried_transactions",(char*) 0, SHOW_SLAVE_RETRIED_TRANS}, - {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING}, +#ifdef HAVE_REPLICATION + {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC}, + {"Slave_running", (char*) &show_slave_running, SHOW_FUNC}, +#endif {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS}, {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS}, @@ -6368,29 +6701,29 @@ struct show_var_st status_vars[]= { {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS}, {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS}, #ifdef HAVE_OPENSSL - {"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, - {"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, - {"Ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, - {"Ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, - {"Ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST}, - {"Ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT}, - {"Ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE}, - {"Ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, - {"Ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, - {"Ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, - {"Ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, - {"Ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD}, - {"Ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS}, - {"Ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES}, - {"Ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, - {"Ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL}, - {"Ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, - {"Ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS}, - {"Ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, - {"Ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, - {"Ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, - {"Ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, - {"Ssl_version", (char*) 0, SHOW_SSL_GET_VERSION}, + {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC}, + {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC}, + {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC}, + {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_FUNC}, + {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_FUNC}, + {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC}, + {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC}, + {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC}, + {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC}, + {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_FUNC}, + {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC}, + {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC}, + {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC}, + {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC}, + {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC}, + {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC}, + {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC}, + {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC}, + {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_FUNC}, + {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC}, + {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC}, + {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC}, + {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC}, #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, @@ -6403,7 +6736,7 @@ struct show_var_st status_vars[]= { {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_created", (char*) &thread_created, SHOW_LONG_CONST}, {"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, - {"Uptime", (char*) 0, SHOW_STARTTIME}, + {"Uptime", (char*) &show_starttime, SHOW_FUNC}, {NullS, NullS, SHOW_LONG} }; diff --git a/sql/set_var.cc b/sql/set_var.cc index 01ff30045c4..dfd451442ca 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -623,6 +623,45 @@ sys_var_have_variable sys_have_row_based_replication("have_row_based_replication /* Global read-only variable describing server license */ sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE)); +#ifdef HAVE_REPLICATION +static int show_slave_skip_errors(THD *thd, show_var_st *var, char *buff) +{ + var->type=SHOW_CHAR; + var->value= buff; + if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask)) + { + var->value= "OFF"; + } + else if (bitmap_is_set_all(&slave_error_mask)) + { + var->value= "ALL"; + } + else + { + /* 10 is enough assuming errors are max 4 digits */ + int i; + var->value= buff; + for (i= 1; + i < MAX_SLAVE_ERROR && + (buff - var->value) < SHOW_VAR_FUNC_BUFF_SIZE; + i++) + { + if (bitmap_is_set(&slave_error_mask, i)) + { + buff= int10_to_str(i, buff, 10); + *buff++= ','; + } + } + if (var->value != buff) + buff--; // Remove last ',' + if (i < MAX_SLAVE_ERROR) + buff= strmov(buff, "..."); // Couldn't show all errors + *buff=0; + } + return 0; +} +#endif /* HAVE_REPLICATION */ + /* Variables shown by SHOW variables in alphabetical order @@ -863,7 +902,7 @@ struct show_var_st init_vars[]= { (char*) &sys_slave_compressed_protocol, SHOW_SYS}, {"slave_load_tmpdir", (char*) &slave_load_tmpdir, SHOW_CHAR_PTR}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, - {"slave_skip_errors", (char*) &slave_error_mask, SHOW_SLAVE_SKIP_ERRORS}, + {"slave_skip_errors", (char*) &show_slave_skip_errors, SHOW_FUNC}, {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries, SHOW_SYS}, #endif {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS}, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 705ebb4aef3..e5723b27b5c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1516,18 +1516,18 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) Status functions *****************************************************************************/ - static bool show_status_array(THD *thd, const char *wild, show_var_st *variables, enum enum_var_type value_type, struct system_status_var *status_var, const char *prefix, TABLE *table) { - char buff[1024], *prefix_end; + char buff[SHOW_VAR_FUNC_BUFF_SIZE], *prefix_end; /* the variable name should not be longer then 80 characters */ char name_buffer[80]; int len; LEX_STRING null_lex_str; + struct show_var_st tmp, *var; DBUG_ENTER("show_status_array"); null_lex_str.str= 0; // For sys_var->value_ptr() @@ -1540,18 +1540,22 @@ static bool show_status_array(THD *thd, const char *wild, { strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ - SHOW_TYPE show_type=variables->type; - if (show_type == SHOW_VARS) + + for (var=variables; var->type == SHOW_FUNC; var= &tmp) + ((show_var_func)(var->value))(thd, &tmp, buff); + + SHOW_TYPE show_type=var->type; + if (show_type == SHOW_ARRAY) { - show_status_array(thd, wild, (show_var_st *) variables->value, - value_type, status_var, variables->name, table); + show_status_array(thd, wild, (show_var_st *) var->value, + value_type, status_var, name_buffer, table); } else { if (!(wild && wild[0] && wild_case_compare(system_charset_info, name_buffer, wild))) { - char *value=variables->value; + char *value=var->value; const char *pos, *end; // We assign a lot of const's long nr; if (show_type == SHOW_SYS) @@ -1562,7 +1566,17 @@ static bool show_status_array(THD *thd, const char *wild, } pos= end= buff; + /* + note that value may be == buff. All SHOW_xxx code below + should still work in this case + */ switch (show_type) { + case SHOW_DOUBLE_STATUS: + { + value= ((char *) status_var + (ulong) value); + end= buff + sprintf(buff, "%f", *(double*) value); + break; + } case SHOW_LONG_STATUS: case SHOW_LONG_CONST_STATUS: value= ((char *) status_var + (ulong) value); @@ -1601,80 +1615,6 @@ static bool show_status_array(THD *thd, const char *wild, end= strend(pos); break; } - case SHOW_STARTTIME: - nr= (long) (thd->query_start() - start_time); - end= int10_to_str(nr, buff, 10); - break; - case SHOW_QUESTION: - end= int10_to_str((long) thd->query_id, buff, 10); - break; -#ifdef HAVE_REPLICATION - case SHOW_RPL_STATUS: - end= strmov(buff, rpl_status_type[(int)rpl_status]); - break; - case SHOW_SLAVE_RUNNING: - { - pthread_mutex_lock(&LOCK_active_mi); - end= strmov(buff, (active_mi && active_mi->slave_running && - active_mi->rli.slave_running) ? "ON" : "OFF"); - pthread_mutex_unlock(&LOCK_active_mi); - break; - } - case SHOW_SLAVE_RETRIED_TRANS: - { - /* - TODO: in 5.1 with multimaster, have one such counter per line in - SHOW SLAVE STATUS, and have the sum over all lines here. - */ - pthread_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - pthread_mutex_lock(&active_mi->rli.data_lock); - end= int10_to_str(active_mi->rli.retried_trans, buff, 10); - pthread_mutex_unlock(&active_mi->rli.data_lock); - } - pthread_mutex_unlock(&LOCK_active_mi); - break; - } - case SHOW_SLAVE_SKIP_ERRORS: - { - MY_BITMAP *bitmap= (MY_BITMAP *)value; - if (!use_slave_mask || bitmap_is_clear_all(bitmap)) - { - end= strmov(buff, "OFF"); - } - else if (bitmap_is_set_all(bitmap)) - { - end= strmov(buff, "ALL"); - } - else - { - /* 10 is enough assuming errors are max 4 digits */ - int i; - for (i= 1; - i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10; - i++) - { - if (bitmap_is_set(bitmap, i)) - { - end= int10_to_str(i, (char*) end, 10); - *(char*) end++= ','; - } - } - if (end != buff) - end--; // Remove last ',' - if (i < MAX_SLAVE_ERROR) - end= strmov((char*) end, "..."); // Couldn't show all errors - } - break; - } -#endif /* HAVE_REPLICATION */ - case SHOW_OPEN_TABLES: - end= int10_to_str((long) cached_open_tables(), buff, 10); - break; - case SHOW_TABLE_DEFINITIONS: - end= int10_to_str((long) cached_table_definitions(), buff, 10); - break; case SHOW_CHAR_PTR: { if (!(pos= *(char**) value)) @@ -1682,200 +1622,16 @@ static bool show_status_array(THD *thd, const char *wild, end= strend(pos); break; } - case SHOW_DOUBLE_STATUS: - { - value= ((char *) status_var + (ulong) value); - end= buff + sprintf(buff, "%f", *(double*) value); - break; - } -#ifdef HAVE_OPENSSL - /* First group - functions relying on CTX */ - case SHOW_SSL_CTX_SESS_ACCEPT: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_accept(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_ACCEPT_GOOD: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_accept_good(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_CONNECT_GOOD: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_connect_good(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd-> ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_CB_HITS: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_cb_hits(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_HITS: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_hits(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_CACHE_FULL: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_cache_full(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_MISSES: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_misses(ssl_acceptor_fd-> - ssl_context)), - buff, 10); - break; - case SHOW_SSL_CTX_SESS_TIMEOUTS: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_SESS_NUMBER: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_SESS_CONNECT: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_GET_VERIFY_MODE: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_GET_VERIFY_DEPTH: - end= int10_to_str((long) (!ssl_acceptor_fd ? 0 : - SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)), - buff,10); - break; - case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE: - if (!ssl_acceptor_fd) - { - pos= "NONE"; - end= pos+4; - break; - } - switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context)) - { - case SSL_SESS_CACHE_OFF: - pos= "OFF"; - break; - case SSL_SESS_CACHE_CLIENT: - pos= "CLIENT"; - break; - case SSL_SESS_CACHE_SERVER: - pos= "SERVER"; - break; - case SSL_SESS_CACHE_BOTH: - pos= "BOTH"; - break; - case SSL_SESS_CACHE_NO_AUTO_CLEAR: - pos= "NO_AUTO_CLEAR"; - break; - case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: - pos= "NO_INTERNAL_LOOKUP"; - break; - default: - pos= "Unknown"; - break; - } - end= strend(pos); - break; - /* First group - functions relying on SSL */ - case SHOW_SSL_GET_VERSION: - pos= (thd->net.vio->ssl_arg ? - SSL_get_version((SSL*) thd->net.vio->ssl_arg) : ""); - end= strend(pos); - break; - case SHOW_SSL_SESSION_REUSED: - end= int10_to_str((long) (thd->net.vio->ssl_arg ? - SSL_session_reused((SSL*) thd->net.vio-> - ssl_arg) : - 0), - buff, 10); - break; - case SHOW_SSL_GET_DEFAULT_TIMEOUT: - end= int10_to_str((long) (thd->net.vio->ssl_arg ? - SSL_get_default_timeout((SSL*) thd->net.vio-> - ssl_arg) : - 0), - buff, 10); - break; - case SHOW_SSL_GET_VERIFY_MODE: - end= int10_to_str((long) (thd->net.vio->ssl_arg ? - SSL_get_verify_mode((SSL*) thd->net.vio-> - ssl_arg): - 0), - buff, 10); - break; - case SHOW_SSL_GET_VERIFY_DEPTH: - end= int10_to_str((long) (thd->net.vio->ssl_arg ? - SSL_get_verify_depth((SSL*) thd->net.vio-> - ssl_arg): - 0), - buff, 10); - break; - case SHOW_SSL_GET_CIPHER: - pos= (thd->net.vio->ssl_arg ? - SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : "" ); - end= strend(pos); - break; - case SHOW_SSL_GET_CIPHER_LIST: - if (thd->net.vio->ssl_arg) - { - char *to= buff; - for (int i=0 ; i++ ;) - { - const char *p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i); - if (p == NULL) - break; - to= strmov(to, p); - *to++= ':'; - } - if (to != buff) - to--; // Remove last ':' - end= to; - } - break; - -#endif /* HAVE_OPENSSL */ case SHOW_KEY_CACHE_LONG: case SHOW_KEY_CACHE_CONST_LONG: - value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache; + value= (char*) dflt_key_cache + (ulong)value; end= int10_to_str(*(long*) value, buff, 10); break; case SHOW_KEY_CACHE_LONGLONG: - value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache; + value= (char*) dflt_key_cache + (ulong)value; end= longlong10_to_str(*(longlong*) value, buff, 10); break; - case SHOW_NET_COMPRESSION: - end= strmov(buff, thd->net.compress ? "ON" : "OFF"); - break; - case SHOW_UNDEF: // Show never happen + case SHOW_UNDEF: case SHOW_SYS: break; // Return empty string default: @@ -3615,7 +3371,6 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) const char *wild= lex->wild ? lex->wild->ptr() : NullS; int res= 0; STATUS_VAR tmp; - ha_update_statistics(); /* Export engines statistics */ pthread_mutex_lock(&LOCK_status); if (lex->option_type == OPT_GLOBAL) calc_sum_of_all_status(&tmp); diff --git a/sql/structs.h b/sql/structs.h index 85af73794ae..d16591c5453 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -173,29 +173,12 @@ typedef struct st_known_date_time_format { enum SHOW_TYPE { SHOW_UNDEF, - SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_DOUBLE_STATUS, SHOW_BOOL, SHOW_MY_BOOL, - SHOW_OPEN_TABLES, SHOW_TABLE_DEFINITIONS, SHOW_STARTTIME, SHOW_QUESTION, SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS, - SHOW_VARS, -#ifdef HAVE_OPENSSL - SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD, - SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE, - SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE, - SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED, - SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER, - SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE, - SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH, - SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT, - SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD, - SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES, - SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL, - SHOW_SSL_GET_CIPHER_LIST, -#endif /* HAVE_OPENSSL */ - SHOW_NET_COMPRESSION, - SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS, + SHOW_ARRAY, SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG, - SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS, SHOW_SLAVE_SKIP_ERRORS + SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS }; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; @@ -204,19 +187,19 @@ extern const char *show_comp_option_name[]; typedef int *(*update_var)(THD *, struct show_var_st *); - typedef struct show_var_st { const char *name; char *value; SHOW_TYPE type; } SHOW_VAR; +#define SHOW_VAR_FUNC_BUFF_SIZE 1024 +typedef int (*show_var_func)(THD *, struct show_var_st *, char *); typedef struct st_lex_user { LEX_STRING user, host, password; } LEX_USER; - /* This structure specifies the maximum amount of resources which can be consumed by each account. Zero value of a member means From 8ce6f3e6ca7fedd2142e784e9aeab72ec2e49951 Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Tue, 3 Jan 2006 14:25:19 +0400 Subject: [PATCH 11/49] Fix for bug#15533 crash, information_schema, function, view enable view prepared mode during getting metedata for I_S table --- mysql-test/r/information_schema.result | 16 ++++++++++++++++ mysql-test/t/information_schema.test | 23 +++++++++++++++++++++++ sql/sql_show.cc | 3 +++ 3 files changed, 42 insertions(+) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e8d343ad711..05f2118a8c7 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1074,3 +1074,19 @@ character_maximum_length character_octet_length 32 32 64 64 drop table t1; +CREATE TABLE t1 (f1 BIGINT, f2 VARCHAR(20), f3 BIGINT); +INSERT INTO t1 SET f1 = 1, f2 = 'Schoenenbourg', f3 = 1; +CREATE FUNCTION func2() RETURNS BIGINT RETURN 1; +CREATE FUNCTION func1() RETURNS BIGINT +BEGIN +RETURN ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS); +END// +CREATE VIEW v1 AS SELECT 1 FROM t1 +WHERE f3 = (SELECT func2 ()); +SELECT func1(); +func1() +1 +DROP TABLE t1; +DROP VIEW v1; +DROP FUNCTION func1; +DROP FUNCTION func2; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index b05798b781f..f835a7148a2 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -767,3 +767,26 @@ create table t1(f1 binary(32), f2 varbinary(64)); select character_maximum_length, character_octet_length from information_schema.columns where table_name='t1'; drop table t1; + +# +# Bug#15533 crash, information_schema, function, view +# +CREATE TABLE t1 (f1 BIGINT, f2 VARCHAR(20), f3 BIGINT); +INSERT INTO t1 SET f1 = 1, f2 = 'Schoenenbourg', f3 = 1; + +CREATE FUNCTION func2() RETURNS BIGINT RETURN 1; + +delimiter //; +CREATE FUNCTION func1() RETURNS BIGINT +BEGIN + RETURN ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.VIEWS); +END// +delimiter ;// + +CREATE VIEW v1 AS SELECT 1 FROM t1 + WHERE f3 = (SELECT func2 ()); +SELECT func1(); +DROP TABLE t1; +DROP VIEW v1; +DROP FUNCTION func1; +DROP FUNCTION func2; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1b31e8f7dc3..089314078a6 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2045,6 +2045,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) int error= 1; db_type not_used; Open_tables_state open_tables_state_backup; + bool save_view_prepare_mode= lex->view_prepare_mode; + lex->view_prepare_mode= TRUE; DBUG_ENTER("get_all_tables"); LINT_INIT(end); @@ -2230,6 +2232,7 @@ err: lex->derived_tables= derived_tables; lex->all_selects_list= old_all_select_lex; lex->query_tables_last= save_query_tables_last; + lex->view_prepare_mode= save_view_prepare_mode; *save_query_tables_last= 0; lex->sql_command= save_sql_command; DBUG_RETURN(error); From a410de984a4af158a35b80e0243b55c687f74f38 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Tue, 3 Jan 2006 23:37:29 +0100 Subject: [PATCH 12/49] BUG#16167: Disable mysqlslap test case until bug is fixed. --- mysql-test/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ef5bdefa1ed..ce5c8ac67f4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -18,10 +18,10 @@ ndb_cache_multi2: Bug #15004 func_group : Bug #15448 func_math : Bug #15448 group_min_max : Bug #15448 -#mysqlslap : Bug #15483 innodb_concurrent : Results are not deterministic, Elliot will fix (BUG#3300) subselect : Bug#15706 type_time : Bug#15805 #rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite sp_trans : Bug#15924 Code dump in RBR mode when executing test suite +mysqlslap : Bug#16167 From 3524b80092486c450366f60ff5b6b7dcc4c39742 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Wed, 4 Jan 2006 10:32:52 +0100 Subject: [PATCH 13/49] Avoid double slash (//) in socket paths, breaks on QNX. --- mysql-test/mysql-test-run.pl | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d64a487758d..2c53b94a248 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -804,6 +804,12 @@ sub command_line_setup () { } } + # On QNX, /tmp/dir/master.sock and /tmp/dir//master.sock seem to be + # considered different, so avoid the extra slash (/) in the socket + # paths. + my $sockdir = $opt_tmpdir; + $sockdir =~ s|/+$||; + # Put this into a hash, will be a C struct $master->[0]= @@ -812,7 +818,7 @@ sub command_line_setup () { path_myerr => "$opt_vardir/log/master.err", path_mylog => "$opt_vardir/log/master.log", path_mypid => "$opt_vardir/run/master.pid", - path_mysock => "$opt_tmpdir/master.sock", + path_mysock => "$sockdir/master.sock", path_myport => $opt_master_myport, start_timeout => 400, # enough time create innodb tables @@ -825,7 +831,7 @@ sub command_line_setup () { path_myerr => "$opt_vardir/log/master1.err", path_mylog => "$opt_vardir/log/master1.log", path_mypid => "$opt_vardir/run/master1.pid", - path_mysock => "$opt_tmpdir/master1.sock", + path_mysock => "$sockdir/master1.sock", path_myport => $opt_master_myport + 1, start_timeout => 400, # enough time create innodb tables }; @@ -836,7 +842,7 @@ sub command_line_setup () { path_myerr => "$opt_vardir/log/slave.err", path_mylog => "$opt_vardir/log/slave.log", path_mypid => "$opt_vardir/run/slave.pid", - path_mysock => "$opt_tmpdir/slave.sock", + path_mysock => "$sockdir/slave.sock", path_myport => $opt_slave_myport, start_timeout => 400, }; @@ -847,7 +853,7 @@ sub command_line_setup () { path_myerr => "$opt_vardir/log/slave1.err", path_mylog => "$opt_vardir/log/slave1.log", path_mypid => "$opt_vardir/run/slave1.pid", - path_mysock => "$opt_tmpdir/slave1.sock", + path_mysock => "$sockdir/slave1.sock", path_myport => $opt_slave_myport + 1, start_timeout => 300, }; @@ -858,7 +864,7 @@ sub command_line_setup () { path_myerr => "$opt_vardir/log/slave2.err", path_mylog => "$opt_vardir/log/slave2.log", path_mypid => "$opt_vardir/run/slave2.pid", - path_mysock => "$opt_tmpdir/slave2.sock", + path_mysock => "$sockdir/slave2.sock", path_myport => $opt_slave_myport + 2, start_timeout => 300, }; @@ -868,7 +874,7 @@ sub command_line_setup () { path_err => "$opt_vardir/log/im.err", path_log => "$opt_vardir/log/im.log", path_pid => "$opt_vardir/run/im.pid", - path_sock => "$opt_tmpdir/im.sock", + path_sock => "$sockdir/im.sock", port => $im_port, start_timeout => $master->[0]->{'start_timeout'}, admin_login => 'im_admin', @@ -883,7 +889,7 @@ sub command_line_setup () { server_id => 1, port => $im_mysqld1_port, path_datadir => "$opt_vardir/im_mysqld_1.data", - path_sock => "$opt_tmpdir/mysqld_1.sock", + path_sock => "$sockdir/mysqld_1.sock", path_pid => "$opt_vardir/run/mysqld_1.pid", }; @@ -892,7 +898,7 @@ sub command_line_setup () { server_id => 2, port => $im_mysqld2_port, path_datadir => "$opt_vardir/im_mysqld_2.data", - path_sock => "$opt_tmpdir/mysqld_2.sock", + path_sock => "$sockdir/mysqld_2.sock", path_pid => "$opt_vardir/run/mysqld_2.pid", nonguarded => 1, }; From 8241a5a8e89af766c43024c4920a1b5102948aed Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 4 Jan 2006 10:36:49 +0100 Subject: [PATCH 14/49] cleanup --- include/my_sys.h | 3 ++- mysys/my_once.c | 2 ++ plugin/fulltext/Makefile.am | 6 +++--- scripts/mysql_create_system_tables.sh | 8 ++++---- sql/sql_parse.cc | 17 +++++++---------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index d76098b8c29..39810e61de3 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -755,8 +755,9 @@ extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); extern void freeze_size(DYNAMIC_ARRAY *array); #define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element) #define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index)) -#define push_dynamic(A,B) insert_dynamic(A,B) +#define push_dynamic(A,B) insert_dynamic((A),(B)) #define reset_dynamic(array) ((array)->elements= 0) +#define sort_dynamic(A,cmp) qsort((A)->buffer, (A)->elements, (A)->size_of_element, (cmp)) extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str, uint init_alloc,uint alloc_increment); diff --git a/mysys/my_once.c b/mysys/my_once.c index ab5fcc51c0e..52f8c4309d5 100644 --- a/mysys/my_once.c +++ b/mysys/my_once.c @@ -75,6 +75,8 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags) point= (gptr) ((char*) next+ (next->size-next->left)); next->left-= Size; + if (MyFlags & MY_ZEROFILL) + bzero(point, Size); return(point); } /* my_once_alloc */ diff --git a/plugin/fulltext/Makefile.am b/plugin/fulltext/Makefile.am index 70c207a992f..0a3186829da 100644 --- a/plugin/fulltext/Makefile.am +++ b/plugin/fulltext/Makefile.am @@ -1,4 +1,4 @@ INCLUDES= -I$(top_builddir)/include -noinst_LTLIBRARIES= libmypluglib.la -libmypluglib_la_SOURCES= plugin_example.c -libmypluglib_la_LDFLAGS= -module +noinst_LTLIBRARIES= mypluglib.la +mypluglib_la_SOURCES= plugin_example.c +mypluglib_la_LDFLAGS= -module -rpath $(pkglibdir) diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index c6deb642edf..2529eaf1937 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -229,7 +229,7 @@ then c_t="$c_t User char(16) binary DEFAULT '' NOT NULL," c_t="$c_t Table_name char(64) binary DEFAULT '' NOT NULL," c_t="$c_t Grantor char(77) DEFAULT '' NOT NULL," - c_t="$c_t Timestamp timestamp(14)," + c_t="$c_t Timestamp timestamp," c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_t="$c_t Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_t="$c_t PRIMARY KEY (Host,Db,User,Table_name)," @@ -251,7 +251,7 @@ then c_c="$c_c User char(16) binary DEFAULT '' NOT NULL," c_c="$c_c Table_name char(64) binary DEFAULT '' NOT NULL," c_c="$c_c Column_name char(64) binary DEFAULT '' NOT NULL," - c_c="$c_c Timestamp timestamp(14)," + c_c="$c_c Timestamp timestamp," c_c="$c_c Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_c="$c_c PRIMARY KEY (Host,Db,User,Table_name,Column_name)" c_c="$c_c ) engine=MyISAM" @@ -273,7 +273,7 @@ then c_pp="$c_pp Routine_type enum('FUNCTION','PROCEDURE') NOT NULL," c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL," c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL," - c_pp="$c_pp Timestamp timestamp(14)," + c_pp="$c_pp Timestamp timestamp," c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name,Routine_type)," c_pp="$c_pp KEY Grantor (Grantor)" c_pp="$c_pp ) engine=MyISAM" @@ -743,7 +743,7 @@ fi cat << END_OF_DATA use mysql; -set table_type=myisam; +set storage_engine=myisam; $c_d $i_d diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 483a3540e47..2c72c52a05b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6642,17 +6642,14 @@ static void refresh_status(void) { pthread_mutex_lock(&LOCK_status); for (struct show_var_st *ptr=status_vars; ptr->name; ptr++) - { - if (ptr->type == SHOW_LONG) + if (ptr->type == SHOW_LONG) // note that SHOW_LONG_NOFLUSH variables are not reset *(ulong*) ptr->value= 0; - else if (ptr->type == SHOW_LONG_STATUS) - { - THD *thd= current_thd; - /* We must update the global status before cleaning up the thread */ - add_to_status(&global_status_var, &thd->status_var); - bzero((char*) &thd->status_var, sizeof(thd->status_var)); - } - } + + /* We must update the global status before cleaning up the thread */ + THD *thd= current_thd; + add_to_status(&global_status_var, &thd->status_var); + bzero((char*) &thd->status_var, sizeof(thd->status_var)); + /* Reset the counters of all key caches (default and named). */ process_key_caches(reset_key_cache_counters); pthread_mutex_unlock(&LOCK_status); From 3377014a3c4559562e04e689064e6f613f3ea4eb Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Wed, 4 Jan 2006 15:04:36 +0100 Subject: [PATCH 15/49] Post-merge fixes. --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3a816a62321..f7894beec6d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1991,7 +1991,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, INSERT INTO t1 VALUES (1), (foo()), (2); */ if (binlog_row_based) - thd->binlog_flush_pending_rows_event(false); + binlog_flush_pending_rows_event(false); if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !binlog_row_based) From 85575904fae96f54a6da456bc104ba5a503e573c Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Wed, 4 Jan 2006 15:25:32 +0100 Subject: [PATCH 16/49] BUG#14931: Temporarily add synchronization to avoid sporadic test failures until the bug is fixed. --- mysql-test/r/rpl_sp.result | 3 +++ mysql-test/t/rpl_sp.test | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 41bcfc7d72c..c9a9e162fa6 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -57,6 +57,9 @@ insert into t1 values (15); grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +SELECT 1; +1 +1 create procedure foo4() deterministic begin diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index 386582f8f1b..8fa330584e2 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -87,6 +87,14 @@ grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +# ToDo: BUG#14931: There is a race between the last grant binlogging, and +# the binlogging in the new connection made below, causing sporadic test +# failures due to switched statement order in binlog. To fix this we do +# SELECT 1 in the first connection before starting the second, ensuring +# that binlogging is done in the expected order. +# Please remove this SELECT 1 when BUG#14931 is fixed. +SELECT 1; + connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connection con1; From 6f6480b064c1d67cc2071d5f5fe335ec37614507 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Wed, 4 Jan 2006 15:25:51 +0100 Subject: [PATCH 17/49] BUG#14931: Temporarily add synchronization to avoid sporadic test failures until the bug is fixed. --- mysql-test/r/rpl_row_sp000.result | 3 +++ mysql-test/r/rpl_stm_sp.result | 3 +++ mysql-test/t/rpl_row_sp000.test | 8 ++++++++ mysql-test/t/rpl_stm_sp.test | 8 ++++++++ 4 files changed, 22 insertions(+) diff --git a/mysql-test/r/rpl_row_sp000.result b/mysql-test/r/rpl_row_sp000.result index a7f72193842..c02fdecf7fd 100644 --- a/mysql-test/r/rpl_row_sp000.result +++ b/mysql-test/r/rpl_row_sp000.result @@ -58,6 +58,9 @@ insert into t1 values (15); grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +SELECT 1; +1 +1 create procedure foo4() deterministic begin diff --git a/mysql-test/r/rpl_stm_sp.result b/mysql-test/r/rpl_stm_sp.result index 4fe0f61b550..1acb57f67d5 100644 --- a/mysql-test/r/rpl_stm_sp.result +++ b/mysql-test/r/rpl_stm_sp.result @@ -57,6 +57,9 @@ insert into t1 values (15); grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +SELECT 1; +1 +1 create procedure foo4() deterministic begin diff --git a/mysql-test/t/rpl_row_sp000.test b/mysql-test/t/rpl_row_sp000.test index e591cb054fc..4d638cfcc1c 100644 --- a/mysql-test/t/rpl_row_sp000.test +++ b/mysql-test/t/rpl_row_sp000.test @@ -82,6 +82,14 @@ grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +# ToDo: BUG#14931: There is a race between the last grant binlogging, and +# the binlogging in the new connection made below, causing sporadic test +# failures due to switched statement order in binlog. To fix this we do +# SELECT 1 in the first connection before starting the second, ensuring +# that binlogging is done in the expected order. +# Please remove this SELECT 1 when BUG#14931 is fixed. +SELECT 1; + connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connection con1; diff --git a/mysql-test/t/rpl_stm_sp.test b/mysql-test/t/rpl_stm_sp.test index 95c4543c952..62ea87e5352 100644 --- a/mysql-test/t/rpl_stm_sp.test +++ b/mysql-test/t/rpl_stm_sp.test @@ -90,6 +90,14 @@ grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; +# ToDo: BUG#14931: There is a race between the last grant binlogging, and +# the binlogging in the new connection made below, causing sporadic test +# failures due to switched statement order in binlog. To fix this we do +# SELECT 1 in the first connection before starting the second, ensuring +# that binlogging is done in the expected order. +# Please remove this SELECT 1 when BUG#14931 is fixed. +SELECT 1; + connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connection con1; From f7d6fa6f1733e64f202e517d7391c868a53b125a Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 4 Jan 2006 17:35:30 +0300 Subject: [PATCH 18/49] A fix for Bug#7209 "Client error with "Access Denied" on updates when high concurrency": remove HASH::current_record and make it an external search parameter, so that it can not be the cause of a race condition under high concurrent load. The bug was in a race condition in table_hash_search, when column_priv_hash.current_record was overwritten simultaneously by multiple threads, causing the search for a suitable grant record to fail. No test case as the bug is repeatable only under concurrent load. --- include/hash.h | 14 +++++++---- mysys/hash.c | 60 ++++++++++++++++++++++++++++-------------------- mysys/testhash.c | 9 ++++---- sql/lock.cc | 5 ++-- sql/sql_acl.cc | 9 ++++---- sql/sql_base.cc | 22 ++++++++++++------ sql/sql_cache.cc | 10 ++++---- 7 files changed, 79 insertions(+), 50 deletions(-) diff --git a/include/hash.h b/include/hash.h index 9a6d91036e1..8f5ff21ae5e 100644 --- a/include/hash.h +++ b/include/hash.h @@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *); typedef struct st_hash { uint key_offset,key_length; /* Length of key if const length */ - uint records,blength,current_record; + uint records, blength; uint flags; DYNAMIC_ARRAY array; /* Place for hash_keys */ hash_get_key get_key; @@ -41,6 +41,9 @@ typedef struct st_hash { CHARSET_INFO *charset; } HASH; +/* A search iterator state */ +typedef uint HASH_SEARCH_STATE; + #define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO) my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, uint default_array_elements, uint key_offset, @@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, void hash_free(HASH *tree); void my_hash_reset(HASH *hash); byte *hash_element(HASH *hash,uint idx); -gptr hash_search(HASH *info,const byte *key,uint length); -gptr hash_next(HASH *info,const byte *key,uint length); +gptr hash_search(const HASH *info, const byte *key, uint length); +gptr hash_first(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); +gptr hash_next(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); my_bool my_hash_insert(HASH *info,const byte *data); my_bool hash_delete(HASH *hash,byte *record); my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); -void hash_replace(HASH *hash, uint idx, byte *new_row); +void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row); my_bool hash_check(HASH *hash); /* Only in debug library */ #define hash_clear(H) bzero((char*) (H),sizeof(*(H))) diff --git a/mysys/hash.c b/mysys/hash.c index ffebdf76144..75135a470c9 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -36,9 +36,10 @@ typedef struct st_hash_info { static uint hash_mask(uint hashnr,uint buffmax,uint maxlength); static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink); -static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length); +static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key, + uint length); -static uint calc_hash(HASH *hash,const byte *key,uint length) +static uint calc_hash(const HASH *hash, const byte *key, uint length) { ulong nr1=1, nr2=4; hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2); @@ -63,7 +64,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, hash->key_offset=key_offset; hash->key_length=key_length; hash->blength=1; - hash->current_record= NO_RECORD; /* For the future */ hash->get_key=get_key; hash->free=free_element; hash->flags=flags; @@ -135,7 +135,6 @@ void my_hash_reset(HASH *hash) reset_dynamic(&hash->array); /* Set row pointers so that the hash can be reused at once */ hash->blength= 1; - hash->current_record= NO_RECORD; DBUG_VOID_RETURN; } @@ -147,7 +146,8 @@ void my_hash_reset(HASH *hash) */ static inline char* -hash_key(HASH *hash,const byte *record,uint *length,my_bool first) +hash_key(const HASH *hash, const byte *record, uint *length, + my_bool first) { if (hash->get_key) return (*hash->get_key)(record,length,first); @@ -163,8 +163,8 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength) return (hashnr & ((buffmax >> 1) -1)); } -static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, - uint maxlength) +static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos, + uint buffmax, uint maxlength) { uint length; byte *key= (byte*) hash_key(hash,pos->data,&length,0); @@ -186,14 +186,25 @@ unsigned int rec_hashnr(HASH *hash,const byte *record) } - /* Search after a record based on a key */ - /* Sets info->current_ptr to found record */ +gptr hash_search(const HASH *hash, const byte *key, uint length) +{ + HASH_SEARCH_STATE state; + return hash_first(hash, key, length, &state); +} -gptr hash_search(HASH *hash,const byte *key,uint length) +/* + Search after a record based on a key + + NOTE + Assigns the number of the found record to HASH_SEARCH_STATE state +*/ + +gptr hash_first(const HASH *hash, const byte *key, uint length, + HASH_SEARCH_STATE *current_record) { HASH_LINK *pos; uint flag,idx; - DBUG_ENTER("hash_search"); + DBUG_ENTER("hash_first"); flag=1; if (hash->records) @@ -206,7 +217,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length) if (!hashcmp(hash,pos,key,length)) { DBUG_PRINT("exit",("found key at %d",idx)); - hash->current_record= idx; + *current_record= idx; DBUG_RETURN (pos->data); } if (flag) @@ -218,31 +229,32 @@ gptr hash_search(HASH *hash,const byte *key,uint length) } while ((idx=pos->next) != NO_RECORD); } - hash->current_record= NO_RECORD; + *current_record= NO_RECORD; DBUG_RETURN(0); } /* Get next record with identical key */ /* Can only be called if previous calls was hash_search */ -gptr hash_next(HASH *hash,const byte *key,uint length) +gptr hash_next(const HASH *hash, const byte *key, uint length, + HASH_SEARCH_STATE *current_record) { HASH_LINK *pos; uint idx; - if (hash->current_record != NO_RECORD) + if (*current_record != NO_RECORD) { HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*); - for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next) + for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next) { pos=data+idx; if (!hashcmp(hash,pos,key,length)) { - hash->current_record= idx; + *current_record= idx; return pos->data; } } - hash->current_record=NO_RECORD; + *current_record= NO_RECORD; } return 0; } @@ -282,7 +294,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink) > 0 key of record > key */ -static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) +static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key, + uint length) { uint rec_keylength; byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1); @@ -308,7 +321,6 @@ my_bool my_hash_insert(HASH *info,const byte *record) if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array))) return(TRUE); /* No more memory */ - info->current_record= NO_RECORD; data=dynamic_element(&info->array,0,HASH_LINK*); halfbuff= info->blength >> 1; @@ -451,7 +463,6 @@ my_bool hash_delete(HASH *hash,byte *record) } if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1; - hash->current_record= NO_RECORD; lastpos=data+hash->records; /* Remove link to record */ @@ -544,7 +555,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length) if ((idx=pos->next) == NO_RECORD) DBUG_RETURN(1); /* Not found in links */ } - hash->current_record= NO_RECORD; org_link= *pos; empty=idx; @@ -594,10 +604,10 @@ byte *hash_element(HASH *hash,uint idx) isn't changed */ -void hash_replace(HASH *hash, uint idx, byte *new_row) +void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, byte *new_row) { - if (idx != NO_RECORD) /* Safety */ - dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row; + if (*current_record != NO_RECORD) /* Safety */ + dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row; } diff --git a/mysys/testhash.c b/mysys/testhash.c index 72badffdbcd..d15016113cd 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -74,7 +74,7 @@ static int do_test() bzero((char*) key1,sizeof(key1[0])*1000); printf("- Creating hash\n"); - if (hash_init(&hash,recant/2,0,6,0,free_record,0)) + if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0)) goto err; printf("- Writing records:\n"); @@ -172,15 +172,16 @@ static int do_test() break; if (key1[j] > 1) { + HASH_SEARCH_STATE state; printf("- Testing identical read\n"); sprintf(key,"%6d",j); pos=1; - if (!(recpos=hash_search(&hash,key,0))) + if (!(recpos= hash_first(&hash, key, 0, &state))) { printf("can't find key1: \"%s\"\n",key); goto err; } - while (hash_next(&hash,key,0) && pos < (ulong) (key1[j]+10)) + while (hash_next(&hash, key, 0, &state) && pos < (ulong) (key1[j]+10)) pos++; if (pos != (ulong) key1[j]) { @@ -189,7 +190,7 @@ static int do_test() } } printf("- Creating output heap-file 2\n"); - if (hash_init(&hash2,hash.records,0,0,hash2_key,free_record,0)) + if (hash_init(&hash2, default_charset_info, hash.records, 0, 0, hash2_key, free_record,0)) goto err; printf("- Copying and removing records\n"); diff --git a/sql/lock.cc b/sql/lock.cc index a571b7f8ee8..f65ce69bb80 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -641,6 +641,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) char key[MAX_DBKEY_LENGTH]; char *db= table_list->db; uint key_length; + HASH_SEARCH_STATE state; DBUG_ENTER("lock_table_name"); DBUG_PRINT("enter",("db: %s name: %s", db, table_list->real_name)); @@ -651,9 +652,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) /* Only insert the table if we haven't insert it already */ - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table=(TABLE*) hash_first(&open_cache, (byte*)key, key_length, &state); table ; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table = (TABLE*) hash_next(&open_cache, (byte*)key, key_length, &state)) if (table->in_use == thd) DBUG_RETURN(0); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0ee83424d9f..74f7a1dcf06 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1988,14 +1988,15 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, char helping [NAME_LEN*2+USERNAME_LENGTH+3]; uint len; GRANT_TABLE *grant_table,*found=0; + HASH_SEARCH_STATE state; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; - for (grant_table=(GRANT_TABLE*) hash_search(&column_priv_hash, - (byte*) helping, - len) ; + for (grant_table=(GRANT_TABLE*) hash_first(&column_priv_hash, + (byte*) helping, + len, &state) ; grant_table ; grant_table= (GRANT_TABLE*) hash_next(&column_priv_hash,(byte*) helping, - len)) + len, &state)) { if (exact) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8b1fa754929..c8443948a4a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -799,6 +799,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, reg1 TABLE *table; char key[MAX_DBKEY_LENGTH]; uint key_length; + HASH_SEARCH_STATE state; DBUG_ENTER("open_table"); /* find a unused table in the open table cache */ @@ -863,9 +864,11 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, /* close handler tables which are marked for flush */ mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, + &state); table && table->in_use ; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, + &state)) { if (table->version != refresh_version) { @@ -1236,12 +1239,14 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) { do { + HASH_SEARCH_STATE state; char *key= table->table_cache_key; uint key_length=table->key_length; - for (TABLE *search=(TABLE*) hash_search(&open_cache, - (byte*) key,key_length) ; + for (TABLE *search= (TABLE*) hash_first(&open_cache, (byte*) key, + key_length, &state); search ; - search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + search= (TABLE*) hash_next(&open_cache, (byte*) key, + key_length, &state)) { if (search->locked_by_flush || search->locked_by_name && wait_for_name_lock || @@ -2958,11 +2963,14 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; for (;;) { + HASH_SEARCH_STATE state; result= signalled= 0; - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, + &state); table; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, + &state)) { THD *in_use; table->version=0L; /* Free when thread is ready */ diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index b40257511f7..457478e90db 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2873,6 +2873,7 @@ my_bool Query_cache::move_by_type(byte **border, } case Query_cache_block::TABLE: { + HASH_SEARCH_STATE record_idx; DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block)); if (*border == 0) break; @@ -2890,7 +2891,7 @@ my_bool Query_cache::move_by_type(byte **border, byte *key; uint key_length; key=query_cache_table_get_key((byte*) block, &key_length, 0); - hash_search(&tables, (byte*) key, key_length); + hash_first(&tables, (byte*) key, key_length, &record_idx); block->destroy(); new_block->init(len); @@ -2924,7 +2925,7 @@ my_bool Query_cache::move_by_type(byte **border, /* Fix pointer to table name */ new_block->table()->table(new_block->table()->db() + tablename_offset); /* Fix hash to point at moved block */ - hash_replace(&tables, tables.current_record, (byte*) new_block); + hash_replace(&tables, &record_idx, (byte*) new_block); DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", len, (ulong) new_block, (ulong) *border)); @@ -2932,6 +2933,7 @@ my_bool Query_cache::move_by_type(byte **border, } case Query_cache_block::QUERY: { + HASH_SEARCH_STATE record_idx; DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block)); if (*border == 0) break; @@ -2949,7 +2951,7 @@ my_bool Query_cache::move_by_type(byte **border, byte *key; uint key_length; key=query_cache_query_get_key((byte*) block, &key_length, 0); - hash_search(&queries, (byte*) key, key_length); + hash_first(&queries, (byte*) key, key_length, &record_idx); // Move table of used tables memmove((char*) new_block->table(0), (char*) block->table(0), ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table))); @@ -3017,7 +3019,7 @@ my_bool Query_cache::move_by_type(byte **border, net->query_cache_query= (gptr) new_block; } /* Fix hash to point at moved block */ - hash_replace(&queries, queries.current_record, (byte*) new_block); + hash_replace(&queries, &record_idx, (byte*) new_block); DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", len, (ulong) new_block, (ulong) *border)); break; From f6b1f10707b75463dc0f1f2a64416feb2ac80432 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Wed, 4 Jan 2006 16:02:41 +0100 Subject: [PATCH 19/49] Fix QNX test abort in release builds and pushbuild, avoid killing our parent when we are not the process group leader. --- mysql-test/lib/mtr_process.pl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index b3a243444c1..4d88c9b3322 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -890,7 +890,14 @@ sub mtr_exit ($) { # cluck("Called mtr_exit()"); mtr_timer_stop_all($::glob_timers); local $SIG{HUP} = 'IGNORE'; - kill('HUP', -$$); + # ToDo: Signalling -$$ will only work if we are the process group + # leader (in fact on QNX it will signal our session group leader, + # which might be Do-compile or Pushbuild, causing tests to be + # aborted). So we only do it if we are the group leader. We might + # set ourselves as the group leader at startup (with + # POSIX::setpgrp(0,0)), but then care must be needed to always do + # proper child process cleanup. + kill('HUP', -$$) if $$ == getpgrp(); sleep 2; exit($code); } From 9e24aedea54f81b383e8436d5070bf46fe0a7090 Mon Sep 17 00:00:00 2001 From: "lars@mysql.com" <> Date: Wed, 4 Jan 2006 16:24:58 +0100 Subject: [PATCH 20/49] BUG#16188: Could not compile --- sql/sql_class.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f7894beec6d..853e8be6629 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1976,6 +1976,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, backup->client_capabilities= client_capabilities; backup->savepoints= transaction.savepoints; +#ifdef HAVE_ROW_BASED_REPLICATION /* For row-based replication and before executing a function/trigger, the pending rows event has to be flushed. The function/trigger @@ -1992,6 +1993,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, */ if (binlog_row_based) binlog_flush_pending_rows_event(false); +#endif /* HAVE_ROW_BASED_REPLICATION */ if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !binlog_row_based) From 5bacd5067f88bcf2ca440a93aae34f9fba5384b4 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Wed, 4 Jan 2006 16:33:06 +0100 Subject: [PATCH 21/49] Add yassl libs to libmysqlclient_r as well. Add a link to extra/yassl/include/openssl to inlude when compiling with yassl Similiar to readline) --- config/ac-macros/yassl.m4 | 4 +++- include/Makefile.am | 3 ++- libmysql_r/Makefile.am | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index 77208faee0c..b4160ad2a99 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -30,7 +30,9 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ ;; esac AC_SUBST([yassl_taocrypt_extra_cxxflags]) - + # Link extra/yassl/include/openssl subdir to include/ + yassl_h_ln_cmd="\$(LN) -s \$(top_srcdir)/extra/yassl/include/openssl openssl" + AC_SUBST(yassl_h_ln_cmd) else yassl_dir="" AC_MSG_RESULT(no) diff --git a/include/Makefile.am b/include/Makefile.am index 8ad63f088ac..12b8c301b8d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -33,7 +33,7 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \ mysql_version.h.in my_handler.h my_time.h decimal.h # mysql_version.h are generated -CLEANFILES = mysql_version.h my_config.h readline +CLEANFILES = mysql_version.h my_config.h readline openssl # Some include files that may be moved and patched by configure DISTCLEANFILES = sched.h $(CLEANFILES) @@ -41,6 +41,7 @@ DISTCLEANFILES = sched.h $(CLEANFILES) link_sources: -$(RM) -fr readline @readline_h_ln_cmd@ + @yassl_h_ln_cmd@ my_config.h: ../config.h $(CP) ../config.h my_config.h diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am index ee6dd4cfded..11e65a28a19 100644 --- a/libmysql_r/Makefile.am +++ b/libmysql_r/Makefile.am @@ -22,7 +22,7 @@ target = libmysqlclient_r.la target_defs = -DDONT_USE_RAID -DMYSQL_CLIENT @LIB_EXTRA_CCFLAGS@ -LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@ @yassl_libs@ +LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) $(yassl_includes) @ZLIB_INCLUDES@ @@ -32,7 +32,7 @@ include $(top_srcdir)/libmysql/Makefile.shared libmysql_dir = $(top_srcdir)/libmysql libmysqlclient_r_la_SOURCES = $(target_sources) -libmysqlclient_r_la_LIBADD = $(target_libadd) +libmysqlclient_r_la_LIBADD = $(target_libadd) $(yassl_libs_with_path) libmysqlclient_r_la_LDFLAGS = $(target_ldflags) # This is called from the toplevel makefile From f13dff7a72f309748f0b687a88421ee67e9239e7 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Wed, 4 Jan 2006 16:38:54 +0100 Subject: [PATCH 22/49] EADDRINUSE is not defined on Windows. --- include/my_global.h | 3 +++ sql/mysqld.cc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/my_global.h b/include/my_global.h index e62f6c269aa..0df9ac78eb2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -862,6 +862,7 @@ typedef off_t os_off_t; #define SOCKET_EAGAIN WSAEINPROGRESS #define SOCKET_ETIMEDOUT WSAETIMEDOUT #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK +#define SOCKET_EADDRINUSE WSAEADDRINUSE #define SOCKET_ENFILE ENFILE #define SOCKET_EMFILE EMFILE #elif defined(OS2) @@ -870,6 +871,7 @@ typedef off_t os_off_t; #define SOCKET_EAGAIN SOCEINPROGRESS #define SOCKET_ETIMEDOUT SOCKET_EINTR #define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK +#define SOCKET_EADDRINUSE SOCEADDRINUSE #define SOCKET_ENFILE SOCENFILE #define SOCKET_EMFILE SOCEMFILE #define closesocket(A) soclose(A) @@ -880,6 +882,7 @@ typedef off_t os_off_t; #define SOCKET_EAGAIN EAGAIN #define SOCKET_ETIMEDOUT SOCKET_EINTR #define SOCKET_EWOULDBLOCK EWOULDBLOCK +#define SOCKET_EADDRINUSE EADDRINUSE #define SOCKET_ENFILE ENFILE #define SOCKET_EMFILE EMFILE #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 14cbaf28ae3..8934b872c94 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1401,7 +1401,7 @@ static void network_init(void) { if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), sizeof(IPaddr))) >= 0) || - (socket_errno != EADDRINUSE) || + (socket_errno != SOCKET_EADDRINUSE) || (waited >= mysqld_port_timeout)) break; sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port); From 4a4b8eacc1b5791ff53c6c596bb756c6d690d38c Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 4 Jan 2006 21:39:39 +0300 Subject: [PATCH 23/49] Post-merge fixes. --- sql/sql_acl.cc | 1 - sql/sql_base.cc | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 22fecda2599..66a1b1f9b11 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2245,7 +2245,6 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, uint len; GRANT_NAME *grant_name,*found=0; HASH_SEARCH_STATE state; - GRANT_TABLE *grant_table,*found=0; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; for (grant_name= (GRANT_NAME*) hash_first(name_hash, (byte*) helping, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 290f16a09d6..0b414f59223 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1624,7 +1624,8 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) { char *key= table->s->table_cache_key; uint key_length= table->s->key_length; - for (TABLE *search= (TABLE*) hash_search(&open_cache, (byte*) key, + HASH_SEARCH_STATE state; + for (TABLE *search= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, &state); search ; search= (TABLE*) hash_next(&open_cache, (byte*) key, From da8030ff7a752ee84f0ba31621e14f07ac161e20 Mon Sep 17 00:00:00 2001 From: "paul@snake-hub.snake.net" <> Date: Wed, 4 Jan 2006 13:37:59 -0600 Subject: [PATCH 24/49] mysqlbinlog.cc: Put options in standard order: help first, then lexically, then variables. --- client/mysqlbinlog.cc | 52 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 6ecbb6802c7..d86e3a44746 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -663,7 +663,8 @@ end: static struct my_option my_long_options[] = { - + {"help", '?', "Display this help and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -683,13 +684,13 @@ static struct my_option my_long_options[] = {"character-sets-dir", OPT_CHARSETS_DIR, "Directory where character sets are.", (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"database", 'd', "List entries for just this database (local log only).", + (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"database", 'd', "List entries for just this database (local log only).", - (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, {"disable-log-bin", 'D', "Disable binary log. This is useful, if you " "enabled --to-last-log and are sending the output to the same MySQL server. " "This way you could avoid an endless loop. You would also like to use it " @@ -700,13 +701,14 @@ static struct my_option my_long_options[] = {"force-read", 'f', "Force reading unknown binlog events.", (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"hexdump", 'H', "Augment output with hexadecimal and ASCII event dump.", (gptr*) &opt_hexdump, (gptr*) &opt_hexdump, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.", + (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0, + GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to connect to remote server.", @@ -722,15 +724,15 @@ static struct my_option my_long_options[] = {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"read-from-remote-server", 'R', "Read binary logs from a MySQL server", (gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"open_files_limit", OPT_OPEN_FILES_LIMIT, - "Used to reserve file descriptors for usage by this program", - (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, - REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"server-id", OPT_SERVER_ID, + "Extract only binlog entries created by the server having the given id.", + (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"short-form", 's', "Just show the queries, no extra info.", (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -745,6 +747,13 @@ static struct my_option my_long_options[] = "(you should probably use quotes for your shell to set it properly).", (gptr*) &start_datetime_str, (gptr*) &start_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"start-position", OPT_START_POSITION, + "Start reading the binlog at position N. Applies to the first binlog " + "passed on the command line.", + (gptr*) &start_position, (gptr*) &start_position, 0, GET_ULL, + REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE, + /* COM_BINLOG_DUMP accepts only 4 bytes for the position */ + (ulonglong)(~(uint32)0), 0, 0, 0}, {"stop-datetime", OPT_STOP_DATETIME, "Stop reading the binlog at first event having a datetime equal or " "posterior to the argument; the argument must be a date and time " @@ -753,24 +762,12 @@ static struct my_option my_long_options[] = "(you should probably use quotes for your shell to set it properly).", (gptr*) &stop_datetime_str, (gptr*) &stop_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"start-position", OPT_START_POSITION, - "Start reading the binlog at position N. Applies to the first binlog " - "passed on the command line.", - (gptr*) &start_position, (gptr*) &start_position, 0, GET_ULL, - REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE, - /* COM_BINLOG_DUMP accepts only 4 bytes for the position */ - (ulonglong)(~(uint32)0), 0, 0, 0}, {"stop-position", OPT_STOP_POSITION, "Stop reading the binlog at position N. Applies to the last binlog " "passed on the command line.", (gptr*) &stop_position, (gptr*) &stop_position, 0, GET_ULL, REQUIRED_ARG, (ulonglong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, (ulonglong)(~(my_off_t)0), 0, 0, 0}, - {"server-id", OPT_SERVER_ID, - "Only extract binlog entries created by a certain server id " - "passed on the command line.", - (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"to-last-log", 't', "Requires -R. Will not stop at the end of the \ requested binlog but rather continue printing until the end of the last \ binlog of the MySQL server. If you send the output to the same MySQL server, \ @@ -780,11 +777,12 @@ that may lead to an endless loop.", {"user", 'u', "Connect to the remote server as username.", (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.", - (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0, - GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"open_files_limit", OPT_OPEN_FILES_LIMIT, + "Used to reserve file descriptors for usage by this program", + (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, + REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; From ebe0b0b8b3c0dfb71294b3b35cfd95f7a48f45b3 Mon Sep 17 00:00:00 2001 From: "paul@snake-hub.snake.net" <> Date: Wed, 4 Jan 2006 13:43:21 -0600 Subject: [PATCH 25/49] set_var.cc: Fix out of order system variable. --- sql/set_var.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/set_var.cc b/sql/set_var.cc index 01ff30045c4..7468e4aadf7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -695,9 +695,9 @@ struct show_var_st init_vars[]= { {sys_have_partition_db.name,(char*) &have_partition_db, SHOW_HAVE}, {sys_have_query_cache.name, (char*) &have_query_cache, SHOW_HAVE}, {sys_have_raid.name, (char*) &have_raid, SHOW_HAVE}, + {sys_have_row_based_replication.name, (char*) &have_row_based_replication, SHOW_HAVE}, {sys_have_rtree_keys.name, (char*) &have_rtree_keys, SHOW_HAVE}, {sys_have_symlink.name, (char*) &have_symlink, SHOW_HAVE}, - {sys_have_row_based_replication.name, (char*) &have_row_based_replication, SHOW_HAVE}, {"init_connect", (char*) &sys_init_connect, SHOW_SYS}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, {"init_slave", (char*) &sys_init_slave, SHOW_SYS}, From 32b19cd1eca74876b8f5f8500ba08676ebff4233 Mon Sep 17 00:00:00 2001 From: "jmiller@mysql.com" <> Date: Thu, 5 Jan 2006 03:56:22 +0100 Subject: [PATCH 26/49] New rbr blob test requested by Lars --- mysql-test/extra/rpl_tests/rpl_row_blob.test | 179 +++++++++++++++++++ mysql-test/r/rpl_row_blob_innodb.result | 159 ++++++++++++++++ mysql-test/r/rpl_row_blob_myisam.result | 159 ++++++++++++++++ mysql-test/t/rpl_row_blob_innodb.test | 7 + mysql-test/t/rpl_row_blob_myisam.test | 6 + 5 files changed, 510 insertions(+) create mode 100644 mysql-test/extra/rpl_tests/rpl_row_blob.test create mode 100644 mysql-test/r/rpl_row_blob_innodb.result create mode 100644 mysql-test/r/rpl_row_blob_myisam.result create mode 100644 mysql-test/t/rpl_row_blob_innodb.test create mode 100644 mysql-test/t/rpl_row_blob_myisam.test diff --git a/mysql-test/extra/rpl_tests/rpl_row_blob.test b/mysql-test/extra/rpl_tests/rpl_row_blob.test new file mode 100644 index 00000000000..5f1e4bea6f3 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_row_blob.test @@ -0,0 +1,179 @@ +################################################# +# Author: JBM +# Date: 2006-01-06 +# Purpose: Test test that BLOBs are replicated +# correctly. +################################################ + +# Includes +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +# Pre test clean up section +connection master; +--disable_warnings +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +--enable_warnings + +# Start test section +--echo ***** Table Create Section **** +--echo +--disable_warnings +--replace_result $engine_type engine_type +CREATE TABLE test.t1 (c1 int not null auto_increment, +data LONGBLOB, PRIMARY KEY(c1))ENGINE=$engine_type; +--enable_warnings +--echo + +--echo **** Data Insert Section test.t1 ***** +--echo +INSERT INTO test.t1 VALUES (NULL, NULL); +INSERT INTO test.t1 VALUES (NULL, repeat('a',1*1024)); +INSERT INTO test.t1 VALUES (NULL, repeat('b',16*1024)); +CHECK TABLE test.t1; +--echo + +--echo **** Data Insert Validation Master Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Insert Validation Slave Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +connection master; +--echo + +--echo **** Data Update Section test.t1 **** +--echo +UPDATE test.t1 set data=repeat('a',18*1024) where c1 = 1; +UPDATE t1 set data=repeat('c',17*1024) where c1 = 2; +--echo + +--echo **** Data Update Validation Master Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Update Validation Slave Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +connection master; +--echo +--echo **** End Test Section test.t1 **** +--echo + +--echo **** Create Table test.t2 **** +--echo +--disable_warnings +--replace_result $engine_type engine_type +CREATE TABLE test.t2 ( + c1 INT NOT NULL PRIMARY KEY, + c2 TEXT, + c3 INT, + c4 LONGBLOB, + KEY(c3))ENGINE=$engine_type; +--enable_warnings +--echo + +--echo *** Setup Values For test.t2 *** +# x0 size 256 (current inline size) +set @x0 = '01234567012345670123456701234567'; +set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0); + +# b1 length 2000+256 (blob part aligned) +set @b1 = 'b1'; +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@x0); +# d1 length 3000 +set @d1 = 'dd1'; +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); + +# b2 length 20000 +set @b2 = 'b2'; +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); + +# d2 length 30000 +set @d2 = 'dd2'; +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +--echo + +--echo **** Data Insert Section test.t2 ***** +--echo +INSERT INTO test.t2 VALUES(1,@b1,111,@d1); +INSERT INTO test.t2 VALUES(2,@b2,222,@d2); +--echo + +--echo **** Data Insert Validation Master Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Insert Validation Slave Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +connection master; +--echo + +--echo **** Data Update Section test.t2 **** +--echo +UPDATE test.t2 SET c2=@b2, c4=@d2 WHERE c1=1; +UPDATE test.t2 SET c2=@b1, c4=@d1 WHERE c1=2; +--echo + +--echo **** Data Update Validation Master Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Update Validation Slave Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +connection master; +--echo + +# Post test clean up section +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/rpl_row_blob_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/rpl_row_blob_slave.sql + +--exec diff ./var/tmp/rpl_row_blob_master.sql ./var/tmp/rpl_row_blob_slave.sql + +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; diff --git a/mysql-test/r/rpl_row_blob_innodb.result b/mysql-test/r/rpl_row_blob_innodb.result new file mode 100644 index 00000000000..92671f10ab9 --- /dev/null +++ b/mysql-test/r/rpl_row_blob_innodb.result @@ -0,0 +1,159 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +***** Table Create Section **** + +CREATE TABLE test.t1 (c1 int not null auto_increment, +data LONGBLOB, PRIMARY KEY(c1))ENGINE=$engine_type; + +**** Data Insert Section test.t1 ***** + +INSERT INTO test.t1 VALUES (NULL, NULL); +INSERT INTO test.t1 VALUES (NULL, repeat('a',1*1024)); +INSERT INTO test.t1 VALUES (NULL, repeat('b',16*1024)); +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK + +**** Data Insert Validation Master Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +NULL +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +1024 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +LENGTH(data) +16384 + +**** Data Insert Validation Slave Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +NULL +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +1024 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +LENGTH(data) +16384 + +**** Data Update Section test.t1 **** + +UPDATE test.t1 set data=repeat('a',18*1024) where c1 = 1; +UPDATE t1 set data=repeat('c',17*1024) where c1 = 2; + +**** Data Update Validation Master Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +18432 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +17408 + +**** Data Update Validation Slave Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +18432 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +17408 + +**** End Test Section test.t1 **** + +**** Create Table test.t2 **** + +CREATE TABLE test.t2 ( +c1 INT NOT NULL PRIMARY KEY, +c2 TEXT, +c3 INT, +c4 LONGBLOB, +KEY(c3))ENGINE=$engine_type; + +*** Setup Values For test.t2 *** +set @x0 = '01234567012345670123456701234567'; +set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0); +set @b1 = 'b1'; +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@x0); +set @d1 = 'dd1'; +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @b2 = 'b2'; +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @d2 = 'dd2'; +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); + +**** Data Insert Section test.t2 ***** + +INSERT INTO test.t2 VALUES(1,@b1,111,@d1); +INSERT INTO test.t2 VALUES(2,@b2,222,@d2); + +**** Data Insert Validation Master Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 2256 b1 3000 dd1 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 20000 b2 30000 dd2 + +**** Data Insert Validation Slave Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 2256 b1 3000 dd1 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 20000 b2 30000 dd2 + +**** Data Update Section test.t2 **** + +UPDATE test.t2 SET c2=@b2, c4=@d2 WHERE c1=1; +UPDATE test.t2 SET c2=@b1, c4=@d1 WHERE c1=2; + +**** Data Update Validation Master Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 20000 b2 30000 dd2 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 2256 b1 3000 dd1 + +**** Data Update Validation Slave Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 20000 b2 30000 dd2 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 2256 b1 3000 dd1 + +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; diff --git a/mysql-test/r/rpl_row_blob_myisam.result b/mysql-test/r/rpl_row_blob_myisam.result new file mode 100644 index 00000000000..92671f10ab9 --- /dev/null +++ b/mysql-test/r/rpl_row_blob_myisam.result @@ -0,0 +1,159 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +***** Table Create Section **** + +CREATE TABLE test.t1 (c1 int not null auto_increment, +data LONGBLOB, PRIMARY KEY(c1))ENGINE=$engine_type; + +**** Data Insert Section test.t1 ***** + +INSERT INTO test.t1 VALUES (NULL, NULL); +INSERT INTO test.t1 VALUES (NULL, repeat('a',1*1024)); +INSERT INTO test.t1 VALUES (NULL, repeat('b',16*1024)); +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK + +**** Data Insert Validation Master Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +NULL +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +1024 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +LENGTH(data) +16384 + +**** Data Insert Validation Slave Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +NULL +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +1024 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +LENGTH(data) +16384 + +**** Data Update Section test.t1 **** + +UPDATE test.t1 set data=repeat('a',18*1024) where c1 = 1; +UPDATE t1 set data=repeat('c',17*1024) where c1 = 2; + +**** Data Update Validation Master Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +18432 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +17408 + +**** Data Update Validation Slave Section test.t1 **** + +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +LENGTH(data) +18432 +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +LENGTH(data) +17408 + +**** End Test Section test.t1 **** + +**** Create Table test.t2 **** + +CREATE TABLE test.t2 ( +c1 INT NOT NULL PRIMARY KEY, +c2 TEXT, +c3 INT, +c4 LONGBLOB, +KEY(c3))ENGINE=$engine_type; + +*** Setup Values For test.t2 *** +set @x0 = '01234567012345670123456701234567'; +set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0); +set @b1 = 'b1'; +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@x0); +set @d1 = 'dd1'; +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @b2 = 'b2'; +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @d2 = 'dd2'; +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); + +**** Data Insert Section test.t2 ***** + +INSERT INTO test.t2 VALUES(1,@b1,111,@d1); +INSERT INTO test.t2 VALUES(2,@b2,222,@d2); + +**** Data Insert Validation Master Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 2256 b1 3000 dd1 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 20000 b2 30000 dd2 + +**** Data Insert Validation Slave Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 2256 b1 3000 dd1 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 20000 b2 30000 dd2 + +**** Data Update Section test.t2 **** + +UPDATE test.t2 SET c2=@b2, c4=@d2 WHERE c1=1; +UPDATE test.t2 SET c2=@b1, c4=@d1 WHERE c1=2; + +**** Data Update Validation Master Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 20000 b2 30000 dd2 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 2256 b1 3000 dd1 + +**** Data Update Validation Slave Section test.t2 **** + +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +1 20000 b2 30000 dd2 +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +c1 LENGTH(c2) SUBSTR(c2,1+2*900,2) LENGTH(c4) SUBSTR(c4,1+3*900,3) +2 2256 b1 3000 dd1 + +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; diff --git a/mysql-test/t/rpl_row_blob_innodb.test b/mysql-test/t/rpl_row_blob_innodb.test new file mode 100644 index 00000000000..b6832010e22 --- /dev/null +++ b/mysql-test/t/rpl_row_blob_innodb.test @@ -0,0 +1,7 @@ +################################# +# Wrapper for rpl_row_blob.test# +################################# +-- source include/have_innodb.inc +let $engine_type=INNODB; +-- source extra/rpl_tests/rpl_row_blob.test + diff --git a/mysql-test/t/rpl_row_blob_myisam.test b/mysql-test/t/rpl_row_blob_myisam.test new file mode 100644 index 00000000000..2914aa7b348 --- /dev/null +++ b/mysql-test/t/rpl_row_blob_myisam.test @@ -0,0 +1,6 @@ +################################# +# Wrapper for rpl_row_blob.test# +################################# +let $engine_type=myisam; +-- source extra/rpl_tests/rpl_row_blob.test + From 9bf1e22b4cbdedd5d87b8d7dd76ea7e634c694f6 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Thu, 5 Jan 2006 11:18:26 +0300 Subject: [PATCH 27/49] Fix -ansi -pedantic compile --- sql/item_xmlfunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 79a5c8e6445..bb5775780fa 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -715,7 +715,7 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str) ((XPathFilter*)str)->append_element(flt->num, pos++); } return str; -}; +} String *Item_nodeset_func_elementbyindex::val_nodeset(String *nodeset) From e46dab62c1f42e93f4f0f63dbe1a7bd621a3421b Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Thu, 5 Jan 2006 10:52:58 +0100 Subject: [PATCH 28/49] Bug#15923 (Test ps_7ndb cause master crash): Always logging statements of the form "DELETE FROM x" statement-based. --- .../r/binlog_row_mix_innodb_myisam.result | 33 ++++++++++--------- mysql-test/t/disabled.def | 2 +- sql/sql_delete.cc | 28 ++++++++++++---- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/binlog_row_mix_innodb_myisam.result b/mysql-test/r/binlog_row_mix_innodb_myisam.result index 3a26d84d575..b444d7a3edc 100644 --- a/mysql-test/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/r/binlog_row_mix_innodb_myisam.result @@ -262,21 +262,22 @@ master-bin.000001 209 Write_rows 1 # master-bin.000001 243 Table_map 1 # test.t1 master-bin.000001 282 Write_rows 1 # master-bin.000001 316 Xid 1 # COMMIT /* xid= */ -master-bin.000001 343 Table_map 1 # test.t1 -master-bin.000001 382 Delete_rows 1 # -master-bin.000001 421 Xid 1 # COMMIT /* xid= */ -master-bin.000001 448 Query 1 # use `test`; alter table t2 type=MyISAM -master-bin.000001 537 Table_map 1 # test.t1 -master-bin.000001 576 Write_rows 1 # -master-bin.000001 610 Xid 1 # COMMIT /* xid= */ -master-bin.000001 637 Table_map 1 # test.t2 -master-bin.000001 676 Write_rows 1 # -master-bin.000001 710 Query 1 # use `test`; drop table t1,t2 -master-bin.000001 789 Query 1 # use `test`; create table t0 (n int) -master-bin.000001 875 Table_map 1 # test.t0 -master-bin.000001 914 Write_rows 1 # -master-bin.000001 948 Table_map 1 # test.t0 -master-bin.000001 987 Write_rows 1 # -master-bin.000001 1021 Query 1 # use `test`; create table t2 (n int) engine=innodb +master-bin.000001 343 Query 1 # use `test`; delete from t1 +master-bin.000001 420 Xid 1 # COMMIT /* xid= */ +master-bin.000001 447 Query 1 # use `test`; delete from t2 +master-bin.000001 524 Xid 1 # COMMIT /* xid= */ +master-bin.000001 551 Query 1 # use `test`; alter table t2 type=MyISAM +master-bin.000001 640 Table_map 1 # test.t1 +master-bin.000001 679 Write_rows 1 # +master-bin.000001 713 Xid 1 # COMMIT /* xid= */ +master-bin.000001 740 Table_map 1 # test.t2 +master-bin.000001 779 Write_rows 1 # +master-bin.000001 813 Query 1 # use `test`; drop table t1,t2 +master-bin.000001 892 Query 1 # use `test`; create table t0 (n int) +master-bin.000001 978 Table_map 1 # test.t0 +master-bin.000001 1017 Write_rows 1 # +master-bin.000001 1051 Table_map 1 # test.t0 +master-bin.000001 1090 Write_rows 1 # +master-bin.000001 1124 Query 1 # use `test`; create table t2 (n int) engine=innodb do release_lock("lock1"); drop table t0,t2; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ef5bdefa1ed..95e7a962eab 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -23,5 +23,5 @@ innodb_concurrent : Results are not deterministic, Elliot will fix (BUG#3300) subselect : Bug#15706 type_time : Bug#15805 #rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR -ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite +#ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite sp_trans : Bug#15924 Code dump in RBR mode when executing test suite diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ba1cce3abfe..c5b5958140b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -40,7 +40,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ha_rows deleted; uint usable_index= MAX_KEY; SELECT_LEX *select_lex= &thd->lex->select_lex; - bool ha_delete_row_bypassed= 0; + bool ha_delete_all_rows= 0; DBUG_ENTER("mysql_delete"); if (open_and_lock_tables(thd, table_list)) @@ -79,17 +79,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, !(table->triggers && table->triggers->has_delete_triggers())) { ha_rows const maybe_deleted= table->file->records; + ha_delete_all_rows= 1; if (!(error=table->file->delete_all_rows())) { error= -1; // ok deleted= maybe_deleted; - ha_delete_row_bypassed= 1; goto cleanup; } if (error != HA_ERR_WRONG_COMMAND) { table->file->print_error(error,MYF(0)); - ha_delete_row_bypassed= 1; error=0; goto cleanup; } @@ -200,6 +199,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, init_ftfuncs(thd, select_lex, 1); thd->proc_info="updating"; will_batch= !table->file->start_bulk_delete(); + + /* + Save the thread options before clearing the OPTION_BIN_LOG, + effectively disabling the binary log (unless it was already + disabled, of course). + */ + ulonglong const saved_options= thd->options; + if (ha_delete_all_rows) + thd->options&= ~static_cast(OPTION_BIN_LOG); + while (!(error=info.read_record(&info)) && !thd->killed && !thd->net.report_error) { @@ -290,6 +299,13 @@ cleanup: delete select; transactional_table= table->file->has_transactions(); + + /* + Restore the saved value of the OPTION_BIN_LOG bit in the thread + options before executing binlog_query() below. + */ + thd->options|= (saved_options & OPTION_BIN_LOG); + /* See similar binlogging code in sql_update.cc, for comments */ if ((error < 0) || (deleted && !transactional_table)) { @@ -304,9 +320,9 @@ cleanup: delete specific rows which we might log row-based. */ THD::enum_binlog_query_type const - query_type(ha_delete_row_bypassed ? - THD::STMT_QUERY_TYPE : - THD::ROW_QUERY_TYPE); + query_type(ha_delete_all_rows ? + THD::STMT_QUERY_TYPE : + THD::ROW_QUERY_TYPE); int log_result= thd->binlog_query(query_type, thd->query, thd->query_length, transactional_table, FALSE); From 46772f0c2ff0e8a432c2d8847c0eaa61671993cc Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Thu, 5 Jan 2006 14:17:05 +0100 Subject: [PATCH 29/49] Some header files were missing from "make dist". --- storage/csv/Makefile.am | 1 + storage/example/Makefile.am | 1 + 2 files changed, 2 insertions(+) diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am index 1d3c47bd650..f1802f4e5b0 100644 --- a/storage/csv/Makefile.am +++ b/storage/csv/Makefile.am @@ -29,6 +29,7 @@ WRAPLIBS= pkglib_LTLIBRARIES = ha_csv.la ha_csv_la_LDFLAGS = -module +noinst_HEADERS = ha_tina.h ha_csv_la_SOURCES = ha_tina.cc LDADD = diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am index d5896946c5b..efc0ede91e9 100644 --- a/storage/example/Makefile.am +++ b/storage/example/Makefile.am @@ -29,6 +29,7 @@ WRAPLIBS= pkglib_LTLIBRARIES = ha_example.la ha_example_la_LDFLAGS = -module +noinst_HEADERS = ha_example.h ha_example_la_SOURCES = ha_example.cc LDADD = From 71215d0cbcae549b23048641e437a04f1ee7de37 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Thu, 5 Jan 2006 23:39:45 +0100 Subject: [PATCH 30/49] Port to Win64/x64 in Visual Studio 2005 --- include/config-win.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 528bc8a8cdd..cebc4c8b82b 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -22,6 +22,11 @@ functions */ #define _WIN32_WINNT 0x0500 #endif +#if defined(_MSC_VER) && _MSC_VER >= 1400 +/* Avoid endless warnings about sprintf() etc. being unsafe. */ +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + #include #include #include /* Because of rint() */ @@ -325,6 +330,11 @@ inline double ulonglong2double(ulonglong value) #define HAVE_SETFILEPOINTER #define HAVE_VIO_READ_BUFF +#if defined(_WIN64) && defined(_M_X64) +/* Avoid type conflicts with built-in functions. */ +#define HAVE_STRNLEN +#endif + #ifndef __NT__ #undef FILE_SHARE_DELETE #define FILE_SHARE_DELETE 0 /* Not implemented on Win 98/ME */ From 6e22e29de669b95aefc4f5f7ce46420e52c99870 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 6 Jan 2006 00:47:49 +0200 Subject: [PATCH 31/49] Review fixes of new pushed code - Fixed tests - Optimized new code - Fixed some unlikely core dumps - Better bug fixes for: - #14397 - OPTIMIZE TABLE with an open HANDLER causes a crash - #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null --- mysql-test/r/create.result | 43 ++++++++++------ mysql-test/r/handler.result | 2 +- mysql-test/r/kill.result | 2 - mysql-test/r/mysqlshow.result | 2 +- mysql-test/r/trigger.result | 7 ++- mysql-test/r/view.result | 3 ++ mysql-test/t/create.test | 16 ++++++ mysql-test/t/disabled.def | 1 - mysql-test/t/handler.test | 2 +- mysql-test/t/kill.test | 13 +++-- mysql-test/t/mysqlshow.test | 2 +- mysql-test/t/trigger.test | 9 ++-- mysql-test/t/view.test | 1 + sql/field.cc | 4 +- sql/ha_federated.cc | 3 +- sql/ha_ndbcluster.cc | 22 +++++---- sql/item.cc | 6 +++ sql/item.h | 6 +-- sql/log_event.cc | 93 ++++++++++++++++++++--------------- sql/opt_range.cc | 14 ++++-- sql/parse_file.cc | 2 +- sql/sp.cc | 70 +++++++++++++------------- sql/sp_head.cc | 68 ++++++++++++++----------- sql/sp_head.h | 4 +- sql/sql_acl.cc | 2 +- sql/sql_base.cc | 1 - sql/sql_handler.cc | 35 +++---------- sql/sql_insert.cc | 6 ++- sql/sql_parse.cc | 12 ++--- sql/sql_select.cc | 2 +- sql/sql_trigger.cc | 32 +++++++----- 31 files changed, 269 insertions(+), 216 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index a201af78518..199fdd1eb5d 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -287,7 +287,6 @@ a b create table if not exists t1 select 3 as 'a',4 as 'b'; Warnings: Note 1050 Table 't1' already exists -Warning 1364 Field 'a' doesn't have a default value create table if not exists t1 select 3 as 'a',3 as 'b'; ERROR 23000: Duplicate entry '3' for key 1 select * from t1; @@ -645,8 +644,6 @@ create table t1 ( a varchar(112) charset utf8 collate utf8_bin not null, primary key (a) ) select 'test' as a ; -Warnings: -Warning 1364 Field 'a' doesn't have a default value show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -662,9 +659,6 @@ create table t1 ( a varchar(12) charset utf8 collate utf8_bin not null, b int not null, primary key (a) ) select a, 1 as b from t2 ; -Warnings: -Warning 1364 Field 'a' doesn't have a default value -Warning 1364 Field 'b' doesn't have a default value show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -674,12 +668,37 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int not null, primary key (a) +) select a, 1 as c from t2 ; +Warnings: +Warning 1364 Field 'b' doesn't have a default value +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) NOT NULL, + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL, + `c` bigint(1) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int null, primary key (a) +) select a, 1 as c from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `b` int(11) default NULL, + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL, + `c` bigint(1) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( a varchar(12) charset utf8 collate utf8_bin not null, b int not null, primary key (a) ) select 'a' as a , 1 as b from t2 ; -Warnings: -Warning 1364 Field 'a' doesn't have a default value -Warning 1364 Field 'b' doesn't have a default value show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -692,8 +711,6 @@ create table t1 ( a varchar(12) charset utf8 collate utf8_bin, b int not null, primary key (a) ) select 'a' as a , 1 as b from t2 ; -Warnings: -Warning 1364 Field 'b' doesn't have a default value show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -712,8 +729,6 @@ a1 varchar(12) charset utf8 collate utf8_bin not null, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, primary key (a1) ) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; -Warnings: -Warning 1364 Field 'a1' doesn't have a default value drop table t2; create table t2 ( a1 varchar(12) charset utf8 collate utf8_bin, @@ -729,8 +744,6 @@ a1 varchar(12) charset utf8 collate utf8_bin not null, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, primary key (a1) ) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; -Warnings: -Warning 1364 Field 'a1' doesn't have a default value drop table t2; create table t2 ( a int default 3, b int default 3) select a1,a2 from t1; diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 133683fb273..104025e83eb 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t3,t4,t5; create table t1 (a int, b char(10), key a(a), key b(a,b)); insert into t1 values (17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"), diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index 754568093ff..2413834be4f 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -5,8 +5,6 @@ select ((@id := kill_id) - kill_id) from t1; ((@id := kill_id) - kill_id) 0 kill @id; -select 1; -Got one of the listed errors select ((@id := kill_id) - kill_id) from t1; ((@id := kill_id) - kill_id) 0 diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index 355c20fdad3..942cde83f21 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -1,4 +1,4 @@ -DROP TABLE IF EXISTS t1,t2; +DROP TABLE IF EXISTS t1,t2,test1,test2; CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); CREATE TABLE t2 (a int, b int); diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index ff92fc543d4..0ad5c485b28 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -767,8 +767,7 @@ deallocate prepare stmt1; drop procedure p1; drop table t1, t2, t3; create table t1 (a int); -drop procedure if exists p2; -CREATE PROCEDURE `p2`() +CREATE PROCEDURE `p1`() begin insert into t1 values (1); end// @@ -777,6 +776,6 @@ begin declare done int default 0; set done= not done; end// -CALL p2(); -drop procedure p2; +CALL p1(); +drop procedure p1; drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index ebb2c190eb1..c26671ac937 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2418,6 +2418,9 @@ drop view v1; drop table t1; create table t1(f1 int, f2 int); insert into t1 values (null, 10), (null,2); +select f1, sum(f2) from t1 group by f1; +f1 sum(f2) +NULL 12 create view v1 as select * from t1; select f1, sum(f2) from v1 group by f1; f1 sum(f2) diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 470a7bcbb59..fcbdff7ec5b 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -571,6 +571,22 @@ create table t1 ( show create table t1; drop table t1; +--warning 1364 +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int not null, primary key (a) +) select a, 1 as c from t2 ; +show create table t1; +drop table t1; + +--warning 1364 +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int null, primary key (a) +) select a, 1 as c from t2 ; +show create table t1; +drop table t1; + --warning 1364 create table t1 ( a varchar(12) charset utf8 collate utf8_bin not null, diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index fe95a543fb5..b96aa7befd9 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -14,4 +14,3 @@ sp-goto : GOTO is currently is disabled - will be fixed in the future rpl_relayrotate : Unstable test case, bug#12429 rpl_until : Unstable test case, bug#12429 rpl_deadlock : Unstable test case, bug#12429 -kill : Unstable test case, bug#9712 diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index f3e14c3cd2b..3fb09df5f2f 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1; +drop table if exists t1,t3,t4,t5; --enable_warnings create table t1 (a int, b char(10), key a(a), key b(a,b)); diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 7f3a9932d31..c50c35825fc 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -25,11 +25,18 @@ select ((@id := kill_id) - kill_id) from t1; kill @id; connection con1; ---sleep 1 +--sleep 2 -# this statement should fail ---error 2006,2013 +--disable_query_log +--disable_result_log +# One of the following statements should fail +--error 0,2006,2013 select 1; +--error 0,2006,2013 +select 1; +--enable_query_log +--enable_result_log + --enable_reconnect # this should work, and we should have a new connection_id() select ((@id := kill_id) - kill_id) from t1; diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 1e2e97a4e07..78c4ae2b531 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -2,7 +2,7 @@ -- source include/not_embedded.inc --disable_warnings -DROP TABLE IF EXISTS t1,t2; +DROP TABLE IF EXISTS t1,t2,test1,test2; --enable_warnings # diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index d4fa5268762..acd3297e12a 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -928,11 +928,8 @@ drop table t1, t2, t3; # operator. # create table t1 (a int); ---disable_warnings -drop procedure if exists p2; ---enable_warnings DELIMITER //; -CREATE PROCEDURE `p2`() +CREATE PROCEDURE `p1`() begin insert into t1 values (1); end// @@ -942,7 +939,7 @@ begin set done= not done; end// DELIMITER ;// -CALL p2(); -drop procedure p2; +CALL p1(); +drop procedure p1; drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index ac103278f08..bc54287afb2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2276,6 +2276,7 @@ drop table t1; # create table t1(f1 int, f2 int); insert into t1 values (null, 10), (null,2); +select f1, sum(f2) from t1 group by f1; create view v1 as select * from t1; select f1, sum(f2) from v1 group by f1; drop view v1; diff --git a/sql/field.cc b/sql/field.cc index b70e2a92618..9e73c132d68 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6204,8 +6204,8 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table) This is done to ensure that ALTER TABLE will convert old VARCHAR fields to now VARCHAR fields. */ - if (new_field= new Field_varstring(field_length, maybe_null(), - field_name, new_table, charset())) + if ((new_field= new Field_varstring(field_length, maybe_null(), + field_name, new_table, charset()))) { /* delayed_insert::get_local_table() needs a ptr copied from old table. diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index d2f827989f5..14b79a9a418 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -2616,8 +2616,7 @@ int ha_federated::stash_remote_error() { DBUG_ENTER("ha_federated::stash_remote_error()"); remote_error_number= mysql_errno(mysql); - my_snprintf(remote_error_buf, sizeof(remote_error_buf), "%s", - mysql_error(mysql)); + strmake(remote_error_buf, mysql_error(mysql), sizeof(remote_error_buf)-1); DBUG_RETURN(HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index cdd406d473c..81d11e0a27c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -300,7 +300,8 @@ Thd_ndb::~Thd_ndb() if (ndb) { #ifndef DBUG_OFF - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (ndb->get_free_list_usage(&tmp)) { uint leaked= (uint) tmp.m_created - tmp.m_free; @@ -312,8 +313,8 @@ Thd_ndb::~Thd_ndb() } #endif delete ndb; + ndb= NULL; } - ndb= NULL; changed_tables.empty(); } @@ -4883,7 +4884,8 @@ bool ndbcluster_end() if (g_ndb) { #ifndef DBUG_OFF - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (g_ndb->get_free_list_usage(&tmp)) { uint leaked= (uint) tmp.m_created - tmp.m_free; @@ -4895,10 +4897,9 @@ bool ndbcluster_end() } #endif delete g_ndb; + g_ndb= NULL; } - g_ndb= NULL; - if (g_ndb_cluster_connection) - delete g_ndb_cluster_connection; + delete g_ndb_cluster_connection; g_ndb_cluster_connection= NULL; hash_free(&ndbcluster_open_tables); @@ -7443,7 +7444,8 @@ ndbcluster_show_status(THD* thd) if (have_ndbcluster != SHOW_OPTION_YES) { my_message(ER_NOT_SUPPORTED_YET, - "Cannot call SHOW NDBCLUSTER STATUS because skip-ndbcluster is defined", + "Cannot call SHOW NDBCLUSTER STATUS because skip-ndbcluster is " + "defined", MYF(0)); DBUG_RETURN(TRUE); } @@ -7454,13 +7456,15 @@ ndbcluster_show_status(THD* thd) field_list.push_back(new Item_return_int("free", 10,MYSQL_TYPE_LONG)); field_list.push_back(new Item_return_int("sizeof", 10,MYSQL_TYPE_LONG)); - if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) + if (protocol->send_fields(&field_list, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); if (get_thd_ndb(thd) && get_thd_ndb(thd)->ndb) { Ndb* ndb= (get_thd_ndb(thd))->ndb; - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (ndb->get_free_list_usage(&tmp)) { protocol->prepare_for_resend(); diff --git a/sql/item.cc b/sql/item.cc index 6d5855cd0ca..dadbd31c81f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4843,6 +4843,12 @@ int Item_ref::save_in_field(Field *to, bool no_conversions) } +void Item_ref::save_org_in_field(Field *field) +{ + (*ref)->save_org_in_field(field); +} + + void Item_ref::make_field(Send_field *field) { (*ref)->make_field(field); diff --git a/sql/item.h b/sql/item.h index 4201790e907..c64e6586d5f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1612,11 +1612,7 @@ public: void make_field(Send_field *field); bool fix_fields(THD *, Item **); int save_in_field(Field *field, bool no_conversions); - void save_org_in_field(Field *field) - { - (*ref)->save_org_in_field(field); - null_value= (*ref)->null_value; - } + void save_org_in_field(Field *field); enum Item_result result_type () const { return (*ref)->result_type(); } enum_field_types field_type() const { return (*ref)->field_type(); } Field *get_tmp_table_field() diff --git a/sql/log_event.cc b/sql/log_event.cc index 056bcca1a02..519b077b17b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -114,13 +114,24 @@ static char *pretty_print_str(char *packet, char *str, int len) /* - slave_load_file_stem() + Creates a temporary name for load data infile: + + SYNOPSIS + slave_load_file_stem() + buf Store new filename here + file_id File_id (part of file name) + event_server_id Event_id (part of file name) + ext Extension for file name + + RETURN + Pointer to start of extension */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static inline char* slave_load_file_stem(char*buf, uint file_id, - int event_server_id) +static char *slave_load_file_stem(char *buf, uint file_id, + int event_server_id, const char *ext) { + char *res; fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME); to_unix_path(buf); @@ -129,7 +140,9 @@ static inline char* slave_load_file_stem(char*buf, uint file_id, *buf++ = '-'; buf = int10_to_str(event_server_id, buf, 10); *buf++ = '-'; - return int10_to_str(file_id, buf, 10); + res= int10_to_str(file_id, buf, 10); + strmov(res, ext); // Add extension last + return res; // Pointer to extension } #endif @@ -901,7 +914,6 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) /* Pretty-print event common header if header is exactly 19 bytes */ if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); fprintf(file, "# Position Timestamp Type Master ID " "Size Master Pos Flags \n"); fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x " @@ -927,7 +939,6 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) if (i % 16 == 15) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); fprintf(file, "# %8.8lx %-48.48s |%16s|\n", (unsigned long) (hexdump_from + (i & 0xfffffff0)), hex_string, char_string); @@ -941,12 +952,10 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) *c= '\0'; /* Non-full last line */ - if (hex_string[0]) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); + if (hex_string[0]) fprintf(file, "# %8.8lx %-48.48s |%s|\n# ", (unsigned long) (hexdump_from + (i & 0xfffffff0)), hex_string, char_string); - } } } @@ -4160,16 +4169,15 @@ void Create_file_log_event::pack_info(Protocol *protocol) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) int Create_file_log_event::exec_event(struct st_relay_log_info* rli) { - char proc_info[17+FN_REFLEN+10], *fname_buf= proc_info+17; - char *p; + char proc_info[17+FN_REFLEN+10], *fname_buf; + char *ext; int fd = -1; IO_CACHE file; int error = 1; bzero((char*)&file, sizeof(file)); - p = slave_load_file_stem(fname_buf, file_id, server_id); - strmov(p, ".info"); // strmov takes less code than memcpy - strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0 + fname_buf= strmov(proc_info, "Making temp file "); + ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info"); thd->proc_info= proc_info; my_delete(fname_buf, MYF(0)); // old copy may exist already if ((fd= my_create(fname_buf, CREATE_MODE, @@ -4178,19 +4186,21 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, + "Error in Create_file event: could not open file '%s'", + fname_buf); goto err; } // a trick to avoid allocating another buffer - strmov(p, ".data"); - fname = fname_buf; - fname_len = (uint)(p-fname) + 5; + fname= fname_buf; + fname_len= (uint) (strmov(ext, ".data") - fname); if (write_base(&file)) { - strmov(p, ".info"); // to have it right in the error message + strmov(ext, ".info"); // to have it right in the error message slave_print_error(rli,my_errno, - "Error in Create_file event: could not write to file '%s'", + "Error in Create_file event: could not write to file " + "'%s'", fname_buf); goto err; } @@ -4203,12 +4213,16 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) { - slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, + "Error in Create_file event: could not open file '%s'", + fname_buf); goto err; } if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf); + slave_print_error(rli,my_errno, + "Error in Create_file event: write to '%s' failed", + fname_buf); goto err; } error=0; // Everything is ok @@ -4332,13 +4346,12 @@ int Append_block_log_event::get_create_or_append() const int Append_block_log_event::exec_event(struct st_relay_log_info* rli) { char proc_info[17+FN_REFLEN+10], *fname= proc_info+17; - char *p= slave_load_file_stem(fname, file_id, server_id); int fd; int error = 1; DBUG_ENTER("Append_block_log_event::exec_event"); - memcpy(p, ".data", 6); - strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0 + fname= strmov(proc_info, "Making temp file "); + slave_load_file_stem(fname, file_id, server_id, ".data"); thd->proc_info= proc_info; if (get_create_or_append()) { @@ -4464,10 +4477,9 @@ void Delete_file_log_event::pack_info(Protocol *protocol) int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) { char fname[FN_REFLEN+10]; - char *p= slave_load_file_stem(fname, file_id, server_id); - memcpy(p, ".data", 6); + char *ext= slave_load_file_stem(fname, file_id, server_id, ".data"); (void) my_delete(fname, MYF(MY_WME)); - memcpy(p, ".info", 6); + strmov(ext, ".info"); (void) my_delete(fname, MYF(MY_WME)); return Log_event::exec_event(rli); } @@ -4560,19 +4572,21 @@ void Execute_load_log_event::pack_info(Protocol *protocol) int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) { char fname[FN_REFLEN+10]; - char *p= slave_load_file_stem(fname, file_id, server_id); + char *ext; int fd; - int error = 1; + int error= 1; IO_CACHE file; - Load_log_event* lev = 0; + Load_log_event *lev= 0; - memcpy(p, ".info", 6); + ext= slave_load_file_stem(fname, file_id, server_id, ".info"); if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW, MYF(MY_WME))) < 0 || init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname); + slave_print_error(rli,my_errno, + "Error in Exec_load event: could not open file '%s'", + fname); goto err; } if (!(lev = (Load_log_event*)Log_event::read_log_event(&file, @@ -4580,7 +4594,9 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) rli->relay_log.description_event_for_exec)) || lev->get_type_code() != NEW_LOAD_EVENT) { - slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname); + slave_print_error(rli,0, + "Error in Exec_load event: file '%s' appears corrupted", + fname); goto err; } @@ -4625,7 +4641,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) fd= -1; } (void) my_delete(fname, MYF(MY_WME)); - memcpy(p, ".data", 6); + memcpy(ext, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); error = 0; @@ -4823,11 +4839,10 @@ Execute_load_query_log_event::exec_event(struct st_relay_log_info* rli) memcpy(p, query, fn_pos_start); p+= fn_pos_start; fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'"))); - p= slave_load_file_stem(p, file_id, server_id); - fname_end= (p= strmake(p, STRING_WITH_LEN(".data"))); + p= slave_load_file_stem(p, file_id, server_id, ".data"); + fname_end= p= strend(p); // Safer than p=p+5 *(p++)='\''; - switch (dup_handling) - { + switch (dup_handling) { case LOAD_DUP_IGNORE: p= strmake(p, STRING_WITH_LEN(" IGNORE")); break; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 323e829f219..12b00a62012 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5737,6 +5737,7 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List *fields) /* Create quick select from ref/ref_or_null scan. + SYNOPSIS get_quick_select_for_ref() thd Thread handle @@ -5756,15 +5757,18 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List *fields) QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref, ha_rows records) { - MEM_ROOT *old_root= thd->mem_root; - /* The following call may change thd->mem_root */ - QUICK_RANGE_SELECT *quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); - /* save mem_root set by QUICK_RANGE_SELECT constructor */ - MEM_ROOT *alloc= thd->mem_root; + MEM_ROOT *old_root, *alloc; + QUICK_RANGE_SELECT *quick; KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; uint part; + + old_root= thd->mem_root; + /* The following call may change thd->mem_root */ + quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); + /* save mem_root set by QUICK_RANGE_SELECT constructor */ + alloc= thd->mem_root; /* return back default mem_root (thd->mem_root) changed by QUICK_RANGE_SELECT constructor diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 69757e0be06..041b770ac0b 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -944,6 +944,6 @@ File_parser_dummy_hook::process_unknown_string(char *&unknown_key, char *end) { DBUG_ENTER("file_parser_dummy_hook::process_unknown_string"); - DBUG_PRINT("info", ("unknown key:%60s", unknown_key)); + DBUG_PRINT("info", ("Unknown key: '%60s'", unknown_key)); DBUG_RETURN(FALSE); } diff --git a/sql/sp.cc b/sql/sp.cc index 8991cc78b5e..983addb2db7 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -399,14 +399,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, const char *body, st_sp_chistics &chistics, const char *definer, longlong created, longlong modified) { - LEX *oldlex= thd->lex, newlex; - sp_rcontext *save_spcont= thd->spcont; + LEX *old_lex= thd->lex, newlex; String defstr; char olddb[128]; bool dbchanged; ulong old_sql_mode= thd->variables.sql_mode; - ha_rows select_limit= thd->variables.select_limit; - int ret= SP_INTERNAL_ERROR; + ha_rows old_select_limit= thd->variables.select_limit; + sp_rcontext *old_spcont= thd->spcont; + int ret; thd->variables.sql_mode= sql_mode; thd->variables.select_limit= HA_POS_ERROR; @@ -422,7 +422,10 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, returns, strlen(returns), body, strlen(body), &chistics)) + { + ret= SP_INTERNAL_ERROR; goto end; + } dbchanged= FALSE; if ((ret= sp_use_new_db(thd, name->m_db.str, olddb, sizeof(olddb), @@ -451,10 +454,10 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, (*sphp)->optimize(); } end: - thd->spcont= save_spcont; + thd->spcont= old_spcont; thd->variables.sql_mode= old_sql_mode; - thd->variables.select_limit= select_limit; - thd->lex= oldlex; + thd->variables.select_limit= old_select_limit; + thd->lex= old_lex; return ret; } @@ -926,7 +929,6 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, ulong depth= (type == TYPE_ENUM_PROCEDURE ? thd->variables.max_sp_recursion_depth : 0); - DBUG_ENTER("sp_find_routine"); DBUG_PRINT("enter", ("name: %.*s.%.*s, type: %d, cache only %d", name->m_db.length, name->m_db.str, @@ -936,6 +938,11 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, if ((sp= sp_cache_lookup(cp, name))) { ulong level; + sp_head *new_sp; + const char *returns= ""; + char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + String retstr(64); + DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); if (sp->m_first_free_instance) { @@ -946,7 +953,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED)); if (sp->m_first_free_instance->m_recursion_level > depth) { - sp->recursion_level_error(); + sp->recursion_level_error(thd); DBUG_RETURN(0); } DBUG_RETURN(sp->m_first_free_instance); @@ -954,37 +961,32 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, level= sp->m_last_cached_sp->m_recursion_level + 1; if (level > depth) { - sp->recursion_level_error(); + sp->recursion_level_error(thd); DBUG_RETURN(0); } + + strxmov(definer, sp->m_definer_user.str, "@", + sp->m_definer_host.str, NullS); + if (type == TYPE_ENUM_FUNCTION) { - sp_head *new_sp; - const char *returns= ""; - char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; - String retstr(64); - strxmov(definer, sp->m_definer_user.str, "@", - sp->m_definer_host.str, NullS); - if (type == TYPE_ENUM_FUNCTION) - { - sp_returns_type(thd, retstr, sp); - returns= retstr.ptr(); - } - if (db_load_routine(thd, type, name, &new_sp, - sp->m_sql_mode, sp->m_params.str, returns, - sp->m_body.str, *sp->m_chistics, definer, - sp->m_created, sp->m_modified) == SP_OK) - { - sp->m_last_cached_sp->m_next_cached_sp= new_sp; - new_sp->m_recursion_level= level; - new_sp->m_first_instance= sp; - sp->m_last_cached_sp= sp->m_first_free_instance= new_sp; - DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x", + sp_returns_type(thd, retstr, sp); + returns= retstr.ptr(); + } + if (db_load_routine(thd, type, name, &new_sp, + sp->m_sql_mode, sp->m_params.str, returns, + sp->m_body.str, *sp->m_chistics, definer, + sp->m_created, sp->m_modified) == SP_OK) + { + sp->m_last_cached_sp->m_next_cached_sp= new_sp; + new_sp->m_recursion_level= level; + new_sp->m_first_instance= sp; + sp->m_last_cached_sp= sp->m_first_free_instance= new_sp; + DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x", (ulong)new_sp, new_sp->m_recursion_level, new_sp->m_flags)); - DBUG_RETURN(new_sp); - } - DBUG_RETURN(0); + DBUG_RETURN(new_sp); } + DBUG_RETURN(0); } if (!cache_only) { diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a6e88c08789..576830a6587 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -24,11 +24,17 @@ #include "sp_rcontext.h" #include "sp_cache.h" +/* + Sufficient max length of printed destinations and frame offsets (all uints). +*/ +#define SP_INSTR_UINT_MAXLEN 8 +#define SP_STMT_PRINT_MAXLEN 40 + + Item_result sp_map_result_type(enum enum_field_types type) { - switch (type) - { + switch (type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: @@ -891,17 +897,17 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) SYNOPSIS sp_head::recursion_level_error() + thd Thread handle NOTE For functions and triggers we return error about prohibited recursion. For stored procedures we return about reaching recursion limit. */ -void sp_head::recursion_level_error() +void sp_head::recursion_level_error(THD *thd) { if (m_type == TYPE_ENUM_PROCEDURE) { - THD *thd= current_thd; my_error(ER_SP_RECURSION_LIMIT, MYF(0), thd->variables.max_sp_recursion_depth, m_name); @@ -952,10 +958,15 @@ int sp_head::execute(THD *thd) DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; m_first_instance->m_first_free_instance= m_next_cached_sp; - DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x", - (ulong)m_first_instance, this, m_next_cached_sp, - m_next_cached_sp->m_recursion_level, - m_next_cached_sp->m_flags)); + if (m_next_cached_sp) + { + DBUG_PRINT("info", + ("first free for 0x%lx ++: 0x%lx->0x%lx level: %lu flags %x", + (ulong)m_first_instance, (ulong) this, + (ulong) m_next_cached_sp, + m_next_cached_sp->m_recursion_level, + m_next_cached_sp->m_flags)); + } /* Check that if there are not any instances after this one then pointer to the last instance points on this instance or if there are @@ -1140,9 +1151,9 @@ int sp_head::execute(THD *thd) } m_flags&= ~IS_INVOKED; DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x", - (ulong)m_first_instance, - m_first_instance->m_first_free_instance, this, - m_recursion_level, m_flags)); + (ulong) m_first_instance, + (ulong) m_first_instance->m_first_free_instance, + (ulong) this, m_recursion_level, m_flags)); /* Check that we have one of following: @@ -1152,7 +1163,7 @@ int sp_head::execute(THD *thd) 2) There are some free instances which mean that first free instance should go just after this one and recursion level of that free instance - should be on 1 more then recursion leven of this instance. + should be on 1 more then recursion level of this instance. */ DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 && this == m_first_instance->m_last_cached_sp && @@ -1684,16 +1695,16 @@ sp_head::set_info(longlong created, longlong modified, void -sp_head::set_definer(char *definer, uint definerlen) + +sp_head::set_definer(const char *definer, uint definerlen) { char *p= strrchr(definer, '@'); if (!p) { - m_definer_user.str= strmake_root(mem_root, "", 0); + m_definer_user.str= (char*) ""; m_definer_user.length= 0; - - m_definer_host.str= strmake_root(mem_root, "", 0); + m_definer_host.str= (char*) ""; m_definer_host.length= 0; } else @@ -1788,9 +1799,9 @@ sp_head::show_create_procedure(THD *thd) byte *sql_mode_str; ulong sql_mode_len; bool full_access; - DBUG_ENTER("sp_head::show_create_procedure"); DBUG_PRINT("info", ("procedure %s", m_name.str)); + LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); @@ -2143,12 +2154,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } -/* - Sufficient max length of printed destinations and frame offsets (all uints). -*/ -#define SP_INSTR_UINT_MAXLEN 8 -#define SP_STMT_PRINT_MAXLEN 40 void sp_instr_stmt::print(String *str) { @@ -2170,16 +2176,16 @@ sp_instr_stmt::print(String *str) /* Copy the query string and replace '\n' with ' ' in the process */ for (i= 0 ; i < len ; i++) { - if (m_query.str[i] == '\n') - str->qs_append(' '); - else - str->qs_append(m_query.str[i]); + char c= m_query.str[i]; + if (c == '\n') + c= ' '; + str->qs_append(c); } if (m_query.length > SP_STMT_PRINT_MAXLEN) str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */ str->qs_append('"'); } -#undef SP_STMT_PRINT_MAXLEN + int sp_instr_stmt::exec_core(THD *thd, uint *nextp) @@ -2523,6 +2529,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } + void sp_instr_hpush_jump::print(String *str) { @@ -2533,8 +2540,7 @@ sp_instr_hpush_jump::print(String *str) str->qs_append(m_dest); str->qs_append(' '); str->qs_append(m_frame); - switch (m_type) - { + switch (m_type) { case SP_HANDLER_NONE: str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug break; @@ -2548,11 +2554,13 @@ sp_instr_hpush_jump::print(String *str) str->qs_append(STRING_WITH_LEN(" UNDO")); break; default: - str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); // This would be a bug as well + // This would be a bug as well + str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); str->qs_append(m_type); } } + uint sp_instr_hpush_jump::opt_mark(sp_head *sp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index 6334bca0fc6..6f4a2de1518 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -283,7 +283,7 @@ public: void set_info(longlong created, longlong modified, st_sp_chistics *chistics, ulong sql_mode); - void set_definer(char *definer, uint definerlen); + void set_definer(const char *definer, uint definerlen); void reset_thd_mem_root(THD *thd); @@ -292,7 +292,7 @@ public: void optimize(); void opt_mark(uint ip); - void recursion_level_error(); + void recursion_level_error(THD *thd); inline sp_instr * get_instr(uint i) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 46be74ae972..8d3bb316630 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3537,7 +3537,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, of other queries). For simple queries first_not_own_table is 0. */ for (i= 0, table= tables; - table && table != first_not_own_table && i < number; + table != first_not_own_table && i < number; table= table->next_global, i++) { /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 39e15675e47..598e6d46a60 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5135,7 +5135,6 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, bool result=0, signalled= 0; DBUG_ENTER("remove_table_from_cache"); - key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; for (;;) { diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index da72d283259..545cf41eeeb 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -227,6 +227,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) /* add to hash */ if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables)) { + my_free((char*) hash_tables, MYF(0)); mysql_ha_close(thd, tables); goto err; } @@ -369,28 +370,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p", hash_tables->db, hash_tables->table_name, hash_tables->alias, table)); - /* Table might have been flushed. */ - if (table && (table->s->version != refresh_version)) - { - /* - We must follow the thd->handler_tables chain, as we need the - address of the 'next' pointer referencing this table - for close_thread_table(). - */ - for (table_ptr= &(thd->handler_tables); - *table_ptr && (*table_ptr != table); - table_ptr= &(*table_ptr)->next) - {} - (*table_ptr)->file->ha_index_or_rnd_end(); - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, table_ptr)) - { - /* Tell threads waiting for refresh that something has happened */ - VOID(pthread_cond_broadcast(&COND_refresh)); - } - VOID(pthread_mutex_unlock(&LOCK_open)); - table= hash_tables->table= NULL; - } if (!table) { /* @@ -448,12 +427,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } } - if (insert_fields(thd, &thd->lex->select_lex.context, - tables->db, tables->alias, &it, 0)) - goto err0; - - protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); - HANDLER_TABLES_HACK(thd); lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); HANDLER_TABLES_HACK(thd); @@ -461,6 +434,12 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, if (!lock) goto err0; // mysql_lock_tables() printed error message already + if (insert_fields(thd, &thd->lex->select_lex.context, + tables->db, tables->alias, &it, 0)) + goto err0; + + protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); + /* In ::external_lock InnoDB resets the fields which tell it that the handle is used in the HANDLER interface. Tell it again that diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5e9ca203632..a291a824e61 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2492,7 +2492,11 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) } /* First field to copy */ - field=table->field+table->s->fields - values.elements; + field= table->field+table->s->fields - values.elements; + + /* Mark all fields that are given values */ + for (Field **f= field ; *f ; f++) + (*f)->query_id= thd->query_id; /* Don't set timestamp if used */ table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1a9b4ef4db7..065406d1f0c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4843,7 +4843,6 @@ end_with_restore_list: if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION) reset_one_shot_variables(thd); - /* The return value for ROW_COUNT() is "implementation dependent" if the statement is not DELETE, INSERT or UPDATE (or a CALL executing @@ -4851,13 +4850,10 @@ end_with_restore_list: */ if (lex->sql_command != SQLCOM_CALL && uc_update_queries[lex->sql_command]<2) thd->row_count_func= -1; - goto cleanup; + DBUG_RETURN(res || thd->net.report_error); error: - res= 1; - -cleanup: - DBUG_RETURN(res || thd->net.report_error); + DBUG_RETURN(1); } @@ -5080,7 +5076,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, the given table list refers to the list for prelocking (contains tables of other queries). For simple queries first_not_own_table is 0. */ - for (; tables && tables != first_not_own_table; tables= tables->next_global) + for (; tables != first_not_own_table; tables= tables->next_global) { if (tables->schema_table && (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) @@ -7558,7 +7554,7 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name) /* Create and initialize. */ - if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER)))) + if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; definer->user= *user_name; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 470015f8869..52070aa8983 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10628,7 +10628,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), item->save_org_in_field(group->field); /* Store in the used key if the field was 0 */ if (item->maybe_null) - group->buff[-1]=item->null_value ? 1 : 0; + group->buff[-1]= (char) group->field->is_null(); } if (!table->file->index_read(table->record[1], join->tmp_table_param.group_buff,0, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 296b55679a3..d3fda132f50 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -51,6 +51,13 @@ static File_option triggers_file_parameters[]= { { 0, 0 }, 0, FILE_OPTIONS_STRING } }; +File_option sql_modes_parameters= +{ + {STRING_WITH_LEN("sql_modes") }, + offsetof(class Table_triggers_list, definition_modes_list), + FILE_OPTIONS_ULLLIST +}; + /* This must be kept up to date whenever a new option is added to the list above, as it specifies the number of required parameters of the trigger in @@ -428,7 +435,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!is_acl_user(lex->definer->host.str, - lex->definer->user.str)) + lex->definer->user.str)) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -771,7 +778,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, sizeof(LEX_STRING)))) DBUG_RETURN(1); // EOM - trg_definer->str= ""; + trg_definer->str= (char*) ""; trg_definer->length= 0; while (it++) @@ -1164,7 +1171,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, if (is_special_var_used(event, time_type)) { - TABLE_LIST table_list; + TABLE_LIST table_list, **save_query_tables_own_last; bzero((char *) &table_list, sizeof (table_list)); table_list.db= (char *) table->s->db; table_list.db_length= strlen(table_list.db); @@ -1172,8 +1179,12 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, table_list.table_name_length= strlen(table_list.table_name); table_list.alias= (char *) table->alias; table_list.table= table; + save_query_tables_own_last= thd->lex->query_tables_own_last; + thd->lex->query_tables_own_last= 0; - if (check_table_access(thd, SELECT_ACL | UPDATE_ACL, &table_list, 0)) + res= check_table_access(thd, SELECT_ACL | UPDATE_ACL, &table_list, 0); + thd->lex->query_tables_own_last= save_query_tables_own_last; + if (res) { sp_restore_security_context(thd, save_ctx); return TRUE; @@ -1215,32 +1226,29 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, TRUE Error */ +#define INVALID_SQL_MODES_LENGTH 13 + bool Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key, gptr base, MEM_ROOT *mem_root, char *end) { -#define INVALID_SQL_MODES_LENGTH 13 DBUG_ENTER("handle_old_incorrect_sql_modes"); DBUG_PRINT("info", ("unknown key:%60s", unknown_key)); + if (unknown_key + INVALID_SQL_MODES_LENGTH + 1 < end && unknown_key[INVALID_SQL_MODES_LENGTH] == '=' && !memcmp(unknown_key, STRING_WITH_LEN("sql_modes"))) { + char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; + DBUG_PRINT("info", ("sql_modes affected by BUG#14090 detected")); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_OLD_FILE_FORMAT, ER(ER_OLD_FILE_FORMAT), (char *)path, "TRIGGER"); - File_option sql_modes_parameters= - { - {STRING_WITH_LEN("sql_modes") }, - offsetof(class Table_triggers_list, definition_modes_list), - FILE_OPTIONS_ULLLIST - }; - char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; if (get_file_options_ulllist(ptr, end, unknown_key, base, &sql_modes_parameters, mem_root)) { From 35a039ffc0476a3ab9c67fe12c4a69697c48d628 Mon Sep 17 00:00:00 2001 From: "jmiller@mysql.com" <> Date: Fri, 6 Jan 2006 00:06:04 +0100 Subject: [PATCH 32/49] File needs to be removed --- mysql-test/t/rpl_stm_loaddata_m.test | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 mysql-test/t/rpl_stm_loaddata_m.test diff --git a/mysql-test/t/rpl_stm_loaddata_m.test b/mysql-test/t/rpl_stm_loaddata_m.test deleted file mode 100644 index ac52a8dfb9e..00000000000 --- a/mysql-test/t/rpl_stm_loaddata_m.test +++ /dev/null @@ -1,10 +0,0 @@ -# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules -# exist. -# This is for BUG#1100 (LOAD DATA INFILE was half-logged). - -# Requires statement logging --- source include/have_binlog_format_statement.inc --- source extra/rpl_tests/rpl_loaddata_m.test - -# End of 4.1 tests -# Adding comment for force manual merge 5.0 -> wl1012: Delete me From d1aacfad696838425c713f788fec833ad4e6f507 Mon Sep 17 00:00:00 2001 From: "jmiller@mysql.com" <> Date: Fri, 6 Jan 2006 01:09:17 +0100 Subject: [PATCH 33/49] Test case clean-up do to causing other test failures --- mysql-test/r/rpl_drop_db.result | 2 +- mysql-test/r/rpl_multi_engine.result | 1 + mysql-test/t/rpl_drop_db.test | 5 +++-- mysql-test/t/rpl_multi_engine.test | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/rpl_drop_db.result b/mysql-test/r/rpl_drop_db.result index ce9d39e87f6..3a35dc266b6 100644 --- a/mysql-test/r/rpl_drop_db.result +++ b/mysql-test/r/rpl_drop_db.result @@ -31,5 +31,5 @@ use test; select * from t1; n 1234 -drop table t1; +DROP DATABASE mysqltest1; stop slave; diff --git a/mysql-test/r/rpl_multi_engine.result b/mysql-test/r/rpl_multi_engine.result index 27482eae6d9..0492231be37 100644 --- a/mysql-test/r/rpl_multi_engine.result +++ b/mysql-test/r/rpl_multi_engine.result @@ -363,3 +363,4 @@ id hex(b1) vc bc d f total y t select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id; id hex(b1) vc bc d f total y t DROP TABLE t1; +DROP DATABASE mysqltest1; diff --git a/mysql-test/t/rpl_drop_db.test b/mysql-test/t/rpl_drop_db.test index 98afc6e3d02..548009b758e 100644 --- a/mysql-test/t/rpl_drop_db.test +++ b/mysql-test/t/rpl_drop_db.test @@ -46,12 +46,13 @@ show tables; use test; select * from t1; +system rm var/master-data/mysqltest1/f1.txt; connection master; -drop table t1; +DROP DATABASE mysqltest1; sync_slave_with_master; #cleanup connection slave; stop slave; -system rm -rf var/master-data/mysqltest1; +#system rm -rf var/master-data/mysqltest1; diff --git a/mysql-test/t/rpl_multi_engine.test b/mysql-test/t/rpl_multi_engine.test index b0879757468..356237d1584 100644 --- a/mysql-test/t/rpl_multi_engine.test +++ b/mysql-test/t/rpl_multi_engine.test @@ -94,6 +94,8 @@ show create table t1; # cleanup connection master; DROP TABLE t1; +# Need to drop mysqltest1 as well so other test will pass. +DROP DATABASE mysqltest1; sync_slave_with_master; # End of 5.1 test case From 64cab9d76717e5fdd819b08858ca6db087e1c7fd Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 6 Jan 2006 12:48:14 +0200 Subject: [PATCH 34/49] After merge fix and a safety fix for handler --- sql/sql_handler.cc | 14 +++++++------- sql/sql_trigger.cc | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 545cf41eeeb..fae48c7d164 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -414,6 +414,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } tables->table=table; + HANDLER_TABLES_HACK(thd); + lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); + HANDLER_TABLES_HACK(thd); + + if (!lock) + goto err0; // mysql_lock_tables() printed error message already + if (cond && ((!cond->fixed && cond->fix_fields(thd, &cond)) || cond->check_cols(1))) goto err0; @@ -427,13 +434,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } } - HANDLER_TABLES_HACK(thd); - lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); - HANDLER_TABLES_HACK(thd); - - if (!lock) - goto err0; // mysql_lock_tables() printed error message already - if (insert_fields(thd, &thd->lex->select_lex.context, tables->db, tables->alias, &it, 0)) goto err0; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 5f2d269ed1e..bbc32950c2d 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1189,9 +1189,10 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, save_query_tables_own_last= thd->lex->query_tables_own_last; thd->lex->query_tables_own_last= 0; - res= check_table_access(thd, SELECT_ACL | UPDATE_ACL, &table_list, 0); + err_status= check_table_access(thd, SELECT_ACL | UPDATE_ACL, + &table_list, 0); thd->lex->query_tables_own_last= save_query_tables_own_last; - if (res) + if (err_status) { sp_restore_security_context(thd, save_ctx); return TRUE; From 4a0fe7348aa270702d830f77b1707c1b93558e7a Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Fri, 6 Jan 2006 12:21:15 +0100 Subject: [PATCH 35/49] Compile fix: An "int" function had accidentally lost its "return 0;", re-add it. --- sql/handler.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/handler.cc b/sql/handler.cc index d36db3281b3..cff7b21ddc2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1178,6 +1178,7 @@ int ha_release_temporary_latches(THD *thd) #ifdef WITH_INNOBASE_STORAGE_ENGINE innobase_release_temporary_latches(thd); #endif + return 0; } From 17ec0394337b5a42eb4f7d0832c016f691b139c8 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Fri, 6 Jan 2006 12:40:32 +0100 Subject: [PATCH 36/49] Disabled mysqlslap test case was errorneously enabled in merge; disable again. --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 2342778671f..cbe9b7d851f 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,3 +24,4 @@ type_time : Bug#15805 #rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite rpl_ddl : Bug#15963 SBR does not show "Definer" correctly +mysqlslap : Bug#16167 From be8f21e8f10b9dec5cc3918894cb4745f554e3ba Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Fri, 6 Jan 2006 14:30:25 +0100 Subject: [PATCH 37/49] Fix compile failure on QNX. --- sql/sp_head.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index d6db9a47748..12f9260e7b1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1755,7 +1755,7 @@ void sp_head::set_definer(const char *definer, uint definerlen) { - char *p= strrchr(definer, '@'); + const char *p= strrchr(definer, '@'); if (!p) { From dca852ff687d73318f9c4d3f85757fb982a59bf4 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Fri, 6 Jan 2006 17:02:57 +0100 Subject: [PATCH 38/49] BUG#16155: Workaround AIX 5.2 64-bit compiler bug. --- sql/sql_delete.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ba1cce3abfe..764aa435cae 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -890,7 +890,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) } // Remove the .frm extension - *(path + path_length - reg_ext_length)= '\0'; + // AIX 5.2 64-bit compiler bug (BUG#16155): this crashes, replacement works. + // *(path + path_length - reg_ext_length)= '\0'; + path[path_length - reg_ext_length] = 0; error= ha_create_table(thd, path, table_list->db, table_list->table_name, &create_info, 1); query_cache_invalidate3(thd, table_list, 0); From a4d7edbb0f1153aedba456024449580a11f5683b Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Fri, 6 Jan 2006 15:16:44 -0800 Subject: [PATCH 39/49] Fix result after merge --- mysql-test/r/binlog_stm_blackhole.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/binlog_stm_blackhole.result b/mysql-test/r/binlog_stm_blackhole.result index 7b6e61984ec..994a40832c7 100644 --- a/mysql-test/r/binlog_stm_blackhole.result +++ b/mysql-test/r/binlog_stm_blackhole.result @@ -121,6 +121,7 @@ master-bin.000001 # Query 1 # use `test`; replace into t1 values(100) master-bin.000001 # Query 1 # use `test`; COMMIT master-bin.000001 # Query 1 # use `test`; create table t2 (a varchar(200)) engine=blackhole master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 +master-bin.000001 # Query 1 # use `test`; COMMIT master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../../std_data/words.dat' into table t2 ;file_id=1 master-bin.000001 # Query 1 # use `test`; COMMIT master-bin.000001 # Query 1 # use `test`; alter table t1 add b int From cfbaad99524f858c956644fd08fd3e5bf8facf84 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sat, 7 Jan 2006 14:41:57 +0100 Subject: [PATCH 40/49] WL#2935 - SHOW STATUS support in plugins The patch adds DYNAMIC_ARRAY all_status_vars, which is now the sole source of status information for SHOW STATUS. Status variables can be added to and removed from the array dynamically. SHOW STATUS command uses this array instead of static array from mysqld.cc Compatibility with the old, global list of status variables is preserved in init_server_components(), where this global list is simply appended to all_status_vars. --- include/plugin.h | 22 +++- plugin/fulltext/plugin_example.c | 18 ++- sql/ha_innodb.cc | 2 +- sql/ha_innodb.h | 2 +- sql/mysql_priv.h | 16 +-- sql/mysqld.cc | 193 ++++++++++++++++--------------- sql/set_var.cc | 4 +- sql/sql_parse.cc | 2 +- sql/sql_plugin.cc | 106 ++++++++--------- sql/sql_plugin.h | 12 +- sql/sql_show.cc | 189 +++++++++++++++++++++++++++--- sql/structs.h | 23 +--- 12 files changed, 395 insertions(+), 194 deletions(-) diff --git a/include/plugin.h b/include/plugin.h index 3faa02cb079..6c571b8504b 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -41,7 +41,26 @@ int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \ int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \ struct st_mysql_plugin _mysql_plugin_declarations_[]= { -#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0}} +#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0}} + +/* + declarations for SHOW STATUS support in plugins +*/ +enum enum_mysql_show_type +{ + SHOW_UNDEF, SHOW_BOOL, SHOW_MY_BOOL, SHOW_INT, SHOW_LONG, + SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, + SHOW_ARRAY, SHOW_FUNC +}; + +struct st_mysql_show_var { + const char *name; + char *value; + enum enum_mysql_show_type type; +}; + +#define SHOW_VAR_FUNC_BUFF_SIZE 1024 +typedef int (*mysql_show_var_func)(void *, struct st_mysql_show_var*, char *); /* Plugin description structure. @@ -57,6 +76,7 @@ struct st_mysql_plugin int (*init)(void); /* the function to invoke when plugin is loaded */ int (*deinit)(void); /* the function to invoke when plugin is unloaded */ uint version; /* plugin version (for SHOW PLUGINS) */ + struct st_mysql_show_var *status_vars; }; /************************************************************************* diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c index c222d3d85c3..4caa6de3197 100644 --- a/plugin/fulltext/plugin_example.c +++ b/plugin/fulltext/plugin_example.c @@ -18,6 +18,8 @@ #include #include +long number_of_calls= 0; /* for SHOW STATUS, see below */ + /* Simple full-text parser plugin that acts as a replacement for the built-in full-text parser: @@ -167,6 +169,8 @@ int simple_parser_parse(MYSQL_FTPARSER_PARAM *param) { char *end, *start, *docend= param->doc + param->length; + number_of_calls++; + for (end= start= param->doc;; end++) { if (end == docend) @@ -198,6 +202,16 @@ static struct st_mysql_ftparser simple_parser_descriptor= simple_parser_deinit /* parser deinit function */ }; +/* + Plugin status variables for SHOW STATUS +*/ + +struct st_mysql_show_var simple_status[]= +{ + {"static", "just a static text", SHOW_CHAR}, + {"called", (char *)&number_of_calls, SHOW_LONG}, + {0,0,0} +}; /* Plugin library descriptor @@ -211,6 +225,8 @@ mysql_declare_plugin "MySQL AB", /* author */ "Simple Full-Text Parser", /* description */ simple_parser_plugin_init, /* init function (when loaded) */ - simple_parser_plugin_deinit /* deinit function (when unloaded) */ + simple_parser_plugin_deinit,/* deinit function (when unloaded) */ + 0x0001, /* version */ + &simple_status /* status variables */ } mysql_declare_plugin_end; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 27262e6f197..75c1c380a42 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -253,7 +253,7 @@ innobase_commit_low( /*================*/ trx_t* trx); /* in: transaction handle */ -struct show_var_st innodb_status_variables[]= { +SHOW_VAR innodb_status_variables[]= { {"buffer_pool_pages_data", (char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG}, {"buffer_pool_pages_dirty", diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 8db7f00ffa9..b9e399509de 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -212,7 +212,7 @@ class ha_innobase: public handler uint table_changes); }; -extern struct show_var_st innodb_status_variables[]; +extern SHOW_VAR innodb_status_variables[]; extern uint innobase_init_flags, innobase_lock_type; extern uint innobase_flush_log_at_trx_commit; extern ulong innobase_cache_size, innobase_fast_shutdown; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b6be03003c6..e9b79afff7a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -292,7 +292,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define OPTION_SETUP_TABLES_DONE (LL(1) << 30) // intern /* If not set then the thread will ignore all warnings with level notes. */ #define OPTION_SQL_NOTES (LL(1) << 31) // THD, user -/* +/* Force the used temporary table to be a MyISAM table (because we will use fulltext functions when reading from it. */ @@ -322,7 +322,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define MODE_DB2 2048 #define MODE_MAXDB 4096 #define MODE_NO_KEY_OPTIONS 8192 -#define MODE_NO_TABLE_OPTIONS 16384 +#define MODE_NO_TABLE_OPTIONS 16384 #define MODE_NO_FIELD_OPTIONS 32768 #define MODE_MYSQL323 65536 #define MODE_MYSQL40 (MODE_MYSQL323*2) @@ -513,13 +513,11 @@ void free_items(Item *item); void cleanup_items(Item *item); class THD; void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0); -bool check_one_table_access(THD *thd, ulong privilege, - TABLE_LIST *tables); +bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); bool check_routine_access(THD *thd,ulong want_access,char *db,char *name, bool is_proc, bool no_errors); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); -bool check_merge_table_access(THD *thd, char *db, - TABLE_LIST *table_list); +bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); @@ -884,6 +882,10 @@ void calc_sum_of_all_status(STATUS_VAR *to); void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, const LEX_STRING *definer_host); +int add_status_vars(SHOW_VAR *list); +void remove_status_vars(SHOW_VAR *list); +void init_status_vars(); +void free_status_vars(); /* information schema */ extern LEX_STRING information_schema_name; @@ -1269,7 +1271,7 @@ extern I_List key_caches; extern MY_BITMAP temp_pool; extern String my_empty_string; extern const String my_null_string; -extern SHOW_VAR init_vars[],status_vars[], internal_vars[]; +extern SHOW_VAR init_vars[], status_vars[], internal_vars[]; extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct system_status_var global_status_var; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 59c317d724e..f40f27d5a32 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -348,7 +348,7 @@ my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; my_bool opt_log_slave_updates= 0; my_bool opt_innodb; #ifdef WITH_INNOBASE_STORAGE_ENGINE -extern struct show_var_st innodb_status_variables[]; +extern SHOW_VAR innodb_status_variables[]; extern uint innobase_init_flags, innobase_lock_type; extern uint innobase_flush_log_at_trx_commit; extern ulong innobase_cache_size, innobase_fast_shutdown; @@ -417,7 +417,7 @@ ulong opt_ndb_cache_check_time; const char *opt_ndb_mgmd; ulong opt_ndb_nodeid; -extern struct show_var_st ndb_status_variables[]; +extern SHOW_VAR ndb_status_variables[]; extern const char *ndb_distribution_names[]; extern TYPELIB ndb_distribution_typelib; extern const char *opt_ndb_distribution; @@ -1154,18 +1154,19 @@ void clean_up(bool print_message) set_var_free(); free_charsets(); (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ +#ifdef HAVE_DLOPEN if (!opt_noacl) { -#ifdef HAVE_DLOPEN udf_free(); -#endif - plugin_free(); } +#endif + plugin_free(); if (tc_log) tc_log->close(); xid_cache_free(); delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache); multi_keycache_free(); + free_status_vars(); end_thr_alarm(1); /* Free allocated memory */ #ifdef USE_RAID end_raid(); @@ -2670,12 +2671,21 @@ static int init_common_variables(const char *conf_file_name, int argc, mysql_log.init_pthread_objects(); mysql_slow_log.init_pthread_objects(); mysql_bin_log.init_pthread_objects(); - + if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) strmov(glob_hostname,"mysql"); strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5); strmov(fn_ext(pidfile_name),".pid"); // Add proper extension + /* + Add server status variables to the dynamic list of + status variables that is shown by SHOW STATUS. + Later, in plugin_init, plugin_load, and mysql_install_plugin + new entries could be added to that list. + */ + if (add_status_vars(status_vars)) + return 1; // an error was already reported + if (plugin_init()) { sql_print_error("Failed to init plugins."); @@ -3557,7 +3567,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); #ifndef __NETWARE__ (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL); #endif /* __NETWARE__ */ - + if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore @@ -3575,6 +3585,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); udf_init(); #endif } + init_status_vars(); if (opt_bootstrap) /* If running with bootstrap, do not start replication. */ opt_skip_slave_start= 1; /* @@ -6186,39 +6197,39 @@ The minimum value for this variable is 4096.", {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static int show_question(THD *thd, show_var_st *var, char *buff) +static int show_question(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONGLONG; + var->type= SHOW_LONGLONG; var->value= (char *)&thd->query_id; return 0; } -static int show_net_compression(THD *thd, show_var_st *var, char *buff) +static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_MY_BOOL; + var->type= SHOW_MY_BOOL; var->value= (char *)&thd->net.compress; return 0; } -static int show_starttime(THD *thd, show_var_st *var, char *buff) +static int show_starttime(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long) (thd->query_start() - start_time); return 0; } #ifdef HAVE_REPLICATION -static int show_rpl_status(THD *thd, show_var_st *var, char *buff) +static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; var->value= const_cast(rpl_status_type[(int)rpl_status]); return 0; } -static int show_slave_running(THD *thd, show_var_st *var, char *buff) +static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; pthread_mutex_lock(&LOCK_active_mi); var->value= const_cast((active_mi && active_mi->slave_running && active_mi->rli.slave_running) ? "ON" : "OFF"); @@ -6226,7 +6237,7 @@ static int show_slave_running(THD *thd, show_var_st *var, char *buff) return 0; } -static int show_slave_retried_trans(THD *thd, show_var_st *var, char *buff) +static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff) { /* TODO: with multimaster, have one such counter per line in @@ -6235,30 +6246,30 @@ static int show_slave_retried_trans(THD *thd, show_var_st *var, char *buff) pthread_mutex_lock(&LOCK_active_mi); if (active_mi) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; pthread_mutex_lock(&active_mi->rli.data_lock); *((long *)buff)= (long)active_mi->rli.retried_trans; pthread_mutex_unlock(&active_mi->rli.data_lock); } else - var->type=SHOW_UNDEF; + var->type= SHOW_UNDEF; pthread_mutex_unlock(&LOCK_active_mi); return 0; } #endif /* HAVE_REPLICATION */ -static int show_open_tables(THD *thd, show_var_st *var, char *buff) +static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)cached_open_tables(); return 0; } -static int show_table_definitions(THD *thd, show_var_st *var, char *buff) +static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)cached_table_definitions(); return 0; @@ -6266,144 +6277,144 @@ static int show_table_definitions(THD *thd, show_var_st *var, char *buff) #ifdef HAVE_OPENSSL /* Functions relying on CTX */ -static int show_ssl_ctx_sess_accept(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_accept_good(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_connect_good(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_cb_hits(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_hits(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_cache_full(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_misses(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_timeouts(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_number(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_connect(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_sess_get_cache_size(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_get_verify_mode(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_get_verify_depth(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)); return 0; } -static int show_ssl_ctx_get_session_cache_mode(THD *thd, show_var_st *var, char *buff) +static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; if (!ssl_acceptor_fd) var->value= "NONE"; else @@ -6428,26 +6439,26 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, show_var_st *var, char } /* Functions relying on SSL */ -static int show_ssl_get_version(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; var->value= const_cast(thd->net.vio->ssl_arg ? SSL_get_version((SSL*) thd->net.vio->ssl_arg) : ""); return 0; } -static int show_ssl_session_reused(THD *thd, show_var_st *var, char *buff) +static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)thd->net.vio->ssl_arg ? SSL_session_reused((SSL*) thd->net.vio->ssl_arg) : 0; } -static int show_ssl_get_default_timeout(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)thd->net.vio->ssl_arg ? SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg) : @@ -6455,9 +6466,9 @@ static int show_ssl_get_default_timeout(THD *thd, show_var_st *var, char *buff) return 0; } -static int show_ssl_get_verify_mode(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)thd->net.vio->ssl_arg ? SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg) : @@ -6465,9 +6476,9 @@ static int show_ssl_get_verify_mode(THD *thd, show_var_st *var, char *buff) return 0; } -static int show_ssl_get_verify_depth(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_LONG; + var->type= SHOW_LONG; var->value= buff; *((long *)buff)= (long)thd->net.vio->ssl_arg ? SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg) : @@ -6475,17 +6486,17 @@ static int show_ssl_get_verify_depth(THD *thd, show_var_st *var, char *buff) return 0; } -static int show_ssl_get_cipher(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; var->value= const_cast(thd->net.vio->ssl_arg ? SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : ""); return 0; } -static int show_ssl_get_cipher_list(THD *thd, show_var_st *var, char *buff) +static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) { - var->type=SHOW_CHAR; + var->type= SHOW_CHAR; var->value= buff; if (thd->net.vio->ssl_arg) { @@ -6507,7 +6518,7 @@ static int show_ssl_get_cipher_list(THD *thd, show_var_st *var, char *buff) #ifdef WITH_INNOBASE_STORAGE_ENGINE int innodb_export_status(void); -static int show_innodb_vars(THD *thd, show_var_st *var, char *buff) +static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff) { innodb_export_status(); var->type= SHOW_ARRAY; @@ -6516,7 +6527,7 @@ static int show_innodb_vars(THD *thd, show_var_st *var, char *buff) } #endif -struct show_var_st status_vars[]= { +SHOW_VAR status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, @@ -6547,7 +6558,7 @@ struct show_var_st status_vars[]= { {"Com_drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS}, {"Com_drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS}, {"Com_drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS}, - {"Com_execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS}, + {"Com_execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS}, {"Com_flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS}, {"Com_grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS}, {"Com_ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS}, @@ -6626,14 +6637,14 @@ struct show_var_st status_vars[]= { {"Com_xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS}, {"Com_xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS}, {"Compression", (char*) &show_net_compression, SHOW_FUNC}, - {"Connections", (char*) &thread_id, SHOW_LONG_CONST}, + {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS}, {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, - {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_CONST}, + {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, - {"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST}, + {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, @@ -6650,11 +6661,11 @@ struct show_var_st status_vars[]= { {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, #ifdef WITH_INNOBASE_STORAGE_ENGINE - {"Innodb_", (char*) &show_innodb_vars, SHOW_FUNC}, + {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, #endif /* WITH_INNOBASE_STORAGE_ENGINE */ {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_CONST_LONG}, - {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_CONST_LONG}, + {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG}, + {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG}, {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG}, {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG}, {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG}, @@ -6662,23 +6673,23 @@ struct show_var_st status_vars[]= { {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE - {"Ndb_", (char*) &ndb_status_variables, SHOW_ARRAY}, + {"Ndb", (char*) &ndb_status_variables, SHOW_ARRAY}, #endif /* WITH_NDBCLUSTER_STORAGE_ENGINE */ - {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST}, - {"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST}, - {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST}, + {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, + {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH}, + {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH}, {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC}, {"Open_tables", (char*) &show_open_tables, SHOW_FUNC}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, #ifdef HAVE_QUERY_CACHE - {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_CONST}, - {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_CONST}, + {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, + {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH}, {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG}, {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG}, {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG}, {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG}, - {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST}, - {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST}, + {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH}, + {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH}, #endif /*HAVE_QUERY_CACHE*/ {"Questions", (char*) &show_question, SHOW_FUNC}, #ifdef HAVE_REPLICATION @@ -6732,10 +6743,10 @@ struct show_var_st status_vars[]= { {"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG}, {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG}, #endif - {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, - {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, - {"Threads_created", (char*) &thread_created, SHOW_LONG_CONST}, - {"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, + {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH}, + {"Threads_connected", (char*) &thread_count, SHOW_INT}, + {"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH}, + {"Threads_running", (char*) &thread_running, SHOW_INT}, {"Uptime", (char*) &show_starttime, SHOW_FUNC}, {NullS, NullS, SHOW_LONG} }; diff --git a/sql/set_var.cc b/sql/set_var.cc index dfd451442ca..377b4fd6f3f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -624,7 +624,7 @@ sys_var_have_variable sys_have_row_based_replication("have_row_based_replication sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE)); #ifdef HAVE_REPLICATION -static int show_slave_skip_errors(THD *thd, show_var_st *var, char *buff) +static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff) { var->type=SHOW_CHAR; var->value= buff; @@ -667,7 +667,7 @@ static int show_slave_skip_errors(THD *thd, show_var_st *var, char *buff) Variables shown by SHOW variables in alphabetical order */ -struct show_var_st init_vars[]= { +SHOW_VAR init_vars[]= { {"auto_increment_increment", (char*) &sys_auto_increment_increment, SHOW_SYS}, {"auto_increment_offset", (char*) &sys_auto_increment_offset, SHOW_SYS}, {sys_automatic_sp_privileges.name,(char*) &sys_automatic_sp_privileges, SHOW_SYS}, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2c72c52a05b..ea9f8c6ffd2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6641,7 +6641,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) static void refresh_status(void) { pthread_mutex_lock(&LOCK_status); - for (struct show_var_st *ptr=status_vars; ptr->name; ptr++) + for (SHOW_VAR *ptr= status_vars; ptr->name; ptr++) if (ptr->type == SHOW_LONG) // note that SHOW_LONG_NOFLUSH variables are not reset *(ulong*) ptr->value= 0; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 9c3d19369c8..4e156fb7c11 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -94,7 +94,8 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) static inline void free_plugin_mem(struct st_plugin_dl *p) { - dlclose(p->handle); + if (p->handle) + dlclose(p->handle); my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR)); if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION) my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR)); @@ -182,7 +183,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) { int i, sizeof_st_plugin; struct st_mysql_plugin *old, *cur; - char *ptr=(char *)sym; + char *ptr= (char *)sym; if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym))) sizeof_st_plugin= *(int *)sym; @@ -196,8 +197,12 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym); DBUG_RETURN(0); #else + /* + When the following assert starts failing, we'll have to switch + to the upper branch of the #ifdef + */ DBUG_ASSERT(min_plugin_interface_version == 0); - sizeof_st_plugin=(int)offsetof(struct st_mysql_plugin, version); + sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version); #endif } @@ -217,29 +222,17 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length); DBUG_RETURN(0); } + /* + All st_plugin fields not initialized in the plugin explicitly, are + set to 0. It matches C standard behaviour for struct initializers that + have less values than the struct definition. + */ for (i=0; (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info; i++) - { - switch (plugin_dl.version) { - default: /* version > MYSQL_PLUGIN_INTERFACE_VERSION */ - /* fall through */ - case 0x0001: - cur[i].version=old->version; - // cur[i].status_vars=old->status_vars; - /* fall through */ - case 0x0000: - cur[i].type=old->type; - cur[i].info=old->info; - cur[i].name=old->name; - cur[i].author=old->author; - cur[i].descr=old->descr; - cur[i].init=old->init; - cur[i].deinit=old->deinit; - } - } + memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin)); - sym=cur; + sym= cur; } plugin_dl.plugins= (struct st_mysql_plugin *)sym; @@ -320,7 +313,7 @@ static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type) { struct st_plugin_int *plugin= (st_plugin_int *) hash_search(&plugin_hash[i], (const byte *)name->str, name->length); - if (plugin) + if (plugin) DBUG_RETURN(plugin); } } @@ -382,7 +375,6 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) struct st_plugin_int *)); } - static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report) { struct st_plugin_int tmp; @@ -429,21 +421,20 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report) tmp.name.length= name_len; tmp.ref_count= 0; tmp.state= PLUGIN_IS_UNINITIALIZED; - if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp))) + if (plugin->status_vars) { - if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_int)); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_int)); - goto err; + SHOW_VAR array[2]= { + {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY}, + {0, 0, SHOW_UNDEF} + }; + if (add_status_vars(array)) // add_status_vars makes a copy + goto err; } + if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp))) + goto err; if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr)) { tmp_plugin_ptr->state= PLUGIN_IS_FREED; - if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_int)); - if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_int)); goto err; } DBUG_RETURN(FALSE); @@ -454,6 +445,14 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report) if (report & REPORT_TO_LOG) sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str); err: + if (plugin->status_vars) + { + SHOW_VAR array[2]= { + {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY}, + {0, 0, SHOW_UNDEF} + }; + remove_status_vars(array); + } plugin_dl_del(dl); DBUG_RETURN(TRUE); } @@ -466,6 +465,14 @@ static void plugin_del(LEX_STRING *name) DBUG_ENTER("plugin_del"); if ((plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN))) { + if (plugin->plugin->status_vars) + { + SHOW_VAR array[2]= { + {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, + {0, 0, SHOW_UNDEF} + }; + remove_status_vars(array); + } hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin); plugin_dl_del(&plugin->plugin_dl->dl); plugin->state= PLUGIN_IS_FREED; @@ -494,7 +501,7 @@ void plugin_unlock(struct st_plugin_int *plugin) static int plugin_initialize(struct st_plugin_int *plugin) { DBUG_ENTER("plugin_initialize"); - + if (plugin->plugin->init) { if (plugin->plugin->init()) @@ -506,7 +513,7 @@ static int plugin_initialize(struct st_plugin_int *plugin) goto err; } } - + switch (plugin->plugin->type) { case MYSQL_STORAGE_ENGINE_PLUGIN: @@ -605,11 +612,11 @@ int plugin_init(void) get_hash_key, NULL, 0)) goto err; } - + initialized= 1; DBUG_RETURN(0); - + err: DBUG_RETURN(1); } @@ -651,9 +658,9 @@ void plugin_load(void) MEM_ROOT mem; THD *new_thd; DBUG_ENTER("plugin_load"); - + DBUG_ASSERT(initialized); - + if (!(new_thd= new THD)) { sql_print_error("Can't allocate memory for plugin structures"); @@ -716,12 +723,7 @@ void plugin_free(void) { struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); -#ifdef HAVE_DLOPEN - if (tmp->handle) - { - free_plugin_mem(tmp); - } -#endif + free_plugin_mem(tmp); } delete_dynamic(&plugin_dl_array); if (initialized) @@ -746,7 +748,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) tables.table_name= tables.alias= (char *)"plugin"; if (check_table_access(thd, INSERT_ACL, &tables, 0)) DBUG_RETURN(TRUE); - + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ if (! (table = open_ltable(thd, &tables, TL_WRITE))) DBUG_RETURN(TRUE); @@ -755,7 +757,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) if (plugin_add(name, dl, REPORT_TO_USER)) goto err; tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN); - + if (plugin_initialize(tmp)) { my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str, @@ -774,7 +776,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) table->file->print_error(error, MYF(0)); goto deinit; } - + rw_unlock(&THR_LOCK_plugin); DBUG_RETURN(FALSE); deinit: @@ -815,7 +817,7 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name) my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); goto err; } - + if (plugin->ref_count) { plugin->state= PLUGIN_IS_DELETED; @@ -858,13 +860,13 @@ my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, struct st_plugin_int *plugin; DBUG_ENTER("mysql_uninstall_plugin"); rw_rdlock(&THR_LOCK_plugin); - + if (type == MYSQL_ANY_PLUGIN) { for (idx= 0; idx < plugin_array.elements; idx++) { plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); - + /* FREED records may have garbage pointers */ if ((plugin->state != PLUGIN_IS_FREED) && func(thd, plugin, arg)) diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index f0b70ca9d26..ce06334ffd7 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -17,7 +17,17 @@ #ifndef _sql_plugin_h #define _sql_plugin_h +/* + the following #define adds server-only members to enum_mysql_show_type, + that is defined in plugin.h +*/ +#define SHOW_FUNC SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \ + SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, \ + SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH #include +#undef SHOW_FUNC +typedef enum enum_mysql_show_type SHOW_TYPE; +typedef struct st_mysql_show_var SHOW_VAR; #define MYSQL_ANY_PLUGIN -1 @@ -65,7 +75,7 @@ extern my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name); extern my_bool plugin_register_builtin(struct st_mysql_plugin *plugin); -typedef my_bool (plugin_foreach_func)(THD *thd, +typedef my_bool (plugin_foreach_func)(THD *thd, st_plugin_int *plugin, void *arg); extern my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e5723b27b5c..0de02337fff 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1516,8 +1516,163 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) Status functions *****************************************************************************/ +static DYNAMIC_ARRAY all_status_vars; +static bool status_vars_inited= 0; +static int show_var_cmp(const void *var1, const void *var2) +{ + return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); +} + +/* + deletes all the SHOW_UNDEF elements from the array and calls + delete_dynamic() if it's completely empty. +*/ +static void shrink_var_array(DYNAMIC_ARRAY *array) +{ + int a,b; + SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *); + + for (a= b= 0; b < array->elements; b++) + if (all[b].type != SHOW_UNDEF) + all[a++]= all[b]; + if (a) + { + bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end + array->elements= a; + } + else // array is completely empty - delete it + delete_dynamic(array); +} + +/* + Adds an array of SHOW_VAR entries to the output of SHOW STATUS + + SYNOPSIS + add_status_vars(SHOW_VAR *list) + list - an array of SHOW_VAR entries to add to all_status_vars + the last entry must be {0,0,SHOW_UNDEF} + + NOTE + The handling of all_status_vars[] is completely internal, it's allocated + automatically when something is added to it, and deleted completely when + the last entry is removed. + + As a special optimization, if add_status_vars() is called before + init_status_vars(), it assumes "startup mode" - neither concurrent access + to the array nor SHOW STATUS are possible (thus it skips locks and qsort) + + The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF} +*/ +int add_status_vars(SHOW_VAR *list) +{ + int res= 0; + if (status_vars_inited) + pthread_mutex_lock(&LOCK_status); + if (!all_status_vars.buffer && // array is not allocated yet - do it now + my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20)) + { + res= 1; + goto err; + } + while (list->name) + res|= insert_dynamic(&all_status_vars, (gptr)list++); + res|= insert_dynamic(&all_status_vars, (gptr)list); // appending NULL-element + all_status_vars.elements--; // but next insert_dynamic should overwite it + if (status_vars_inited) + sort_dynamic(&all_status_vars, show_var_cmp); +err: + if (status_vars_inited) + pthread_mutex_unlock(&LOCK_status); + return res; +} + +/* + Make all_status_vars[] usable for SHOW STATUS + + NOTE + See add_status_vars(). Before init_status_vars() call, add_status_vars() + works in a special fast "startup" mode. Thus init_status_vars() + should be called as late as possible but before enabling multi-threading. +*/ +void init_status_vars() +{ + status_vars_inited=1; + sort_dynamic(&all_status_vars, show_var_cmp); +} + +/* + catch-all cleanup function, cleans up everything no matter what + + DESCRIPTION + This function is not strictly required if all add_to_status/ + remove_status_vars are properly paired, but it's a safety measure that + deletes everything from the all_status_vars[] even if some + remove_status_vars were forgotten +*/ +void free_status_vars() +{ + delete_dynamic(&all_status_vars); +} + +/* + Removes an array of SHOW_VAR entries from the output of SHOW STATUS + + SYNOPSIS + remove_status_vars(SHOW_VAR *list) + list - an array of SHOW_VAR entries to remove to all_status_vars + the last entry must be {0,0,SHOW_UNDEF} + + NOTE + there's lots of room for optimizing this, especially in non-sorted mode, + but nobody cares - it may be called only in case of failed plugin + initialization in the mysqld startup. + +*/ +void remove_status_vars(SHOW_VAR *list) +{ + if (status_vars_inited) + { + pthread_mutex_lock(&LOCK_status); + SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *); + int a= 0, b= all_status_vars.elements, c= (a+b)/2, res; + + for (; list->name; list++) + { + for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2) + { + res= show_var_cmp(list, all+c); + if (res < 0) + b= c; + else if (res > 0) + a= c; + else break; + } + if (res == 0) + all[c].type= SHOW_UNDEF; + } + shrink_var_array(&all_status_vars); + pthread_mutex_unlock(&LOCK_status); + } + else + { + SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *); + int i; + for (; list->name; list++) + { + for (i= 0; i < all_status_vars.elements; i++) + { + if (show_var_cmp(list, all+i)) + continue; + all[i].type= SHOW_UNDEF; + break; + } + } + shrink_var_array(&all_status_vars); + } +} + static bool show_status_array(THD *thd, const char *wild, - show_var_st *variables, + SHOW_VAR *variables, enum enum_var_type value_type, struct system_status_var *status_var, const char *prefix, TABLE *table) @@ -1527,13 +1682,15 @@ static bool show_status_array(THD *thd, const char *wild, char name_buffer[80]; int len; LEX_STRING null_lex_str; - struct show_var_st tmp, *var; + SHOW_VAR tmp, *var; DBUG_ENTER("show_status_array"); null_lex_str.str= 0; // For sys_var->value_ptr() null_lex_str.length= 0; prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1); + if (*prefix) + *prefix_end++= '_'; len=name_buffer + sizeof(name_buffer) - prefix_end; for (; variables->name; variables++) @@ -1541,13 +1698,17 @@ static bool show_status_array(THD *thd, const char *wild, strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ + /* + if var->type is SHOW_FUNC, call the function. + Repeat as necessary, if new var is again SHOW_FUNC + */ for (var=variables; var->type == SHOW_FUNC; var= &tmp) - ((show_var_func)(var->value))(thd, &tmp, buff); + ((mysql_show_var_func)(var->value))(thd, &tmp, buff); SHOW_TYPE show_type=var->type; if (show_type == SHOW_ARRAY) { - show_status_array(thd, wild, (show_var_st *) var->value, + show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type, status_var, name_buffer, table); } else @@ -1578,11 +1739,10 @@ static bool show_status_array(THD *thd, const char *wild, break; } case SHOW_LONG_STATUS: - case SHOW_LONG_CONST_STATUS: value= ((char *) status_var + (ulong) value); /* fall through */ case SHOW_LONG: - case SHOW_LONG_CONST: + case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status() end= int10_to_str(*(long*) value, buff, 10); break; case SHOW_LONGLONG: @@ -1597,7 +1757,6 @@ static bool show_status_array(THD *thd, const char *wild, case SHOW_MY_BOOL: end= strmov(buff, *(my_bool*) value ? "ON" : "OFF"); break; - case SHOW_INT_CONST: case SHOW_INT: end= int10_to_str((long) *(uint32*) value, buff, 10); break; @@ -1623,7 +1782,6 @@ static bool show_status_array(THD *thd, const char *wild, break; } case SHOW_KEY_CACHE_LONG: - case SHOW_KEY_CACHE_CONST_LONG: value= (char*) dflt_key_cache + (ulong)value; end= int10_to_str(*(long*) value, buff, 10); break; @@ -1632,9 +1790,10 @@ static bool show_status_array(THD *thd, const char *wild, end= longlong10_to_str(*(longlong*) value, buff, 10); break; case SHOW_UNDEF: - case SHOW_SYS: - break; // Return empty string + break; // Return empty string + case SHOW_SYS: // Cannot happen default: + DBUG_ASSERT(0); break; } restore_record(table, s->default_values); @@ -3357,7 +3516,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; pthread_mutex_lock(&LOCK_global_system_variables); - res= show_status_array(thd, wild, init_vars, + res= show_status_array(thd, wild, init_vars, lex->option_type, 0, "", tables->table); pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); @@ -3374,8 +3533,10 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) pthread_mutex_lock(&LOCK_status); if (lex->option_type == OPT_GLOBAL) calc_sum_of_all_status(&tmp); - res= show_status_array(thd, wild, status_vars, OPT_GLOBAL, - (lex->option_type == OPT_GLOBAL ? + res= show_status_array(thd, wild, + (SHOW_VAR *)all_status_vars.buffer, + OPT_GLOBAL, + (lex->option_type == OPT_GLOBAL ? &tmp: &thd->status_var), "",tables->table); pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); @@ -4146,7 +4307,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0}, {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status"}, - {"PLUGIN_TYPE", 10, MYSQL_TYPE_STRING, 0, 0, "Type"}, + {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type"}, {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0}, {"PLUGIN_LIBRARY", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"}, {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0}, diff --git a/sql/structs.h b/sql/structs.h index d16591c5453..e369d8ed7e8 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -169,32 +169,11 @@ typedef struct st_known_date_time_format { const char *time_format; } KNOWN_DATE_TIME_FORMAT; - -enum SHOW_TYPE -{ - SHOW_UNDEF, - SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_DOUBLE_STATUS, SHOW_BOOL, SHOW_MY_BOOL, - SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS, - SHOW_ARRAY, SHOW_FUNC, - SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG, - SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS -}; - enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; extern const char *show_comp_option_name[]; -typedef int *(*update_var)(THD *, struct show_var_st *); - -typedef struct show_var_st { - const char *name; - char *value; - SHOW_TYPE type; -} SHOW_VAR; - -#define SHOW_VAR_FUNC_BUFF_SIZE 1024 -typedef int (*show_var_func)(THD *, struct show_var_st *, char *); +typedef int *(*update_var)(THD *, struct st_mysql_show_var *); typedef struct st_lex_user { LEX_STRING user, host, password; From 86e35affcf4bb6999b9175ac4fd0b8dedfcd6fb2 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sat, 7 Jan 2006 16:27:40 +0100 Subject: [PATCH 41/49] after merge fix --- sql/ha_ndbcluster.cc | 2 +- sql/ha_ndbcluster.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index a72bfa7d170..7bb0eca20b1 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -224,7 +224,7 @@ static int update_status_variables(Ndb_cluster_connection *c) return 0; } -struct show_var_st ndb_status_variables[]= { +SHOW_VAR ndb_status_variables[]= { {"cluster_node_id", (char*) &ndb_cluster_node_id, SHOW_LONG}, {"connected_host", (char*) &ndb_connected_host, SHOW_CHAR_PTR}, {"connected_port", (char*) &ndb_connected_port, SHOW_LONG}, diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index fb506375797..2c6af550ffe 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -769,7 +769,7 @@ private: Ndb *get_ndb(); }; -extern struct show_var_st ndb_status_variables[]; +extern SHOW_VAR ndb_status_variables[]; bool ndbcluster_init(void); int ndbcluster_end(ha_panic_function flag); From 44ea4f5441dba0960c47d7733796bd8cf96848dd Mon Sep 17 00:00:00 2001 From: "pekka@mysql.com" <> Date: Mon, 9 Jan 2006 01:09:42 +0100 Subject: [PATCH 42/49] ndb - wl#2972 ndb api test_event_merge 5.0+5.1 --- ndb/test/ndbapi/test_event_merge.cpp | 1245 ++++++++++++++++++-------- 1 file changed, 877 insertions(+), 368 deletions(-) diff --git a/ndb/test/ndbapi/test_event_merge.cpp b/ndb/test/ndbapi/test_event_merge.cpp index 1332455cdc5..f57667caf62 100644 --- a/ndb/test/ndbapi/test_event_merge.cpp +++ b/ndb/test/ndbapi/test_event_merge.cpp @@ -27,6 +27,9 @@ #undef version50 #endif +// until rbr in 5.1 +#undef version51rbr + #if !defined(min) || !defined(max) #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) @@ -42,13 +45,20 @@ * 2) In event API version >= 5.1 separate commits within same GCI are * by default merged. This is required to read blob data via NdbBlob. * - * This test program ignores Blob columns in version 5.0. + * Option --separate-events disables GCI merge and implies --no-blobs. + * This is used to test basic events functionality. + * + * Option --no-blobs omits blob attributes. This is used to test GCI + * merge without getting into blob bugs. + * + * Option --no-multiops allows 1 operation per commit. This avoids TUP + * and blob multi-operation bugs. * * There are 5 ways (ignoring NUL operand) to compose 2 ops: * 5.0 bugs 5.1 bugs * INS o DEL = NUL - * INS o UPD = INS 5.1 - * DEL o INS = UPD type=INS 5.1 + * INS o UPD = INS type=INS + * DEL o INS = UPD type=INS type=INS * UPD o DEL = DEL no event * UPD o UPD = UPD */ @@ -59,41 +69,69 @@ struct Opts { uint loop; uint maxops; uint maxpk; - const char* opstr; + my_bool no_blobs; + my_bool no_multiops; + my_bool one_blob; + const char* opstring; uint seed; my_bool separate_events; my_bool use_table; }; static Opts g_opts; -static const uint g_maxops = 10000; static const uint g_maxpk = 100; +static const uint g_maxopstringpart = 100; +static const char* g_opstringpart[g_maxopstringpart]; +static uint g_opstringparts = 0; +static uint g_loop = 0; static Ndb_cluster_connection* g_ncc = 0; static Ndb* g_ndb = 0; static NdbDictionary::Dictionary* g_dic = 0; static NdbTransaction* g_con = 0; static NdbOperation* g_op = 0; +static NdbScanOperation* g_scan_op = 0; static const char* g_tabname = "tem1"; static const char* g_evtname = "tem1ev1"; static const uint g_charlen = 5; +static const char* g_charval = "abcdefgh"; static const char* g_csname = "latin1_swedish_ci"; +static uint g_blobinlinesize = 256; +static uint g_blobpartsize = 2000; +static uint g_blobstripesize = 2; +static const uint g_maxblobsize = 100000; + static const NdbDictionary::Table* g_tab = 0; static const NdbDictionary::Event* g_evt = 0; static NdbEventOperation* g_evt_op = 0; +static NdbBlob* g_bh = 0; static uint -urandom(uint n) +urandom() { uint r = (uint)random(); - if (n != 0) - r = r % n; return r; } +static uint +urandom(uint m) +{ + if (m == 0) + return 0; + uint r = urandom(); + r = r % m; + return r; +} + +static bool +urandom(uint per, uint cent) +{ + return urandom(cent) < per; +} + static int& g_loglevel = g_opts.loglevel; // default log level #define chkdb(x) \ @@ -138,11 +176,21 @@ errdb() if (e.code != 0) ll0(++any << " op: error " << e); } + if (g_scan_op != 0) { + const NdbError& e = g_scan_op->getNdbError(); + if (e.code != 0) + ll0(++any << " scan_op: error " << e); + } if (g_evt_op != 0) { const NdbError& e = g_evt_op->getNdbError(); if (e.code != 0) ll0(++any << " evt_op: error " << e); } + if (g_bh != 0) { + const NdbError& e = g_bh->getNdbError(); + if (e.code != 0) + ll0(++any << " evt_op: error " << e); + } if (! any) ll0("unknown db error"); } @@ -155,31 +203,47 @@ struct Col { bool nullable; uint length; uint size; + bool isblob() const { + return type == NdbDictionary::Column::Text; + } }; static Col g_col[] = { { 0, "pk1", NdbDictionary::Column::Unsigned, true, false, 1, 4 }, { 1, "pk2", NdbDictionary::Column::Char, true, false, g_charlen, g_charlen }, { 2, "seq", NdbDictionary::Column::Unsigned, false, false, 1, 4 }, - { 3, "cc1", NdbDictionary::Column::Char, false, true, g_charlen, g_charlen } + { 3, "cc1", NdbDictionary::Column::Char, false, true, g_charlen, g_charlen }, + { 4, "tx1", NdbDictionary::Column::Text, false, true, 0, 0 }, + { 5, "tx2", NdbDictionary::Column::Text, false, true, 0, 0 } }; -static const uint g_ncol = sizeof(g_col)/sizeof(g_col[0]); +static const uint g_maxcol = sizeof(g_col)/sizeof(g_col[0]); + +static uint +ncol() +{ + uint n = g_maxcol; + if (g_opts.no_blobs) + n -= 2; + else if (g_opts.one_blob) + n -= 1; + return n; +} static const Col& getcol(uint i) { - if (i < g_ncol) + if (i < ncol()) return g_col[i]; assert(false); - return g_col[g_ncol]; + return g_col[0]; } static const Col& getcol(const char* name) { uint i; - for (i = 0; i < g_ncol; i++) + for (i = 0; i < ncol(); i++) if (strcmp(g_col[i].name, name) == 0) break; return getcol(i); @@ -194,7 +258,7 @@ createtable() CHARSET_INFO* cs; chkrc((cs = get_charset_by_name(g_csname, MYF(0))) != 0); uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = g_col[i]; NdbDictionary::Column col(c.name); col.setType(c.type); @@ -209,6 +273,12 @@ createtable() col.setLength(c.length); col.setCharset(cs); break; + case NdbDictionary::Column::Text: + col.setInlineSize(g_blobinlinesize); + col.setPartSize(g_blobpartsize); + col.setStripeSize(g_blobstripesize); + col.setCharset(cs); + break; default: assert(false); break; @@ -229,9 +299,9 @@ createtable() chkdb((g_op = g_con->getNdbOperation(g_tabname)) != 0); chkdb(g_op->insertTuple() == 0); Uint32 pk1; - char pk2[g_charlen]; + char pk2[g_charlen + 1]; pk1 = g_maxpk; - memset(pk2, 0x20, g_charlen); + sprintf(pk2, "%-*u", g_charlen, pk1); chkdb(g_op->equal("pk1", (char*)&pk1) == 0); chkdb(g_op->equal("pk2", (char*)&pk2[0]) == 0); chkdb(g_con->execute(Commit) == 0); @@ -255,34 +325,86 @@ droptable() } struct Data { + struct Txt { char* val; uint len; }; + union Ptr { Uint32* u32; char* ch; Txt* txt; void* v; }; Uint32 pk1; - char pk2[g_charlen]; + char pk2[g_charlen + 1]; Uint32 seq; - char cc1[g_charlen]; - void* ptr[g_ncol]; - int ind[g_ncol]; // -1 = no data, 1 = NULL, 0 = not NULL + char cc1[g_charlen + 1]; + Txt tx1; + Txt tx2; + Ptr ptr[g_maxcol]; + int ind[g_maxcol]; // -1 = no data, 1 = NULL, 0 = not NULL + uint noop; // bit: omit in NdbOperation (implicit NULL INS or no UPD) + uint ppeq; // bit: post/pre data value equal in GCI data[0]/data[1] void init() { uint i; pk1 = 0; memset(pk2, 0, sizeof(pk2)); seq = 0; memset(cc1, 0, sizeof(cc1)); - ptr[0] = &pk1; - ptr[1] = pk2; - ptr[2] = &seq; - ptr[3] = cc1; - for (i = 0; i < g_ncol; i++) + tx1.val = tx2.val = 0; + tx1.len = tx2.len = 0; + ptr[0].u32 = &pk1; + ptr[1].ch = pk2; + ptr[2].u32 = &seq; + ptr[3].ch = cc1; + ptr[4].txt = &tx1; + ptr[5].txt = &tx2; + for (i = 0; i < g_maxcol; i++) ind[i] = -1; + noop = 0; + ppeq = 0; + } + void free() { + delete [] tx1.val; + delete [] tx2.val; + init(); } }; +static int +cmpcol(const Col& c, const Data& d1, const Data& d2) +{ + uint i = c.no; + if (d1.ind[i] != d2.ind[i]) + return 1; + if (d1.ind[i] == 0) { + switch (c.type) { + case NdbDictionary::Column::Unsigned: + if (*d1.ptr[i].u32 != *d2.ptr[i].u32) + return 1; + break; + case NdbDictionary::Column::Char: + if (memcmp(d1.ptr[i].ch, d2.ptr[i].ch, c.size) != 0) + return 1; + break; + case NdbDictionary::Column::Text: + { + const Data::Txt& t1 = *d1.ptr[i].txt; + const Data::Txt& t2 = *d2.ptr[i].txt; + if (t1.len != t2.len) + return 1; + if (memcmp(t1.val, t2.val, t1.len) != 0) + return 1; + } + break; + default: + assert(false); + break; + } + } + return 0; +} + static NdbOut& operator<<(NdbOut& out, const Data& d) { uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = getcol(i); - out << (i == 0 ? "" : " ") << c.name << "="; + out << (i == 0 ? "" : " ") << c.name; + out << (! (d.noop & (1 << i)) ? "=" : ":"); if (d.ind[i] == -1) continue; if (d.ind[i] == 1) { @@ -291,12 +413,12 @@ operator<<(NdbOut& out, const Data& d) } switch (c.type) { case NdbDictionary::Column::Unsigned: - out << *(Uint32*)d.ptr[i]; + out << *d.ptr[i].u32; break; case NdbDictionary::Column::Char: { char buf[g_charlen + 1]; - memcpy(buf, d.ptr[i], g_charlen); + memcpy(buf, d.ptr[i].ch, g_charlen); uint n = g_charlen; while (1) { buf[n] = 0; @@ -304,11 +426,30 @@ operator<<(NdbOut& out, const Data& d) break; n--; } - out << buf; + out << "'" << buf << "'"; + } + break; + case NdbDictionary::Column::Text: + { + Data::Txt& t = *d.ptr[i].txt; + bool first = true; + uint j = 0; + while (j < t.len) { + char c[2]; + c[0] = t.val[j++]; + c[1] = 0; + uint m = 1; + while (j < t.len && t.val[j] == c[0]) + j++, m++; + if (! first) + out << "+"; + first = false; + out << m << c; + } } break; default: - out << "?"; + assert(false); break; } } @@ -329,18 +470,26 @@ struct Op { // single or composite Type type; Op* next_op; // within one commit Op* next_com; // next commit chain or next event + Op* next_gci; // groups commit chains (unless --separate-events) + Op* next_ev; + Op* next_free; // free list + bool free; // on free list uint num_op; uint num_com; Data data[2]; // 0-post 1-pre bool match; // matched to event - void init() { + Uint32 gci; // defined for com op and event + void init(Kind a_kind) { + kind = a_kind; assert(kind == OP || kind == EV); type = NUL; - next_op = next_com = 0; + next_op = next_com = next_gci = next_ev = next_free = 0; + free = false; num_op = num_com = 0; data[0].init(); data[1].init(); match = false; + gci = 0; } }; @@ -370,9 +519,11 @@ operator<<(NdbOut& out, Op::Type t) static NdbOut& operator<<(NdbOut& out, const Op& op) { - out << "t=" << op.type; + out << op.type; out << " " << op.data[0]; out << " [" << op.data[1] << "]"; + if (op.gci != 0) + out << " gci:" << op.gci; return out; } @@ -398,75 +549,104 @@ seteventtype(Op* ev, NdbDictionary::Event::TableEvent te) return 0; } +static Op* g_opfree = 0; +static uint g_freeops = 0; static uint g_usedops = 0; -static uint g_usedevs = 0; -static Op g_oplist[g_maxops]; -static Op g_evlist[g_maxops]; -static uint g_maxcom = 8; // max ops per commit - +static uint g_maxcom = 10; // max ops per commit static Op* g_pk_op[g_maxpk]; static Op* g_pk_ev[g_maxpk]; static uint g_seq = 0; - -static NdbRecAttr* g_ra[2][g_ncol]; // 0-post 1-pre +static NdbRecAttr* g_ev_ra[2][g_maxcol]; // 0-post 1-pre +static NdbBlob* g_ev_bh[2][g_maxcol]; // 0-post 1-pre static Op* g_rec_ev; -static uint g_ev_cnt[g_maxpk]; - -static uint -getfreeops() -{ - assert(g_opts.maxops >= g_usedops); - return g_opts.maxops - g_usedops; -} - -static uint -getfreeevs() -{ - assert(g_opts.maxops >= g_usedevs); - return g_opts.maxops - g_usedevs; -} +static uint g_ev_pos[g_maxpk]; static Op* -getop() +getop(Op::Kind a_kind) { - if (g_usedops < g_opts.maxops) { - Op* op = &g_oplist[g_usedops++]; - op->kind = Op::OP; - op->init(); - return op; + if (g_opfree == 0) { + assert(g_freeops == 0); + Op* op = new Op; + assert(op != 0); + op->next_free = g_opfree; + g_opfree = op; + op->free = true; + g_freeops++; } - assert(false); - return 0; + Op* op = g_opfree; + g_opfree = op->next_free; + assert(g_freeops != 0); + g_freeops--; + g_usedops++; + op->init(a_kind); + return op; } -static Op* -getev() +static void +freeop(Op* op) { - if (g_usedevs < g_opts.maxops) { - Op* ev = &g_evlist[g_usedevs++]; - ev->kind = Op::EV; - ev->init(); - return ev; - } - assert(false); - return 0; + assert(! op->free); + op->data[0].free(); + op->data[1].free(); + op->free = true; + op->next_free = g_opfree; + g_opfree = op; + g_freeops++; + assert(g_usedops != 0); + g_usedops--; } static void resetmem() { int i, j; - for (j = 0; j < 2; j++) - for (i = 0; i < g_ncol; i++) - g_ra[j][i] = 0; - g_rec_ev = 0; - for (i = 0; i < g_opts.maxpk; i++) - g_pk_op[i] = 0; - for (i = 0; i < g_opts.maxpk; i++) - g_ev_cnt[i] = 0; - g_seq = 0; - g_usedops = 0; - g_usedevs = 0; + for (j = 0; j < 2; j++) { + for (i = 0; i < g_maxcol; i++) { + g_ev_ra[j][i] = 0; + g_ev_bh[j][i] = 0; + } + } + if (g_rec_ev != 0) { + freeop(g_rec_ev); + g_rec_ev = 0; + } + Uint32 pk1; + for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) + g_ev_pos[pk1] = 0; + // leave g_seq + for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) { + if (g_pk_op[pk1] != 0) { + Op* tot_op = g_pk_op[pk1]; + while (tot_op->next_gci != 0) { + Op* gci_op = tot_op->next_gci; + while (gci_op->next_com != 0) { + Op* com_op = gci_op->next_com; + while (com_op->next_op != 0) { + Op* op = com_op->next_op; + com_op->next_op = op->next_op; + freeop(op); + } + gci_op->next_com = com_op->next_com; + freeop(com_op); + } + tot_op->next_gci = gci_op->next_gci; + freeop(gci_op); + } + freeop(tot_op); + g_pk_op[pk1] = 0; + } + if (g_pk_ev[pk1] != 0) { + Op* tot_op = g_pk_ev[pk1]; + while (tot_op->next_ev != 0) { + Op* ev = tot_op->next_ev; + tot_op->next_ev = ev->next_ev; + freeop(ev); + } + freeop(tot_op); + g_pk_ev[pk1] = 0; + } + } + assert(g_usedops == 0); } struct Comp { @@ -487,43 +667,43 @@ static const uint g_ncomp = sizeof(g_comp)/sizeof(g_comp[0]); static int checkop(const Op* op, Uint32& pk1) { - const Data (&d)[2] = op->data; Op::Type t = op->type; - chkrc(t == Op::NUL || t == Op::INS || t == Op::DEL || t == Op::UPD); - { const Col& c = getcol("pk1"); - chkrc(d[0].ind[c.no] == 0); - pk1 = d[0].pk1; + if (t == Op::NUL) + return 0; + chkrc(t == Op::INS || t == Op::DEL || t == Op::UPD); + const Data& d0 = op->data[0]; + const Data& d1 = op->data[1]; + { + const Col& c = getcol("pk1"); + chkrc(d0.ind[c.no] == 0); + pk1 = d0.pk1; chkrc(pk1 < g_opts.maxpk); } uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = getcol(i); - if (t != Op::NUL) { - if (c.pk) { - chkrc(d[0].ind[i] == 0); // even DEL has PK in post data - if (t == Op::INS) { - chkrc(d[1].ind[i] == -1); - } else if (t == Op::DEL) { -#ifdef ndb_event_cares_about_pk_pre_data - chkrc(d[1].ind[i] == -1); -#endif - } else { -#ifdef ndb_event_cares_about_pk_pre_data - chkrc(d[1].ind[i] == 0); -#endif - } - } else { - if (t == Op::INS) { - chkrc(d[0].ind[i] >= 0); - chkrc(d[1].ind[i] == -1); - } else if (t == Op::DEL) { - chkrc(d[0].ind[i] == -1); - chkrc(d[1].ind[i] >= 0); - } else if (op->kind == Op::OP) { - chkrc(d[0].ind[i] >= 0); - chkrc(d[1].ind[i] >= 0); - } - } + const int ind0 = d0.ind[i]; + const int ind1 = d1.ind[i]; + // the rules are the rules.. + if (c.pk) { + chkrc(ind0 == 0); // always PK in post data + if (t == Op::INS) + chkrc(ind1 == -1); + if (t == Op::DEL) + chkrc(ind1 == -1); // no PK in pre data + if (t == Op::UPD) + chkrc(ind1 == 0); + } + if (! c.pk) { + if (t == Op::INS) + chkrc(ind0 >= 0 && ind1 == -1); + if (t == Op::DEL) + chkrc(ind0 == -1 && ind1 >= 0); // always non-PK in pre data + if (t == Op::UPD) + chkrc(ind0 == -1 || ind1 >= 0); // update must have pre data + } + if (! c.nullable) { + chkrc(ind0 <= 0 && ind1 <= 0); } } return 0; @@ -542,28 +722,51 @@ comptype(Op::Type t1, Op::Type t2) // only non-NUL static void copycol(const Col& c, const Data& d1, Data& d3) { - if ((d3.ind[c.no] = d1.ind[c.no]) != -1) - memmove(d3.ptr[c.no], d1.ptr[c.no], c.size); + uint i = c.no; + if ((d3.ind[i] = d1.ind[i]) == 0) { + if (! c.isblob()) { + memmove(d3.ptr[i].v, d1.ptr[i].v, c.size); + } else { + Data::Txt& t1 = *d1.ptr[i].txt; + Data::Txt& t3 = *d3.ptr[i].txt; + delete [] t3.val; + t3.val = new char [t1.len]; + t3.len = t1.len; + memcpy(t3.val, t1.val, t1.len); + } + } } static void -copykeys(const Data& d1, Data& d3) +copydata(const Data& d1, Data& d3, bool pk, bool nonpk) { uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = g_col[i]; - if (c.pk) + if (c.pk && pk || ! c.pk && nonpk) copycol(c, d1, d3); } } static void -copydata(const Data& d1, Data& d3) +compdata(const Data& d1, const Data& d2, Data& d3, bool pk, bool nonpk) { uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = g_col[i]; - copycol(c, d1, d3); + if (c.pk && pk || ! c.pk && nonpk) { + const Data* d = 0; + if (d1.ind[i] == -1 && d2.ind[i] == -1) + d3.ind[i] = -1; + else if (d1.ind[i] == -1 && d2.ind[i] != -1) + d = &d2; + else if (d1.ind[i] != -1 && d2.ind[i] == -1) + d = &d1; + else + d = &d2; + if (d != 0) + copycol(c, *d, d3); + } } } @@ -571,33 +774,13 @@ static void copyop(const Op* op1, Op* op3) { op3->type = op1->type; - copydata(op1->data[0], op3->data[0]); - copydata(op1->data[1], op3->data[1]); + copydata(op1->data[0], op3->data[0], true, true); + copydata(op1->data[1], op3->data[1], true, true); + op3->gci = op1->gci; Uint32 pk1_tmp; reqrc(checkop(op3, pk1_tmp) == 0); } -// not needed for ops -static void -compdata(const Data& d1, const Data& d2, Data& d3) // d2 overrides d1 -{ - uint i; - for (i = 0; i < g_ncol; i++) { - const Col& c = g_col[i]; - const Data* d = 0; - if (d1.ind[i] == -1 && d2.ind[i] == -1) - d3.ind[i] = -1; - else if (d1.ind[i] == -1 && d2.ind[i] != -1) - d = &d2; - else if (d1.ind[i] != -1 && d2.ind[i] == -1) - d = &d1; - else - d = &d2; - if (d != 0) - copycol(c, *d, d3); - } -} - static int compop(const Op* op1, const Op* op2, Op* op3) // op1 o op2 = op3 { @@ -610,16 +793,38 @@ compop(const Op* op1, const Op* op2, Op* op3) // op1 o op2 = op3 copyop(op2, op3); return 0; } + Op::Kind kind = + op1->kind == Op::OP && op2->kind == Op::OP ? Op::OP : Op::EV; + Op* res_op = getop(kind); chkrc((comp = comptype(op1->type, op2->type)) != 0); - op3->type = comp->t3; - copykeys(op2->data[0], op3->data[0]); - if (op3->type != Op::DEL) - copydata(op2->data[0], op3->data[0]); - if (op3->type != Op::INS) - copydata(op1->data[1], op3->data[1]); + res_op->type = comp->t3; + if (res_op->type == Op::INS) { + // INS o UPD + compdata(op1->data[0], op2->data[0], res_op->data[0], true, true); + // pre = undef + } + if (res_op->type == Op::DEL) { + // UPD o DEL + copydata(op2->data[0], res_op->data[0], true, false); // PK + copydata(op1->data[1], res_op->data[1], false, true); // non-PK + } + if (res_op->type == Op::UPD && op1->type == Op::DEL) { + // DEL o INS + copydata(op2->data[0], res_op->data[0], true, true); + copydata(op1->data[0], res_op->data[1], true, false); // PK + copydata(op1->data[1], res_op->data[1], false, true); // non-PK + } + if (res_op->type == Op::UPD && op1->type == Op::UPD) { + // UPD o UPD + compdata(op1->data[0], op2->data[0], res_op->data[0], true, true); + compdata(op2->data[1], op1->data[1], res_op->data[1], true, true); + } + assert(op1->gci == op2->gci); + res_op->gci = op2->gci; Uint32 pk1_tmp; - reqrc(checkop(op3, pk1_tmp) == 0); - // not eliminating identical post-pre fields + reqrc(checkop(res_op, pk1_tmp) == 0); + copyop(res_op, op3); + freeop(res_op); return 0; } @@ -632,12 +837,14 @@ createevent() NdbDictionary::Event evt(g_evtname); evt.setTable(*g_tab); evt.addTableEvent(NdbDictionary::Event::TE_ALL); - // pk always - evt.addEventColumn("pk1"); - evt.addEventColumn("pk2"); - // simple cols - evt.addEventColumn("seq"); - evt.addEventColumn("cc1"); + uint i; + for (i = 0; i < ncol(); i++) { + const Col& c = g_col[i]; + evt.addEventColumn(c.name); + } +#ifdef version51rbr + evt.separateEvents(g_opts.separate_events); +#endif if (g_dic->getEvent(evt.getName()) != 0) chkdb(g_dic->dropEvent(evt.getName()) == 0); chkdb(g_dic->createEvent(evt) == 0); @@ -666,20 +873,22 @@ createeventop() chkdb((g_evt_op = g_ndb->createEventOperation(g_evt->getName(), bsz)) != 0); #else chkdb((g_evt_op = g_ndb->createEventOperation(g_evt->getName())) != 0); +#ifdef version51rbr + g_evt_op->separateEvents(g_opts.separate_events); // not yet inherited +#endif #endif uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = g_col[i]; Data (&d)[2] = g_rec_ev->data; - switch (c.type) { - case NdbDictionary::Column::Unsigned: - case NdbDictionary::Column::Char: - chkdb((g_ra[0][i] = g_evt_op->getValue(c.name, (char*)d[0].ptr[i])) != 0); - chkdb((g_ra[1][i] = g_evt_op->getPreValue(c.name, (char*)d[1].ptr[i])) != 0); - break; - default: - assert(false); - break; + if (! c.isblob()) { + chkdb((g_ev_ra[0][i] = g_evt_op->getValue(c.name, (char*)d[0].ptr[i].v)) != 0); + chkdb((g_ev_ra[1][i] = g_evt_op->getPreValue(c.name, (char*)d[1].ptr[i].v)) != 0); + } else { +#ifdef version51rbr + chkdb((g_ev_bh[0][i] = g_evt_op->getBlobHandle(c.name)) != 0); + chkdb((g_ev_bh[1][i] = g_evt_op->getPreBlobHandle(c.name)) != 0); +#endif } } return 0; @@ -705,9 +914,9 @@ waitgci() // wait for event to be installed and for at least 1 GCI to pass chkdb((g_con = g_ndb->startTransaction()) != 0); { // forced to exec a dummy op Uint32 pk1; - char pk2[g_charlen]; + char pk2[g_charlen + 1]; pk1 = g_maxpk; - memset(pk2, 0x20, g_charlen); + sprintf(pk2, "%-*u", g_charlen, pk1); chkdb((g_op = g_con->getNdbOperation(g_tabname)) != 0); chkdb(g_op->readTuple() == 0); chkdb(g_op->equal("pk1", (char*)&pk1) == 0); @@ -723,61 +932,153 @@ waitgci() // wait for event to be installed and for at least 1 GCI to pass break; } i = 1; + sleep(1); } return 0; } +// scan table and set current tot_op for each pk1 static int -makeop(Op* op, Uint32 pk1, Op::Type t, const Op* prev_op) +scantab() { - op->type = t; - if (t != Op::INS) - copydata(prev_op->data[0], op->data[1]); + NdbRecAttr* ra[g_maxcol]; + NdbBlob* bh[g_maxcol]; + Op* rec_op = getop(Op::OP); + Data& d0 = rec_op->data[0]; + chkdb((g_con = g_ndb->startTransaction()) != 0); + chkdb((g_scan_op = g_con->getNdbScanOperation(g_tabname)) != 0); + chkdb(g_scan_op->readTuples() == 0); uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = getcol(i); - Data (&d)[2] = op->data; - if (i == getcol("pk1").no) { - d[0].pk1 = pk1; - d[0].ind[i] = 0; - continue; + if (! c.isblob()) { + chkdb((ra[i] = g_scan_op->getValue(c.name, (char*)d0.ptr[i].v)) != 0); + } else { + chkdb((bh[i] = g_scan_op->getBlobHandle(c.name)) != 0); } - if (i == getcol("pk2").no) { - sprintf(d[0].pk2, "%-*u", g_charlen, d[0].pk1); - d[0].ind[i] = 0; - continue; - } - if (t == Op::DEL) { - d[0].ind[i] = -1; - continue; - } - if (i == getcol("seq").no) { - d[0].seq = g_seq++; - d[0].ind[i] = 0; - continue; - } - uint u; - u = urandom(100); - if (c.nullable && u < 20) { - d[0].ind[i] = 1; + } + chkdb(g_con->execute(NoCommit) == 0); + int ret; + while ((ret = g_scan_op->nextResult()) == 0) { + Uint32 pk1 = d0.pk1; + if (pk1 >= g_opts.maxpk) continue; + rec_op->type = Op::INS; + for (i = 0; i < ncol(); i++) { + const Col& c = getcol(i); + int ind; + if (! c.isblob()) { + ind = ra[i]->isNULL(); + } else { +#ifdef version51rbr + int ret; + ret = bh[i]->getDefined(ind); + assert(ret == 0); + if (ind == 0) { + Data::Txt& t = *d0.ptr[i].txt; + Uint64 len64; + ret = bh[i]->getLength(len64); + assert(ret == 0); + t.len = (uint)len64; + delete [] t.val; + t.val = new char [t.len]; + memset(t.val, 'X', t.len); + Uint32 len = t.len; + ret = bh[i]->readData(t.val, len); + assert(ret == 0 && len == t.len); + } +#endif + } + assert(ind >= 0); + d0.ind[i] = ind; } + assert(g_pk_op[pk1] == 0); + Op* tot_op = g_pk_op[pk1] = getop(Op::OP); + copyop(rec_op, tot_op); + tot_op->type = Op::INS; + } + chkdb(ret == 1); + g_ndb->closeTransaction(g_con); + g_scan_op = 0; + g_con = 0; + freeop(rec_op); + return 0; +} + +static void +makedata(const Col& c, Data& d, Uint32 pk1, Op::Type t) +{ + uint i = c.no; + if (c.pk) { switch (c.type) { case NdbDictionary::Column::Unsigned: { - u = urandom(0); - Uint32* p = (Uint32*)d[0].ptr[i]; + Uint32* p = d.ptr[i].u32; + *p = pk1; + } + break; + case NdbDictionary::Column::Char: + { + char* p = d.ptr[i].ch; + sprintf(p, "%-*u", g_charlen, pk1); + } + break; + default: + assert(false); + break; + } + d.ind[i] = 0; + } else if (t == Op::DEL) { + ; + } else if (i == getcol("seq").no) { + d.seq = g_seq++; + d.ind[i] = 0; + } else if (t == Op::INS && c.nullable && urandom(10, 100)) { + d.noop |= (1 << i); + d.ind[i] = 1; // implicit NULL value is known + } else if (t == Op::UPD && urandom(10, 100)) { + d.noop |= (1 << i); + d.ind[i] = -1; // fixed up in caller + } else if (c.nullable && urandom(10, 100)) { + d.ind[i] = 1; + } else { + switch (c.type) { + case NdbDictionary::Column::Unsigned: + { + Uint32* p = d.ptr[i].u32; + uint u = urandom(); *p = u; } break; case NdbDictionary::Column::Char: { - u = urandom(g_charlen); - char* p = (char*)d[0].ptr[i]; + char* p = d.ptr[i].ch; + uint u = urandom(g_charlen); uint j; for (j = 0; j < g_charlen; j++) { - uint v = urandom(3); - p[j] = j < u ? "abcde"[v] : 0x20; + uint v = urandom(strlen(g_charval)); + p[j] = j < u ? g_charval[v] : 0x20; + } + } + break; + case NdbDictionary::Column::Text: + { + Data::Txt& t = *d.ptr[i].txt; + uint u = urandom(g_maxblobsize); + u = urandom(u); // 4x bias for smaller blobs + u = urandom(u); + delete [] t.val; + t.val = new char [u]; + t.len = u; + uint j = 0; + while (j < u) { + assert(u > 0); + uint k = 1 + urandom(u - 1); + if (k > u - j) + k = u - j; + uint v = urandom(strlen(g_charval)); + memset(&t.val[j], g_charval[v], k); + j += k; } } break; @@ -785,74 +1086,78 @@ makeop(Op* op, Uint32 pk1, Op::Type t, const Op* prev_op) assert(false); break; } - d[0].ind[i] = 0; + d.ind[i] = 0; } - Uint32 pk1_tmp = ~(Uint32)0; - chkrc(checkop(op, pk1_tmp) == 0); - reqrc(pk1 == pk1_tmp); - return 0; } static void -makeop(Op* tot_op, Op* com_op, Uint32 pk1, Op::Type t) +makeop(const Op* prev_op, Op* op, Uint32 pk1, Op::Type t) { - Op tmp_op; - tmp_op.kind = Op::OP; - Op* op = getop(); - reqrc(makeop(op, pk1, t, tot_op) == 0); - // add to end - Op* last_op = com_op; - while (last_op->next_op != 0) - last_op = last_op->next_op; - last_op->next_op = op; - // merge into chain head - tmp_op.init(); - reqrc(compop(com_op, op, &tmp_op) == 0); - copyop(&tmp_op, com_op); - // merge into total op - tmp_op.init(); - reqrc(compop(tot_op, op, &tmp_op) == 0); - copyop(&tmp_op, tot_op); - // counts - com_op->num_op += 1; - tot_op->num_op += 1; + op->type = t; + const Data& dp = prev_op->data[0]; + Data& d0 = op->data[0]; + Data& d1 = op->data[1]; + uint i; + for (i = 0; i < ncol(); i++) { + const Col& c = getcol(i); + makedata(c, d0, pk1, t); + if (t == Op::INS) { + d1.ind[i] = -1; + } else if (t == Op::DEL) { + assert(dp.ind[i] >= 0); + if (c.pk) + d1.ind[i] = -1; + else + copycol(c, dp, d1); + } else if (t == Op::UPD) { + assert(dp.ind[i] >= 0); + if (d0.ind[i] == -1) // not updating this col + copycol(c, dp, d0); // must keep track of data + copycol(c, dp, d1); + } else { + assert(false); + } + } + Uint32 pk1_tmp = ~(Uint32)0; + reqrc(checkop(op, pk1_tmp) == 0); + reqrc(pk1 == pk1_tmp); } static void makeops() { ll1("makeops"); - uint resv = g_opts.opstr == 0 ? 2 * g_opts.maxpk : 0; // for final deletes - uint next = g_opts.opstr == 0 ? g_maxcom : strlen(g_opts.opstr); - Op tmp_op; - tmp_op.kind = Op::OP; Uint32 pk1 = 0; - while (getfreeops() >= resv + 2 + next && pk1 < g_opts.maxpk) { - if (g_opts.opstr == 0) + while (g_usedops < g_opts.maxops && pk1 < g_opts.maxpk) { + if (g_opts.opstring == 0) pk1 = urandom(g_opts.maxpk); - ll2("makeops: pk1=" << pk1 << " free=" << getfreeops()); + ll2("makeops: pk1=" << pk1); // total op on the pk so far // optype either NUL=initial/deleted or INS=created Op* tot_op = g_pk_op[pk1]; if (tot_op == 0) - tot_op = g_pk_op[pk1] = getop(); //1 + tot_op = g_pk_op[pk1] = getop(Op::OP); assert(tot_op->type == Op::NUL || tot_op->type == Op::INS); // add new commit chain to end - Op* last_com = tot_op; - while (last_com->next_com != 0) - last_com = last_com->next_com; - Op* com_op = getop(); //2 - last_com->next_com = com_op; + Op* last_gci = tot_op; + while (last_gci->next_gci != 0) + last_gci = last_gci->next_gci; + Op* gci_op = getop(Op::OP); + last_gci->next_gci = gci_op; + Op* com_op = getop(Op::OP); + gci_op->next_com = com_op; // length of random chain uint len = ~0; - if (g_opts.opstr == 0) + if (g_opts.opstring == 0) { len = 1 + urandom(g_maxcom - 1); + len = 1 + urandom(len - 1); // 2x bias for short chain + } ll2("makeops: com chain"); uint n = 0; while (1) { - // random or from g_opts.opstr + // random or from current g_opts.opstring part Op::Type t; - if (g_opts.opstr == 0) { + if (g_opts.opstring == 0) { if (n == len) break; do { @@ -860,10 +1165,11 @@ makeops() } while (tot_op->type == Op::NUL && (t == Op::DEL || t == Op::UPD) || tot_op->type == Op::INS && t == Op::INS); } else { - uint m = strlen(g_opts.opstr); + const char* str = g_opstringpart[g_loop % g_opstringparts]; + uint m = strlen(str); uint k = tot_op->num_com + tot_op->num_op; assert(k < m); - char c = g_opts.opstr[k]; + char c = str[k]; if (c == 'c') { if (k + 1 == m) pk1 += 1; @@ -874,30 +1180,27 @@ makeops() assert(q != 0); t = (Op::Type)(q - p); } - makeop(tot_op, com_op, pk1, t); + Op* op = getop(Op::OP); + makeop(tot_op, op, pk1, t); + // add to end + Op* last_op = com_op; + while (last_op->next_op != 0) + last_op = last_op->next_op; + last_op->next_op = op; + // merge into chain head and total op + reqrc(compop(com_op, op, com_op) == 0); + reqrc(compop(tot_op, op, tot_op) == 0); assert(tot_op->type == Op::NUL || tot_op->type == Op::INS); + // counts + com_op->num_op += 1; + tot_op->num_op += 1; n++; } + // copy to gci level + copyop(com_op, gci_op); tot_op->num_com += 1; } - assert(getfreeops() >= resv); - // terminate with DEL if necessary - for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) { - Op* tot_op = g_pk_op[pk1]; - if (tot_op == 0) - continue; - if (tot_op->type == Op::NUL) - continue; - assert(g_opts.opstr == 0); - Op* last_com = tot_op; - while (last_com->next_com != 0) - last_com = last_com->next_com; - Op* com_op = getop(); //1 - last_com->next_com = com_op; - makeop(tot_op, com_op, pk1, Op::DEL); - assert(tot_op->type == Op::NUL); - tot_op->num_com += 1; - } + ll1("makeops: used ops = " << g_usedops); } static int @@ -919,23 +1222,36 @@ addndbop(Op* op) break; } uint i; - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = getcol(i); const Data& d = op->data[0]; if (! c.pk) continue; - chkdb(g_op->equal(c.name, (char*)d.ptr[i]) == 0); + chkdb(g_op->equal(c.name, (const char*)d.ptr[i].v) == 0); } if (op->type != Op::DEL) { - for (i = 0; i < g_ncol; i++) { + for (i = 0; i < ncol(); i++) { const Col& c = getcol(i); const Data& d = op->data[0]; if (c.pk) continue; - if (d.ind[i] == -1) + if (d.noop & (1 << i)) continue; - const char* ptr = d.ind[i] == 0 ? (char*)d.ptr[i] : 0; - chkdb(g_op->setValue(c.name, ptr) == 0); + assert(d.ind[i] >= 0); + if (! c.isblob()) { + if (d.ind[i] == 0) + chkdb(g_op->setValue(c.name, (const char*)d.ptr[i].v) == 0); + else + chkdb(g_op->setValue(c.name, (const char*)0) == 0); + } else { + const Data::Txt& t = *d.ptr[i].txt; + g_bh = g_op->getBlobHandle(c.name); + if (d.ind[i] == 0) + chkdb(g_bh->setValue(t.val, t.len) == 0); + else + chkdb(g_bh->setValue(0, 0) == 0); + g_bh = 0; + } } } g_op = 0; @@ -947,40 +1263,43 @@ runops() { ll1("runops"); Uint32 pk1; - const Op* com_op[g_maxpk]; - uint left = 0; + Op* gci_op[g_maxpk]; + uint left = 0; // number of pks with ops for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) { - com_op[pk1] = 0; + gci_op[pk1] = 0; // total op on the pk Op* tot_op = g_pk_op[pk1]; if (tot_op == 0) continue; // first commit chain - assert(tot_op->next_com != 0); - com_op[pk1] = tot_op->next_com; + assert(tot_op->next_gci != 0); + gci_op[pk1] = tot_op->next_gci; left++; } while (left != 0) { pk1 = urandom(g_opts.maxpk); - if (com_op[pk1] == 0) + if (gci_op[pk1] == 0) continue; // do the ops in one transaction - ll2("runops: pk1=" << pk1); chkdb((g_con = g_ndb->startTransaction()) != 0); + Op* com_op = gci_op[pk1]->next_com; + assert(com_op != 0); // first op in chain - Op* op = com_op[pk1]->next_op; + Op* op = com_op->next_op; assert(op != 0); while (op != 0) { - ll2("add op:" << *op); + ll2("runops:" << *op); chkrc(addndbop(op) == 0); op = op->next_op; } chkdb(g_con->execute(Commit) == 0); + gci_op[pk1]->gci = com_op->gci = g_con->getGCI(); + ll2("commit: gci=" << com_op->gci); g_ndb->closeTransaction(g_con); g_con = 0; // next chain - com_op[pk1] = com_op[pk1]->next_com; - if (com_op[pk1] == 0) { + gci_op[pk1] = gci_op[pk1]->next_gci; + if (gci_op[pk1] == 0) { assert(left != 0); left--; } @@ -989,13 +1308,106 @@ runops() return 0; } +// move com chains with same gci under same gci entry +static int +mergeops() +{ + ll1("mergeops"); + uint mergecnt = 0; + Uint32 pk1; + for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) { + Op* tot_op = g_pk_op[pk1]; + if (tot_op == 0) + continue; + Op* gci_op = tot_op->next_gci; + assert(gci_op != 0); + while (gci_op != 0) { + Op* com_op = gci_op->next_com; + assert(com_op != 0 && com_op->next_com == 0); + assert(gci_op->gci == com_op->gci); + Op* last_com = com_op; + Op* gci_op2 = gci_op->next_gci; + while (gci_op2 != 0 && gci_op->gci == gci_op2->gci) { + // move link to com level + last_com = last_com->next_com = gci_op2->next_com; + // merge to gci + reqrc(compop(gci_op, gci_op2, gci_op) == 0); + // move to next and discard + Op* tmp_op = gci_op2; + gci_op2 = gci_op2->next_gci; + freeop(tmp_op); + mergecnt++; + } + gci_op = gci_op->next_gci = gci_op2; + } + } + ll1("mergeops: used ops = " << g_usedops); + ll1("mergeops: merged " << mergecnt << " gci entries"); + return 0; +} + +// set bit for equal post/pre data in UPD, for use in event match +static void +cmppostpre() +{ + ll1("cmppostpre"); + Uint32 pk1; + for (pk1 = 0; pk1 < g_opts.maxpk; pk1++) { + Op* tot_op = g_pk_op[pk1]; + Op* gci_op = tot_op ? tot_op->next_gci : 0; + while (gci_op != 0) { + if (gci_op->type == Op::UPD) { + Data (&d)[2] = gci_op->data; + uint i; + for (i = 0; i < ncol(); i++) { + const Col& c = getcol(i); + bool eq = + d[0].ind[i] == 1 && d[1].ind[i] == 1 || + d[0].ind[i] == 0 && d[1].ind[i] == 0 && cmpcol(c, d[0], d[1]) == 0; + if (eq) { + d[0].ppeq |= (1 << i); + d[1].ppeq |= (1 << i); + } + } + } + gci_op = gci_op->next_gci; + } + } +} +static int +cmpopevdata(const Data& d1, const Data& d2) +{ + uint i; + for (i = 0; i < ncol(); i++) { + const Col& c = getcol(i); + if (cmpcol(c, d1, d2) != 0) { + if ((d1.ppeq & (1 << i)) && d2.ind[i] == -1) + ; // post/pre data equal and no event data returned is OK + else + return 1; + } + } + return 0; +} + +// compare operation to event data +static int +cmpopevdata(const Data (&d1)[2], const Data (&d2)[2]) +{ + if (cmpopevdata(d1[0], d2[0]) != 0) + return 1; + if (cmpopevdata(d1[1], d2[1]) != 0) + return 1; + return 0; +} + static int matchevent(Op* ev) { Op::Type t = ev->type; - Data (&d)[2] = ev->data; + Data (&d2)[2] = ev->data; // get PK - Uint32 pk1 = d[0].pk1; + Uint32 pk1 = d2[0].pk1; chkrc(pk1 < g_opts.maxpk); // on error repeat and print details uint loop = 0; @@ -1004,42 +1416,59 @@ matchevent(Op* ev) ll1("matchevent: pk1=" << pk1 << " type=" << t); ll2("EVT: " << *ev); Op* tot_op = g_pk_op[pk1]; - Op* com_op = tot_op ? tot_op->next_com : 0; - uint cnt = 0; + Op* gci_op = tot_op ? tot_op->next_gci : 0; + uint pos = 0; bool ok = false; - while (com_op != 0) { - ll2("COM: " << *com_op); - Op* op = com_op->next_op; - assert(op != 0); - while (op != 0) { - ll2("---: " << *op); - op = op->next_op; + while (gci_op != 0) { + ll2("GCI: " << *gci_op); + // print details + Op* com_op = gci_op->next_com; + assert(com_op != 0); + while (com_op != 0) { + ll2("COM: " << *com_op); + Op* op = com_op->next_op; + assert(op != 0); + while (op != 0) { + ll2("OP : " << *op); + op = op->next_op; + } + com_op = com_op->next_com; } - if (com_op->type != Op::NUL) { - if (com_op->type == t) { - const Data (&d2)[2] = com_op->data; - if (t == Op::INS && d2[0].seq == d[0].seq || - t == Op::DEL && d2[1].seq == d[1].seq || - t == Op::UPD && d2[0].seq == d[0].seq) { - if (cnt == g_ev_cnt[pk1]) { - if (! com_op->match) { - ll2("match pos " << cnt); - ok = com_op->match = true; - } else { - ll2("duplicate match"); - } - } else { - ll2("match bad pos event=" << g_ev_cnt[pk1] << " op=" << cnt); - } + // match agains GCI op + if (gci_op->type != Op::NUL) { + const Data (&d1)[2] = gci_op->data; + if (cmpopevdata(d1, d2) == 0) { + bool tmpok = true; + if (gci_op->type != t) { + ll2("***: wrong type " << gci_op->type << " != " << t); + tmpok = false; + } + if (gci_op->match) { + ll2("***: duplicate match"); + tmpok = false; + } + if (pos != g_ev_pos[pk1]) { + ll2("***: wrong pos " << pos << " != " << g_ev_pos[pk1]); + tmpok = false; + } + if (gci_op->gci != ev->gci) { + ll2("***: wrong gci " << gci_op->gci << " != " << ev->gci); + tmpok = false; + } + if (tmpok) { + ok = gci_op->match = true; + ll2("===: match"); } } - cnt++; + pos++; } - com_op = com_op->next_com; + gci_op = gci_op->next_gci; } - if (ok) + if (ok) { + ll1("matchevent: match"); return 0; - ll2("no match"); + } + ll1("matchevent: ERROR: no match"); if (g_loglevel >= 2) return -1; loop++; @@ -1056,12 +1485,12 @@ matchevents() Op* tot_ev = g_pk_ev[pk1]; if (tot_ev == 0) continue; - Op* com_ev = tot_ev->next_com; - while (com_ev != 0) { - if (matchevent(com_ev) < 0) + Op* ev = tot_ev->next_ev; + while (ev != 0) { + if (matchevent(ev) < 0) nomatch++; - g_ev_cnt[pk1]++; - com_ev = com_ev->next_com; + g_ev_pos[pk1]++; + ev = ev->next_ev; } } chkrc(nomatch == 0); @@ -1095,22 +1524,58 @@ matchops() return 0; } +static void +geteventdata() +{ + Data (&d)[2] = g_rec_ev->data; + int i, j; + for (j = 0; j < 2; j++) { + for (i = 0; i < ncol(); i++) { + const Col& c = getcol(i); + int ind, ret; + if (! c.isblob()) { + NdbRecAttr* ra = g_ev_ra[j][i]; + ind = ra->isNULL(); + } else { +#ifdef version51rbr + NdbBlob* bh = g_ev_bh[j][i]; + ret = bh->getDefined(ind); + assert(ret == 0); + if (ind == 0) { // value was returned and is not NULL + Data::Txt& t = *d[j].ptr[i].txt; + Uint64 len64; + ret = bh->getLength(len64); + assert(ret == 0); + t.len = (uint)len64; + delete [] t.val; + t.val = new char [t.len]; + memset(t.val, 'X', t.len); + Uint32 len = t.len; + ret = bh->readData(t.val, len); + assert(ret == 0 && len == t.len); + } +#endif + } + d[j].ind[i] = ind; + } + } +} + static int runevents() { ll1("runevents"); - NdbEventOperation* evt_op; - uint npoll = 3; + uint mspoll = 1000; + uint npoll = 6; // strangely long delay while (npoll != 0) { npoll--; int ret; ll1("poll"); - ret = g_ndb->pollEvents(1000); + ret = g_ndb->pollEvents(mspoll); if (ret <= 0) continue; while (1) { - g_rec_ev->init(); - Data (&d)[2] = g_rec_ev->data; + g_rec_ev->init(Op::EV); #ifdef version50 int overrun = g_opts.maxops; chkdb((ret = g_evt_op->next(&overrun)) >= 0); @@ -1124,32 +1589,35 @@ runevents() reqrc(g_evt_op == tmp_op); #endif chkrc(seteventtype(g_rec_ev, g_evt_op->getEventType()) == 0); - // get indicators - { int i, j; - for (j = 0; j < 2; j++) - for (i = 0; i < g_ncol; i++) - d[j].ind[i] = g_ra[j][i]->isNULL(); + geteventdata(); + g_rec_ev->gci = g_evt_op->getGCI(); +#ifdef version50 + // fix to match 5.1 + if (g_rec_ev->type == Op::UPD) { + Uint32 pk1 = g_rec_ev->data[0].pk1; + makedata(getcol("pk1"), g_rec_ev->data[1], pk1, Op::UPD); + makedata(getcol("pk2"), g_rec_ev->data[1], pk1, Op::UPD); } +#endif + // get indicators and blob value ll2("runevents: EVT: " << *g_rec_ev); // check basic sanity Uint32 pk1 = ~(Uint32)0; chkrc(checkop(g_rec_ev, pk1) == 0); // add to events - chkrc(getfreeevs() >= 2); Op* tot_ev = g_pk_ev[pk1]; if (tot_ev == 0) - tot_ev = g_pk_ev[pk1] = getev(); //1 - Op* last_com = tot_ev; - while (last_com->next_com != 0) - last_com = last_com->next_com; + tot_ev = g_pk_ev[pk1] = getop(Op::EV); + Op* last_ev = tot_ev; + while (last_ev->next_ev != 0) + last_ev = last_ev->next_ev; // copy and add - Op* ev = getev(); //3 + Op* ev = getop(Op::EV); copyop(g_rec_ev, ev); - last_com->next_com = ev; + last_ev->next_ev = ev; } } - chkrc(matchevents() == 0); - chkrc(matchops() == 0); + ll1("runevents: used ops = " << g_usedops); return 0; } @@ -1179,18 +1647,23 @@ runtest() setseed(-1); chkrc(createtable() == 0); chkrc(createevent() == 0); - uint n; - for (n = 0; n < g_opts.loop; n++) { - ll0("loop " << n); - setseed(n); + for (g_loop = 0; g_opts.loop == 0 || g_loop < g_opts.loop; g_loop++) { + ll0("loop " << g_loop); + setseed(g_loop); resetmem(); - g_rec_ev = getev(); + chkrc(scantab() == 0); // alternative: save tot_op for loop > 0 + makeops(); + g_rec_ev = getop(Op::EV); chkrc(createeventop() == 0); chkdb(g_evt_op->execute() == 0); chkrc(waitgci() == 0); - makeops(); chkrc(runops() == 0); + if (! g_opts.separate_events) + chkrc(mergeops() == 0); + cmppostpre(); chkrc(runevents() == 0); + chkrc(matchevents() == 0); + chkrc(matchops() == 0); chkrc(dropeventop() == 0); } chkrc(dropevent() == 0); @@ -1204,31 +1677,41 @@ static struct my_option my_long_options[] = { NDB_STD_OPTS("test_event_merge"), - { "abort-on-error", 1008, "Do abort() on any error", + { "abort-on-error", 1001, "Do abort() on any error", (gptr*)&g_opts.abort_on_error, (gptr*)&g_opts.abort_on_error, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "loglevel", 1001, "Logging level in this program (default 0)", + { "loglevel", 1002, "Logging level in this program (default 0)", (gptr*)&g_opts.loglevel, (gptr*)&g_opts.loglevel, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - { "loop", 1002, "Number of test loops (default 1, 0=forever)", + { "loop", 1003, "Number of test loops (default 2, 0=forever)", (gptr*)&g_opts.loop, (gptr*)&g_opts.loop, 0, - GET_INT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 }, - { "maxops", 1003, "Number of PK operations (default 2000)", + GET_INT, REQUIRED_ARG, 2, 0, 0, 0, 0, 0 }, + { "maxops", 1004, "Approx number of PK operations (default 1000)", (gptr*)&g_opts.maxops, (gptr*)&g_opts.maxops, 0, - GET_UINT, REQUIRED_ARG, 2000, 0, g_maxops, 0, 0, 0 }, - { "maxpk", 1004, "Number of different PK values (default 10)", + GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0 }, + { "maxpk", 1005, "Number of different PK values (default 10)", (gptr*)&g_opts.maxpk, (gptr*)&g_opts.maxpk, 0, GET_UINT, REQUIRED_ARG, 10, 1, g_maxpk, 0, 0, 0 }, - { "opstr", 1005, "Ops to run e.g. idiucdc (c = commit, default random)", - (gptr*)&g_opts.opstr, (gptr*)&g_opts.opstr, 0, + { "no-blobs", 1006, "Omit blob attributes (5.0: true)", + (gptr*)&g_opts.no_blobs, (gptr*)&g_opts.no_blobs, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "no-multiops", 1007, "Allow only 1 operation per commit", + (gptr*)&g_opts.no_multiops, (gptr*)&g_opts.no_multiops, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "one-blob", 1008, "Only one blob attribute (defautt 2)", + (gptr*)&g_opts.one_blob, (gptr*)&g_opts.one_blob, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "opstring", 1009, "Operations to run e.g. idiucdc (c is commit) or" + " iuuc:uudc (the : separates loops)", + (gptr*)&g_opts.opstring, (gptr*)&g_opts.opstring, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - { "seed", 1006, "Random seed (0=loop number, default -1=random)", + { "seed", 1010, "Random seed (0=loop number, default -1=random)", (gptr*)&g_opts.seed, (gptr*)&g_opts.seed, 0, GET_INT, REQUIRED_ARG, -1, 0, 0, 0, 0, 0 }, - { "separate-events", 1007, "Do not combine events per GCI >5.0", + { "separate-events", 1011, "Do not combine events per GCI (5.0: true)", (gptr*)&g_opts.separate_events, (gptr*)&g_opts.separate_events, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "use-table", 1008, "Use existing table 'tem1'", + { "use-table", 1012, "Use existing table 'tem1'", (gptr*)&g_opts.use_table, (gptr*)&g_opts.use_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, @@ -1245,14 +1728,36 @@ usage() static int checkopts() { - if (g_opts.opstr != 0) { - const char* s = g_opts.opstr; - uint n = strlen(s); - if (n < 3 || s[0] != 'i' || s[n-2] != 'd' || s[n-1] != 'c') - return -1; - while (*s != 0) - if (strchr("iduc", *s++) == 0) +#ifdef version50 + g_opts.separate_events = true; +#endif + if (g_opts.separate_events) { + g_opts.no_blobs = true; + } + if (g_opts.no_multiops) { + g_maxcom = 1; + } + if (g_opts.opstring != 0) { + uint len = strlen(g_opts.opstring); + char* str = new char [len + 1]; + memcpy(str, g_opts.opstring, len + 1); + char* s = str; + while (1) { + g_opstringpart[g_opstringparts++] = s; + s = strchr(s, ':'); + if (s == 0) + break; + *s++ = 0; + } + uint i; + for (i = 0; i < g_opstringparts; i++) { + const char* s = g_opstringpart[i]; + while (*s != 0) + if (strchr("iduc", *s++) == 0) + return -1; + if (s == g_opstringpart[i] || s[-1] != 'c') return -1; + } } return 0; } @@ -1280,6 +1785,10 @@ main(int argc, char** argv) return NDBT_ProgramExit(NDBT_OK); } } + if (g_evt_op != 0) { + (void)dropeventop(); + g_evt_op = 0; + } delete g_ndb; delete g_ncc; return NDBT_ProgramExit(NDBT_FAILED); From fb0145c55c9c9896e448c1d83ee0d9fdb3806876 Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Mon, 9 Jan 2006 09:37:21 +0100 Subject: [PATCH 43/49] Bug#15923 (Test ps_7ndb cause master crash): Always log statements "DELETE FROM x" statement-based. --- sql/sql_delete.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index c5b5958140b..fd74fc5adc4 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -79,6 +79,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, !(table->triggers && table->triggers->has_delete_triggers())) { ha_rows const maybe_deleted= table->file->records; + /* + If all rows shall be deleted, we always log this statement-based + (see [binlog], below), so we set this flag and test it below. + */ ha_delete_all_rows= 1; if (!(error=table->file->delete_all_rows())) { @@ -315,9 +319,9 @@ cleanup: thd->clear_error(); /* - If 'handler::delete_all_rows()' was called, we replicate - statement-based; otherwise, 'ha_delete_row()' was used to - delete specific rows which we might log row-based. + [binlog]: If 'handler::delete_all_rows()' was called, we + replicate statement-based; otherwise, 'ha_delete_row()' was + used to delete specific rows which we might log row-based. */ THD::enum_binlog_query_type const query_type(ha_delete_all_rows ? From 848383feb87f3c5c41d487b63433bced2a2fdf75 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Mon, 9 Jan 2006 11:08:23 +0100 Subject: [PATCH 44/49] Fix template problem with Sun compiler by using anonymous namespace instead of static for referenged function. --- sql/handler.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 8befec80529..ae38e376d54 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2794,13 +2794,18 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) */ #ifdef HAVE_ROW_BASED_REPLICATION -static bool check_table_binlog_row_based(THD *thd, TABLE *table) -{ - return - binlog_row_based && - thd && (thd->options & OPTION_BIN_LOG) && - (table->s->tmp_table == NO_TMP_TABLE) && - binlog_filter->db_ok(table->s->db.str); +/* The Sun compiler cannot instantiate the template below if this is + declared static, but it works by putting it into an anonymous + namespace. */ +namespace { + bool check_table_binlog_row_based(THD *thd, TABLE *table) + { + return + binlog_row_based && + thd && (thd->options & OPTION_BIN_LOG) && + (table->s->tmp_table == NO_TMP_TABLE) && + binlog_filter->db_ok(table->s->db.str); + } } template int binlog_log_row(TABLE* table, From e952a7005ba8df3b9ded66915338dd906ce83ed3 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Mon, 9 Jan 2006 11:23:15 +0100 Subject: [PATCH 45/49] Fix "jump to label crosses initialization" compile error. --- sql/sql_delete.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 991456fdfec..7b30b2d4a3d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -41,6 +41,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, uint usable_index= MAX_KEY; SELECT_LEX *select_lex= &thd->lex->select_lex; bool ha_delete_all_rows= 0; + ulonglong const saved_options= thd->options; DBUG_ENTER("mysql_delete"); if (open_and_lock_tables(thd, table_list)) @@ -205,11 +206,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, will_batch= !table->file->start_bulk_delete(); /* - Save the thread options before clearing the OPTION_BIN_LOG, - effectively disabling the binary log (unless it was already - disabled, of course). + We saved the thread options above before clearing the + OPTION_BIN_LOG, and will restore below, effectively disabling the + binary log (unless it was already disabled, of course). */ - ulonglong const saved_options= thd->options; if (ha_delete_all_rows) thd->options&= ~static_cast(OPTION_BIN_LOG); From eecec4cf14de2f60218ab7ed5acae5e72193670e Mon Sep 17 00:00:00 2001 From: "lars@mysql.com" <> Date: Mon, 9 Jan 2006 11:53:37 +0100 Subject: [PATCH 46/49] Added synchronization to avoid race condition in tests --- mysql-test/t/rpl_multi_engine.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/rpl_multi_engine.test b/mysql-test/t/rpl_multi_engine.test index 356237d1584..3f7b7b11c0d 100644 --- a/mysql-test/t/rpl_multi_engine.test +++ b/mysql-test/t/rpl_multi_engine.test @@ -24,6 +24,7 @@ use mysqltest1; connection master; alter table t1 engine=myisam; show create table t1; +sync_slave_with_master; connection slave; alter table t1 engine=myisam; @@ -48,6 +49,7 @@ show create table t1; connection master; alter table t1 engine=memory; show create table t1; +sync_slave_with_master; connection slave; alter table t1 engine=myisam; @@ -72,6 +74,7 @@ show create table t1; connection master; alter table t1 engine=innodb; show create table t1; +sync_slave_with_master; connection slave; alter table t1 engine=myisam; From 94d3a8e050e6521c5aae071df40781a6db9f4248 Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Mon, 9 Jan 2006 15:59:39 +0100 Subject: [PATCH 47/49] Changes to support aCC on HP-UX. --- sql/log_event.h | 5 ++++- sql/sql_class.cc | 39 +++++++++++++++++++++++---------------- sql/sql_class.h | 3 ++- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/sql/log_event.h b/sql/log_event.h index 5d58a204ec9..3ddf177a9cf 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1673,8 +1673,11 @@ public: { /* Nothing here right now, but the flags support is there in - preparation for changes that are coming. + preparation for changes that are coming. Need to add a + constant to make it compile under HP-UX: aCC does not like + empty enumerations. */ + ENUM_FLAG_COUNT }; typedef uint16 flag_set; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 853e8be6629..5b095bb29d3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2173,7 +2173,8 @@ THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, MY_BITMAP const* cols, my_size_t colcnt, my_size_t needed, - bool is_transactional) + bool is_transactional, + RowsEventT *hint __attribute__((unused))) { /* Pre-conditions */ DBUG_ASSERT(table->s->table_map_id != ULONG_MAX); @@ -2238,16 +2239,19 @@ THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, compiling option. */ template Rows_log_event* -THD::binlog_prepare_pending_rows_event -(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool); +THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*, + my_size_t, my_size_t, bool, + Write_rows_log_event*); template Rows_log_event* -THD::binlog_prepare_pending_rows_event -(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool); +THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*, + my_size_t colcnt, my_size_t, bool, + Delete_rows_log_event *); template Rows_log_event* -THD::binlog_prepare_pending_rows_event -(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool); +THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*, + my_size_t colcnt, my_size_t, bool, + Update_rows_log_event *); static char const* field_type_name(enum_field_types type) @@ -2384,9 +2388,10 @@ int THD::binlog_write_row(TABLE* table, bool is_trans, } my_size_t const len= pack_row(table, cols, row_data, record); - Rows_log_event* const - ev= binlog_prepare_pending_rows_event - (table, server_id, cols, colcnt, len, is_trans); + Rows_log_event* const ev= + binlog_prepare_pending_rows_event(table, server_id, cols, colcnt, + len, is_trans, + static_cast(0)); /* add_row_data copies row_data to internal buffer */ error= likely(ev != 0) ? ev->add_row_data(row_data,len) : HA_ERR_OUT_OF_MEM ; @@ -2429,9 +2434,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, my_size_t const after_size= pack_row(table, cols, after_row, after_record); - Rows_log_event* const - ev= binlog_prepare_pending_rows_event - (table, server_id, cols, colcnt, before_size + after_size, is_trans); + Rows_log_event* const ev= + binlog_prepare_pending_rows_event(table, server_id, cols, colcnt, + before_size + after_size, is_trans, + static_cast(0)); error= (unlikely(!ev)) || ev->add_row_data(before_row, before_size) || ev->add_row_data(after_row, after_size); @@ -2462,9 +2468,10 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans, return HA_ERR_OUT_OF_MEM; my_size_t const len= pack_row(table, cols, row_data, record); - Rows_log_event* const - ev= binlog_prepare_pending_rows_event - (table, server_id, cols, colcnt, len, is_trans); + Rows_log_event* const ev= + binlog_prepare_pending_rows_event(table, server_id, cols, colcnt, + len, is_trans, + static_cast(0)); error= (unlikely(!ev)) || ev->add_row_data(row_data, len); diff --git a/sql/sql_class.h b/sql/sql_class.h index 1ef3322bc8f..c56924774ba 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -922,7 +922,8 @@ public: MY_BITMAP const* cols, my_size_t colcnt, my_size_t needed, - bool is_transactional); + bool is_transactional, + RowsEventT* hint); Rows_log_event* binlog_get_pending_rows_event() const; void binlog_set_pending_rows_event(Rows_log_event* ev); int binlog_setup_trx_data(); From 1c0b916ec1605f00429c02c0ccd6e6889c11bd49 Mon Sep 17 00:00:00 2001 From: "mats@mysql.com" <> Date: Mon, 9 Jan 2006 16:37:24 +0100 Subject: [PATCH 48/49] Changes to support HP-UX. --- sql/log.cc | 2 +- sql/log_event.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index dd08ca7b9b5..45ce7776d1a 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2560,7 +2560,7 @@ bool MYSQL_LOG::write_table_map(THD *thd, IO_CACHE *file, TABLE* table, #endif Table_map_log_event::flag_set const - flags= Table_map_log_event::NO_FLAGS; + flags= Table_map_log_event::TM_NO_FLAGS; Table_map_log_event the_event(thd, table, table->s->table_map_id, is_transactional, flags); diff --git a/sql/log_event.h b/sql/log_event.h index 3ddf177a9cf..ab11c064921 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1685,7 +1685,7 @@ public: /* Special constants representing sets of flags */ enum { - NO_FLAGS = 0U + TM_NO_FLAGS = 0U }; void set_flags(flag_set flag) { m_flags |= flag; } From b6bfac0aaac339b9acfe27a4722b71c26e0e786e Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Mon, 9 Jan 2006 17:26:17 +0100 Subject: [PATCH 49/49] Version number increase. --- configure.in | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/configure.in b/configure.in index 9e2a0748b0d..e8256a5a526 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.1.5-alpha) +AM_INIT_AUTOMAKE(mysql, 5.1.6-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -15,12 +15,6 @@ DOT_FRM_VERSION=6 # See the libtool docs for information on how to do shared lib versions. SHARED_LIB_VERSION=15:0:0 -# ndb version -NDB_VERSION_MAJOR=5 -NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=19 -NDB_VERSION_STATUS="" - # Set all version vars based on $VERSION. How do we do this more elegant ? # Remember that regexps needs to quote [ and ] since this is run through m4 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`