Manual merge from mysql-trunk.

This commit is contained in:
Alexander Nozdrin 2010-02-23 17:06:06 +03:00
commit e7e1a36755
37 changed files with 663 additions and 141 deletions

View file

@ -1,4 +1,4 @@
[MYSQL]
post_commit_to = "commits@lists.mysql.com"
post_push_to = "commits@lists.mysql.com"
tree_name = "mysql-5.5-trunk"
tree_name = "mysql-trunk"

View file

@ -12,7 +12,7 @@ dnl
dnl Remember to also update version.c in ndb.
dnl When changing major version number please also check switch statement
dnl in client/mysqlbinlog.cc:check_master_version().
AC_INIT([MySQL Server], [5.5.2-m2], [], [mysql])
AC_INIT([MySQL Server], [5.5.3-m2], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
# USTAR format gives us the possibility to store longer path names in

View file

@ -66,8 +66,9 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
#define MYSQL_REPLICATION_PLUGIN 5 /* The replication plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 6 /* The number of plugin types */
#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM 7 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0

View file

@ -1354,3 +1354,15 @@ DROP i,
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1;
DROP TABLE t1;
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
CREATE TABLE t1 (a CHAR(1));
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
ALTER TABLE t1 ADD KEY (a(20));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
CREATE UNIQUE INDEX i1 ON t1 (a(20));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
CREATE INDEX i2 ON t1 (a(20));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
DROP TABLE t1;

View file

@ -1058,3 +1058,33 @@ SELECT Polygon(12345123,'');
Polygon(12345123,'')
NULL
End of 5.1 tests
CREATE TABLE t1(
col0 BINARY NOT NULL,
col2 TIMESTAMP,
SPATIAL INDEX i1 (col0)
) ENGINE=MyISAM;
ERROR 42000: A SPATIAL index may only contain a geometrical type column
CREATE TABLE t1 (
col0 BINARY NOT NULL,
col2 TIMESTAMP
) ENGINE=MyISAM;
CREATE SPATIAL INDEX idx0 ON t1(col0);
ERROR 42000: A SPATIAL index may only contain a geometrical type column
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
ERROR 42000: A SPATIAL index may only contain a geometrical type column
CREATE TABLE t2 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 POINT
);
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
CREATE TABLE t3 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 LINESTRING,
SPATIAL INDEX i1 (col1, col2)
);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
DROP TABLE t1;
DROP TABLE t2;

View file

@ -2699,7 +2699,7 @@ a c COUNT(DISTINCT c, a, b)
1 1 1
1 1 1
1 1 1
2 1 1
1 1 1
2 1 1
2 1 1
2 1 1
@ -2727,7 +2727,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL a 10 NULL 9 Using index for group-by
SELECT a, COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a;
a COUNT(DISTINCT b) SUM(DISTINCT b)
2 8 36
1 8 36
2 8 36
EXPLAIN SELECT COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
@ -2774,7 +2774,7 @@ SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c;
126
126
126
168
126
168
168
168
@ -2792,3 +2792,24 @@ SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
10
DROP TABLE t1,t2;
# end of WL#3220 tests
#
# Bug#50539: Wrong result when loose index scan is used for an aggregate
# function with distinct
#
CREATE TABLE t1 (
f1 int(11) NOT NULL DEFAULT '0',
f2 char(1) NOT NULL DEFAULT '',
PRIMARY KEY (f1,f2)
) ;
insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'),
(3, 'A'), (3, 'B'), (3, 'C'), (3, 'D');
SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
f1 COUNT(DISTINCT f2)
1 3
2 1
3 4
explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL PRIMARY 5 NULL 9 Using index for group-by (scanning)
drop table t1;
# End of test#50539.

View file

@ -0,0 +1,14 @@
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
INSERT INTO t1 VALUES (0), (1), (2);
START TRANSACTION;
UPDATE t1 SET a = 5 WHERE a = 1;
# Connection con1
# InnoDB lock timeout and monitor thread runs every 15 seconds
SET innodb_lock_wait_timeout = 20;
START TRANSACTION;
UPDATE t1 SET a = 3 WHERE a = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
COMMIT;
# Connection default
COMMIT;
DROP TABLE t1;

View file

@ -0,0 +1 @@
--innodb-status-file=1

View file

@ -0,0 +1,20 @@
--source include/have_innodb.inc
--source include/have_partition.inc
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
INSERT INTO t1 VALUES (0), (1), (2);
START TRANSACTION;
UPDATE t1 SET a = 5 WHERE a = 1;
connect (con1, localhost, root,,);
--echo # Connection con1
--echo # InnoDB lock timeout and monitor thread runs every 15 seconds
SET innodb_lock_wait_timeout = 20;
START TRANSACTION;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t1 SET a = 3 WHERE a = 1;
COMMIT;
disconnect con1;
connection default;
--echo # Connection default
COMMIT;
DROP TABLE t1;

