Commit 262c1568 authored by Georgi Kodinov's avatar Georgi Kodinov

merge mysql-5.1->mysql-5.1-security

parents 2e72df37 8a1a4cbd
......@@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software
is released under the version 2 of the GNU General Public License.
MySQL is brought to you by Oracle.
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
License information can be found in the COPYING file.
......
......@@ -2331,10 +2331,10 @@ static uint dump_routines_for_db(char *db)
{
if (opt_xml)
{
if (i) // Procedures.
if (i) /* Procedures. */
print_xml_row(sql_file, "routine", routine_res, &row,
"Create Procedure");
else // Functions.
else /* Functions. */
print_xml_row(sql_file, "routine", routine_res, &row,
"Create Function");
continue;
......
......@@ -21,8 +21,7 @@ See normal build instructions below under 1.0.6.
See libcurl build instructions below under 1.3.0 and note in 1.5.8.
*****************yaSSL Release notes, version 1.9.9 (1/26/2010)
yaSSL Release notes, version 2.0.0 (7/6/2010)
*****************yaSSL Release notes, version 2.0.0 (7/6/2010)
This release of yaSSL contains bug fixes, new testing certs,
and a security patch for a potential heap overflow on forged application
......
/*
Copyright (c) 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
......@@ -35,7 +35,7 @@
#include "rsa.h"
#define YASSL_VERSION "2.1.4"
#define YASSL_VERSION "2.2.0"
#if defined(__cplusplus)
......
/*
Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -1087,19 +1087,37 @@ void Certificate::Process(input_buffer& input, SSL& ssl)
uint32 list_sz;
byte tmp[3];
if (input.get_remaining() < sizeof(tmp)) {
ssl.SetError(YasslError(bad_input));
return;
}
tmp[0] = input[AUTO];
tmp[1] = input[AUTO];
tmp[2] = input[AUTO];
c24to32(tmp, list_sz);
if (list_sz > (uint)MAX_RECORD_SIZE) { // sanity check
ssl.SetError(YasslError(bad_input));
return;
}
while (list_sz) {
// cert size
uint32 cert_sz;
if (input.get_remaining() < sizeof(tmp)) {
ssl.SetError(YasslError(bad_input));
return;
}
tmp[0] = input[AUTO];
tmp[1] = input[AUTO];
tmp[2] = input[AUTO];
c24to32(tmp, cert_sz);
if (cert_sz > (uint)MAX_RECORD_SIZE || input.get_remaining() < cert_sz){
ssl.SetError(YasslError(bad_input));
return;
}
x509* myCert;
cm.AddPeerCert(myCert = NEW_YS x509(cert_sz));
input.read(myCert->use_buffer(), myCert->get_length());
......
/*
Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -308,8 +308,9 @@ SSL::SSL(SSL_CTX* ctx)
SetError(YasslError(err));
return;
}
else if (serverSide && !(ctx->GetCiphers().setSuites_)) {
else if (serverSide && ctx->GetCiphers().setSuites_ == 0) {
// remove RSA or DSA suites depending on cert key type
// but don't override user sets
ProtocolVersion pv = secure_.get_connection().version_;
bool removeDH = secure_.use_parms().removeDH_;
......
/*
Copyright (C) 2000-2007 MySQL AB
Copyright (C) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -39,25 +39,32 @@ public:
explicit Source(word32 sz = 0) : buffer_(sz), current_(0) {}
Source(const byte* b, word32 sz) : buffer_(b, sz), current_(0) {}
word32 remaining() { if (GetError().What()) return 0;
else return buffer_.size() - current_; }
word32 size() const { return buffer_.size(); }
void grow(word32 sz) { buffer_.CleanGrow(sz); }
bool IsLeft(word32 sz) { if (remaining() >= sz) return true;
else { SetError(CONTENT_E); return false; } }
const byte* get_buffer() const { return buffer_.get_buffer(); }
const byte* get_current() const { return &buffer_[current_]; }
word32 get_index() const { return current_; }
void set_index(word32 i) { current_ = i; }
void set_index(word32 i) { if (i < size()) current_ = i; }
byte operator[] (word32 i) { current_ = i; return next(); }
byte next() { return buffer_[current_++]; }
byte prev() { return buffer_[--current_]; }
byte next() { if (IsLeft(1)) return buffer_[current_++]; else return 0; }
byte prev() { if (current_) return buffer_[--current_]; else return 0; }
void add(const byte* data, word32 len)
{
memcpy(buffer_.get_buffer() + current_, data, len);
current_ += len;
if (IsLeft(len)) {
memcpy(buffer_.get_buffer() + current_, data, len);
current_ += len;
}
}
void advance(word32 i) { current_ += i; }
void advance(word32 i) { if (IsLeft(i)) current_ += i; }
void reset(ByteBlock&);
Error GetError() { return error_; }
......
/*
Copyright (c) 2005-2007 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
Use is subject to license terms.
This program is free software; you can redistribute it and/or modify
......@@ -144,6 +144,8 @@ word32 GetLength(Source& source)
if (b >= LONG_LENGTH) {
word32 bytes = b & 0x7F;
if (source.IsLeft(bytes) == false) return 0;
while (bytes--) {
b = source.next();
length = (length << 8) | b;
......@@ -578,8 +580,10 @@ void CertDecoder::StoreKey()
read = source_.get_index() - read;
length += read;
if (source_.GetError().What()) return;
while (read--) source_.prev();
if (source_.IsLeft(length) == false) return;
key_.SetSize(length);
key_.SetKey(source_.get_current());
source_.advance(length);
......@@ -611,6 +615,8 @@ void CertDecoder::AddDSA()
word32 length = GetLength(source_);
length += source_.get_index() - idx;
if (source_.IsLeft(length) == false) return;
key_.AddToEnd(source_.get_buffer() + idx, length);
}
......@@ -620,6 +626,8 @@ word32 CertDecoder::GetAlgoId()
{
if (source_.GetError().What()) return 0;
word32 length = GetSequence();
if (source_.GetError().What()) return 0;
byte b = source_.next();
if (b != OBJECT_IDENTIFIER) {
......@@ -628,8 +636,9 @@ word32 CertDecoder::GetAlgoId()
}
length = GetLength(source_);
if (source_.IsLeft(length) == false) return 0;
word32 oid = 0;
while(length--)
oid += source_.next(); // just sum it up for now
......@@ -662,6 +671,10 @@ word32 CertDecoder::GetSignature()
}
sigLength_ = GetLength(source_);
if (sigLength_ == 0 || source_.IsLeft(sigLength_) == false) {
source_.SetError(CONTENT_E);
return 0;
}
b = source_.next();
if (b != 0) {
......@@ -728,6 +741,7 @@ void CertDecoder::GetName(NameType nt)
if (length >= ASN_NAME_MAX)
return;
if (source_.IsLeft(length) == false) return;
length += source_.get_index();
char* ptr;
......@@ -753,7 +767,10 @@ void CertDecoder::GetName(NameType nt)
}
word32 oidSz = GetLength(source_);
if (source_.IsLeft(oidSz) == false) return;
byte joint[2];
if (source_.IsLeft(sizeof(joint)) == false) return;
memcpy(joint, source_.get_current(), sizeof(joint));
// v1 name types
......@@ -763,6 +780,8 @@ void CertDecoder::GetName(NameType nt)
b = source_.next(); // strType
word32 strLen = GetLength(source_);
if (source_.IsLeft(strLen) == false) return;
switch (id) {
case COMMON_NAME:
if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen)))
......@@ -804,6 +823,7 @@ void CertDecoder::GetName(NameType nt)
source_.advance(oidSz + 1);
word32 length = GetLength(source_);
if (source_.IsLeft(length) == false) return;
if (email) {
if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) {
......@@ -837,6 +857,8 @@ void CertDecoder::GetDate(DateType dt)
}
word32 length = GetLength(source_);
if (source_.IsLeft(length) == false) return;
byte date[MAX_DATE_SZ];
if (length > MAX_DATE_SZ || length < MIN_DATE_SZ) {
source_.SetError(DATE_SZ_E);
......
/*
Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -2587,11 +2587,14 @@ void Integer::Decode(Source& source)
}
word32 length = GetLength(source);
if (length == 0 || source.GetError().What()) return;
if ( (b = source.next()) == 0x00)
length--;
else
source.prev();
if (source.IsLeft(length) == false) return;
unsigned int words = (length + WORD_SIZE - 1) / WORD_SIZE;
words = RoundupSize(words);
......
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
# Bug 11766634 59783: InnoDB data grows unexpectedly when inserting,
# truncating, inserting the same set of rows.
#
# Scenario:
# create table t1. Insert $recs records. check size of ibdata1.
# drop table t1. create table t1. Insert the same set of $recs
# records. The size of ibdata1 must not increase.
#
-- source include/not_embedded.inc
-- source include/have_innodb.inc
create table t1 (f1 char(255)) engine innodb;
let $MYSQLD_DATADIR=`select @@datadir`;
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
let $recs = 36262;
--disable_query_log
let $c = $recs;
start transaction;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
commit work;
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
--disable_query_log
let $c = $recs;
start transaction;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
commit work;
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
create table t1 (f1 char(255)) engine innodb;
ibdata1 size: 27262976 bytes
drop table t1;
# Bug 11766634 59783: InnoDB data grows unexpectedly when inserting,
# truncating, inserting the same set of rows.
#
# Scenario:
# create table t1. Insert $recs records. check size of ibdata1.
# drop table t1. create table t1. Insert the same set of $recs
# records. The size of ibdata1 must not increase.
#
-- source include/not_embedded.inc
-- source include/have_innodb_plugin.inc
create table t1 (f1 char(255)) engine innodb;
let $MYSQLD_DATADIR=`select @@datadir`;
let IBDATA1=$MYSQLD_DATADIR/ibdata1;
let $recs = 36262;
--disable_query_log
let $c = $recs;
start transaction;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
commit work;
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
create table t1 (f1 char(255)) engine innodb;
--disable_query_log
let $c = $recs;
start transaction;
while ($c)
{
insert into t1 values ('Hello World');
dec $c;
}
commit work;
--enable_query_log
perl;
my $filesize = -s $ENV{'IBDATA1'};
print "ibdata1 size: $filesize bytes\n";
EOF
drop table t1;
include/master-slave.inc
[connection master]
include/assert.inc [Assert that relay log space is close to the limit]
include/diff_tables.inc [master:test.t1,slave:test.t1]
include/rpl_end.inc
--relay-log-space-limit=8192 --relay-log-purge --max-relay-log-size=4096
This diff is collapsed.
......@@ -3194,8 +3194,6 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
pthread_mutex_lock(&rli->log_space_lock);
rli->relay_log.purge_logs(to_purge_if_included, included,
0, 0, &rli->log_space_total);
// Tell the I/O thread to take the relay_log_space_limit into account
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
/*
......
......@@ -189,6 +189,13 @@ public:
ulonglong log_space_limit,log_space_total;
bool ignore_log_space_limit;
/*
Used by the SQL thread to instructs the IO thread to rotate
the logs when the SQL thread needs to purge to release some
disk space.
*/
bool sql_force_rotate_relay;
/*
When it commits, InnoDB internally stores the master log position it has
processed so far; the position to store is the one of the end of the
......
......@@ -1450,6 +1450,54 @@ Waiting for the slave SQL thread to free enough relay log space");
!(slave_killed=io_slave_killed(thd,mi)) &&
!rli->ignore_log_space_limit)
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
/*
Makes the IO thread read only one event at a time
until the SQL thread is able to purge the relay
logs, freeing some space.
Therefore, once the SQL thread processes this next
event, it goes to sleep (no more events in the queue),
sets ignore_log_space_limit=true and wakes the IO thread.
However, this event may have been enough already for
the SQL thread to purge some log files, freeing
rli->log_space_total .
This guarantees that the SQL and IO thread move
forward only one event at a time (to avoid deadlocks),
when the relay space limit is reached. It also
guarantees that when the SQL thread is prepared to
rotate (to be able to purge some logs), the IO thread
will know about it and will rotate.
NOTE: The ignore_log_space_limit is only set when the SQL
thread sleeps waiting for events.
*/
if (rli->ignore_log_space_limit)
{
#ifndef DBUG_OFF
{
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("log_space_limit=%s "
"log_space_total=%s "
"ignore_log_space_limit=%d "
"sql_force_rotate_relay=%d",
llstr(rli->log_space_limit,llbuf1),
llstr(rli->log_space_total,llbuf2),
(int) rli->ignore_log_space_limit,
(int) rli->sql_force_rotate_relay));
}
#endif
if (rli->sql_force_rotate_relay)
{
rotate_relay_log(rli->mi);
rli->sql_force_rotate_relay= false;
}
rli->ignore_log_space_limit= false;
}
thd->exit_cond(save_proc_info);
DBUG_RETURN(slave_killed);
}
......@@ -4260,19 +4308,45 @@ static Log_event* next_event(Relay_log_info* rli)
constraint, because we do not want the I/O thread to block because of
space (it's ok if it blocks for any other reason (e.g. because the
master does not send anything). Then the I/O thread stops waiting
and reads more events.
The SQL thread decides when the I/O thread should take log_space_limit
into account again : ignore_log_space_limit is reset to 0
in purge_first_log (when the SQL thread purges the just-read relay
log), and also when the SQL thread starts. We should also reset
ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
fact, no need as RESET SLAVE requires that the slave
and reads one more event and starts honoring log_space_limit again.
If the SQL thread needs more events to be able to rotate the log (it
might need to finish the current group first), then it can ask for one
more at a time. Thus we don't outgrow the relay log indefinitely,
but rather in a controlled manner, until the next rotate.
When the SQL thread starts it sets ignore_log_space_limit to false.
We should also reset ignore_log_space_limit to 0 when the user does
RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave
be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
it stops.
*/
pthread_mutex_lock(&rli->log_space_lock);
// prevent the I/O thread from blocking next times
rli->ignore_log_space_limit= 1;
/*
If we have reached the limit of the relay space and we
are going to sleep, waiting for more events:
1. If outside a group, SQL thread asks the IO thread
to force a rotation so that the SQL thread purges
logs next time it processes an event (thus space is
freed).
2. If in a group, SQL thread asks the IO thread to
ignore the limit and queues yet one more event
so that the SQL thread finishes the group and
is are able to rotate and purge sometime soon.
*/
if (rli->log_space_limit &&
rli->log_space_limit < rli->log_space_total)
{
/* force rotation if not in an unfinished group */
rli->sql_force_rotate_relay= !rli->is_in_group();
/* ask for one more event */
rli->ignore_log_space_limit= true;
}
/*
If the I/O thread is blocked, unblock it. Ok to broadcast
after unlock, because the mutex is only destroyed in
......
......@@ -301,10 +301,9 @@ btr_pcur_restore_position(
case BTR_PCUR_BEFORE:
mode = PAGE_CUR_L;
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
mode = 0; /* silence a warning */
}
btr_pcur_open_with_no_init(index, tuple, mode, latch_mode,
......
......@@ -245,13 +245,13 @@ fseg_n_reserved_pages_low(
/************************************************************************
Marks a page used. The page must reside within the extents of the given
segment. */
static
static __attribute__((nonnull))
void
fseg_mark_page_used(
/*================*/
fseg_inode_t* seg_inode,/* in: segment inode */
ulint space, /* in: space id */
ulint page, /* in: page offset */
xdes_t* descr, /* in: extent descriptor */
mtr_t* mtr); /* in: mtr */
/**************************************************************************
Returns the first extent descriptor for a segment. We think of the extent
......@@ -635,10 +635,8 @@ xdes_calc_descriptor_index(
/************************************************************************
Gets pointer to a the extent descriptor of a page. The page where the extent
descriptor resides is x-locked. If the page offset is equal to the free limit
of the space, adds new extents from above the free limit to the space free
list, if not free limit == space size. This adding is necessary to make the
descriptor defined, as they are uninitialized above the free limit. */
descriptor resides is x-locked. This function no longer extends the data
file. */
UNIV_INLINE
xdes_t*
xdes_get_descriptor_with_space_hdr(
......@@ -666,19 +664,10 @@ xdes_get_descriptor_with_space_hdr(
limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);
size = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr);
/* If offset is >= size or > limit, return NULL */
if ((offset >= size) || (offset > limit)) {
if ((offset >= size) || (offset >= limit)) {
return(NULL);
}
/* If offset is == limit, fill free list of the space. */
if (offset == limit) {
fsp_fill_free_list(FALSE, space, sp_header, mtr);
}
descr_page_no = xdes_calc_descriptor_page(offset);
if (descr_page_no == 0) {
......@@ -2552,7 +2541,7 @@ fseg_alloc_free_page_low(
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
fseg_mark_page_used(seg_inode, space, ret_page, mtr);
fseg_mark_page_used(seg_inode, ret_page, ret_descr, mtr);
}
return(ret_page);
......@@ -2946,22 +2935,17 @@ fsp_get_available_space_in_free_extents(
/************************************************************************
Marks a page used. The page must reside within the extents of the given
segment. */
static
static __attribute__((nonnull))
void
fseg_mark_page_used(
/*================*/
fseg_inode_t* seg_inode,/* in: segment inode */
ulint space, /* in: space id */
ulint page, /* in: page offset */
xdes_t* descr, /* in: extent descriptor */
mtr_t* mtr) /* in: mtr */
{
xdes_t* descr;
ulint not_full_n_used;
ut_ad(seg_inode && mtr);
descr = xdes_get_descriptor(space, page, mtr);
ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr)
== mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr));
......
2012-03-15 The InnoDB Team
* fil/fil0fil.c, ibuf/ibuf0ibuf.c, include/fil0fil.h,
lock/lock0lock.c:
Fix Bug#13825266 RACE IN LOCK_VALIDATE() WHEN ACCESSING PAGES
DIRECTLY FROM BUFFER POOL
2012-03-15 The InnoDB Team
* handler/ha_innodb.cc:
Fix Bug#13851171STRING OVERFLOW IN INNODB CODE FOUND BY STATIC
ANALYSIS
2012-03-15 The InnoDB Team
* include/sync0rw.ic:
Fix Bug#13537504 VALGRIND: COND. JUMP/MOVE DEPENDS ON
UNINITIALISED VALUES IN OS_THREAD_EQ
2012-03-08 The InnoDB Team
* btr/btr0pcur.c:
......
......@@ -325,10 +325,9 @@ btr_pcur_restore_position_func(
case BTR_PCUR_BEFORE:
mode = PAGE_CUR_L;
break;
#ifdef UNIV_DEBUG
default:
ut_error;
#endif /* UNIV_DEBUG */
mode = 0;
}
btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode,
......
......@@ -175,7 +175,7 @@ struct fil_space_struct {
.ibd file of tablespace and want to
stop temporarily posting of new i/o
requests on the file */
ibool stop_ibuf_merges;
ibool stop_new_ops;
/*!< we set this TRUE when we start
deleting a single-table tablespace */
ibool is_being_deleted;
......@@ -200,12 +200,13 @@ struct fil_space_struct {
ulint n_pending_flushes; /*!< this is positive when flushing
the tablespace to disk; dropping of the
tablespace is forbidden if this is positive */
ulint n_pending_ibuf_merges;/*!< this is positive
when merging insert buffer entries to
a page so that we may need to access
the ibuf bitmap page in the
tablespade: dropping of the tablespace
is forbidden if this is positive */
ulint n_pending_ops;/*!< this is positive when we
have pending operations against this
tablespace. The pending operations can
be ibuf merges or lock validation code
trying to read a block.
Dropping of the tablespace is forbidden
if this is positive */
hash_node_t hash; /*!< hash chain node */
hash_node_t name_hash;/*!< hash chain the name_hash table */
#ifndef UNIV_HOTBACKUP
......@@ -1236,7 +1237,7 @@ try_again:
}
space->stop_ios = FALSE;
space->stop_ibuf_merges = FALSE;
space->stop_new_ops = FALSE;
space->is_being_deleted = FALSE;
space->purpose = purpose;
space->size = 0;
......@@ -1245,7 +1246,7 @@ try_again:
space->n_reserved_extents = 0;
space->n_pending_flushes = 0;
space->n_pending_ibuf_merges = 0;
space->n_pending_ops = 0;
UT_LIST_INIT(space->chain);
space->magic_n = FIL_SPACE_MAGIC_N;
......@@ -1836,13 +1837,12 @@ fil_read_flushed_lsn_and_arch_log_no(
#ifndef UNIV_HOTBACKUP
/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
being deleted.
@return TRUE if being deleted, and ibuf merges should be skipped */
Increments the count of pending operation, if space is not being deleted.
@return TRUE if being deleted, and operation should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
fil_inc_pending_ops(
/*================*/
ulint id) /*!< in: space id */
{
fil_space_t* space;
......@@ -1858,13 +1858,13 @@ fil_inc_pending_ibuf_merges(
(ulong) id);
}
if (space == NULL || space->stop_ibuf_merges) {
if (space == NULL || space->stop_new_ops) {
mutex_exit(&fil_system->mutex);
return(TRUE);
}
space->n_pending_ibuf_merges++;
space->n_pending_ops++;
mutex_exit(&fil_system->mutex);
......@@ -1872,11 +1872,11 @@ fil_inc_pending_ibuf_merges(
}
/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
Decrements the count of pending operations. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
fil_decr_pending_ops(
/*=================*/
ulint id) /*!< in: space id */
{
fil_space_t* space;
......@@ -1887,13 +1887,13 @@ fil_decr_pending_ibuf_merges(
if (space == NULL) {
fprintf(stderr,
"InnoDB: Error: decrementing ibuf merge of a"
" dropped tablespace %lu\n",
"InnoDB: Error: decrementing pending operation"
" of a dropped tablespace %lu\n",
(ulong) id);
}
if (space != NULL) {
space->n_pending_ibuf_merges--;
space->n_pending_ops--;
}
mutex_exit(&fil_system->mutex);
......@@ -2183,15 +2183,15 @@ fil_delete_tablespace(
char* path;
ut_a(id != 0);
stop_ibuf_merges:
stop_new_ops:
mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
if (space != NULL) {
space->stop_ibuf_merges = TRUE;
space->stop_new_ops = TRUE;
if (space->n_pending_ibuf_merges == 0) {
if (space->n_pending_ops == 0) {
mutex_exit(&fil_system->mutex);
count = 0;
......@@ -2205,9 +2205,10 @@ stop_ibuf_merges:
ut_print_filename(stderr, space->name);
fprintf(stderr, ",\n"
"InnoDB: but there are %lu pending"
" ibuf merges on it.\n"
" operations (most likely ibuf merges)"
" on it.\n"
"InnoDB: Loop %lu.\n",
(ulong) space->n_pending_ibuf_merges,
(ulong) space->n_pending_ops,
(ulong) count);
}
......@@ -2216,7 +2217,7 @@ stop_ibuf_merges:
os_thread_sleep(20000);
count++;
goto stop_ibuf_merges;
goto stop_new_ops;
}
}
......@@ -2242,7 +2243,7 @@ try_again:
}
ut_a(space);
ut_a(space->n_pending_ibuf_merges == 0);
ut_a(space->n_pending_ops == 0);
space->is_being_deleted = TRUE;
......
......@@ -273,15 +273,13 @@ fseg_n_reserved_pages_low(
/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
static __attribute__((nonnull))
void
fseg_mark_page_used(
/*================*/
fseg_inode_t* seg_inode,/*!< in: segment inode */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint page, /*!< in: page offset */
xdes_t* descr, /* extent descriptor */
mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
......@@ -705,12 +703,10 @@ xdes_calc_descriptor_index(
/********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the extent
descriptor resides is x-locked. If the page offset is equal to the free limit
of the space, adds new extents from above the free limit to the space free
list, if not free limit == space size. This adding is necessary to make the
descriptor defined, as they are uninitialized above the free limit.
descriptor resides is x-locked. This function no longer extends the data
file.
@return pointer to the extent descriptor, NULL if the page does not
exist in the space or if the offset exceeds the free limit */
exist in the space or if the offset is >= the free limit */
UNIV_INLINE __attribute__((nonnull, warn_unused_result))
xdes_t*
xdes_get_descriptor_with_space_hdr(
......@@ -740,19 +736,10 @@ xdes_get_descriptor_with_space_hdr(
zip_size = dict_table_flags_to_zip_size(
mach_read_from_4(sp_header + FSP_SPACE_FLAGS));
/* If offset is >= size or > limit, return NULL */
if ((offset >= size) || (offset > limit)) {
if ((offset >= size) || (offset >= limit)) {
return(NULL);
}
/* If offset is == limit, fill free list of the space. */
if (offset == limit) {
fsp_fill_free_list(FALSE, space, sp_header, mtr);
}
descr_page_no = xdes_calc_descriptor_page(zip_size, offset);
if (descr_page_no == 0) {
......@@ -2877,7 +2864,7 @@ got_hinted_page:
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT,
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE);
fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr);
fseg_mark_page_used(seg_inode, ret_page, ret_descr, mtr);
}
return(fsp_page_create(
......@@ -3283,27 +3270,21 @@ fsp_get_available_space_in_free_extents(
/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
static __attribute__((nonnull))
void
fseg_mark_page_used(
/*================*/
fseg_inode_t* seg_inode,/*!< in: segment inode */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint page, /*!< in: page offset */
xdes_t* descr, /* extent descriptor */
mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint not_full_n_used;
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
== FSEG_MAGIC_N_VALUE);
descr = xdes_get_descriptor(space, zip_size, page, mtr);
ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr)
== mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr));
......
......@@ -6721,6 +6721,8 @@ ha_innobase::create(
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
}
ut_a(strlen(name) < sizeof(name2));
strcpy(name2, name);
normalize_table_name(norm_name, name2);
......
......@@ -3281,7 +3281,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
tablespace_being_deleted = fil_inc_pending_ibuf_merges(space);
tablespace_being_deleted = fil_inc_pending_ops(space);
if (UNIV_UNLIKELY(tablespace_being_deleted)) {
/* Do not try to read the bitmap page from space;
......@@ -3305,7 +3305,7 @@ ibuf_merge_or_delete_for_page(
mtr_commit(&mtr);
if (!tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
return;
......@@ -3537,7 +3537,7 @@ reset_bit:
if (update_ibuf_bitmap && !tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
ibuf_exit();
......
......@@ -340,20 +340,19 @@ fil_read_flushed_lsn_and_arch_log_no(
ib_uint64_t* min_flushed_lsn, /*!< in/out: */
ib_uint64_t* max_flushed_lsn); /*!< in/out: */
/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
being deleted.
@return TRUE if being deleted, and ibuf merges should be skipped */
Increments the count of pending operation, if space is not being deleted.
@return TRUE if being deleted, and operation should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
fil_inc_pending_ops(
/*================*/
ulint id); /*!< in: space id */
/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
Decrements the count of pending operations. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
fil_decr_pending_ops(
/*=================*/
ulint id); /*!< in: space id */
#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
......
......@@ -564,8 +564,6 @@ rw_lock_x_unlock_func(
if (lock->lock_word == 0) {
/* Last caller in a possible recursive chain. */
lock->recursive = FALSE;
UNIV_MEM_INVALID(&lock->writer_thread,
sizeof lock->writer_thread);
}
#ifdef UNIV_SYNC_DEBUG
......@@ -606,8 +604,6 @@ rw_lock_x_unlock_direct(
if (lock->lock_word == 0) {
lock->recursive = FALSE;
UNIV_MEM_INVALID(&lock->writer_thread,
sizeof lock->writer_thread);
}
#ifdef UNIV_SYNC_DEBUG
......
......@@ -5040,9 +5040,17 @@ lock_validate(void)
lock_mutex_exit_kernel();
lock_rec_validate_page(space,
fil_space_get_zip_size(space),
page_no);
/* Make sure that the tablespace is not
deleted while we are trying to access
the page. */
if (!fil_inc_pending_ops(space)) {
lock_rec_validate_page(
space,
fil_space_get_zip_size(space),
page_no);
fil_decr_pending_ops(space);
}
lock_mutex_enter_kernel();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment