1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

merge mysql-5.5->mysql-5.5-security

This commit is contained in:
Georgi Kodinov
2012-03-21 14:56:29 +02:00
29 changed files with 392 additions and 130 deletions

2
README
View File

@ -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.

View File

@ -2315,10 +2315,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;

View File

@ -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

View File

@ -1,5 +1,5 @@
/*
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)

View File

@ -1,5 +1,5 @@
/*
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());

View File

@ -1,5 +1,5 @@
/*
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_;

View File

@ -1,5 +1,5 @@
/*
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_; }

View File

@ -1,5 +1,5 @@
/*
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);
}
@ -621,6 +627,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) {
source_.SetError(OBJECT_ID_E);
@ -628,8 +636,9 @@ word32 CertDecoder::GetAlgoId()
}
length = GetLength(source_);
word32 oid = 0;
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);

View File

@ -1,5 +1,5 @@
/*
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,12 +2587,15 @@ 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);
if (words > reg_.size()) reg_.CleanNew(words);

View File

@ -4107,5 +4107,16 @@ DROP TABLE t1;
SET sql_mode=default;
SET NAMES latin1;
#
# Bug #13832953 MY_STRNXFRM_UNICODE: ASSERTION `SRC' FAILED
#
CREATE TABLE t1 (c1 SET('','') CHARACTER SET ucs2);
Warnings:
Note 1291 Column 'c1' has duplicated value '' in SET
INSERT INTO t1 VALUES ('');
SELECT COALESCE(c1) FROM t1 ORDER BY 1;
COALESCE(c1)
DROP TABLE t1;
#
# End of 5.5 tests
#

View File

@ -18,11 +18,13 @@ 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;
@ -35,11 +37,13 @@ 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;

View File

@ -759,6 +759,15 @@ SET collation_connection=ucs2_general_ci;
--source include/ctype_numconv.inc
SET NAMES latin1;
--echo #
--echo # Bug #13832953 MY_STRNXFRM_UNICODE: ASSERTION `SRC' FAILED
--echo #
CREATE TABLE t1 (c1 SET('','') CHARACTER SET ucs2);
INSERT INTO t1 VALUES ('');
SELECT COALESCE(c1) FROM t1 ORDER BY 1;
DROP TABLE t1;
--echo #
--echo # End of 5.5 tests
--echo #

View File

@ -2,7 +2,7 @@
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2010, 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
@ -30,7 +30,7 @@
<Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" Disabled="yes" />
<Control Id="Description" Type="Text" X="135" Y="80" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgTitle)" />
<Control Id="CopyrightText" Type="Text" X="135" Y="200" Width="220" Height="40" Transparent="yes" Text="Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved." />
<Control Id="CopyrightText" Type="Text" X="135" Y="200" Width="220" Height="40" Transparent="yes" Text="Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved." />
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeDlgBitmap)" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
</Dialog>

View File

@ -8257,8 +8257,7 @@ String *Field_set::val_str(String *val_buffer,
ulonglong tmp=(ulonglong) Field_enum::val_int();
uint bitnr=0;
val_buffer->length(0);
val_buffer->set_charset(field_charset);
val_buffer->set("", 0, field_charset);
while (tmp && bitnr < (uint) typelib->count)
{
if (tmp & 1)

View File

@ -2461,7 +2461,7 @@ wait_until_unfixed:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
rw_lock_x_lock_func(&block->lock, 0, file, line);
rw_lock_x_lock_inline(&block->lock, 0, file, line);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
@ -2601,14 +2601,14 @@ wait_until_unfixed:
break;
case RW_S_LATCH:
rw_lock_s_lock_func(&(block->lock), 0, file, line);
rw_lock_s_lock_inline(&(block->lock), 0, file, line);
fix_type = MTR_MEMO_PAGE_S_FIX;
break;
default:
ut_ad(rw_latch == RW_X_LATCH);
rw_lock_x_lock_func(&(block->lock), 0, file, line);
rw_lock_x_lock_inline(&(block->lock), 0, file, line);
fix_type = MTR_MEMO_PAGE_X_FIX;
break;
@ -2688,8 +2688,8 @@ buf_page_optimistic_get(
file, line);
fix_type = MTR_MEMO_PAGE_S_FIX;
} else {
success = rw_lock_x_lock_func_nowait(&(block->lock),
file, line);
success = rw_lock_x_lock_func_nowait_inline(&(block->lock),
file, line);
fix_type = MTR_MEMO_PAGE_X_FIX;
}
@ -2818,8 +2818,8 @@ buf_page_get_known_nowait(
file, line);
fix_type = MTR_MEMO_PAGE_S_FIX;
} else {
success = rw_lock_x_lock_func_nowait(&(block->lock),
file, line);
success = rw_lock_x_lock_func_nowait_inline(&(block->lock),
file, line);
fix_type = MTR_MEMO_PAGE_X_FIX;
}
@ -2906,8 +2906,8 @@ buf_page_try_get_func(
S-latch. */
fix_type = MTR_MEMO_PAGE_X_FIX;
success = rw_lock_x_lock_func_nowait(&block->lock,
file, line);
success = rw_lock_x_lock_func_nowait_inline(&block->lock,
file, line);
}
if (!success) {
@ -4750,34 +4750,32 @@ buf_all_freed(void)
/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
pool.
@return TRUE if there is no pending i/o */
@return number of pending i/o */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void)
/*==============================*/
ulint
buf_pool_check_num_pending_io(void)
/*===============================*/
{
ulint i;
ibool ret = TRUE;
ulint pending_io = 0;
buf_pool_mutex_enter_all();
for (i = 0; i < srv_buf_pool_instances && ret; i++) {
for (i = 0; i < srv_buf_pool_instances; i++) {
const buf_pool_t* buf_pool;
buf_pool = buf_pool_from_array(i);
if (buf_pool->n_pend_reads
+ buf_pool->n_flush[BUF_FLUSH_LRU]
+ buf_pool->n_flush[BUF_FLUSH_LIST]
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]) {
pending_io += buf_pool->n_pend_reads
+ buf_pool->n_flush[BUF_FLUSH_LRU]
+ buf_pool->n_flush[BUF_FLUSH_LIST]
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE];
ret = FALSE;
}
}
buf_pool_mutex_exit_all();
return(ret);
return(pending_io);
}
#if 0

View File

@ -185,7 +185,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;
@ -210,12 +210,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
@ -1282,7 +1283,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;
@ -1291,7 +1292,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;
@ -1891,13 +1892,12 @@ fil_read_first_page(
#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;
@ -1913,13 +1913,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);
@ -1927,11 +1927,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;
@ -1942,13 +1942,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);
@ -2238,15 +2238,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;
@ -2260,9 +2260,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);
}
@ -2271,7 +2272,7 @@ stop_ibuf_merges:
os_thread_sleep(20000);
count++;
goto stop_ibuf_merges;
goto stop_new_ops;
}
}
@ -2297,7 +2298,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;

View File

@ -7006,6 +7006,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);

View File

@ -4428,7 +4428,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;
@ -4454,7 +4454,7 @@ ibuf_merge_or_delete_for_page(
/* No inserts buffered for this page */
if (!tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
return;
@ -4753,7 +4753,7 @@ reset_bit:
if (update_ibuf_bitmap && !tablespace_being_deleted) {
fil_decr_pending_ibuf_merges(space);
fil_decr_pending_ops(space);
}
#ifdef UNIV_IBUF_COUNT_DEBUG

View File

@ -789,11 +789,11 @@ buf_all_freed(void);
/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
pool.
@return TRUE if there is no pending i/o */
@return number of pending i/o operations */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void);
/*==============================*/
ulint
buf_pool_check_num_pending_io(void);
/*===============================*/
/*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when

View File

@ -346,20 +346,19 @@ fil_read_first_page(
ib_uint64_t* max_flushed_lsn); /*!< out: max of flushed
lsn values in data files */
/*******************************************************************//**
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 */
/*******************************************************************//**

View File

@ -249,7 +249,7 @@ mtr_s_lock_func(
ut_ad(mtr);
ut_ad(lock);
rw_lock_s_lock_func(lock, 0, file, line);
rw_lock_s_lock_inline(lock, 0, file, line);
mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK);
}
@ -268,7 +268,7 @@ mtr_x_lock_func(
ut_ad(mtr);
ut_ad(lock);
rw_lock_x_lock_func(lock, 0, file, line);
rw_lock_x_lock_inline(lock, 0, file, line);
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}

View File

@ -678,12 +678,14 @@ srv_que_task_enqueue_low(
que_thr_t* thr); /*!< in: query thread */
/**********************************************************************//**
Check whether any background thread is active.
@return FALSE if all are are suspended or have exited. */
Check whether any background thread is active. If so, return the thread
type.
@return ULINT_UNDEFINED if all are are suspended or have exited, thread
type if any are still active. */
UNIV_INTERN
ibool
srv_is_any_background_thread_active(void);
/*======================================*/
ulint
srv_get_active_thread_type(void);
/*============================*/
/** Status variables to be passed to MySQL */
struct export_var_struct{

View File

@ -154,6 +154,9 @@ unlocking, not the corresponding function. */
# define rw_lock_s_lock(M) \
rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
# define rw_lock_s_lock_inline(M, P, F, L) \
rw_lock_s_lock_func((M), (P), (F), (L))
# define rw_lock_s_lock_gen(M, P) \
rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
@ -170,12 +173,18 @@ unlocking, not the corresponding function. */
# define rw_lock_x_lock(M) \
rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
# define rw_lock_x_lock_inline(M, P, F, L) \
rw_lock_x_lock_func((M), (P), (F), (L))
# define rw_lock_x_lock_gen(M, P) \
rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
# define rw_lock_x_lock_nowait(M) \
rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
# define rw_lock_x_lock_func_nowait_inline(M, F, L) \
rw_lock_x_lock_func_nowait((M), (F), (L))
# ifdef UNIV_SYNC_DEBUG
# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
# else
@ -207,6 +216,9 @@ unlocking, not the corresponding function. */
# define rw_lock_s_lock(M) \
pfs_rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
# define rw_lock_s_lock_inline(M, P, F, L) \
pfs_rw_lock_s_lock_func((M), (P), (F), (L))
# define rw_lock_s_lock_gen(M, P) \
pfs_rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
@ -222,12 +234,18 @@ unlocking, not the corresponding function. */
# define rw_lock_x_lock(M) \
pfs_rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
# define rw_lock_x_lock_inline(M, P, F, L) \
pfs_rw_lock_x_lock_func((M), (P), (F), (L))
# define rw_lock_x_lock_gen(M, P) \
pfs_rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
# define rw_lock_x_lock_nowait(M) \
pfs_rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
# define rw_lock_x_lock_func_nowait_inline(M, F, L) \
pfs_rw_lock_x_lock_func_nowait((M), (F), (L))
# ifdef UNIV_SYNC_DEBUG
# define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(P, L)
# else

View File

@ -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
@ -610,8 +608,6 @@ rw_lock_x_unlock_direct(
if (lock->lock_word == 0) {
lock->recursive = FALSE;
UNIV_MEM_INVALID(&lock->writer_thread,
sizeof lock->writer_thread);
}
lock->lock_word += X_LOCK_DECR;

View File

@ -5018,18 +5018,23 @@ lock_rec_block_validate(
mtr_t mtr;
buf_block_t* block;
mtr_start(&mtr);
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
if (!fil_inc_pending_ops(space)) {
mtr_start(&mtr);
block = buf_page_get_gen(
space, fil_space_get_zip_size(space),
page_no, RW_X_LATCH, NULL,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr);
block = buf_page_get_gen(
space, fil_space_get_zip_size(space),
page_no, RW_X_LATCH, NULL,
BUF_GET_POSSIBLY_FREED,
__FILE__, __LINE__, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
ut_ad(lock_rec_validate_page(block));
mtr_commit(&mtr);
ut_ad(lock_rec_validate_page(block));
mtr_commit(&mtr);
fil_decr_pending_ops(space);
}
}
/*********************************************************************//**

View File

@ -3076,9 +3076,12 @@ void
logs_empty_and_mark_files_at_shutdown(void)
/*=======================================*/
{
ib_uint64_t lsn;
ulint arch_log_no;
ibool server_busy;
ib_uint64_t lsn;
ulint arch_log_no;
ibool server_busy;
ulint count = 0;
ulint pending_io;
ulint active_thd;
if (srv_print_verbose_log) {
ut_print_timestamp(stderr);
@ -3091,6 +3094,8 @@ logs_empty_and_mark_files_at_shutdown(void)
loop:
os_thread_sleep(100000);
count++;
mutex_enter(&kernel_mutex);
/* We need the monitor threads to stop before we proceed with
@ -3099,6 +3104,21 @@ loop:
if (srv_error_monitor_active
|| srv_lock_timeout_active
|| srv_monitor_active) {
const char* thread_active = NULL;
/* Print a message every 60 seconds if we are waiting
for the monitor thread to exit. Master and worker threads
check will be done later. */
if (srv_print_verbose_log && count > 600) {
if (srv_error_monitor_active) {
thread_active = "srv_error_monitor_thread";
} else if (srv_lock_timeout_active) {
thread_active = "srv_lock_timeout thread";
} else if (srv_monitor_active) {
thread_active = "srv_monitor_thread";
}
}
mutex_exit(&kernel_mutex);
@ -3106,6 +3126,13 @@ loop:
os_event_set(srv_monitor_event);
os_event_set(srv_timeout_event);
if (thread_active) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %s to exit\n",
thread_active);
count = 0;
}
goto loop;
}
@ -3116,9 +3143,54 @@ loop:
server_busy = trx_n_mysql_transactions > 0
|| UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared;
if (server_busy) {
ulint total_trx = UT_LIST_GET_LEN(trx_sys->trx_list)
+ trx_n_mysql_transactions;
mutex_exit(&kernel_mutex);
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %lu "
"active transactions to finish\n",
(ulong) total_trx);
count = 0;
}
goto loop;
}
mutex_exit(&kernel_mutex);
if (server_busy || srv_is_any_background_thread_active()) {
/* Check that the background threads are suspended */
active_thd = srv_get_active_thread_type();
if (active_thd != ULINT_UNDEFINED) {
/* The srv_lock_timeout_thread, srv_error_monitor_thread
and srv_monitor_thread should already exit by now. The
only threads to be suspended are the master threads
and worker threads (purge threads). Print the thread
type if any of such threads not in suspended mode */
if (srv_print_verbose_log && count > 600) {
const char* thread_type = "<null>";
switch (active_thd) {
case SRV_WORKER:
thread_type = "worker threads";
break;
case SRV_MASTER:
thread_type = "master thread";
break;
}
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %s "
"to be suspended\n", thread_type);
count = 0;
}
goto loop;
}
@ -3130,10 +3202,35 @@ loop:
|| log_sys->n_pending_writes;
mutex_exit(&log_sys->mutex);
if (server_busy || !buf_pool_check_no_pending_io()) {
if (server_busy) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Pending checkpoint_writes: %lu\n"
" InnoDB: Pending log flush writes: %lu\n",
(ulong) log_sys->n_pending_checkpoint_writes,
(ulong) log_sys->n_pending_writes);
count = 0;
}
goto loop;
}
pending_io = buf_pool_check_num_pending_io();
if (pending_io) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %lu buffer page "
"I/Os to complete\n",
(ulong) pending_io);
count = 0;
}
goto loop;
}
#ifdef UNIV_LOG_ARCHIVE
log_archive_all();
#endif /* UNIV_LOG_ARCHIVE */
@ -3157,7 +3254,7 @@ loop:
log_buffer_flush_to_disk();
/* Check that the background threads stay suspended */
if (srv_is_any_background_thread_active()) {
if (srv_get_active_thread_type() != ULINT_UNDEFINED) {
fprintf(stderr,
"InnoDB: Warning: some background thread"
" woke up during shutdown\n");
@ -3166,7 +3263,7 @@ loop:
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
fil_close_all_files();
ut_a(!srv_is_any_background_thread_active());
ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
return;
}
@ -3204,7 +3301,7 @@ loop:
mutex_exit(&log_sys->mutex);
/* Check that the background threads stay suspended */
if (srv_is_any_background_thread_active()) {
if (srv_get_active_thread_type() != ULINT_UNDEFINED) {
fprintf(stderr,
"InnoDB: Warning: some background thread woke up"
" during shutdown\n");
@ -3222,13 +3319,20 @@ loop:
if (!buf_all_freed()) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for dirty buffer "
"pages to be flushed\n");
count = 0;
}
goto loop;
}
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Make some checks that the server really is quiet */
ut_a(!srv_is_any_background_thread_active());
ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);
@ -3250,7 +3354,7 @@ loop:
fil_close_all_files();
/* Make some checks that the server really is quiet */
ut_a(!srv_is_any_background_thread_active());
ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn);