View file

@ -89,6 +89,7 @@ show grants for rpl_do_grant2@localhost;
ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
show grants for rpl_do_grant2@localhost;
ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
DROP DATABASE IF EXISTS bug42217_db;
CREATE DATABASE bug42217_db;
GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost'
@ -166,9 +167,12 @@ DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
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;
######## BUG#49119 #######
### i) test case from the 'how to repeat section'
stop slave;

View file

@ -120,8 +120,27 @@ min(a)
select max(a) from t1;
max(a)
300
# BUG#50157
# semi-sync replication crashes when replicating a transaction which
# include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
[ on master ]
SET SESSION AUTOCOMMIT= 0;
CREATE TABLE t2(c1 INT) ENGINE=innodb;
BEGIN;
# Even though it is in a transaction, this statement is binlogged into binlog
# file immediately.
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
# These statements will not be binlogged until the transaction is committed
INSERT INTO t2 VALUES(11);
INSERT INTO t2 VALUES(22);
COMMIT;
DROP TABLE t2, t3;
SET SESSION AUTOCOMMIT= 1;
#
# Test semi-sync master will switch OFF after one transacton
# Test semi-sync master will switch OFF after one transaction
# timeout waiting for slave reply.
#
include/stop_slave.inc
@ -135,7 +154,7 @@ Variable_name Value
Rpl_semi_sync_master_no_tx 0
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
Rpl_semi_sync_master_yes_tx 304
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
@ -150,7 +169,7 @@ Variable_name Value
Rpl_semi_sync_master_no_tx 1
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
Rpl_semi_sync_master_yes_tx 304
insert into t1 values (100);
[ master status should be OFF ]
show status like 'Rpl_semi_sync_master_status';
@ -161,7 +180,7 @@ Variable_name Value
Rpl_semi_sync_master_no_tx 302
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
Rpl_semi_sync_master_yes_tx 304
#
# Test semi-sync status on master will be ON again when slave catches up
#
@ -194,7 +213,7 @@ Variable_name Value
Rpl_semi_sync_master_no_tx 302
show status like 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 301
Rpl_semi_sync_master_yes_tx 304
show status like 'Rpl_semi_sync_master_clients';
Variable_name Value
Rpl_semi_sync_master_clients 1
@ -213,7 +232,7 @@ Variable_name Value
Rpl_semi_sync_master_no_tx 302
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
Variable_name Value
Rpl_semi_sync_master_yes_tx 302
Rpl_semi_sync_master_yes_tx 305
FLUSH NO_WRITE_TO_BINLOG STATUS;
[ Semi-sync master status variables after FLUSH STATUS ]
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';

View file

@ -12,5 +12,4 @@
rpl_get_master_version_and_clock: # Bug#46931 2009-10-17 joro rpl.rpl_get_master_version_and_clock fails
rpl_row_create_table : Bug#45576 2009-12-01 joro rpl_row_create_table fails on PB2
rpl_cross_version : BUG#43913 2009-10-22 luis rpl_cross_version fails with symptom in described in bug report
rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux

View file

@ -1 +1 @@
--replicate-same-server-id --relay-log=slave-relay-bin --secure-file-priv=$MYSQL_TMP_DIR
--replicate-same-server-id --relay-log=slave-relay-bin

View file

@ -120,6 +120,9 @@ show grants for rpl_do_grant2@localhost;
# BUG42217 mysql.procs_priv does not get replicated
#####################################################
connection master;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
sync_slave_with_master;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS bug42217_db;
@ -209,12 +212,19 @@ USE bug42217_db;
DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
-- sync_slave_with_master
-- connection master
# user was already dropped in the slave before
# so no need to wait for the slave to replicate
# this statement (if it did and we later synced
# the slave it would end up in an error anyway)
DROP USER 'create_rout_db'@'localhost';
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
connection slave;
USE mtr;
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
# finish entire clean up (remove binlogs)
# so that we leave a pristine environment for the
# following tests
-- source include/master-slave-reset.inc
# BUG#49119: Master crashes when executing 'REVOKE ... ON
# {PROCEDURE|FUNCTION} FROM ...'

View file

