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:
2
README
2
README
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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_;
|
||||
|
@ -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_; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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,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);
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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;
|
||||
|
@ -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 #
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
/*******************************************************************//**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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",
|
||||
|
Reference in New Issue
Block a user