mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge gbichot@213.136.52.20:/home/bk/mysql-4.1
into mysql.com:/home/mysql_src/mysql-4.1
This commit is contained in:
199
mysql-test/r/rpl_charset.result
Normal file
199
mysql-test/r/rpl_charset.result
Normal file
@ -0,0 +1,199 @@
|
||||
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 test2;
|
||||
drop database if exists test3;
|
||||
create database test2 character set latin2;
|
||||
set @@character_set_server=latin5;
|
||||
create database test3;
|
||||
|
||||
--- --master--
|
||||
show create database test2;
|
||||
Database Create Database
|
||||
test2 CREATE DATABASE `test2` /*!40100 DEFAULT CHARACTER SET latin2 */
|
||||
show create database test3;
|
||||
Database Create Database
|
||||
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET latin5 */
|
||||
|
||||
--- --slave--
|
||||
show create database test2;
|
||||
Database Create Database
|
||||
test2 CREATE DATABASE `test2` /*!40100 DEFAULT CHARACTER SET latin2 */
|
||||
show create database test3;
|
||||
Database Create Database
|
||||
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET latin5 */
|
||||
set @@collation_server=armscii_bin;
|
||||
drop database test3;
|
||||
create database test3;
|
||||
|
||||
--- --master--
|
||||
show create database test3;
|
||||
Database Create Database
|
||||
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii_bin */
|
||||
|
||||
--- --slave--
|
||||
show create database test3;
|
||||
Database Create Database
|
||||
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii_bin */
|
||||
use test2;
|
||||
create table t1 (a int auto_increment primary key, b varchar(100));
|
||||
set character_set_client=cp850, collation_connection=latin2_croatian_ci;
|
||||
insert into t1 (b) values(@@character_set_server);
|
||||
insert into t1 (b) values(@@collation_server);
|
||||
insert into t1 (b) values(@@character_set_client);
|
||||
insert into t1 (b) values(@@character_set_connection);
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
|
||||
--- --master--
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
1 armscii8
|
||||
2 armscii_bin
|
||||
3 cp850
|
||||
4 latin2
|
||||
5 latin2_croatian_ci
|
||||
|
||||
--- --slave--
|
||||
select * from test2.t1 order by a;
|
||||
a b
|
||||
1 armscii8
|
||||
2 armscii_bin
|
||||
3 cp850
|
||||
4 latin2
|
||||
5 latin2_croatian_ci
|
||||
set character_set_client=latin1, collation_connection=latin1_german1_ci;
|
||||
truncate table t1;
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
insert into t1 (b) values(LEAST("M<>ller","Muffler"));
|
||||
set collation_connection=latin1_german2_ci;
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
insert into t1 (b) values(LEAST("M<>ller","Muffler"));
|
||||
|
||||
--- --master--
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
1 latin1_german1_ci
|
||||
2 Muffler
|
||||
3 latin1_german2_ci
|
||||
4 M<>ller
|
||||
|
||||
--- --slave--
|
||||
select * from test2.t1 order by a;
|
||||
a b
|
||||
1 latin1_german1_ci
|
||||
2 Muffler
|
||||
3 latin1_german2_ci
|
||||
4 M<>ller
|
||||
load data infile '../../std_data/words.dat' into table t1 (b);
|
||||
set @a= _cp850 'M<>ller' collate cp850_general_ci;
|
||||
truncate table t1;
|
||||
insert into t1 (b) values(collation(@a));
|
||||
|
||||
--- --master--
|
||||
select * from t1 order by a;
|
||||
a b
|
||||
1 cp850_general_ci
|
||||
|
||||
--- --slave--
|
||||
select * from test2.t1 order by a;
|
||||
a b
|
||||
1 cp850_general_ci
|
||||
drop database test2;
|
||||
drop database test3;
|
||||
show binlog events from 79;
|
||||
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||
master-bin.000001 79 Query 1 79 use `test`; create database test2 character set latin2
|
||||
master-bin.000001 156 Query 1 156 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=8,COLLATION_DATABASE=8,COLLATION_SERVER=30
|
||||
master-bin.000001 290 Query 1 290 use `test`; create database test3
|
||||
master-bin.000001 346 Query 1 346 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=8,COLLATION_DATABASE=8,COLLATION_SERVER=64
|
||||
master-bin.000001 480 Query 1 480 use `test`; drop database test3
|
||||
master-bin.000001 534 Query 1 534 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=8,COLLATION_DATABASE=8,COLLATION_SERVER=64
|
||||
master-bin.000001 668 Query 1 668 use `test`; create database test3
|
||||
master-bin.000001 724 Query 1 724 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=8,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 859 Query 1 859 use `test2`; create table t1 (a int auto_increment primary key, b varchar(100))
|
||||
master-bin.000001 961 Query 1 961 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=4,COLLATION_CONNECTION=27,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 1097 Intvar 1 1097 INSERT_ID=1
|
||||
master-bin.000001 1125 Query 1 1125 use `test2`; insert into t1 (b) values(@@character_set_server)
|
||||
master-bin.000001 1210 Query 1 1210 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=4,COLLATION_CONNECTION=27,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 1346 Intvar 1 1346 INSERT_ID=2
|
||||
master-bin.000001 1374 Query 1 1374 use `test2`; insert into t1 (b) values(@@collation_server)
|
||||
master-bin.000001 1455 Query 1 1455 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=4,COLLATION_CONNECTION=27,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 1591 Intvar 1 1591 INSERT_ID=3
|
||||
master-bin.000001 1619 Query 1 1619 use `test2`; insert into t1 (b) values(@@character_set_client)
|
||||
master-bin.000001 1704 Query 1 1704 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=4,COLLATION_CONNECTION=27,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 1840 Intvar 1 1840 INSERT_ID=4
|
||||
master-bin.000001 1868 Query 1 1868 use `test2`; insert into t1 (b) values(@@character_set_connection)
|
||||
master-bin.000001 1957 Query 1 1957 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=4,COLLATION_CONNECTION=27,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 2093 Intvar 1 2093 INSERT_ID=5
|
||||
master-bin.000001 2121 Query 1 2121 use `test2`; insert into t1 (b) values(@@collation_connection)
|
||||
master-bin.000001 2206 Query 1 2206 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=5,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 2341 Query 1 2341 use `test2`; truncate table t1
|
||||
master-bin.000001 2394 Query 1 2394 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=5,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 2529 Intvar 1 2529 INSERT_ID=1
|
||||
master-bin.000001 2557 Query 1 2557 use `test2`; insert into t1 (b) values(@@collation_connection)
|
||||
master-bin.000001 2642 Query 1 2642 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=5,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 2777 Intvar 1 2777 INSERT_ID=2
|
||||
master-bin.000001 2805 Query 1 2805 use `test2`; insert into t1 (b) values(LEAST("M<>ller","Muffler"))
|
||||
master-bin.000001 2893 Query 1 2893 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 3029 Intvar 1 3029 INSERT_ID=3
|
||||
master-bin.000001 3057 Query 1 3057 use `test2`; insert into t1 (b) values(@@collation_connection)
|
||||
master-bin.000001 3142 Query 1 3142 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 3278 Intvar 1 3278 INSERT_ID=4
|
||||
master-bin.000001 3306 Query 1 3306 use `test2`; insert into t1 (b) values(LEAST("M<>ller","Muffler"))
|
||||
master-bin.000001 3394 Query 1 3394 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 3530 Intvar 1 3530 INSERT_ID=74
|
||||
master-bin.000001 3558 Create_file 1 3558 db=test2;table=t1;file_id=1;block_len=581
|
||||
master-bin.000001 4226 Query 1 4226 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 4362 Intvar 1 4362 INSERT_ID=5
|
||||
master-bin.000001 4390 Exec_load 1 4390 ;file_id=1
|
||||
master-bin.000001 4413 Query 1 4413 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 4549 Query 1 4549 use `test2`; truncate table t1
|
||||
master-bin.000001 4602 Query 1 4602 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 4738 Intvar 1 4738 INSERT_ID=1
|
||||
master-bin.000001 4766 User var 1 4766 @`a`=_cp850'M<>ller' COLLATE cp850_general_ci
|
||||
master-bin.000001 4806 Query 1 4806 use `test2`; insert into t1 (b) values(collation(@a))
|
||||
master-bin.000001 4882 Query 1 4882 use `test2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 5018 Query 1 5018 use `test2`; drop database test2
|
||||
master-bin.000001 5073 Query 1 5073 SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64
|
||||
master-bin.000001 5204 Query 1 5204 drop database test3
|
||||
set global character_set_server=latin2;
|
||||
ERROR HY000: Binary logging and replication forbid changing the global server character set or collation
|
||||
set global character_set_server=latin2;
|
||||
ERROR HY000: Binary logging and replication forbid changing the global server character set or collation
|
||||
set one_shot @@character_set_server=latin5;
|
||||
set @@max_join_size=1000;
|
||||
select @@character_set_server;
|
||||
@@character_set_server
|
||||
latin5
|
||||
select @@character_set_server;
|
||||
@@character_set_server
|
||||
latin1
|
||||
set @@character_set_server=latin5;
|
||||
select @@character_set_server;
|
||||
@@character_set_server
|
||||
latin5
|
||||
select @@character_set_server;
|
||||
@@character_set_server
|
||||
latin5
|
||||
set one_shot max_join_size=10;
|
||||
ERROR HY000: The SET ONE_SHOT syntax is reserved for purposes internal to the MySQL server
|
||||
set character_set_client=9999999;
|
||||
ERROR 42000: Unknown character set: '9999999'
|
||||
set collation_server=9999998;
|
||||
ERROR HY000: Unknown collation: '9999998'
|
||||
use test;
|
||||
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
|
||||
SET CHARACTER_SET_CLIENT=koi8r,
|
||||
CHARACTER_SET_CONNECTION=cp1251,
|
||||
CHARACTER_SET_RESULTS=koi8r;
|
||||
INSERT INTO t1 (c1, c2) VALUES ('<27><>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>','<27><>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>');
|
||||
select hex(c1), hex(c2) from t1;
|
||||
hex(c1) hex(c2)
|
||||
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
|
||||
select hex(c1), hex(c2) from t1;
|
||||
hex(c1) hex(c2)
|
||||
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
|
||||
drop table t1;
|
@ -15,8 +15,5 @@ start slave;
|
||||
insert into t1 values (1);
|
||||
show status like "slave_running";
|
||||
Variable_name Value
|
||||
Slave_running ON
|
||||
select * from t1;
|
||||
n
|
||||
1
|
||||
Slave_running OFF
|
||||
drop table t1;
|
||||
|
@ -86,11 +86,11 @@ slave-bin.000001 313 Query 1 313 use `test`; insert into t1 values (@i1), (@i2),
|
||||
slave-bin.000001 396 User var 2 396 @r1=12.5
|
||||
slave-bin.000001 439 User var 2 439 @r2=-12.5
|
||||
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
|
||||
slave-bin.000001 551 User var 2 551 @s1='This is a test'
|
||||
slave-bin.000001 600 User var 2 600 @s2=''
|
||||
slave-bin.000001 635 User var 2 635 @s3='abc'def'
|
||||
slave-bin.000001 677 User var 2 677 @s4='abc\def'
|
||||
slave-bin.000001 719 User var 2 719 @s5='abc'def'
|
||||
slave-bin.000001 551 User var 2 551 @s1=_latin1'This is a test' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 600 User var 2 600 @s2=_latin1'' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 635 User var 2 635 @s3=_latin1'abc'def' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 677 User var 2 677 @s4=_latin1'abc\def' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 719 User var 2 719 @s5=_latin1'abc'def' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
|
||||
slave-bin.000001 851 User var 2 851 @n1=NULL
|
||||
slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
|
||||
@ -99,7 +99,7 @@ slave-bin.000001 965 Query 1 965 use `test`; insert into t1 values (@n2)
|
||||
slave-bin.000001 1027 Query 1 1027 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
|
||||
slave-bin.000001 1115 User var 2 1115 @a=2
|
||||
slave-bin.000001 1157 Query 1 1157 use `test`; insert into t1 values (@a+(@b:=@a+1))
|
||||
slave-bin.000001 1229 User var 2 1229 @q='abc'
|
||||
slave-bin.000001 1229 User var 2 1229 @q=_latin1'abc' COLLATE latin1_swedish_ci
|
||||
slave-bin.000001 1266 Query 1 1266 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
|
||||
slave-bin.000001 1370 User var 2 1370 @a=5
|
||||
slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a)
|
||||
|
@ -162,3 +162,36 @@ charset(@a) collation(@a) coercibility(@a)
|
||||
latin2 latin2_bin 0
|
||||
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci;
|
||||
ERROR HY000: Illegal mix of collations (latin2_bin,EXPLICIT) and (latin2_general_ci,EXPLICIT) for operation '='
|
||||
create table t1 (a varchar(50));
|
||||
reset master;
|
||||
SET TIMESTAMP=10000;
|
||||
SET @`a b`='hello';
|
||||
INSERT INTO t1 VALUES(@`a b`);
|
||||
set @var1= "';aaa";
|
||||
insert into t1 values (@var1);
|
||||
create table t2 (c char(30)) charset=ucs2;
|
||||
set @v=convert('abc' using ucs2);
|
||||
insert into t2 values (@v);
|
||||
show binlog events from 79;
|
||||
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||
master-bin.000001 79 User var 1 79 @`a b`=_latin1'hello' COLLATE latin1_swedish_ci
|
||||
master-bin.000001 120 Query 1 120 use `test`; INSERT INTO t1 VALUES(@`a b`)
|
||||
master-bin.000001 184 User var 1 184 @`var1`=_latin1'\';aaa' COLLATE latin1_swedish_ci
|
||||
master-bin.000001 226 Query 1 226 use `test`; insert into t1 values (@var1)
|
||||
master-bin.000001 290 Query 1 290 use `test`; create table t2 (c char(30)) charset=ucs2
|
||||
master-bin.000001 366 User var 1 366 @`v`=_ucs2'\0a\0b\0c' COLLATE ucs2_general_ci
|
||||
master-bin.000001 406 Query 1 406 use `test`; insert into t2 values (@v)
|
||||
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||
SET @`a b`:=_latin1'hello' COLLATE latin1_swedish_ci;
|
||||
use test;
|
||||
SET TIMESTAMP=10000;
|
||||
INSERT INTO t1 VALUES(@`a b`);
|
||||
SET @`var1`:=_latin1'\';aaa' COLLATE latin1_swedish_ci;
|
||||
SET TIMESTAMP=10000;
|
||||
insert into t1 values (@var1);
|
||||
SET TIMESTAMP=10000;
|
||||
create table t2 (c char(30)) charset=ucs2;
|
||||
SET @`v`:=_ucs2'\0a\0b\0c' COLLATE ucs2_general_ci;
|
||||
SET TIMESTAMP=10000;
|
||||
insert into t2 values (@v);
|
||||
drop table t1, t2;
|
||||
|
153
mysql-test/t/rpl_charset.test
Normal file
153
mysql-test/t/rpl_charset.test
Normal file
@ -0,0 +1,153 @@
|
||||
# Replication of character sets.
|
||||
# This test will fail if the server/client does not support enough charsets.
|
||||
|
||||
# Remember that there currently exists
|
||||
# Bug #2326: Charset of table is determined by charset of db only if "USE db;"
|
||||
|
||||
source include/master-slave.inc;
|
||||
--disable_warnings
|
||||
drop database if exists test2;
|
||||
drop database if exists test3;
|
||||
--enable_warnings
|
||||
|
||||
create database test2 character set latin2;
|
||||
set @@character_set_server=latin5;
|
||||
create database test3;
|
||||
--disable_query_log
|
||||
select "--- --master--" as "";
|
||||
--enable_query_log
|
||||
show create database test2;
|
||||
show create database test3;
|
||||
sync_slave_with_master;
|
||||
--disable_query_log
|
||||
select "--- --slave--" as "";
|
||||
--enable_query_log
|
||||
show create database test2;
|
||||
show create database test3;
|
||||
|
||||
connection master;
|
||||
set @@collation_server=armscii_bin;
|
||||
drop database test3;
|
||||
create database test3;
|
||||
--disable_query_log
|
||||
select "--- --master--" as "";
|
||||
--enable_query_log
|
||||
show create database test3;
|
||||
sync_slave_with_master;
|
||||
--disable_query_log
|
||||
select "--- --slave--" as "";
|
||||
--enable_query_log
|
||||
show create database test3;
|
||||
|
||||
connection master;
|
||||
use test2;
|
||||
create table t1 (a int auto_increment primary key, b varchar(100));
|
||||
set character_set_client=cp850, collation_connection=latin2_croatian_ci;
|
||||
insert into t1 (b) values(@@character_set_server);
|
||||
insert into t1 (b) values(@@collation_server);
|
||||
# character_set_database and collation_database are not tested as they
|
||||
# are not replicated (Bar said that this variable may be removed shortly).
|
||||
insert into t1 (b) values(@@character_set_client);
|
||||
# collation_client does not exist
|
||||
insert into t1 (b) values(@@character_set_connection);
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
--disable_query_log
|
||||
select "--- --master--" as "";
|
||||
--enable_query_log
|
||||
select * from t1 order by a;
|
||||
sync_slave_with_master;
|
||||
--disable_query_log
|
||||
select "--- --slave--" as "";
|
||||
--enable_query_log
|
||||
select * from test2.t1 order by a;
|
||||
|
||||
connection master;
|
||||
set character_set_client=latin1, collation_connection=latin1_german1_ci;
|
||||
truncate table t1;
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
insert into t1 (b) values(LEAST("M<>ller","Muffler"));
|
||||
set collation_connection=latin1_german2_ci;
|
||||
insert into t1 (b) values(@@collation_connection);
|
||||
insert into t1 (b) values(LEAST("M<>ller","Muffler"));
|
||||
--disable_query_log
|
||||
select "--- --master--" as "";
|
||||
--enable_query_log
|
||||
select * from t1 order by a;
|
||||
sync_slave_with_master;
|
||||
--disable_query_log
|
||||
select "--- --slave--" as "";
|
||||
--enable_query_log
|
||||
select * from test2.t1 order by a;
|
||||
|
||||
# See if SET ONE_SHOT gets into binlog when LOAD DATA
|
||||
connection master;
|
||||
load data infile '../../std_data/words.dat' into table t1 (b);
|
||||
|
||||
# See if user var is prefixed with collation in binlog and replicated well.
|
||||
# Note: replication of user variables is broken as far as derivation is
|
||||
# concerned. That's because when we store a user variable in the binlog,
|
||||
# we lose its derivation. So later on the slave, it's impossible to
|
||||
# know if the collation was explicit or not, so we use DERIVATION_NONE,
|
||||
# which provokes error messages (like 'Illegal mix of collation') when
|
||||
# we replay the master's INSERT/etc statements.
|
||||
set @a= _cp850 'M<>ller' collate cp850_general_ci;
|
||||
truncate table t1;
|
||||
insert into t1 (b) values(collation(@a));
|
||||
--disable_query_log
|
||||
select "--- --master--" as "";
|
||||
--enable_query_log
|
||||
select * from t1 order by a;
|
||||
sync_slave_with_master;
|
||||
--disable_query_log
|
||||
select "--- --slave--" as "";
|
||||
--enable_query_log
|
||||
select * from test2.t1 order by a;
|
||||
|
||||
connection master;
|
||||
drop database test2;
|
||||
drop database test3;
|
||||
show binlog events from 79;
|
||||
sync_slave_with_master;
|
||||
|
||||
# Check that we can't change global.collation_server
|
||||
|
||||
error 1105;
|
||||
set global character_set_server=latin2;
|
||||
connection master;
|
||||
error 1105;
|
||||
set global character_set_server=latin2;
|
||||
|
||||
# Check that SET ONE_SHOT is really one shot
|
||||
|
||||
set one_shot @@character_set_server=latin5;
|
||||
set @@max_join_size=1000;
|
||||
select @@character_set_server;
|
||||
select @@character_set_server;
|
||||
set @@character_set_server=latin5;
|
||||
select @@character_set_server;
|
||||
select @@character_set_server;
|
||||
|
||||
# ONE_SHOT on not charset/collation stuff is not allowed
|
||||
error 1105;
|
||||
set one_shot max_join_size=10;
|
||||
|
||||
# Test of wrong character set numbers;
|
||||
error 1115;
|
||||
set character_set_client=9999999;
|
||||
error 1273;
|
||||
set collation_server=9999998;
|
||||
|
||||
# This one was contributed by Sergey Petrunia (BUG#3943)
|
||||
|
||||
use test;
|
||||
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
|
||||
SET CHARACTER_SET_CLIENT=koi8r,
|
||||
CHARACTER_SET_CONNECTION=cp1251,
|
||||
CHARACTER_SET_RESULTS=koi8r;
|
||||
INSERT INTO t1 (c1, c2) VALUES ('<27><>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>','<27><>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>');
|
||||
select hex(c1), hex(c2) from t1;
|
||||
sync_slave_with_master;
|
||||
select hex(c1), hex(c2) from t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
sync_slave_with_master;
|
@ -1,5 +1,8 @@
|
||||
# This test checks that a slave does not execute queries originating
|
||||
# from itself, by default.
|
||||
# This test checks that the slave I/O thread refuses to start if slave
|
||||
# and master have the same server id (because this is a useless setup,
|
||||
# and otherwise SHOW SLAVE STATUS shows progress but all queries are
|
||||
# ignored, which has caught our customers), unless
|
||||
# --replicate-same-server-id.
|
||||
|
||||
source include/master-slave.inc;
|
||||
connection slave;
|
||||
@ -18,5 +21,4 @@ insert into t1 values (1);
|
||||
# (when slave is its own master without --replicate-same-server-id)
|
||||
sleep 2; # enough time for the event to be replicated (it should not)
|
||||
show status like "slave_running";
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
@ -99,3 +99,24 @@ select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST';
|
||||
select charset(@a),collation(@a),coercibility(@a);
|
||||
--error 1267
|
||||
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci;
|
||||
|
||||
# Check that user variables are binlogged correctly (BUG#3875)
|
||||
create table t1 (a varchar(50));
|
||||
reset master;
|
||||
SET TIMESTAMP=10000;
|
||||
SET @`a b`='hello';
|
||||
INSERT INTO t1 VALUES(@`a b`);
|
||||
set @var1= "';aaa";
|
||||
insert into t1 values (@var1);
|
||||
create table t2 (c char(30)) charset=ucs2;
|
||||
set @v=convert('abc' using ucs2);
|
||||
insert into t2 values (@v);
|
||||
show binlog events from 79;
|
||||
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
|
||||
# absolutely need variables names to be quoted and strings to be
|
||||
# escaped).
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
|
||||
drop table t1, t2;
|
||||
|
||||
|
||||
|
@ -310,6 +310,7 @@ static SYMBOL symbols[] = {
|
||||
{ "OFFSET", SYM(OFFSET_SYM)},
|
||||
{ "OLD_PASSWORD", SYM(OLD_PASSWORD)},
|
||||
{ "ON", SYM(ON)},
|
||||
{ "ONE_SHOT", SYM(ONE_SHOT_SYM)},
|
||||
{ "OPEN", SYM(OPEN_SYM)},
|
||||
{ "OPTIMIZE", SYM(OPTIMIZE)},
|
||||
{ "OPTION", SYM(OPTION)},
|
||||
|
34
sql/log.cc
34
sql/log.cc
@ -1231,6 +1231,40 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
|
||||
if (thd)
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
/*
|
||||
To make replication of charsets working in 4.1 we are writing values
|
||||
of charset related variables before every statement in the binlog,
|
||||
if values of those variables differ from global server-wide defaults.
|
||||
We are using SET ONE_SHOT command so that the charset vars get reset
|
||||
to default after the first non-SET statement.
|
||||
In the next 5.0 this won't be needed as we will use the new binlog
|
||||
format to store charset info.
|
||||
*/
|
||||
if ((thd->variables.character_set_client->number !=
|
||||
global_system_variables.collation_server->number) ||
|
||||
(thd->variables.character_set_client->number !=
|
||||
thd->variables.collation_connection->number) ||
|
||||
(thd->variables.collation_server->number !=
|
||||
thd->variables.collation_connection->number))
|
||||
{
|
||||
char buf[200];
|
||||
int written= my_snprintf(buf, sizeof(buf)-1,
|
||||
"SET ONE_SHOT CHARACTER_SET_CLIENT=%lu,\
|
||||
COLLATION_CONNECTION=%lu,COLLATION_DATABASE=%lu,COLLATION_SERVER=%lu",
|
||||
thd->variables.character_set_client->number,
|
||||
thd->variables.collation_connection->number,
|
||||
thd->variables.collation_database->number,
|
||||
thd->variables.collation_server->number);
|
||||
Query_log_event e(thd, buf, written, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add logging of timezones here */
|
||||
|
||||
if (thd->last_insert_id_used)
|
||||
{
|
||||
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
|
||||
|
@ -2176,7 +2176,7 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
void User_var_log_event::pack_info(Protocol* protocol)
|
||||
{
|
||||
char *buf= 0;
|
||||
uint val_offset= 2 + name_len;
|
||||
uint val_offset= 4 + name_len;
|
||||
uint event_len= val_offset;
|
||||
|
||||
if (is_null)
|
||||
@ -2200,16 +2200,21 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
||||
event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
/*
|
||||
This is correct as pack_info is used for SHOW BINLOG command
|
||||
only. But be carefull this is may be incorrect in other cases as
|
||||
string may contain \ and '.
|
||||
*/
|
||||
event_len= val_offset + 2 + val_len;
|
||||
buf= my_malloc(event_len, MYF(MY_WME));
|
||||
buf[val_offset]= '\'';
|
||||
memcpy(buf + val_offset + 1, val, val_len);
|
||||
buf[val_offset + val_len + 1]= '\'';
|
||||
/* 15 is for 'COLLATE' and other chars */
|
||||
buf= my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15, MYF(MY_WME));
|
||||
CHARSET_INFO *cs;
|
||||
if (!(cs= get_charset(charset_number, MYF(0))))
|
||||
{
|
||||
strmov(buf+val_offset, "???");
|
||||
event_len+= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p= strxmov(buf + val_offset, "_", cs->csname, "'", NullS);
|
||||
p+= escape_string_for_mysql(&my_charset_bin, p, val, val_len);
|
||||
p= strxmov(p, "' COLLATE ", cs->name, NullS);
|
||||
event_len= p-buf;
|
||||
}
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
@ -2218,8 +2223,10 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
||||
}
|
||||
}
|
||||
buf[0]= '@';
|
||||
buf[1+name_len]= '=';
|
||||
memcpy(buf+1, name, name_len);
|
||||
buf[1]= '`';
|
||||
buf[2+name_len]= '`';
|
||||
buf[3+name_len]= '=';
|
||||
memcpy(buf+2, name, name_len);
|
||||
protocol->store(buf, event_len, &my_charset_bin);
|
||||
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
@ -2311,8 +2318,9 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||
fprintf(file, "\tUser_var\n");
|
||||
}
|
||||
|
||||
fprintf(file, "SET @");
|
||||
fprintf(file, "SET @`");
|
||||
my_fwrite(file, (byte*) name, (uint) (name_len), MYF(MY_NABP | MY_WME));
|
||||
fprintf(file, "`");
|
||||
|
||||
if (is_null)
|
||||
{
|
||||
@ -2332,7 +2340,36 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||
fprintf(file, ":=%s;\n", int_buf);
|
||||
break;
|
||||
case STRING_RESULT:
|
||||
fprintf(file, ":='%s';\n", val);
|
||||
{
|
||||
char *p;
|
||||
if (!(p= (char *)my_alloca(2*val_len+1)))
|
||||
break; // no error, as we are 'void'
|
||||
escape_string_for_mysql(&my_charset_bin, p, val, val_len);
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
/*
|
||||
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
|
||||
specify the variable's collation. It will however cause problems when
|
||||
people want to mysqlbinlog|mysql into another server not supporting the
|
||||
character set. But there's not much to do about this and it's unlikely.
|
||||
*/
|
||||
CHARSET_INFO *cs;
|
||||
if (!(cs= get_charset(charset_number, MYF(0))))
|
||||
/*
|
||||
Generate an unusable command (=> syntax error) is probably the best
|
||||
thing we can do here.
|
||||
*/
|
||||
fprintf(file, ":=???;\n");
|
||||
else
|
||||
fprintf(file, ":=_%s'%s' COLLATE %s;\n", cs->csname, p, cs->name);
|
||||
#else
|
||||
/*
|
||||
In 5.0 we will have some SET CHARACTER_SET_ect automatically printed
|
||||
for all events where it's needed.
|
||||
*/
|
||||
fprintf(file, ":='%s';\n", p);
|
||||
#endif
|
||||
my_afree(p);
|
||||
}
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
@ -2353,7 +2390,9 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||
int User_var_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
Item *it= 0;
|
||||
CHARSET_INFO *charset= get_charset(charset_number, MYF(0));
|
||||
CHARSET_INFO *charset;
|
||||
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
|
||||
return 1;
|
||||
LEX_STRING user_var_name;
|
||||
user_var_name.str= name;
|
||||
user_var_name.length= name_len;
|
||||
|
@ -1710,20 +1710,32 @@ CHARSET_INFO *get_old_charset_by_name(const char *name)
|
||||
bool sys_var_collation::check(THD *thd, set_var *var)
|
||||
{
|
||||
CHARSET_INFO *tmp;
|
||||
|
||||
if (var->value->result_type() == STRING_RESULT)
|
||||
{
|
||||
char buff[80];
|
||||
String str(buff,sizeof(buff), system_charset_info), *res;
|
||||
|
||||
if (!(res=var->value->val_str(&str)))
|
||||
{
|
||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
|
||||
{
|
||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else // INT_RESULT
|
||||
{
|
||||
if (!(tmp=get_charset(var->value->val_int(),MYF(0))))
|
||||
{
|
||||
char buf[20];
|
||||
int10_to_str(var->value->val_int(), buf, -10);
|
||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
var->save_result.charset= tmp; // Save for update
|
||||
return 0;
|
||||
}
|
||||
@ -1732,9 +1744,11 @@ bool sys_var_collation::check(THD *thd, set_var *var)
|
||||
bool sys_var_character_set::check(THD *thd, set_var *var)
|
||||
{
|
||||
CHARSET_INFO *tmp;
|
||||
|
||||
if (var->value->result_type() == STRING_RESULT)
|
||||
{
|
||||
char buff[80];
|
||||
String str(buff,sizeof(buff), system_charset_info), *res;
|
||||
|
||||
if (!(res=var->value->val_str(&str)))
|
||||
{
|
||||
if (!nullable)
|
||||
@ -1750,6 +1764,17 @@ bool sys_var_character_set::check(THD *thd, set_var *var)
|
||||
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else // INT_RESULT
|
||||
{
|
||||
if (!(tmp=get_charset(var->value->val_int(),MYF(0))))
|
||||
{
|
||||
char buf[20];
|
||||
int10_to_str(var->value->val_int(), buf, -10);
|
||||
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
var->save_result.charset= tmp; // Save for update
|
||||
return 0;
|
||||
}
|
||||
@ -1861,6 +1886,20 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50000)
|
||||
bool sys_var_character_set_server::check(THD *thd, set_var *var)
|
||||
{
|
||||
if ((var->type == OPT_GLOBAL) &&
|
||||
(mysql_bin_log.is_open() ||
|
||||
active_mi->slave_running || active_mi->rli.slave_running))
|
||||
{
|
||||
my_printf_error(0, "Binary logging and replication forbid changing \
|
||||
the global server character set or collation", MYF(0));
|
||||
return 1;
|
||||
}
|
||||
return sys_var_character_set::check(thd,var);
|
||||
}
|
||||
#endif
|
||||
|
||||
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
|
||||
enum_var_type type)
|
||||
@ -1954,6 +1993,20 @@ void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50000)
|
||||
bool sys_var_collation_server::check(THD *thd, set_var *var)
|
||||
{
|
||||
if ((var->type == OPT_GLOBAL) &&
|
||||
(mysql_bin_log.is_open() ||
|
||||
active_mi->slave_running || active_mi->rli.slave_running))
|
||||
{
|
||||
my_printf_error(0, "Binary logging and replication forbid changing \
|
||||
the global server character set or collation", MYF(0));
|
||||
return 1;
|
||||
}
|
||||
return sys_var_collation::check(thd,var);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool sys_var_collation_server::update(THD *thd, set_var *var)
|
||||
{
|
||||
@ -2526,6 +2579,36 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Say if all variables set by a SET support the ONE_SHOT keyword (currently,
|
||||
only character set and collation do; later timezones will).
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
not_all_support_one_shot
|
||||
set_var List of variables to update
|
||||
|
||||
NOTES
|
||||
It has a "not_" because it makes faster tests (no need to "!")
|
||||
|
||||
RETURN VALUE
|
||||
0 all variables of the list support ONE_SHOT
|
||||
1 at least one does not support ONE_SHOT
|
||||
*/
|
||||
|
||||
bool not_all_support_one_shot(List<set_var_base> *var_list)
|
||||
{
|
||||
List_iterator_fast<set_var_base> it(*var_list);
|
||||
set_var_base *var;
|
||||
while ((var= it++))
|
||||
{
|
||||
if (var->no_support_one_shot())
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Functions to handle SET mysql_internal_variable=const_expr
|
||||
*****************************************************************************/
|
||||
|
@ -49,10 +49,20 @@ public:
|
||||
const char *name;
|
||||
|
||||
sys_after_update_func after_update;
|
||||
sys_var(const char *name_arg) :name(name_arg),after_update(0)
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
bool no_support_one_shot;
|
||||
#endif
|
||||
sys_var(const char *name_arg)
|
||||
:name(name_arg), after_update(0)
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
, no_support_one_shot(1)
|
||||
#endif
|
||||
{}
|
||||
sys_var(const char *name_arg,sys_after_update_func func)
|
||||
:name(name_arg), after_update(func)
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
, no_support_one_shot(1)
|
||||
#endif
|
||||
{}
|
||||
virtual ~sys_var() {}
|
||||
virtual bool check(THD *thd, set_var *var);
|
||||
@ -487,12 +497,17 @@ public:
|
||||
class sys_var_collation :public sys_var_thd
|
||||
{
|
||||
public:
|
||||
sys_var_collation(const char *name_arg) :sys_var_thd(name_arg) {}
|
||||
sys_var_collation(const char *name_arg) :sys_var_thd(name_arg)
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
no_support_one_shot= 0;
|
||||
#endif
|
||||
}
|
||||
bool check(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_CHAR; }
|
||||
bool check_update_type(Item_result type)
|
||||
{
|
||||
return type != STRING_RESULT; /* Only accept strings */
|
||||
return ((type != STRING_RESULT) && (type != INT_RESULT));
|
||||
}
|
||||
bool check_default(enum_var_type type) { return 0; }
|
||||
virtual void set_default(THD *thd, enum_var_type type)= 0;
|
||||
@ -502,13 +517,23 @@ class sys_var_character_set :public sys_var_thd
|
||||
{
|
||||
public:
|
||||
bool nullable;
|
||||
sys_var_character_set(const char *name_arg) :sys_var_thd(name_arg)
|
||||
{ nullable= 0; }
|
||||
sys_var_character_set(const char *name_arg) :
|
||||
sys_var_thd(name_arg)
|
||||
{
|
||||
nullable= 0;
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
/*
|
||||
In fact only almost all variables derived from sys_var_character_set
|
||||
support ONE_SHOT; character_set_results doesn't. But that's good enough.
|
||||
*/
|
||||
no_support_one_shot= 0;
|
||||
#endif
|
||||
}
|
||||
bool check(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_CHAR; }
|
||||
bool check_update_type(Item_result type)
|
||||
{
|
||||
return type != STRING_RESULT; /* Only accept strings */
|
||||
return ((type != STRING_RESULT) && (type != INT_RESULT));
|
||||
}
|
||||
bool check_default(enum_var_type type) { return 0; }
|
||||
bool update(THD *thd, set_var *var);
|
||||
@ -541,6 +566,9 @@ class sys_var_character_set_server :public sys_var_character_set
|
||||
public:
|
||||
sys_var_character_set_server(const char *name_arg) :
|
||||
sys_var_character_set(name_arg) {}
|
||||
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50000)
|
||||
bool check(THD *thd, set_var *var);
|
||||
#endif
|
||||
void set_default(THD *thd, enum_var_type type);
|
||||
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
|
||||
};
|
||||
@ -576,6 +604,9 @@ class sys_var_collation_server :public sys_var_collation
|
||||
{
|
||||
public:
|
||||
sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
|
||||
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50000)
|
||||
bool check(THD *thd, set_var *var);
|
||||
#endif
|
||||
bool update(THD *thd, set_var *var);
|
||||
void set_default(THD *thd, enum_var_type type);
|
||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||
@ -690,6 +721,9 @@ public:
|
||||
virtual int update(THD *thd)=0; /* To set the value */
|
||||
/* light check for PS */
|
||||
virtual int light_check(THD *thd) { return check(thd); }
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
virtual bool no_support_one_shot() { return 1; }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -731,6 +765,9 @@ public:
|
||||
int check(THD *thd);
|
||||
int update(THD *thd);
|
||||
int light_check(THD *thd);
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
bool no_support_one_shot() { return var->no_support_one_shot; }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -833,6 +870,7 @@ void set_var_init();
|
||||
void set_var_free();
|
||||
sys_var *find_sys_var(const char *str, uint length=0);
|
||||
int sql_set_variables(THD *thd, List<set_var_base> *var_list);
|
||||
bool not_all_support_one_shot(List<set_var_base> *var_list);
|
||||
void fix_delay_key_write(THD *thd, enum_var_type type);
|
||||
ulong fix_sql_mode(ulong sql_mode);
|
||||
extern sys_var_str sys_charset_system;
|
||||
|
75
sql/slave.cc
75
sql/slave.cc
@ -72,7 +72,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
|
||||
static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
|
||||
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
||||
const char* table_name, bool overwrite);
|
||||
static int check_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi);
|
||||
static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi);
|
||||
|
||||
|
||||
/*
|
||||
@ -1187,38 +1187,75 @@ slaves can't replicate a 5.0 or newer master.";
|
||||
break;
|
||||
}
|
||||
|
||||
MYSQL_RES *master_clock_res;
|
||||
MYSQL_ROW master_clock_row;
|
||||
time_t slave_clock;
|
||||
/*
|
||||
Compare the master and slave's clock. Do not die if master's clock is
|
||||
unavailable (very old master not supporting UNIX_TIMESTAMP()?).
|
||||
*/
|
||||
MYSQL_RES *master_res= 0;
|
||||
MYSQL_ROW master_row;
|
||||
|
||||
if (mysql_real_query(mysql, "SELECT UNIX_TIMESTAMP()", 23))
|
||||
errmsg= "\"SELECT UNIX_TIMESTAMP()\" failed on master";
|
||||
else if (!(master_clock_res= mysql_store_result(mysql)))
|
||||
if (!mysql_real_query(mysql, "SELECT UNIX_TIMESTAMP()", 23) &&
|
||||
(master_res= mysql_store_result(mysql)) &&
|
||||
(master_row= mysql_fetch_row(master_res)))
|
||||
{
|
||||
errmsg= "Could not read the result of \"SELECT UNIX_TIMESTAMP()\" on \
|
||||
master";
|
||||
mi->clock_diff_with_master=
|
||||
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(master_clock_row= mysql_fetch_row(master_clock_res)))
|
||||
errmsg= "Could not read a row from the result of \"SELECT \
|
||||
UNIX_TIMESTAMP()\" on master";
|
||||
else
|
||||
mi->clock_diff_with_master= 0; /* The "most sensible" value */
|
||||
sql_print_error("Warning: \"SELECT UNIX_TIMESTAMP()\" failed on master, \
|
||||
do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS");
|
||||
}
|
||||
if (master_res)
|
||||
mysql_free_result(master_res);
|
||||
|
||||
/*
|
||||
Check that the master's server id and ours are different. Because if they
|
||||
are equal (which can result from a simple copy of master's datadir to slave,
|
||||
thus copying some my.cnf), replication will work but all events will be
|
||||
skipped.
|
||||
Do not die if SHOW VARIABLES LIKE 'SERVER_ID' fails on master (very old
|
||||
master?).
|
||||
Note: we could have put a @@SERVER_ID in the previous SELECT
|
||||
UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
|
||||
*/
|
||||
if (!mysql_real_query(mysql, "SHOW VARIABLES LIKE 'SERVER_ID'", 31) &&
|
||||
(master_res= mysql_store_result(mysql)))
|
||||
{
|
||||
slave_clock= time((time_t*) 0);
|
||||
mi->clock_diff_with_master= (long) (slave_clock -
|
||||
strtoul(master_clock_row[0], 0, 10));
|
||||
DBUG_PRINT("info",("slave_clock=%lu, master_clock=%s",
|
||||
slave_clock, master_clock_row[0]));
|
||||
if ((master_row= mysql_fetch_row(master_res)) &&
|
||||
(::server_id == strtoul(master_row[1], 0, 10)) &&
|
||||
!replicate_same_server_id)
|
||||
errmsg= "The slave I/O thread stops because master and slave have equal \
|
||||
MySQL server ids; these ids must be different for replication to work (or \
|
||||
the --replicate-same-server-id option must be used on slave but this does \
|
||||
not always make sense; please check the manual before using it).";
|
||||
mysql_free_result(master_res);
|
||||
}
|
||||
mysql_free_result(master_clock_res);
|
||||
|
||||
/*
|
||||
Check that the master's global character_set_server and ours are the same.
|
||||
Not fatal if query fails (old master?).
|
||||
*/
|
||||
if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) &&
|
||||
(master_res= mysql_store_result(mysql)))
|
||||
{
|
||||
if ((master_row= mysql_fetch_row(master_res)) &&
|
||||
strcmp(master_row[0], global_system_variables.collation_server->name))
|
||||
errmsg= "The slave I/O thread stops because master and slave have \
|
||||
different values for the COLLATION_SERVER global variable. The values must \
|
||||
be equal for replication to work";
|
||||
mysql_free_result(master_res);
|
||||
}
|
||||
|
||||
/* Add a timezones check here */
|
||||
|
||||
if (errmsg)
|
||||
{
|
||||
sql_print_error(errmsg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,7 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
|
||||
current_linfo = 0;
|
||||
slave_thread = 0;
|
||||
variables.pseudo_thread_id= 0;
|
||||
one_shot_set= 0;
|
||||
file_id = 0;
|
||||
warn_id= 0;
|
||||
db_charset= global_system_variables.collation_database;
|
||||
|
@ -801,7 +801,7 @@ public:
|
||||
/* scramble - random string sent to client on handshake */
|
||||
char scramble[SCRAMBLE_LENGTH+1];
|
||||
|
||||
bool slave_thread;
|
||||
bool slave_thread, one_shot_set;
|
||||
bool locked, some_tables_deleted;
|
||||
bool last_cuted_field;
|
||||
bool no_errors, password, is_fatal_error;
|
||||
|
@ -611,7 +611,7 @@ typedef struct st_lex
|
||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||
uint slave_thd_opt;
|
||||
uint8 describe;
|
||||
bool drop_if_exists, drop_temporary, local_file;
|
||||
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
|
||||
bool in_comment, ignore_space, verbose, no_write_to_binlog;
|
||||
bool derived_tables;
|
||||
bool safe_to_cache_query;
|
||||
|
@ -2918,14 +2918,31 @@ unsent_create_error:
|
||||
}
|
||||
|
||||
case SQLCOM_SET_OPTION:
|
||||
{
|
||||
List<set_var_base> *lex_var_list= &lex->var_list;
|
||||
if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) ||
|
||||
(res= open_and_lock_tables(thd,tables))))
|
||||
break;
|
||||
if (!(res= sql_set_variables(thd, &lex->var_list)))
|
||||
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
|
||||
{
|
||||
my_printf_error(0, "The SET ONE_SHOT syntax is reserved for \
|
||||
purposes internal to the MySQL server", MYF(0));
|
||||
res= -1;
|
||||
break;
|
||||
}
|
||||
if (!(res= sql_set_variables(thd, lex_var_list)))
|
||||
{
|
||||
/*
|
||||
If the previous command was a SET ONE_SHOT, we don't want to forget
|
||||
about the ONE_SHOT property of that SET. So we use a |= instead of = .
|
||||
*/
|
||||
thd->one_shot_set|= lex->one_shot_set;
|
||||
send_ok(thd);
|
||||
}
|
||||
if (thd->net.report_error)
|
||||
res= -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLCOM_UNLOCK_TABLES:
|
||||
unlock_locked_tables(thd);
|
||||
@ -3377,6 +3394,29 @@ unsent_create_error:
|
||||
break;
|
||||
}
|
||||
thd->proc_info="query end"; // QQ
|
||||
if (thd->one_shot_set)
|
||||
{
|
||||
/*
|
||||
If this is a SET, do nothing. This is to allow mysqlbinlog to print
|
||||
many SET commands (in this case we want the charset temp setting to
|
||||
live until the real query). This is also needed so that SET
|
||||
CHARACTER_SET_CLIENT... does not cancel itself immediately.
|
||||
*/
|
||||
if (lex->sql_command != SQLCOM_SET_OPTION)
|
||||
{
|
||||
thd->variables.character_set_client=
|
||||
global_system_variables.character_set_client;
|
||||
thd->variables.collation_connection=
|
||||
global_system_variables.collation_connection;
|
||||
thd->variables.collation_database=
|
||||
global_system_variables.collation_database;
|
||||
thd->variables.collation_server=
|
||||
global_system_variables.collation_server;
|
||||
thd->update_charset();
|
||||
/* Add timezone stuff here */
|
||||
thd->one_shot_set= 0;
|
||||
}
|
||||
}
|
||||
if (res < 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
|
||||
|
@ -316,6 +316,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token NUM
|
||||
%token OFFSET_SYM
|
||||
%token ON
|
||||
%token ONE_SHOT_SYM
|
||||
%token OPEN_SYM
|
||||
%token OPTION
|
||||
%token OPTIONALLY
|
||||
@ -5002,6 +5003,7 @@ keyword:
|
||||
| NVARCHAR_SYM {}
|
||||
| OFFSET_SYM {}
|
||||
| OLD_PASSWORD {}
|
||||
| ONE_SHOT_SYM {}
|
||||
| OPEN_SYM {}
|
||||
| PACK_KEYS_SYM {}
|
||||
| PARTIAL {}
|
||||
@ -5088,6 +5090,7 @@ set:
|
||||
lex->sql_command= SQLCOM_SET_OPTION;
|
||||
lex->option_type=OPT_SESSION;
|
||||
lex->var_list.empty();
|
||||
lex->one_shot_set= 0;
|
||||
}
|
||||
option_value_list
|
||||
{}
|
||||
@ -5106,6 +5109,7 @@ option_type:
|
||||
| GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; }
|
||||
| LOCAL_SYM { Lex->option_type= OPT_SESSION; }
|
||||
| SESSION_SYM { Lex->option_type= OPT_SESSION; }
|
||||
| ONE_SHOT_SYM { Lex->option_type= OPT_SESSION; Lex->one_shot_set= 1; }
|
||||
;
|
||||
|
||||
opt_var_type:
|
||||
|
Reference in New Issue
Block a user