@ -382,7 +382,7 @@ let $slave_param_comparison= =;
let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
# Flush logs every 0.1 second during 5 sec
--disable_query_log
let $i=50;
let $i=100;
while ($i) {
FLUSH LOGS;
dec $i;

View file

@ -11,6 +11,7 @@ disable_query_log;
connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
call mtr.add_suppression("Read semi-sync reply");
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT.");
connection slave;
call mtr.add_suppression("Master server does not support semi-sync");
call mtr.add_suppression("Semi-sync slave .* reply");
@ -193,8 +194,38 @@ select count(distinct a) from t1;
select min(a) from t1;
select max(a) from t1;
--echo
--echo # BUG#50157
--echo # semi-sync replication crashes when replicating a transaction which
--echo # include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
connection master;
echo [ on master ];
SET SESSION AUTOCOMMIT= 0;
CREATE TABLE t2(c1 INT) ENGINE=innodb;
sync_slave_with_master;
connection master;
BEGIN;
--echo
--echo # Even though it is in a transaction, this statement is binlogged into binlog
--echo # file immediately.
--disable_warnings
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
--enable_warnings
--echo
--echo # These statements will not be binlogged until the transaction is committed
INSERT INTO t2 VALUES(11);
INSERT INTO t2 VALUES(22);
COMMIT;
DROP TABLE t2, t3;
SET SESSION AUTOCOMMIT= 1;
sync_slave_with_master;
--echo #
--echo # Test semi-sync master will switch OFF after one transacton
--echo # Test semi-sync master will switch OFF after one transaction
--echo # timeout waiting for slave reply.
--echo #
connection slave;

View file

@ -10,4 +10,5 @@ source include/have_binlog_format_row.inc;
LET $ENGINE_TYPE= MyISAM;
source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
sync_slave_with_master;

View file

@ -1089,3 +1089,31 @@ ALTER TABLE t1
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1;
DROP TABLE t1;
#
# Bug#50542 5.5.x doesn't check length of key prefixes:
# corruption and crash results
#
# This case is related to Bug#31031 (above)
# A statement where the index key is larger/wider than
# the column type, should cause an error
#
--error ER_WRONG_SUB_KEY
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
# Test other variants of creating indices
CREATE TABLE t1 (a CHAR(1));
# ALTER TABLE
--error ER_WRONG_SUB_KEY
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
--error ER_WRONG_SUB_KEY
ALTER TABLE t1 ADD KEY (a(20));
# CREATE INDEX
--error ER_WRONG_SUB_KEY
CREATE UNIQUE INDEX i1 ON t1 (a(20));
--error ER_WRONG_SUB_KEY
CREATE INDEX i2 ON t1 (a(20));
# cleanup
DROP TABLE t1;

View file

@ -723,3 +723,48 @@ SELECT Polygon(1234512,'');
SELECT Polygon(12345123,'');
--echo End of 5.1 tests
#
# Bug #50574 5.5.x allows spatial indexes on non-spatial
# columns, causing crashes!
#
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
CREATE TABLE t1(
col0 BINARY NOT NULL,
col2 TIMESTAMP,
SPATIAL INDEX i1 (col0)
) ENGINE=MyISAM;
# Test other ways to add indices
CREATE TABLE t1 (
col0 BINARY NOT NULL,
col2 TIMESTAMP
) ENGINE=MyISAM;
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
CREATE SPATIAL INDEX idx0 ON t1(col0);
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
CREATE TABLE t2 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 POINT
);
--error ER_WRONG_ARGUMENTS
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
--error ER_WRONG_ARGUMENTS
CREATE TABLE t3 (
col0 INTEGER NOT NULL,
col1 POINT,
col2 LINESTRING,
SPATIAL INDEX i1 (col1, col2)
);
# cleanup
DROP TABLE t1;
DROP TABLE t2;

View file

@ -1176,3 +1176,22 @@ SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
DROP TABLE t1,t2;
--echo # end of WL#3220 tests
--echo #
--echo # Bug#50539: Wrong result when loose index scan is used for an aggregate
--echo # function with distinct
--echo #
CREATE TABLE t1 (
f1 int(11) NOT NULL DEFAULT '0',
f2 char(1) NOT NULL DEFAULT '',
PRIMARY KEY (f1,f2)
) ;
insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'),
(3, 'A'), (3, 'B'), (3, 'C'), (3, 'D');
SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
drop table t1;
--echo # End of test#50539.

View file

@ -65,7 +65,7 @@ static int gettimeofday(struct timeval *tv, void *tz)
ActiveTranx::ActiveTranx(pthread_mutex_t *lock,
unsigned long trace_level)
: Trace(trace_level),
: Trace(trace_level), allocator_(max_connections),
num_entries_(max_connections << 1), /* Transaction hash table size
* is set to double the size
* of max_connections */
@ -115,25 +115,6 @@ unsigned int ActiveTranx::get_hash_value(const char *log_file_name,
return (hash1 + hash2) % num_entries_;
}
ActiveTranx::TranxNode* ActiveTranx::alloc_tranx_node()
{
MYSQL_THD thd= (MYSQL_THD)current_thd;
/* The memory allocated for TranxNode will be automatically freed at
the end of the command of current THD. And because
ha_autocommit_or_rollback() will always be called before that, so
we are sure that the node will be removed from the active list
before it get freed. */
TranxNode *trx_node = (TranxNode *)thd_alloc(thd, sizeof(TranxNode));
if (trx_node)
{
trx_node->log_name_[0] = '\0';
trx_node->log_pos_= 0;
trx_node->next_= 0;
trx_node->hash_next_= 0;
}
return trx_node;
}
int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
const char *log_file_name2, my_off_t log_file_pos2)
{
@ -159,7 +140,7 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
function_enter(kWho);
ins_node = alloc_tranx_node();
ins_node = allocator_.allocate_node();
if (!ins_node)
{
sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
@ -271,6 +252,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
/* Clear the hash table. */
memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *));
allocator_.free_all_nodes();
/* Clear the active transaction list. */
if (trx_front_ != NULL)
@ -311,6 +293,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
}
trx_front_ = new_front;
allocator_.free_nodes_before(trx_front_);
if (trace_level_ & kTraceDetail)
sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)",