View File

@ -1788,7 +1788,7 @@ row_mysql_freeze_data_dictionary_func(
{
ut_a(trx->dict_operation_lock_mode == 0);
rw_lock_s_lock_func(&dict_operation_lock, 0, file, line);
rw_lock_s_lock_inline(&dict_operation_lock, 0, file, line);
trx->dict_operation_lock_mode = RW_S_LATCH;
}
@ -1825,7 +1825,7 @@ row_mysql_lock_data_dictionary_func(
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks or lock waits can occur then in these operations */
rw_lock_x_lock_func(&dict_operation_lock, 0, file, line);
rw_lock_x_lock_inline(&dict_operation_lock, 0, file, line);
trx->dict_operation_lock_mode = RW_X_LATCH;
mutex_enter(&(dict_sys->mutex));

View File

@ -2485,21 +2485,23 @@ loop:
}
/**********************************************************************//**
Check whether any background thread is active.
@return FALSE if all are are suspended or have exited. */
Check whether any background thread is active. If so return the thread
type
@return ULINT_UNDEFINED if all are suspended or have exited, thread
type if any are still active. */
UNIV_INTERN
ibool
srv_is_any_background_thread_active(void)
/*=====================================*/
ulint
srv_get_active_thread_type(void)
/*============================*/
{
ulint i;
ibool ret = FALSE;
ibool ret = ULINT_UNDEFINED;
mutex_enter(&kernel_mutex);
for (i = 0; i <= SRV_MASTER; ++i) {
if (srv_n_threads_active[i] != 0) {
ret = TRUE;
ret = i;
break;
}
}
@ -2509,6 +2511,57 @@ srv_is_any_background_thread_active(void)
return(ret);
}
/*********************************************************************//**
This function prints progress message every 60 seconds during server
shutdown, for any activities that master thread is pending on. */
static
void
srv_shutdown_print_master_pending(
/*==============================*/
ib_time_t* last_print_time, /*!< last time the function
print the message */
ulint n_tables_to_drop, /*!< number of tables to
be dropped */
ulint n_bytes_merged, /*!< number of change buffer
just merged */
ulint n_pages_flushed) /*!< number of pages flushed */
{
ib_time_t current_time;
double time_elapsed;
current_time = ut_time();
time_elapsed = ut_difftime(current_time, *last_print_time);
if (time_elapsed > 60) {
*last_print_time = ut_time();
if (n_tables_to_drop) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for "
"%lu table(s) to be dropped\n",
(ulong) n_tables_to_drop);
}
/* Check change buffer merge, we only wait for change buffer
merge if it is a slow shutdown */
if (!srv_fast_shutdown && n_bytes_merged) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for change "
"buffer merge to complete\n"
" InnoDB: number of bytes of change buffer "
"just merged: %lu\n",
n_bytes_merged);
}
if (n_pages_flushed) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for "
"%lu pages to be flushed\n",
(ulong) n_pages_flushed);
}
}
}
/*******************************************************************//**
Tells the InnoDB server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
@ -2664,6 +2717,7 @@ srv_master_thread(
ulint n_pend_ios;
ulint next_itr_time;
ulint i;
ib_time_t last_print_time;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
@ -2685,6 +2739,7 @@ srv_master_thread(
mutex_exit(&kernel_mutex);
last_print_time = ut_time();
loop:
/*****************************************************************/
/* ---- When there is database activity by users, we cycle in this
@ -3030,6 +3085,14 @@ flush_loop:
*/
n_bytes_archived = 0;
/* Print progress message every 60 seconds during shutdown */
if (srv_shutdown_state > 0 && srv_print_verbose_log) {
srv_shutdown_print_master_pending(&last_print_time,
n_tables_to_drop,
n_bytes_merged,
n_pages_flushed);
}
/* Keep looping in the background loop if still work to do */
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@ -3048,6 +3111,7 @@ flush_loop:
} else if (n_tables_to_drop
+ n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_bytes_archived != 0) {
/* In a 'slow' shutdown we run purge and the insert buffer
merge to completion */

View File

@ -155,7 +155,7 @@ int main(void)
"conn %ld to: '%-.64s' user: '%-.32s' host: '%-.64s' (%-.64s)",
1L, NULL, NULL, NULL, NULL);
test1("Hello string `I am a string`",
"Hello string `%s", "I am a string");
"Hello string %`s", "I am a string");
test1("Hello TEST",
"Hello %05s", "TEST");
test1("My `Q` test",