View file

@ -20,6 +20,267 @@
#include "semisync.h"
struct TranxNode {
char log_name_[FN_REFLEN];
my_off_t log_pos_;
struct TranxNode *next_; /* the next node in the sorted list */
struct TranxNode *hash_next_; /* the next node during hash collision */
};
/**
@class TranxNodeAllocator
This class provides memory allocating and freeing methods for
TranxNode. The main target is performance.
@section ALLOCATE How to allocate a node
The pointer of the first node after 'last_node' in current_block is
returned. current_block will move to the next free Block when all nodes of
it are in use. A new Block is allocated and is put into the rear of the
Block link table if no Block is free.
The list starts up empty (ie, there is no allocated Block).
After some nodes are freed, there probably are some free nodes before
the sequence of the allocated nodes, but we do not reuse it. It is better
to keep the allocated nodes are in the sequence, for it is more efficient
for allocating and freeing TranxNode.
@section FREENODE How to free nodes
There are two methods for freeing nodes. They are free_all_nodes and
free_nodes_before.
'A Block is free' means all of its nodes are free.
@subsection free_nodes_before
As all allocated nodes are in the sequence, 'Before one node' means all
nodes before given node in the same Block and all Blocks before the Block
which containing the given node. As such, all Blocks before the given one
('node') are free Block and moved into the rear of the Block link table.
The Block containing the given 'node', however, is not. For at least the
given 'node' is still in use. This will waste at most one Block, but it is
more efficient.
*/
#define BLOCK_TRANX_NODES 16
class TranxNodeAllocator
{
public:
/**
@param reserved_nodes
The number of reserved TranxNodes. It is used to set 'reserved_blocks'
which can contain at least 'reserved_nodes' number of TranxNodes. When
freeing memory, we will reserve at least reserved_blocks of Blocks not
freed.
*/
TranxNodeAllocator(uint reserved_nodes) :
reserved_blocks(reserved_nodes/BLOCK_TRANX_NODES +
(reserved_nodes%BLOCK_TRANX_NODES > 1 ? 2 : 1)),
first_block(NULL), last_block(NULL),
current_block(NULL), last_node(-1), block_num(0) {}
~TranxNodeAllocator()
{
Block *block= first_block;
while (block != NULL)
{
Block *next= block->next;
free_block(block);
block= next;
}
}
/**
The pointer of the first node after 'last_node' in current_block is
returned. current_block will move to the next free Block when all nodes of
it are in use. A new Block is allocated and is put into the rear of the
Block link table if no Block is free.
@return Return a TranxNode *, or NULL if an error occured.
*/
TranxNode *allocate_node()
{
TranxNode *trx_node;
Block *block= current_block;
if (last_node == BLOCK_TRANX_NODES-1)
{
current_block= current_block->next;
last_node= -1;
}
if (current_block == NULL && allocate_block())
{
current_block= block;
if (current_block)
last_node= BLOCK_TRANX_NODES-1;
return NULL;
}
trx_node= &(current_block->nodes[++last_node]);
trx_node->log_name_[0] = '\0';
trx_node->log_pos_= 0;
trx_node->next_= 0;
trx_node->hash_next_= 0;
return trx_node;
}
/**
All nodes are freed.
@return Return 0, or 1 if an error occured.
*/
int free_all_nodes()
{
current_block= first_block;
last_node= -1;
free_blocks();
return 0;
}
/**
All Blocks before the given 'node' are free Block and moved into the rear
of the Block link table.
@param node All nodes before 'node' will be freed
@return Return 0, or 1 if an error occured.
*/
int free_nodes_before(TranxNode* node)
{
Block *block;
Block *prev_block;
block= first_block;
while (block != current_block->next)
{
/* Find the Block containing the given node */
if (&(block->nodes[0]) <= node && &(block->nodes[BLOCK_TRANX_NODES]) >= node)
{
/* All Blocks before the given node are put into the rear */
if (first_block != block)
{
last_block->next= first_block;
first_block= block;
last_block= prev_block;
last_block->next= NULL;
free_blocks();
}
return 0;
}
prev_block= block;
block= block->next;
}
/* Node does not find should never happen */
DBUG_ASSERT(0);
return 1;
}
private:
uint reserved_blocks;
/**
A sequence memory which contains BLOCK_TRANX_NODES TranxNodes.
BLOCK_TRANX_NODES The number of TranxNodes which are in a Block.
next Every Block has a 'next' pointer which points to the next Block.
These linking Blocks constitute a Block link table.
*/
struct Block {
Block *next;
TranxNode nodes[BLOCK_TRANX_NODES];
};
/**
The 'first_block' is the head of the Block link table;
*/
Block *first_block;
/**
The 'last_block' is the rear of the Block link table;
*/
Block *last_block;
/**
current_block always points the Block in the Block link table in
which the last allocated node is. The Blocks before it are all in use
and the Blocks after it are all free.
*/
Block *current_block;
/**
It always points to the last node which has been allocated in the
current_block.
*/
int last_node;
/**
How many Blocks are in the Block link table.
*/
uint block_num;
/**
Allocate a block and then assign it to current_block.
*/
int allocate_block()
{
Block *block= (Block *)my_malloc(sizeof(Block), MYF(0));
if (block)
{
block->next= NULL;
if (first_block == NULL)
first_block= block;
else
last_block->next= block;
/* New Block is always put into the rear */
last_block= block;
/* New Block is always the current_block */
current_block= block;
++block_num;
return 0;
}
return 1;
}
/**
Free a given Block.
@param block The Block will be freed.
*/
void free_block(Block *block)
{
my_free(block, MYF(0));
--block_num;
}
/**
If there are some free Blocks and the total number of the Blocks in the
Block link table is larger than the 'reserved_blocks', Some free Blocks
will be freed until the total number of the Blocks is equal to the
'reserved_blocks' or there is only one free Block behind the
'current_block'.
*/
void free_blocks()
{
if (current_block == NULL || current_block->next == NULL)
return;
/* One free Block is always kept behind the current block */
Block *block= current_block->next->next;
while (block_num > reserved_blocks && block != NULL)
{
Block *next= block->next;
free_block(block);
block= next;
}
current_block->next->next= block;
if (block == NULL)
last_block= current_block->next;
}
};
/**
This class manages memory for active transaction list.
@ -31,13 +292,8 @@
class ActiveTranx
:public Trace {
private:
struct TranxNode {
char log_name_[FN_REFLEN];
my_off_t log_pos_;
struct TranxNode *next_; /* the next node in the sorted list */
struct TranxNode *hash_next_; /* the next node during hash collision */
};
TranxNodeAllocator allocator_;
/* These two record the active transaction list in sort order. */
TranxNode *trx_front_, *trx_rear_;
@ -48,24 +304,22 @@ private:
inline void assert_lock_owner();
inline TranxNode* alloc_tranx_node();
inline unsigned int calc_hash(const unsigned char *key,unsigned int length);
unsigned int get_hash_value(const char *log_file_name, my_off_t log_file_pos);
int compare(const char *log_file_name1, my_off_t log_file_pos1,
const TranxNode *node2) {
const TranxNode *node2) {
return compare(log_file_name1, log_file_pos1,
node2->log_name_, node2->log_pos_);
node2->log_name_, node2->log_pos_);
}
int compare(const TranxNode *node1,
const char *log_file_name2, my_off_t log_file_pos2) {
const char *log_file_name2, my_off_t log_file_pos2) {
return compare(node1->log_name_, node1->log_pos_,
log_file_name2, log_file_pos2);
log_file_name2, log_file_pos2);
}
int compare(const TranxNode *node1, const TranxNode *node2) {
return compare(node1->log_name_, node1->log_pos_,
node2->log_name_, node2->log_pos_);
node2->log_name_, node2->log_pos_);
}
public:
@ -88,7 +342,7 @@ public:
* 0: success; non-zero: error
*/
int clear_active_tranx_nodes(const char *log_file_name,
my_off_t log_file_pos);
my_off_t log_file_pos);
/* Given a position, check to see whether the position is an active
* transaction's ending position by probing the hash table.
@ -99,7 +353,7 @@ public:
* (file_name, file_position).
*/
static int compare(const char *log_file_name1, my_off_t log_file_pos1,
const char *log_file_name2, my_off_t log_file_pos2);
const char *log_file_name2, my_off_t log_file_pos2);
};

View file

@ -4646,10 +4646,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
thd->warning_info->opt_clear_warning_info(thd->query_id);
TABLE_LIST tables;
bzero((char*) &tables,sizeof(tables));
tables.db= thd->strmake(thd->db, thd->db_length);
tables.alias = tables.table_name = (char*) table_name;
tables.lock_type = TL_WRITE;
tables.init_one_table(thd->db, table_name, TL_WRITE);
tables.updating= 1;
// the table will be opened in mysql_load

View file

@ -10952,17 +10952,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next()
} while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
is_last_prefix != 0);
if (result == 0)
{
/*
Partially mimic the behavior of end_select_send. Copy the
field data from Item_field::field into Item_field::result_field
of each non-aggregated field (the group fields, and optionally
other fields in non-ANSI SQL mode).
*/
copy_fields(&join->tmp_table_param);
}
else if (result == HA_ERR_KEY_NOT_FOUND)
if (result == HA_ERR_KEY_NOT_FOUND)
result= HA_ERR_END_OF_FILE;
DBUG_RETURN(result);

View file

@ -977,7 +977,7 @@ bool load_master_data(THD* thd)
host was specified; there could have been a problem when replication
started, which led to relay log's IO_CACHE to not be inited.
*/
if (flush_master_info(active_mi, 0))
if (flush_master_info(active_mi, FALSE, FALSE))
sql_print_error("Failed to flush master info file");
}
mysql_free_result(master_status_res);

View file

@ -190,8 +190,8 @@ int Trans_delegate::after_commit(THD *thd, bool all)
{
Trans_param param;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
if (is_real_trans)
param.flags |= TRANS_IS_REAL_TRANS;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
Trans_binlog_info *log_info=
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
@ -218,8 +218,8 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
{
Trans_param param;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
if (is_real_trans)
param.flags |= TRANS_IS_REAL_TRANS;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
Trans_binlog_info *log_info=
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
@ -228,7 +228,7 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
param.log_pos= log_info ? log_info->log_pos : 0;
int ret= 0;
FOREACH_OBSERVER(ret, after_commit, thd, (&param));
FOREACH_OBSERVER(ret, after_rollback, thd, (&param));
/*
This is the end of a real transaction or autocommit statement, we

View file

@ -387,7 +387,7 @@ file '%s')", fname);
mi->rli.is_relay_log_recovery= FALSE;
// now change cache READ -> WRITE - must do this before flush_master_info
reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
if ((error=test(flush_master_info(mi, 1))))
if ((error=test(flush_master_info(mi, TRUE, TRUE))))
sql_print_error("Failed to flush master info file");
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(error);
@ -413,7 +413,9 @@ err:
1 - flush master info failed
0 - all ok
*/
int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
int flush_master_info(Master_info* mi,
bool flush_relay_log_cache,
bool need_lock_relay_log)
{
IO_CACHE* file = &mi->file;
char lbuf[22];
@ -436,8 +438,19 @@ int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
*/
if (flush_relay_log_cache)
{
pthread_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
IO_CACHE *log_file= mi->rli.relay_log.get_log_file();
if (flush_io_cache(log_file))
if (need_lock_relay_log)
pthread_mutex_lock(log_lock);
safe_mutex_assert_owner(log_lock);
err= flush_io_cache(log_file);
if (need_lock_relay_log)
pthread_mutex_unlock(log_lock);
if (err)
DBUG_RETURN(2);
}

View file

@ -120,7 +120,9 @@ int init_master_info(Master_info* mi, const char* master_info_fname,
bool abort_if_no_master_info_file,
int thread_mask);
void end_master_info(Master_info* mi);
int flush_master_info(Master_info* mi, bool flush_relay_log_cache);
int flush_master_info(Master_info* mi,
bool flush_relay_log_cache,
bool need_lock_relay_log);
int change_master_server_id_cmp(ulong *id1, ulong *id2);
#endif /* HAVE_REPLICATION */

View file

@ -121,7 +121,7 @@ int init_relay_log_info(Relay_log_info* rli,
/*
The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
Note that the I/O thread flushes it to disk after writing every
event, in flush_master_info(mi, 1).
event, in flush_master_info(mi, 1, ?).
*/
/*

View file

@ -6260,3 +6260,5 @@ ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
eng "Field '%-.192s' is of a not allowed type for this type of partitioning"
ER_PARTITION_FIELDS_TOO_LONG
eng "The total length of the partitioning fields is too large"
ER_SPATIAL_MUST_HAVE_GEOM_COL 42000
eng "A SPATIAL index may only contain a geometrical type column"

View file

@ -1726,7 +1726,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
" to the relay log, SHOW SLAVE STATUS may be"
" inaccurate");
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
if (flush_master_info(mi, 1))
if (flush_master_info(mi, TRUE, FALSE))
sql_print_error("Failed to flush master info file");
delete ev;
}
@ -3047,7 +3047,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
goto err;
}
if (flush_master_info(mi, 1))
if (flush_master_info(mi, TRUE, TRUE))
{
sql_print_error("Failed to flush master info file");
goto err;

View file

@ -47,6 +47,7 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{ C_STRING_WITH_LEN("FTPARSER") },
{ C_STRING_WITH_LEN("DAEMON") },
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") },
{ C_STRING_WITH_LEN("AUDIT") },
{ C_STRING_WITH_LEN("REPLICATION") },
};
@ -87,6 +88,7 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
0x0000, /* place holder for audit plugin */
MYSQL_REPLICATION_INTERFACE_VERSION,
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
@ -96,6 +98,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
0x0000, /* place holder for audit plugin */
MYSQL_REPLICATION_INTERFACE_VERSION,
};
@ -745,6 +748,14 @@ static bool plugin_add(MEM_ROOT *tmp_root,
name_len))
{
struct st_plugin_int *tmp_plugin_ptr;
if (plugin->type == MYSQL_AUDIT_PLUGIN)
{
/* Bug#49894 */
sql_print_error("Plugin type 'AUDIT' not supported by this server.");
goto err;
}
if (*(int*)plugin->info <
min_plugin_info_interface_version[plugin->type] ||
((*(int*)plugin->info) >> 8) >

View file

@ -1535,7 +1535,7 @@ bool change_master(THD* thd, Master_info* mi)
Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
a slave before).
*/
if (flush_master_info(mi, 0))
if (flush_master_info(mi, FALSE, FALSE))
{
my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
ret= TRUE;

View file

@ -12301,6 +12301,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
int error;
if (join->tables &&
join->join_tab->is_using_loose_index_scan())
{
/* Copy non-aggregated fields when loose index scan is used. */
copy_fields(&join->tmp_table_param);
}
if (join->having && join->having->val_int() == 0)
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
error=0;

View file

@ -292,7 +292,8 @@ uint explain_filename(THD* thd,
{
if (explain_mode == EXPLAIN_ALL_VERBOSE)
{
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_DATABASE_NAME),
end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ", ", end_p - to_p);
@ -305,7 +306,7 @@ uint explain_filename(THD* thd,
}
if (explain_mode == EXPLAIN_ALL_VERBOSE)
{
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TABLE_NAME), end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
}
@ -322,18 +323,22 @@ uint explain_filename(THD* thd,
if (name_type != NORMAL)
{
if (name_type == TEMP)
to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME),
end_p - to_p);
else
to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_RENAMED_NAME),
end_p - to_p);
to_p= strnmov(to_p, " ", end_p - to_p);
}
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_PARTITION_NAME),
end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
if (subpart_name)
{
to_p= strnmov(to_p, ", ", end_p - to_p);
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_SUBPARTITION_NAME),
end_p - to_p);
*(to_p++)= ' ';
to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
}
@ -3187,11 +3192,19 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
column->length*= sql_field->charset->mbmaxlen;
if (key->type == Key::SPATIAL && column->length)
if (key->type == Key::SPATIAL)
{
my_error(ER_WRONG_SUB_KEY, MYF(0));
DBUG_RETURN(TRUE);
}
if (column->length)
{
my_error(ER_WRONG_SUB_KEY, MYF(0));
DBUG_RETURN(TRUE);
}
if (!f_is_geom(sql_field->pack_flag))
{
my_error(ER_SPATIAL_MUST_HAVE_GEOM_COL, MYF(0));
DBUG_RETURN(TRUE);
}
}
if (f_is_blob(sql_field->pack_flag) ||
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
@ -3286,22 +3299,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
}
// Catch invalid use of partial keys
else if (!f_is_geom(sql_field->pack_flag) &&
((column->length > length &&
!Field::type_can_have_key_part (sql_field->sql_type)) ||
((f_is_packed(sql_field->pack_flag) ||
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
(key_info->flags & HA_NOSAME))) &&
column->length != length)))
{
/* Catch invalid uses of partial keys.
A key is identified as 'partial' if column->length != length.
A partial key is invalid if they data type does
not allow it, or the field is packed (as in MyISAM),
or the storage engine doesn't allow prefixed search and
the key is primary key.
*/
// is the key partial?
column->length != length &&
// is prefix length bigger than field length?
(column->length > length ||
// can the field have a partial key?
!Field::type_can_have_key_part (sql_field->sql_type) ||
// a packed field can't be used in a partial key
f_is_packed(sql_field->pack_flag) ||
// does the storage engine allow prefixed search?
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
// and is this a 'unique' key?
(key_info->flags & HA_NOSAME))))
{
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
DBUG_RETURN(TRUE);
}

View file

@ -46,6 +46,9 @@
#define ER(X) CURRENT_THD_ERRMSGS[(X) - ER_ERROR_FIRST]
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[(X) - ER_ERROR_FIRST]
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
#define ER_THD(thd,X) ((thd)->variables.lc_messages->errmsgs->errmsgs[(X) - \
ER_ERROR_FIRST])
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
#define ERRMAPP 1 /* Errormap f|r my_error */

View file

@ -87,12 +87,10 @@
%{?_without_bundled_zlib:%define WITH_BUNDLED_ZLIB 0}
# ----------------------------------------------------------------------
# use "rpmbuild --without innodb_plugin" or "rpm --define '_without_innodb_plugin 1'"
# (for RPM 3.x) to not build the innodb plugin (on by default with innodb builds)
# support optional "tcmalloc" stuff (experimental)
# ----------------------------------------------------------------------
%{!?_with_innodb_plugin: %{!?_without_innodb_plugin: %define WITH_INNODB_PLUGIN 1}}
%{?_with_innodb_plugin:%define WITH_INNODB_PLUGIN 1}
%{?_without_innodb_plugin:%define WITH_INNODB_PLUGIN 0}
%{?malloc_lib_target:%define WITH_TCMALLOC 1}
%{!?malloc_lib_target:%define WITH_TCMALLOC 0}
# ----------------------------------------------------------------------
# use "rpmbuild --with cluster" or "rpm --define '_with_cluster 1'" (for RPM 3.x)
@ -419,13 +417,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
%endif
%if %{INNODB_BUILD}
--with-plugin-innobase \
%if %{WITH_INNODB_PLUGIN}
%else
--without-plugin-innodb_plugin \
%endif
%else
--without-plugin-innobase \
--without-plugin-innodb_plugin \
%endif
%if %{PARTITION_BUILD}
--with-plugin-partition \
@ -579,13 +572,6 @@ $MBD/libtool --mode=execute install -m 755 \
$RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/mysqld \
$RBR%{_sbindir}/mysqld-debug
%if %{WITH_TCMALLOC}
# Even though this is a shared library, put it under /usr/lib/mysql, so it
# doesn't conflict with possible shared lib by the same name in /usr/lib. See
# `mysql_config --variable=pkglibdir` and mysqld_safe for how this is used.
install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
%endif
# install saved perror binary with NDB support (BUG#13740)
install -m 755 $MBD/extra/perror $RBR%{_bindir}/perror
@ -605,10 +591,17 @@ rm -fr $RBR%{_datadir}/sql-bench
# will appreciate that, as all services usually offer this.
ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql
# Touch the place where the my.cnf config file might be located.
# Just to make sure it's in the file list and marked as a config file.
# Touch the place where the my.cnf config file might be located
# Just to make sure it's in the file list and marked as a config file
touch $RBR%{_sysconfdir}/my.cnf
%if %{WITH_TCMALLOC}
# Even though this is a shared library, put it under /usr/lib/mysql, so it
# doesn't conflict with possible shared lib by the same name in /usr/lib. See
# `mysql_config --variable=pkglibdir` and mysqld_safe for how this is used.
install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
%endif
##############################################################################
# Post processing actions, i.e. when installed
##############################################################################
@ -875,12 +868,13 @@ fi
%attr(755, root, root) %{_sbindir}/mysqld
%attr(755, root, root) %{_sbindir}/mysqld-debug
%attr(755, root, root) %{_sbindir}/rcmysql
%if %{INNODB_BUILD}
%if %{WITH_INNODB_PLUGIN}
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_innodb_plugin.so*
%endif
%endif
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so*
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so*
%if %{WITH_TCMALLOC}
%attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target}
%endif
%attr(644, root, root) %config(noreplace,missingok) %{_sysconfdir}/logrotate.d/mysql
%attr(755, root, root) %{_sysconfdir}/init.d/mysql
@ -905,6 +899,7 @@ fi
%doc %attr(644, root, man) %{_mandir}/man1/msql2mysql.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_find_rows.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_waitpid.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqladmin.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlbinlog.1*
@ -976,6 +971,7 @@ fi
%files devel
%defattr(-, root, root, 0755)
%doc mysql-release-%{mysql_version}/EXCEPTIONS-CLIENT
%doc %attr(644, root, man) %{_mandir}/man1/comp_err.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1*
%attr(755, root, root) %{_bindir}/mysql_config
%dir %attr(755, root, root) %{_includedir}/mysql
@ -1044,7 +1040,7 @@ fi
# merging BK trees)
##############################################################################
%changelog
* Fri Feb 05 2010 Joerg Bruehe <joerg.bruehe@sun.com>
* Fri Feb 12 2010 Joerg Bruehe <joerg.bruehe@sun.com>
- Formatting changes:
Have a consistent structure of separator lines and of indentation
@ -1056,8 +1052,6 @@ fi
in 5.1 since ages.
- Introduce variables to control the handlers individually, as well
as other options.
- Handle the InnoDB plugin using a positive logic: "WITH_INNODB_PLUGIN",
the old negative logic ("WITHOUT_INNODB_PLUGIN") was obfuscating.
- Use the new "--with-plugin" notation for the table handlers.
- Drop handling "/etc/rc.d/init.d/mysql", the switch to "/etc/init.d/mysql"
was done back in 2002 already.