mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge mysql-5.5-innodb -> mysql-5.5
This commit is contained in:
73
mysql-test/suite/innodb/r/innodb_bug60196.result
Executable file
73
mysql-test/suite/innodb/r/innodb_bug60196.result
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
CREATE TABLE Bug_60196_FK1 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE Bug_60196_FK2 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE Bug_60196 (
|
||||||
|
FK1_Key INT NOT NULL,
|
||||||
|
FK2_Key INT NOT NULL,
|
||||||
|
PRIMARY KEY (FK2_Key, FK1_Key),
|
||||||
|
KEY FK1_Key (FK1_Key),
|
||||||
|
KEY FK2_Key (FK2_Key),
|
||||||
|
CONSTRAINT FK_FK1 FOREIGN KEY (FK1_Key)
|
||||||
|
REFERENCES Bug_60196_FK1 (Primary_Key)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT FK_FK2 FOREIGN KEY (FK2_Key)
|
||||||
|
REFERENCES Bug_60196_FK2 (Primary_Key)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO Bug_60196_FK1 VALUES (1), (2), (3), (4), (5);
|
||||||
|
INSERT INTO Bug_60196_FK2 VALUES (1), (2), (3), (4), (5);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 1);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 2);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 3);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 99);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`bug_60196`, CONSTRAINT `FK_FK2` FOREIGN KEY (`FK2_Key`) REFERENCES `Bug_60196_FK2` (`Primary_Key`) ON DELETE CASCADE ON UPDATE CASCADE)
|
||||||
|
INSERT INTO Bug_60196 VALUES (99, 1);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`bug_60196`, CONSTRAINT `FK_FK1` FOREIGN KEY (`FK1_Key`) REFERENCES `Bug_60196_FK1` (`Primary_Key`) ON DELETE CASCADE ON UPDATE CASCADE)
|
||||||
|
SELECT * FROM bug_60196_FK1;
|
||||||
|
Primary_Key
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
SELECT * FROM bug_60196_FK2;
|
||||||
|
Primary_Key
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
SELECT * FROM bug_60196;
|
||||||
|
FK1_Key FK2_Key
|
||||||
|
1 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
# Stop server
|
||||||
|
# Restart server.
|
||||||
|
#
|
||||||
|
# Try to insert more to the example table with foreign keys.
|
||||||
|
# Bug60196 causes the foreign key file not to be found after
|
||||||
|
# the resstart above.
|
||||||
|
#
|
||||||
|
SELECT * FROM Bug_60196;
|
||||||
|
FK1_Key FK2_Key
|
||||||
|
1 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 1);
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 2);
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 3);
|
||||||
|
SELECT * FROM Bug_60196;
|
||||||
|
FK1_Key FK2_Key
|
||||||
|
1 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
2 1
|
||||||
|
2 2
|
||||||
|
2 3
|
||||||
|
|
||||||
|
# Clean up.
|
||||||
|
DROP TABLE Bug_60196;
|
||||||
|
DROP TABLE Bug_60196_FK1;
|
||||||
|
DROP TABLE Bug_60196_FK2;
|
1
mysql-test/suite/innodb/t/innodb_bug60196-master.opt
Executable file
1
mysql-test/suite/innodb/t/innodb_bug60196-master.opt
Executable file
@ -0,0 +1 @@
|
|||||||
|
--lower-case-table-names=2
|
87
mysql-test/suite/innodb/t/innodb_bug60196.test
Executable file
87
mysql-test/suite/innodb/t/innodb_bug60196.test
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
# Bug#60196 - Setting lowercase_table_names to 2 on Windows causing
|
||||||
|
# Foreign Key problems after an engine is restarted.
|
||||||
|
|
||||||
|
# This test case needs InnoDB, a lowercase file system,
|
||||||
|
# lower-case-table-names=2, and cannot use the embedded server
|
||||||
|
# because it restarts the server.
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_lowercase2.inc
|
||||||
|
--source include/have_case_insensitive_file_system.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create test data.
|
||||||
|
#
|
||||||
|
CREATE TABLE Bug_60196_FK1 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE Bug_60196_FK2 (Primary_Key INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE Bug_60196 (
|
||||||
|
FK1_Key INT NOT NULL,
|
||||||
|
FK2_Key INT NOT NULL,
|
||||||
|
PRIMARY KEY (FK2_Key, FK1_Key),
|
||||||
|
KEY FK1_Key (FK1_Key),
|
||||||
|
KEY FK2_Key (FK2_Key),
|
||||||
|
CONSTRAINT FK_FK1 FOREIGN KEY (FK1_Key)
|
||||||
|
REFERENCES Bug_60196_FK1 (Primary_Key)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT FK_FK2 FOREIGN KEY (FK2_Key)
|
||||||
|
REFERENCES Bug_60196_FK2 (Primary_Key)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO Bug_60196_FK1 VALUES (1), (2), (3), (4), (5);
|
||||||
|
INSERT INTO Bug_60196_FK2 VALUES (1), (2), (3), (4), (5);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 1);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 2);
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 3);
|
||||||
|
--error ER_NO_REFERENCED_ROW_2
|
||||||
|
INSERT INTO Bug_60196 VALUES (1, 99);
|
||||||
|
--error ER_NO_REFERENCED_ROW_2
|
||||||
|
INSERT INTO Bug_60196 VALUES (99, 1);
|
||||||
|
|
||||||
|
SELECT * FROM bug_60196_FK1;
|
||||||
|
SELECT * FROM bug_60196_FK2;
|
||||||
|
SELECT * FROM bug_60196;
|
||||||
|
|
||||||
|
--echo # Stop server
|
||||||
|
|
||||||
|
# Write file to make mysql-test-run.pl wait for the server to stop
|
||||||
|
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
|
||||||
|
# Send a shutdown request to the server
|
||||||
|
-- shutdown_server 10
|
||||||
|
|
||||||
|
# Call script that will poll the server waiting for it to disapear
|
||||||
|
-- source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
--echo # Restart server.
|
||||||
|
|
||||||
|
# Write file to make mysql-test-run.pl start up the server again
|
||||||
|
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
|
||||||
|
# Turn on reconnect
|
||||||
|
--enable_reconnect
|
||||||
|
|
||||||
|
# Call script that will poll the server waiting for it to be back online again
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
# Turn off reconnect again
|
||||||
|
--disable_reconnect
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Try to insert more to the example table with foreign keys.
|
||||||
|
--echo # Bug60196 causes the foreign key file not to be found after
|
||||||
|
--echo # the resstart above.
|
||||||
|
--echo #
|
||||||
|
SELECT * FROM Bug_60196;
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 1);
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 2);
|
||||||
|
INSERT INTO Bug_60196 VALUES (2, 3);
|
||||||
|
SELECT * FROM Bug_60196;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo # Clean up.
|
||||||
|
DROP TABLE Bug_60196;
|
||||||
|
DROP TABLE Bug_60196_FK1;
|
||||||
|
DROP TABLE Bug_60196_FK2;
|
||||||
|
|
@ -241,7 +241,6 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
|||||||
row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
|
row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
|
||||||
srv/srv0srv.c srv/srv0start.c
|
srv/srv0srv.c srv/srv0start.c
|
||||||
sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
|
sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
|
||||||
thr/thr0loc.c
|
|
||||||
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
|
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
|
||||||
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
|
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
|
||||||
usr/usr0sess.c
|
usr/usr0sess.c
|
||||||
|
@ -402,7 +402,7 @@ btr_cur_search_to_nth_level(
|
|||||||
|
|
||||||
ut_ad(level == 0 || mode == PAGE_CUR_LE);
|
ut_ad(level == 0 || mode == PAGE_CUR_LE);
|
||||||
ut_ad(dict_index_check_search_tuple(index, tuple));
|
ut_ad(dict_index_check_search_tuple(index, tuple));
|
||||||
ut_ad(!dict_index_is_ibuf(index) || ibuf_inside());
|
ut_ad(!dict_index_is_ibuf(index) || ibuf_inside(mtr));
|
||||||
ut_ad(dtuple_check_typed(tuple));
|
ut_ad(dtuple_check_typed(tuple));
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
@ -4904,27 +4904,45 @@ btr_copy_blob_prefix(
|
|||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Copies the prefix of a compressed BLOB. The clustered index record
|
Copies the prefix of a compressed BLOB. The clustered index record
|
||||||
that points to this BLOB must be protected by a lock or a page latch. */
|
that points to this BLOB must be protected by a lock or a page latch.
|
||||||
|
@return number of bytes written to buf */
|
||||||
static
|
static
|
||||||
void
|
ulint
|
||||||
btr_copy_zblob_prefix(
|
btr_copy_zblob_prefix(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
z_stream* d_stream,/*!< in/out: the decompressing stream */
|
byte* buf, /*!< out: the externally stored part of
|
||||||
|
the field, or a prefix of it */
|
||||||
|
ulint len, /*!< in: length of buf, in bytes */
|
||||||
ulint zip_size,/*!< in: compressed BLOB page size */
|
ulint zip_size,/*!< in: compressed BLOB page size */
|
||||||
ulint space_id,/*!< in: space id of the BLOB pages */
|
ulint space_id,/*!< in: space id of the BLOB pages */
|
||||||
ulint page_no,/*!< in: page number of the first BLOB page */
|
ulint page_no,/*!< in: page number of the first BLOB page */
|
||||||
ulint offset) /*!< in: offset on the first BLOB page */
|
ulint offset) /*!< in: offset on the first BLOB page */
|
||||||
{
|
{
|
||||||
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
|
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
|
||||||
|
mem_heap_t* heap;
|
||||||
|
int err;
|
||||||
|
z_stream d_stream;
|
||||||
|
|
||||||
|
d_stream.next_out = buf;
|
||||||
|
d_stream.avail_out = len;
|
||||||
|
d_stream.next_in = Z_NULL;
|
||||||
|
d_stream.avail_in = 0;
|
||||||
|
|
||||||
|
/* Zlib inflate needs 32 kilobytes for the default
|
||||||
|
window size, plus a few kilobytes for small objects. */
|
||||||
|
heap = mem_heap_create(40000);
|
||||||
|
page_zip_set_alloc(&d_stream, heap);
|
||||||
|
|
||||||
ut_ad(ut_is_2pow(zip_size));
|
ut_ad(ut_is_2pow(zip_size));
|
||||||
ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE);
|
ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE);
|
||||||
ut_ad(zip_size <= UNIV_PAGE_SIZE);
|
ut_ad(zip_size <= UNIV_PAGE_SIZE);
|
||||||
ut_ad(space_id);
|
ut_ad(space_id);
|
||||||
|
|
||||||
|
err = inflateInit(&d_stream);
|
||||||
|
ut_a(err == Z_OK);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
buf_page_t* bpage;
|
buf_page_t* bpage;
|
||||||
int err;
|
|
||||||
ulint next_page_no;
|
ulint next_page_no;
|
||||||
|
|
||||||
/* There is no latch on bpage directly. Instead,
|
/* There is no latch on bpage directly. Instead,
|
||||||
@ -4940,7 +4958,7 @@ btr_copy_zblob_prefix(
|
|||||||
" compressed BLOB"
|
" compressed BLOB"
|
||||||
" page %lu space %lu\n",
|
" page %lu space %lu\n",
|
||||||
(ulong) page_no, (ulong) space_id);
|
(ulong) page_no, (ulong) space_id);
|
||||||
return;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY
|
if (UNIV_UNLIKELY
|
||||||
@ -4966,13 +4984,13 @@ btr_copy_zblob_prefix(
|
|||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
d_stream->next_in = bpage->zip.data + offset;
|
d_stream.next_in = bpage->zip.data + offset;
|
||||||
d_stream->avail_in = zip_size - offset;
|
d_stream.avail_in = zip_size - offset;
|
||||||
|
|
||||||
err = inflate(d_stream, Z_NO_FLUSH);
|
err = inflate(&d_stream, Z_NO_FLUSH);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case Z_OK:
|
case Z_OK:
|
||||||
if (!d_stream->avail_out) {
|
if (!d_stream.avail_out) {
|
||||||
goto end_of_blob;
|
goto end_of_blob;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4989,13 +5007,13 @@ inflate_error:
|
|||||||
" compressed BLOB"
|
" compressed BLOB"
|
||||||
" page %lu space %lu returned %d (%s)\n",
|
" page %lu space %lu returned %d (%s)\n",
|
||||||
(ulong) page_no, (ulong) space_id,
|
(ulong) page_no, (ulong) space_id,
|
||||||
err, d_stream->msg);
|
err, d_stream.msg);
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
goto end_of_blob;
|
goto end_of_blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next_page_no == FIL_NULL) {
|
if (next_page_no == FIL_NULL) {
|
||||||
if (!d_stream->avail_in) {
|
if (!d_stream.avail_in) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: unexpected end of"
|
" InnoDB: unexpected end of"
|
||||||
@ -5004,7 +5022,7 @@ inflate_error:
|
|||||||
(ulong) page_no,
|
(ulong) page_no,
|
||||||
(ulong) space_id);
|
(ulong) space_id);
|
||||||
} else {
|
} else {
|
||||||
err = inflate(d_stream, Z_FINISH);
|
err = inflate(&d_stream, Z_FINISH);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case Z_STREAM_END:
|
case Z_STREAM_END:
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
@ -5016,7 +5034,7 @@ inflate_error:
|
|||||||
|
|
||||||
end_of_blob:
|
end_of_blob:
|
||||||
buf_page_release_zip(bpage);
|
buf_page_release_zip(bpage);
|
||||||
return;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_page_release_zip(bpage);
|
buf_page_release_zip(bpage);
|
||||||
@ -5028,6 +5046,12 @@ end_of_blob:
|
|||||||
offset = FIL_PAGE_NEXT;
|
offset = FIL_PAGE_NEXT;
|
||||||
page_type = FIL_PAGE_TYPE_ZBLOB2;
|
page_type = FIL_PAGE_TYPE_ZBLOB2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func_exit:
|
||||||
|
inflateEnd(&d_stream);
|
||||||
|
mem_heap_free(heap);
|
||||||
|
UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
|
||||||
|
return(d_stream.total_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
@ -5053,28 +5077,8 @@ btr_copy_externally_stored_field_prefix_low(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(zip_size)) {
|
if (UNIV_UNLIKELY(zip_size)) {
|
||||||
int err;
|
return(btr_copy_zblob_prefix(buf, len, zip_size,
|
||||||
z_stream d_stream;
|
space_id, page_no, offset));
|
||||||
mem_heap_t* heap;
|
|
||||||
|
|
||||||
/* Zlib inflate needs 32 kilobytes for the default
|
|
||||||
window size, plus a few kilobytes for small objects. */
|
|
||||||
heap = mem_heap_create(40000);
|
|
||||||
page_zip_set_alloc(&d_stream, heap);
|
|
||||||
|
|
||||||
err = inflateInit(&d_stream);
|
|
||||||
ut_a(err == Z_OK);
|
|
||||||
|
|
||||||
d_stream.next_out = buf;
|
|
||||||
d_stream.avail_out = len;
|
|
||||||
d_stream.avail_in = 0;
|
|
||||||
|
|
||||||
btr_copy_zblob_prefix(&d_stream, zip_size,
|
|
||||||
space_id, page_no, offset);
|
|
||||||
inflateEnd(&d_stream);
|
|
||||||
mem_heap_free(heap);
|
|
||||||
UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
|
|
||||||
return(d_stream.total_out);
|
|
||||||
} else {
|
} else {
|
||||||
return(btr_copy_blob_prefix(buf, len, space_id,
|
return(btr_copy_blob_prefix(buf, len, space_id,
|
||||||
page_no, offset));
|
page_no, offset));
|
||||||
|
@ -1213,8 +1213,8 @@ btr_search_drop_page_hash_when_freed(
|
|||||||
having to fear a deadlock. */
|
having to fear a deadlock. */
|
||||||
|
|
||||||
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL,
|
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL,
|
||||||
BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
|
BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__,
|
||||||
&mtr);
|
&mtr);
|
||||||
/* Because the buffer pool mutex was released by
|
/* Because the buffer pool mutex was released by
|
||||||
buf_page_peek_if_search_hashed(), it is possible that the
|
buf_page_peek_if_search_hashed(), it is possible that the
|
||||||
block was removed from the buffer pool by another thread
|
block was removed from the buffer pool by another thread
|
||||||
|
@ -1233,7 +1233,7 @@ buf_pool_init_instance(
|
|||||||
|
|
||||||
buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
|
buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
|
||||||
buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
|
buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
|
||||||
|
|
||||||
buf_pool->last_printout_time = ut_time();
|
buf_pool->last_printout_time = ut_time();
|
||||||
}
|
}
|
||||||
/* 2. Initialize flushing fields
|
/* 2. Initialize flushing fields
|
||||||
@ -1365,11 +1365,11 @@ buf_pool_drop_hash_index_instance(
|
|||||||
/* block->is_hashed cannot be modified
|
/* block->is_hashed cannot be modified
|
||||||
when we have an x-latch on btr_search_latch;
|
when we have an x-latch on btr_search_latch;
|
||||||
see the comment in buf0buf.h */
|
see the comment in buf0buf.h */
|
||||||
|
|
||||||
if (!block->is_hashed) {
|
if (!block->is_hashed) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To follow the latching order, we
|
/* To follow the latching order, we
|
||||||
have to release btr_search_latch
|
have to release btr_search_latch
|
||||||
before acquiring block->latch. */
|
before acquiring block->latch. */
|
||||||
@ -1378,14 +1378,14 @@ buf_pool_drop_hash_index_instance(
|
|||||||
we must rescan all blocks, because
|
we must rescan all blocks, because
|
||||||
some may become hashed again. */
|
some may become hashed again. */
|
||||||
*released_search_latch = TRUE;
|
*released_search_latch = TRUE;
|
||||||
|
|
||||||
rw_lock_x_lock(&block->lock);
|
rw_lock_x_lock(&block->lock);
|
||||||
|
|
||||||
/* This should be guaranteed by the
|
/* This should be guaranteed by the
|
||||||
callers, which will be holding
|
callers, which will be holding
|
||||||
btr_search_enabled_mutex. */
|
btr_search_enabled_mutex. */
|
||||||
ut_ad(!btr_search_enabled);
|
ut_ad(!btr_search_enabled);
|
||||||
|
|
||||||
/* Because we did not buffer-fix the
|
/* Because we did not buffer-fix the
|
||||||
block by calling buf_block_get_gen(),
|
block by calling buf_block_get_gen(),
|
||||||
it is possible that the block has been
|
it is possible that the block has been
|
||||||
@ -1395,7 +1395,7 @@ buf_pool_drop_hash_index_instance(
|
|||||||
block is mapped to. All we want to do
|
block is mapped to. All we want to do
|
||||||
is to drop any hash entries referring
|
is to drop any hash entries referring
|
||||||
to the page. */
|
to the page. */
|
||||||
|
|
||||||
/* It is possible that
|
/* It is possible that
|
||||||
block->page.state != BUF_FILE_PAGE.
|
block->page.state != BUF_FILE_PAGE.
|
||||||
Even that does not matter, because
|
Even that does not matter, because
|
||||||
@ -1403,18 +1403,18 @@ buf_pool_drop_hash_index_instance(
|
|||||||
check block->is_hashed before doing
|
check block->is_hashed before doing
|
||||||
anything. block->is_hashed can only
|
anything. block->is_hashed can only
|
||||||
be set on uncompressed file pages. */
|
be set on uncompressed file pages. */
|
||||||
|
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
|
|
||||||
rw_lock_x_unlock(&block->lock);
|
rw_lock_x_unlock(&block->lock);
|
||||||
|
|
||||||
rw_lock_x_lock(&btr_search_latch);
|
rw_lock_x_lock(&btr_search_latch);
|
||||||
|
|
||||||
ut_ad(!btr_search_enabled);
|
ut_ad(!btr_search_enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Drops the adaptive hash index. To prevent a livelock, this function
|
Drops the adaptive hash index. To prevent a livelock, this function
|
||||||
is only to be called while holding btr_search_latch and while
|
is only to be called while holding btr_search_latch and while
|
||||||
@ -1990,30 +1990,30 @@ buf_pool_resize(void)
|
|||||||
ulint min_change_size = 1048576 * srv_buf_pool_instances;
|
ulint min_change_size = 1048576 * srv_buf_pool_instances;
|
||||||
|
|
||||||
buf_pool_mutex_enter_all();
|
buf_pool_mutex_enter_all();
|
||||||
|
|
||||||
if (srv_buf_pool_old_size == srv_buf_pool_size) {
|
if (srv_buf_pool_old_size == srv_buf_pool_size) {
|
||||||
|
|
||||||
buf_pool_mutex_exit_all();
|
buf_pool_mutex_exit_all();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (srv_buf_pool_curr_size + min_change_size
|
} else if (srv_buf_pool_curr_size + min_change_size
|
||||||
> srv_buf_pool_size) {
|
> srv_buf_pool_size) {
|
||||||
|
|
||||||
change_size = (srv_buf_pool_curr_size - srv_buf_pool_size)
|
change_size = (srv_buf_pool_curr_size - srv_buf_pool_size)
|
||||||
/ UNIV_PAGE_SIZE;
|
/ UNIV_PAGE_SIZE;
|
||||||
|
|
||||||
buf_pool_mutex_exit_all();
|
buf_pool_mutex_exit_all();
|
||||||
|
|
||||||
/* Disable adaptive hash indexes and empty the index
|
/* Disable adaptive hash indexes and empty the index
|
||||||
in order to free up memory in the buffer pool chunks. */
|
in order to free up memory in the buffer pool chunks. */
|
||||||
buf_pool_shrink(change_size);
|
buf_pool_shrink(change_size);
|
||||||
|
|
||||||
} else if (srv_buf_pool_curr_size + min_change_size
|
} else if (srv_buf_pool_curr_size + min_change_size
|
||||||
< srv_buf_pool_size) {
|
< srv_buf_pool_size) {
|
||||||
|
|
||||||
/* Enlarge the buffer pool by at least one megabyte */
|
/* Enlarge the buffer pool by at least one megabyte */
|
||||||
|
|
||||||
change_size = srv_buf_pool_size - srv_buf_pool_curr_size;
|
change_size = srv_buf_pool_size - srv_buf_pool_curr_size;
|
||||||
|
|
||||||
buf_pool_mutex_exit_all();
|
buf_pool_mutex_exit_all();
|
||||||
@ -2026,10 +2026,10 @@ buf_pool_resize(void)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_pool_page_hash_rebuild();
|
buf_pool_page_hash_rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Remove the sentinel block for the watch before replacing it with a real block.
|
Remove the sentinel block for the watch before replacing it with a real block.
|
||||||
buf_page_watch_clear() or buf_page_watch_occurred() will notice that
|
buf_page_watch_clear() or buf_page_watch_occurred() will notice that
|
||||||
@ -2316,9 +2316,6 @@ buf_page_get_zip(
|
|||||||
unsigned access_time;
|
unsigned access_time;
|
||||||
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
||||||
|
|
||||||
#ifndef UNIV_LOG_DEBUG
|
|
||||||
ut_ad(!ibuf_inside());
|
|
||||||
#endif
|
|
||||||
buf_pool->stat.n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -2533,16 +2530,19 @@ buf_block_align_instance(
|
|||||||
/* TODO: protect buf_pool->chunks with a mutex (it will
|
/* TODO: protect buf_pool->chunks with a mutex (it will
|
||||||
currently remain constant after buf_pool_init()) */
|
currently remain constant after buf_pool_init()) */
|
||||||
for (chunk = buf_pool->chunks, i = buf_pool->n_chunks; i--; chunk++) {
|
for (chunk = buf_pool->chunks, i = buf_pool->n_chunks; i--; chunk++) {
|
||||||
lint offs = ptr - chunk->blocks->frame;
|
ulint offs;
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(offs < 0)) {
|
if (UNIV_UNLIKELY(ptr < chunk->blocks->frame)) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* else */
|
||||||
|
|
||||||
|
offs = ptr - chunk->blocks->frame;
|
||||||
|
|
||||||
offs >>= UNIV_PAGE_SIZE_SHIFT;
|
offs >>= UNIV_PAGE_SIZE_SHIFT;
|
||||||
|
|
||||||
if (UNIV_LIKELY((ulint) offs < chunk->size)) {
|
if (UNIV_LIKELY(offs < chunk->size)) {
|
||||||
buf_block_t* block = &chunk->blocks[offs];
|
buf_block_t* block = &chunk->blocks[offs];
|
||||||
|
|
||||||
/* The function buf_chunk_init() invokes
|
/* The function buf_chunk_init() invokes
|
||||||
@ -2719,7 +2719,7 @@ buf_page_get_gen(
|
|||||||
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
|
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
|
||||||
buf_block_t* guess, /*!< in: guessed block or NULL */
|
buf_block_t* guess, /*!< in: guessed block or NULL */
|
||||||
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
|
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
|
||||||
BUF_GET_NO_LATCH, or
|
BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or
|
||||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
ulint line, /*!< in: line where called */
|
ulint line, /*!< in: line where called */
|
||||||
@ -2738,16 +2738,26 @@ buf_page_get_gen(
|
|||||||
ut_ad((rw_latch == RW_S_LATCH)
|
ut_ad((rw_latch == RW_S_LATCH)
|
||||||
|| (rw_latch == RW_X_LATCH)
|
|| (rw_latch == RW_X_LATCH)
|
||||||
|| (rw_latch == RW_NO_LATCH));
|
|| (rw_latch == RW_NO_LATCH));
|
||||||
ut_ad((mode != BUF_GET_NO_LATCH) || (rw_latch == RW_NO_LATCH));
|
#ifdef UNIV_DEBUG
|
||||||
ut_ad(mode == BUF_GET
|
switch (mode) {
|
||||||
|| mode == BUF_GET_IF_IN_POOL
|
case BUF_GET_NO_LATCH:
|
||||||
|| mode == BUF_GET_NO_LATCH
|
ut_ad(rw_latch == RW_NO_LATCH);
|
||||||
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH);
|
break;
|
||||||
|
case BUF_GET:
|
||||||
|
case BUF_GET_IF_IN_POOL:
|
||||||
|
case BUF_PEEK_IF_IN_POOL:
|
||||||
|
case BUF_GET_IF_IN_POOL_OR_WATCH:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
ut_ad(zip_size == fil_space_get_zip_size(space));
|
ut_ad(zip_size == fil_space_get_zip_size(space));
|
||||||
ut_ad(ut_is_2pow(zip_size));
|
ut_ad(ut_is_2pow(zip_size));
|
||||||
#ifndef UNIV_LOG_DEBUG
|
#ifndef UNIV_LOG_DEBUG
|
||||||
ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset,
|
ut_ad(!ibuf_inside(mtr)
|
||||||
FALSE, file, line, NULL));
|
|| ibuf_page_low(space, zip_size, offset,
|
||||||
|
FALSE, file, line, NULL));
|
||||||
#endif
|
#endif
|
||||||
buf_pool->stat.n_page_gets++;
|
buf_pool->stat.n_page_gets++;
|
||||||
fold = buf_page_address_fold(space, offset);
|
fold = buf_page_address_fold(space, offset);
|
||||||
@ -2802,6 +2812,7 @@ loop2:
|
|||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
|
|
||||||
if (mode == BUF_GET_IF_IN_POOL
|
if (mode == BUF_GET_IF_IN_POOL
|
||||||
|
|| mode == BUF_PEEK_IF_IN_POOL
|
||||||
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -2842,7 +2853,8 @@ got_block:
|
|||||||
|
|
||||||
must_read = buf_block_get_io_fix(block) == BUF_IO_READ;
|
must_read = buf_block_get_io_fix(block) == BUF_IO_READ;
|
||||||
|
|
||||||
if (must_read && mode == BUF_GET_IF_IN_POOL) {
|
if (must_read && (mode == BUF_GET_IF_IN_POOL
|
||||||
|
|| mode == BUF_PEEK_IF_IN_POOL)) {
|
||||||
|
|
||||||
/* The page is being read to buffer pool,
|
/* The page is being read to buffer pool,
|
||||||
but we cannot wait around for the read to
|
but we cannot wait around for the read to
|
||||||
@ -2876,7 +2888,7 @@ wait_until_unfixed:
|
|||||||
Try again later. */
|
Try again later. */
|
||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
os_thread_sleep(WAIT_FOR_READ);
|
os_thread_sleep(WAIT_FOR_READ);
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2965,6 +2977,7 @@ wait_until_unfixed:
|
|||||||
mutex_exit(&buf_pool->zip_mutex);
|
mutex_exit(&buf_pool->zip_mutex);
|
||||||
buf_pool->n_pend_unzip++;
|
buf_pool->n_pend_unzip++;
|
||||||
|
|
||||||
|
bpage->state = BUF_BLOCK_ZIP_FREE;
|
||||||
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
|
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
|
||||||
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
@ -3058,7 +3071,9 @@ wait_until_unfixed:
|
|||||||
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
|
|
||||||
buf_page_set_accessed_make_young(&block->page, access_time);
|
if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
|
||||||
|
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
|
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
|
||||||
ut_a(!block->page.file_page_was_freed);
|
ut_a(!block->page.file_page_was_freed);
|
||||||
@ -3111,11 +3126,12 @@ wait_until_unfixed:
|
|||||||
|
|
||||||
mtr_memo_push(mtr, block, fix_type);
|
mtr_memo_push(mtr, block, fix_type);
|
||||||
|
|
||||||
if (!access_time) {
|
if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
|
||||||
/* In the case of a first access, try to apply linear
|
/* In the case of a first access, try to apply linear
|
||||||
read-ahead */
|
read-ahead */
|
||||||
|
|
||||||
buf_read_ahead_linear(space, zip_size, offset);
|
buf_read_ahead_linear(space, zip_size, offset,
|
||||||
|
ibuf_inside(mtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||||
@ -3172,7 +3188,7 @@ buf_page_optimistic_get(
|
|||||||
access_time = buf_page_is_accessed(&block->page);
|
access_time = buf_page_is_accessed(&block->page);
|
||||||
buf_page_set_accessed_make_young(&block->page, access_time);
|
buf_page_set_accessed_make_young(&block->page, access_time);
|
||||||
|
|
||||||
ut_ad(!ibuf_inside()
|
ut_ad(!ibuf_inside(mtr)
|
||||||
|| ibuf_page(buf_block_get_space(block),
|
|| ibuf_page(buf_block_get_space(block),
|
||||||
buf_block_get_zip_size(block),
|
buf_block_get_zip_size(block),
|
||||||
buf_block_get_page_no(block), NULL));
|
buf_block_get_page_no(block), NULL));
|
||||||
@ -3228,7 +3244,8 @@ buf_page_optimistic_get(
|
|||||||
|
|
||||||
buf_read_ahead_linear(buf_block_get_space(block),
|
buf_read_ahead_linear(buf_block_get_space(block),
|
||||||
buf_block_get_zip_size(block),
|
buf_block_get_zip_size(block),
|
||||||
buf_block_get_page_no(block));
|
buf_block_get_page_no(block),
|
||||||
|
ibuf_inside(mtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||||
@ -3304,7 +3321,7 @@ buf_page_get_known_nowait(
|
|||||||
buf_pool_mutex_exit(buf_pool);
|
buf_pool_mutex_exit(buf_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
|
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
|
||||||
|
|
||||||
if (rw_latch == RW_S_LATCH) {
|
if (rw_latch == RW_S_LATCH) {
|
||||||
success = rw_lock_s_lock_nowait(&(block->lock),
|
success = rw_lock_s_lock_nowait(&(block->lock),
|
||||||
@ -3569,14 +3586,13 @@ buf_page_init_for_read(
|
|||||||
/* It is a read-ahead within an ibuf routine */
|
/* It is a read-ahead within an ibuf routine */
|
||||||
|
|
||||||
ut_ad(!ibuf_bitmap_page(zip_size, offset));
|
ut_ad(!ibuf_bitmap_page(zip_size, offset));
|
||||||
ut_ad(ibuf_inside());
|
|
||||||
|
|
||||||
mtr_start(&mtr);
|
ibuf_mtr_start(&mtr);
|
||||||
|
|
||||||
if (!recv_no_ibuf_operations
|
if (!recv_no_ibuf_operations
|
||||||
&& !ibuf_page(space, zip_size, offset, &mtr)) {
|
&& !ibuf_page(space, zip_size, offset, &mtr)) {
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
ibuf_mtr_commit(&mtr);
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
@ -3700,6 +3716,7 @@ err_exit:
|
|||||||
|
|
||||||
/* The block was added by some other thread. */
|
/* The block was added by some other thread. */
|
||||||
watch_page = NULL;
|
watch_page = NULL;
|
||||||
|
bpage->state = BUF_BLOCK_ZIP_FREE;
|
||||||
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
|
buf_buddy_free(buf_pool, bpage, sizeof *bpage);
|
||||||
buf_buddy_free(buf_pool, data, zip_size);
|
buf_buddy_free(buf_pool, data, zip_size);
|
||||||
|
|
||||||
@ -3760,7 +3777,7 @@ func_exit:
|
|||||||
|
|
||||||
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
|
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
ibuf_mtr_commit(&mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!bpage || buf_page_in_file(bpage));
|
ut_ad(!bpage || buf_page_in_file(bpage));
|
||||||
@ -4788,7 +4805,7 @@ buf_get_modified_ratio_pct(void)
|
|||||||
buf_get_total_list_len(&lru_len, &free_len, &flush_list_len);
|
buf_get_total_list_len(&lru_len, &free_len, &flush_list_len);
|
||||||
|
|
||||||
ratio = (100 * flush_list_len) / (1 + lru_len + free_len);
|
ratio = (100 * flush_list_len) / (1 + lru_len + free_len);
|
||||||
|
|
||||||
/* 1 + is there to avoid division by zero */
|
/* 1 + is there to avoid division by zero */
|
||||||
|
|
||||||
return(ratio);
|
return(ratio);
|
||||||
@ -5171,7 +5188,7 @@ buf_all_freed(void)
|
|||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Checks that there currently are no pending i/o-operations for the buffer
|
Checks that there currently are no pending i/o-operations for the buffer
|
||||||
pool.
|
pool.
|
||||||
|
@ -247,74 +247,78 @@ buf_LRU_drop_page_hash_for_tablespace(
|
|||||||
sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
||||||
|
|
||||||
buf_pool_mutex_enter(buf_pool);
|
buf_pool_mutex_enter(buf_pool);
|
||||||
|
num_entries = 0;
|
||||||
|
|
||||||
scan_again:
|
scan_again:
|
||||||
num_entries = 0;
|
|
||||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||||
|
|
||||||
while (bpage != NULL) {
|
while (bpage != NULL) {
|
||||||
mutex_t* block_mutex = buf_page_get_mutex(bpage);
|
|
||||||
buf_page_t* prev_bpage;
|
buf_page_t* prev_bpage;
|
||||||
|
ibool is_fixed;
|
||||||
|
|
||||||
mutex_enter(block_mutex);
|
|
||||||
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||||
|
|
||||||
ut_a(buf_page_in_file(bpage));
|
ut_a(buf_page_in_file(bpage));
|
||||||
|
|
||||||
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|
||||||
|| bpage->space != id
|
|| bpage->space != id
|
||||||
|| bpage->buf_fix_count > 0
|
|
||||||
|| bpage->io_fix != BUF_IO_NONE) {
|
|| bpage->io_fix != BUF_IO_NONE) {
|
||||||
/* We leave the fixed pages as is in this scan.
|
/* Compressed pages are never hashed.
|
||||||
To be dealt with later in the final scan. */
|
Skip blocks of other tablespaces.
|
||||||
mutex_exit(block_mutex);
|
Skip I/O-fixed blocks (to be dealt with later). */
|
||||||
|
next_page:
|
||||||
|
bpage = prev_bpage;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_enter(&((buf_block_t*) bpage)->mutex);
|
||||||
|
is_fixed = bpage->buf_fix_count > 0
|
||||||
|
|| !((buf_block_t*) bpage)->is_hashed;
|
||||||
|
mutex_exit(&((buf_block_t*) bpage)->mutex);
|
||||||
|
|
||||||
|
if (is_fixed) {
|
||||||
goto next_page;
|
goto next_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((buf_block_t*) bpage)->is_hashed) {
|
/* Store the page number so that we can drop the hash
|
||||||
|
index in a batch later. */
|
||||||
|
page_arr[num_entries] = bpage->offset;
|
||||||
|
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
||||||
|
++num_entries;
|
||||||
|
|
||||||
/* Store the offset(i.e.: page_no) in the array
|
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
|
||||||
so that we can drop hash index in a batch
|
goto next_page;
|
||||||
later. */
|
|
||||||
page_arr[num_entries] = bpage->offset;
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
|
|
||||||
++num_entries;
|
|
||||||
|
|
||||||
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
|
|
||||||
goto next_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Array full. We release the buf_pool->mutex to
|
|
||||||
obey the latching order. */
|
|
||||||
buf_pool_mutex_exit(buf_pool);
|
|
||||||
|
|
||||||
buf_LRU_drop_page_hash_batch(
|
|
||||||
id, zip_size, page_arr, num_entries);
|
|
||||||
|
|
||||||
num_entries = 0;
|
|
||||||
|
|
||||||
buf_pool_mutex_enter(buf_pool);
|
|
||||||
} else {
|
|
||||||
mutex_exit(block_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_page:
|
/* Array full. We release the buf_pool->mutex to obey
|
||||||
/* Note that we may have released the buf_pool mutex
|
the latching order. */
|
||||||
above after reading the prev_bpage during processing
|
buf_pool_mutex_exit(buf_pool);
|
||||||
of a page_hash_batch (i.e.: when the array was full).
|
|
||||||
This means that prev_bpage can change in LRU list.
|
buf_LRU_drop_page_hash_batch(
|
||||||
This is OK because this function is a 'best effort'
|
id, zip_size, page_arr, num_entries);
|
||||||
to drop as many search hash entries as possible and
|
|
||||||
it does not guarantee that ALL such entries will be
|
num_entries = 0;
|
||||||
dropped. */
|
|
||||||
bpage = prev_bpage;
|
buf_pool_mutex_enter(buf_pool);
|
||||||
|
|
||||||
|
/* Note that we released the buf_pool mutex above
|
||||||
|
after reading the prev_bpage during processing of a
|
||||||
|
page_hash_batch (i.e.: when the array was full).
|
||||||
|
Because prev_bpage could belong to a compressed-only
|
||||||
|
block, it may have been relocated, and thus the
|
||||||
|
pointer cannot be trusted. Because bpage is of type
|
||||||
|
buf_block_t, it is safe to dereference.
|
||||||
|
|
||||||
|
bpage can change in the LRU list. This is OK because
|
||||||
|
this function is a 'best effort' to drop as many
|
||||||
|
search hash entries as possible and it does not
|
||||||
|
guarantee that ALL such entries will be dropped. */
|
||||||
|
|
||||||
/* If, however, bpage has been removed from LRU list
|
/* If, however, bpage has been removed from LRU list
|
||||||
to the free list then we should restart the scan.
|
to the free list then we should restart the scan.
|
||||||
bpage->state is protected by buf_pool mutex. */
|
bpage->state is protected by buf_pool mutex. */
|
||||||
if (bpage && !buf_page_in_file(bpage)) {
|
if (bpage
|
||||||
ut_a(num_entries == 0);
|
&& buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
|
||||||
goto scan_again;
|
goto scan_again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1889,6 +1893,7 @@ buf_LRU_block_remove_hashed_page(
|
|||||||
buf_pool, bpage->zip.data,
|
buf_pool, bpage->zip.data,
|
||||||
page_zip_get_size(&bpage->zip));
|
page_zip_get_size(&bpage->zip));
|
||||||
|
|
||||||
|
bpage->state = BUF_BLOCK_ZIP_FREE;
|
||||||
buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
|
buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
|
||||||
buf_pool_mutex_exit_allow(buf_pool);
|
buf_pool_mutex_exit_allow(buf_pool);
|
||||||
|
|
||||||
|
@ -236,10 +236,10 @@ UNIV_INTERN
|
|||||||
ulint
|
ulint
|
||||||
buf_read_ahead_linear(
|
buf_read_ahead_linear(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
|
||||||
ulint offset) /*!< in: page number of a page; NOTE: the current thread
|
ulint offset, /*!< in: page number; see NOTE 3 above */
|
||||||
must want access to this page (see NOTE 3 above) */
|
ibool inside_ibuf) /*!< in: TRUE if we are inside ibuf routine */
|
||||||
{
|
{
|
||||||
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
buf_pool_t* buf_pool = buf_pool_get(space, offset);
|
||||||
ib_int64_t tablespace_version;
|
ib_int64_t tablespace_version;
|
||||||
@ -429,11 +429,9 @@ buf_read_ahead_linear(
|
|||||||
|
|
||||||
/* If we got this far, read-ahead can be sensible: do it */
|
/* If we got this far, read-ahead can be sensible: do it */
|
||||||
|
|
||||||
if (ibuf_inside()) {
|
ibuf_mode = inside_ibuf
|
||||||
ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
|
? BUF_READ_IBUF_PAGES_ONLY | OS_AIO_SIMULATED_WAKE_LATER
|
||||||
} else {
|
: BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER;
|
||||||
ibuf_mode = BUF_READ_ANY_PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
@ -450,7 +448,7 @@ buf_read_ahead_linear(
|
|||||||
if (!ibuf_bitmap_page(zip_size, i)) {
|
if (!ibuf_bitmap_page(zip_size, i)) {
|
||||||
count += buf_read_page_low(
|
count += buf_read_page_low(
|
||||||
&err, FALSE,
|
&err, FALSE,
|
||||||
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
|
ibuf_mode,
|
||||||
space, zip_size, FALSE, tablespace_version, i);
|
space, zip_size, FALSE, tablespace_version, i);
|
||||||
if (err == DB_TABLESPACE_DELETED) {
|
if (err == DB_TABLESPACE_DELETED) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
@ -520,7 +518,6 @@ buf_read_ibuf_merge_pages(
|
|||||||
{
|
{
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
ut_ad(!ibuf_inside());
|
|
||||||
#ifdef UNIV_IBUF_DEBUG
|
#ifdef UNIV_IBUF_DEBUG
|
||||||
ut_a(n_stored < UNIV_PAGE_SIZE);
|
ut_a(n_stored < UNIV_PAGE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2258,10 +2258,12 @@ loop:
|
|||||||
/* Since table names in SYS_FOREIGN are stored in a case-insensitive
|
/* Since table names in SYS_FOREIGN are stored in a case-insensitive
|
||||||
order, we have to check that the table name matches also in a binary
|
order, we have to check that the table name matches also in a binary
|
||||||
string comparison. On Unix, MySQL allows table names that only differ
|
string comparison. On Unix, MySQL allows table names that only differ
|
||||||
in character case. */
|
in character case. If lower_case_table_names=2 then what is stored
|
||||||
|
may not be the same case, but the previous comparison showed that they
|
||||||
if (0 != ut_memcmp(field, table_name, len)) {
|
match with no-case. */
|
||||||
|
|
||||||
|
if ((srv_lower_case_table_names != 2)
|
||||||
|
&& (0 != ut_memcmp(field, table_name, len))) {
|
||||||
goto next_rec;
|
goto next_rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4342,8 +4342,6 @@ fil_io(
|
|||||||
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|
||||||
|| !ibuf_bitmap_page(zip_size, block_offset)
|
|| !ibuf_bitmap_page(zip_size, block_offset)
|
||||||
|| sync || is_log);
|
|| sync || is_log);
|
||||||
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|
|
||||||
|| ibuf_page(space_id, zip_size, block_offset, NULL));
|
|
||||||
# endif /* UNIV_LOG_DEBUG */
|
# endif /* UNIV_LOG_DEBUG */
|
||||||
if (sync) {
|
if (sync) {
|
||||||
mode = OS_AIO_SYNC;
|
mode = OS_AIO_SYNC;
|
||||||
|
@ -51,6 +51,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <mysql/plugin.h>
|
#include <mysql/plugin.h>
|
||||||
#include <mysql/innodb_priv.h>
|
#include <mysql/innodb_priv.h>
|
||||||
#include <mysql/psi/psi.h>
|
#include <mysql/psi/psi.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
|
||||||
/** @file ha_innodb.cc */
|
/** @file ha_innodb.cc */
|
||||||
|
|
||||||
@ -81,7 +82,6 @@ extern "C" {
|
|||||||
#include "fil0fil.h"
|
#include "fil0fil.h"
|
||||||
#include "trx0xa.h"
|
#include "trx0xa.h"
|
||||||
#include "row0merge.h"
|
#include "row0merge.h"
|
||||||
#include "thr0loc.h"
|
|
||||||
#include "dict0boot.h"
|
#include "dict0boot.h"
|
||||||
#include "ha_prototypes.h"
|
#include "ha_prototypes.h"
|
||||||
#include "ut0mem.h"
|
#include "ut0mem.h"
|
||||||
@ -279,7 +279,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
|
|||||||
{&sync_thread_mutex_key, "sync_thread_mutex", 0},
|
{&sync_thread_mutex_key, "sync_thread_mutex", 0},
|
||||||
# endif /* UNIV_SYNC_DEBUG */
|
# endif /* UNIV_SYNC_DEBUG */
|
||||||
{&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0},
|
{&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0},
|
||||||
{&thr_local_mutex_key, "thr_local_mutex", 0},
|
|
||||||
{&trx_undo_mutex_key, "trx_undo_mutex", 0}
|
{&trx_undo_mutex_key, "trx_undo_mutex", 0}
|
||||||
};
|
};
|
||||||
# endif /* UNIV_PFS_MUTEX */
|
# endif /* UNIV_PFS_MUTEX */
|
||||||
@ -1146,6 +1145,20 @@ innobase_strcasecmp(
|
|||||||
return(my_strcasecmp(system_charset_info, a, b));
|
return(my_strcasecmp(system_charset_info, a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************//**
|
||||||
|
Strip dir name from a full path name and return only the file name
|
||||||
|
@return file name or "null" if no file name */
|
||||||
|
extern "C" UNIV_INTERN
|
||||||
|
const char*
|
||||||
|
innobase_basename(
|
||||||
|
/*==============*/
|
||||||
|
const char* path_name) /*!< in: full path name */
|
||||||
|
{
|
||||||
|
const char* name = base_name(path_name);
|
||||||
|
|
||||||
|
return((name) ? name : "null");
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
Makes all characters in a NUL-terminated UTF-8 string lower case. */
|
Makes all characters in a NUL-terminated UTF-8 string lower case. */
|
||||||
extern "C" UNIV_INTERN
|
extern "C" UNIV_INTERN
|
||||||
@ -3028,7 +3041,6 @@ innobase_close_connection(
|
|||||||
|
|
||||||
innobase_rollback_trx(trx);
|
innobase_rollback_trx(trx);
|
||||||
|
|
||||||
thr_local_free(trx->mysql_thread_id);
|
|
||||||
trx_free_for_mysql(trx);
|
trx_free_for_mysql(trx);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -9263,7 +9275,8 @@ innodb_mutex_show_status(
|
|||||||
if (mutex->count_using > 0) {
|
if (mutex->count_using > 0) {
|
||||||
buf1len= my_snprintf(buf1, sizeof(buf1),
|
buf1len= my_snprintf(buf1, sizeof(buf1),
|
||||||
"%s:%s",
|
"%s:%s",
|
||||||
mutex->cmutex_name, mutex->cfile_name);
|
mutex->cmutex_name,
|
||||||
|
innobase_basename(mutex->cfile_name));
|
||||||
buf2len= my_snprintf(buf2, sizeof(buf2),
|
buf2len= my_snprintf(buf2, sizeof(buf2),
|
||||||
"count=%lu, spin_waits=%lu,"
|
"count=%lu, spin_waits=%lu,"
|
||||||
" spin_rounds=%lu, "
|
" spin_rounds=%lu, "
|
||||||
@ -9293,7 +9306,8 @@ innodb_mutex_show_status(
|
|||||||
}
|
}
|
||||||
#else /* UNIV_DEBUG */
|
#else /* UNIV_DEBUG */
|
||||||
buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
|
buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
|
||||||
mutex->cfile_name, (ulong) mutex->cline);
|
innobase_basename(mutex->cfile_name),
|
||||||
|
(ulong) mutex->cline);
|
||||||
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
|
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
|
||||||
(ulong) mutex->count_os_wait);
|
(ulong) mutex->count_os_wait);
|
||||||
|
|
||||||
@ -9309,7 +9323,8 @@ innodb_mutex_show_status(
|
|||||||
if (block_mutex) {
|
if (block_mutex) {
|
||||||
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
|
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
|
||||||
"combined %s:%lu",
|
"combined %s:%lu",
|
||||||
block_mutex->cfile_name,
|
innobase_basename(
|
||||||
|
block_mutex->cfile_name),
|
||||||
(ulong) block_mutex->cline);
|
(ulong) block_mutex->cline);
|
||||||
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
|
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
|
||||||
"os_waits=%lu",
|
"os_waits=%lu",
|
||||||
@ -9340,7 +9355,8 @@ innodb_mutex_show_status(
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf1len = my_snprintf(buf1, sizeof buf1, "%s:%lu",
|
buf1len = my_snprintf(buf1, sizeof buf1, "%s:%lu",
|
||||||
lock->cfile_name, (ulong) lock->cline);
|
innobase_basename(lock->cfile_name),
|
||||||
|
(ulong) lock->cline);
|
||||||
buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
|
buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
|
||||||
(ulong) lock->count_os_wait);
|
(ulong) lock->count_os_wait);
|
||||||
|
|
||||||
@ -9355,7 +9371,8 @@ innodb_mutex_show_status(
|
|||||||
if (block_lock) {
|
if (block_lock) {
|
||||||
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
|
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
|
||||||
"combined %s:%lu",
|
"combined %s:%lu",
|
||||||
block_lock->cfile_name,
|
innobase_basename(
|
||||||
|
block_lock->cfile_name),
|
||||||
(ulong) block_lock->cline);
|
(ulong) block_lock->cline);
|
||||||
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
|
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
|
||||||
"os_waits=%lu",
|
"os_waits=%lu",
|
||||||
@ -11359,7 +11376,7 @@ mysql_declare_plugin(innobase)
|
|||||||
MYSQL_STORAGE_ENGINE_PLUGIN,
|
MYSQL_STORAGE_ENGINE_PLUGIN,
|
||||||
&innobase_storage_engine,
|
&innobase_storage_engine,
|
||||||
innobase_hton_name,
|
innobase_hton_name,
|
||||||
"Innobase Oy",
|
plugin_author,
|
||||||
"Supports transactions, row-level locking, and foreign keys",
|
"Supports transactions, row-level locking, and foreign keys",
|
||||||
PLUGIN_LICENSE_GPL,
|
PLUGIN_LICENSE_GPL,
|
||||||
innobase_init, /* Plugin Init */
|
innobase_init, /* Plugin Init */
|
||||||
|
@ -47,8 +47,6 @@ extern "C" {
|
|||||||
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
|
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char plugin_author[] = "Innobase Oy";
|
|
||||||
|
|
||||||
#define OK(expr) \
|
#define OK(expr) \
|
||||||
if ((expr) != 0) { \
|
if ((expr) != 0) { \
|
||||||
DBUG_RETURN(1); \
|
DBUG_RETURN(1); \
|
||||||
@ -1059,7 +1057,7 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
|
|||||||
|
|
||||||
/* plugin author (for SHOW PLUGINS) */
|
/* plugin author (for SHOW PLUGINS) */
|
||||||
/* const char* */
|
/* const char* */
|
||||||
STRUCT_FLD(author, "Innobase Oy"),
|
STRUCT_FLD(author, plugin_author),
|
||||||
|
|
||||||
/* general descriptive text (for SHOW PLUGINS) */
|
/* general descriptive text (for SHOW PLUGINS) */
|
||||||
/* const char* */
|
/* const char* */
|
||||||
|
@ -26,6 +26,8 @@ Created July 18, 2007 Vasil Dimov
|
|||||||
#ifndef i_s_h
|
#ifndef i_s_h
|
||||||
#define i_s_h
|
#define i_s_h
|
||||||
|
|
||||||
|
const char plugin_author[] = "Oracle Corporation";
|
||||||
|
|
||||||
extern struct st_mysql_plugin i_s_innodb_trx;
|
extern struct st_mysql_plugin i_s_innodb_trx;
|
||||||
extern struct st_mysql_plugin i_s_innodb_locks;
|
extern struct st_mysql_plugin i_s_innodb_locks;
|
||||||
extern struct st_mysql_plugin i_s_innodb_lock_waits;
|
extern struct st_mysql_plugin i_s_innodb_lock_waits;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -150,7 +150,7 @@ UNIV_INLINE
|
|||||||
ulint
|
ulint
|
||||||
btr_pcur_get_up_match(
|
btr_pcur_get_up_match(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
|
const btr_pcur_t* cursor); /*!< in: persistent cursor */
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Gets the low_match value for a pcur after a search.
|
Gets the low_match value for a pcur after a search.
|
||||||
@return number of matched fields at the cursor or to the right if
|
@return number of matched fields at the cursor or to the right if
|
||||||
@ -159,7 +159,7 @@ UNIV_INLINE
|
|||||||
ulint
|
ulint
|
||||||
btr_pcur_get_low_match(
|
btr_pcur_get_low_match(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
|
const btr_pcur_t* cursor); /*!< in: persistent cursor */
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
|
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
|
||||||
user record satisfying the search condition, in the case PAGE_CUR_L or
|
user record satisfying the search condition, in the case PAGE_CUR_L or
|
||||||
@ -264,22 +264,6 @@ ulint
|
|||||||
btr_pcur_get_rel_pos(
|
btr_pcur_get_rel_pos(
|
||||||
/*=================*/
|
/*=================*/
|
||||||
const btr_pcur_t* cursor);/*!< in: persistent cursor */
|
const btr_pcur_t* cursor);/*!< in: persistent cursor */
|
||||||
/*********************************************************//**
|
|
||||||
Sets the mtr field for a pcur. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
btr_pcur_set_mtr(
|
|
||||||
/*=============*/
|
|
||||||
btr_pcur_t* cursor, /*!< in: persistent cursor */
|
|
||||||
mtr_t* mtr); /*!< in, own: mtr */
|
|
||||||
/*********************************************************//**
|
|
||||||
Gets the mtr field for a pcur.
|
|
||||||
@return mtr */
|
|
||||||
UNIV_INLINE
|
|
||||||
mtr_t*
|
|
||||||
btr_pcur_get_mtr(
|
|
||||||
/*=============*/
|
|
||||||
btr_pcur_t* cursor); /*!< in: persistent cursor */
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
|
||||||
that is, the cursor becomes detached. If there have been modifications
|
that is, the cursor becomes detached. If there have been modifications
|
||||||
@ -387,10 +371,6 @@ page_cur_t*
|
|||||||
btr_pcur_get_page_cur(
|
btr_pcur_get_page_cur(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
const btr_pcur_t* cursor); /*!< in: persistent cursor */
|
const btr_pcur_t* cursor); /*!< in: persistent cursor */
|
||||||
#else /* UNIV_DEBUG */
|
|
||||||
# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
|
|
||||||
# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Returns the page of a persistent cursor.
|
Returns the page of a persistent cursor.
|
||||||
@return pointer to the page */
|
@return pointer to the page */
|
||||||
@ -398,7 +378,7 @@ UNIV_INLINE
|
|||||||
page_t*
|
page_t*
|
||||||
btr_pcur_get_page(
|
btr_pcur_get_page(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
btr_pcur_t* cursor);/*!< in: persistent cursor */
|
const btr_pcur_t* cursor);/*!< in: persistent cursor */
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Returns the buffer block of a persistent cursor.
|
Returns the buffer block of a persistent cursor.
|
||||||
@return pointer to the block */
|
@return pointer to the block */
|
||||||
@ -406,7 +386,7 @@ UNIV_INLINE
|
|||||||
buf_block_t*
|
buf_block_t*
|
||||||
btr_pcur_get_block(
|
btr_pcur_get_block(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
btr_pcur_t* cursor);/*!< in: persistent cursor */
|
const btr_pcur_t* cursor);/*!< in: persistent cursor */
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Returns the record of a persistent cursor.
|
Returns the record of a persistent cursor.
|
||||||
@return pointer to the record */
|
@return pointer to the record */
|
||||||
@ -414,7 +394,14 @@ UNIV_INLINE
|
|||||||
rec_t*
|
rec_t*
|
||||||
btr_pcur_get_rec(
|
btr_pcur_get_rec(
|
||||||
/*=============*/
|
/*=============*/
|
||||||
btr_pcur_t* cursor);/*!< in: persistent cursor */
|
const btr_pcur_t* cursor);/*!< in: persistent cursor */
|
||||||
|
#else /* UNIV_DEBUG */
|
||||||
|
# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
|
||||||
|
# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
|
||||||
|
# define btr_pcur_get_page(cursor) ((cursor)->btr_cur.page_cur.block->frame)
|
||||||
|
# define btr_pcur_get_block(cursor) ((cursor)->btr_cur.page_cur.block)
|
||||||
|
# define btr_pcur_get_rec(cursor) ((cursor)->btr_cur.page_cur.rec)
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Checks if the persistent cursor is on a user record. */
|
Checks if the persistent cursor is on a user record. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
@ -517,9 +504,6 @@ struct btr_pcur_struct{
|
|||||||
/* NOTE that the following fields may possess dynamically allocated
|
/* NOTE that the following fields may possess dynamically allocated
|
||||||
memory which should be freed if not needed anymore! */
|
memory which should be freed if not needed anymore! */
|
||||||
|
|
||||||
mtr_t* mtr; /*!< NULL, or this field may contain
|
|
||||||
a mini-transaction which holds the
|
|
||||||
latch on the cursor page */
|
|
||||||
byte* old_rec_buf; /*!< NULL, or a dynamically allocated
|
byte* old_rec_buf; /*!< NULL, or a dynamically allocated
|
||||||
buffer for old_rec */
|
buffer for old_rec */
|
||||||
ulint buf_size; /*!< old_rec_buf size if old_rec_buf
|
ulint buf_size; /*!< old_rec_buf size if old_rec_buf
|
||||||
|
@ -42,34 +42,6 @@ btr_pcur_get_rel_pos(
|
|||||||
return(cursor->rel_pos);
|
return(cursor->rel_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************//**
|
|
||||||
Sets the mtr field for a pcur. */
|
|
||||||
UNIV_INLINE
|
|
||||||
void
|
|
||||||
btr_pcur_set_mtr(
|
|
||||||
/*=============*/
|
|
||||||
btr_pcur_t* cursor, /*!< in: persistent cursor */
|
|
||||||
mtr_t* mtr) /*!< in, own: mtr */
|
|
||||||
{
|
|
||||||
ut_ad(cursor);
|
|
||||||
|
|
||||||
cursor->mtr = mtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************//**
|
|
||||||
Gets the mtr field for a pcur.
|
|
||||||
@return mtr */
|
|
||||||
UNIV_INLINE
|
|
||||||
mtr_t*
|
|
||||||
btr_pcur_get_mtr(
|
|
||||||
/*=============*/
|
|
||||||
btr_pcur_t* cursor) /*!< in: persistent cursor */
|
|
||||||
{
|
|
||||||
ut_ad(cursor);
|
|
||||||
|
|
||||||
return(cursor->mtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Returns the btr cursor component of a persistent cursor.
|
Returns the btr cursor component of a persistent cursor.
|
||||||
@ -95,7 +67,7 @@ btr_pcur_get_page_cur(
|
|||||||
{
|
{
|
||||||
return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
|
return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Returns the page of a persistent cursor.
|
Returns the page of a persistent cursor.
|
||||||
@return pointer to the page */
|
@return pointer to the page */
|
||||||
@ -103,7 +75,7 @@ UNIV_INLINE
|
|||||||
page_t*
|
page_t*
|
||||||
btr_pcur_get_page(
|
btr_pcur_get_page(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
btr_pcur_t* cursor) /*!< in: persistent cursor */
|
const btr_pcur_t* cursor) /*!< in: persistent cursor */
|
||||||
{
|
{
|
||||||
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||||
|
|
||||||
@ -117,7 +89,7 @@ UNIV_INLINE
|
|||||||
buf_block_t*
|
buf_block_t*
|
||||||
btr_pcur_get_block(
|
btr_pcur_get_block(
|
||||||
/*===============*/
|
/*===============*/
|
||||||
btr_pcur_t* cursor) /*!< in: persistent cursor */
|
const btr_pcur_t* cursor) /*!< in: persistent cursor */
|
||||||
{
|
{
|
||||||
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||||
|
|
||||||
@ -131,13 +103,14 @@ UNIV_INLINE
|
|||||||
rec_t*
|
rec_t*
|
||||||
btr_pcur_get_rec(
|
btr_pcur_get_rec(
|
||||||
/*=============*/
|
/*=============*/
|
||||||
btr_pcur_t* cursor) /*!< in: persistent cursor */
|
const btr_pcur_t* cursor) /*!< in: persistent cursor */
|
||||||
{
|
{
|
||||||
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||||
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
|
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
|
||||||
|
|
||||||
return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
|
return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Gets the up_match value for a pcur after a search.
|
Gets the up_match value for a pcur after a search.
|
||||||
@ -147,9 +120,9 @@ UNIV_INLINE
|
|||||||
ulint
|
ulint
|
||||||
btr_pcur_get_up_match(
|
btr_pcur_get_up_match(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
|
const btr_pcur_t* cursor) /*!< in: persistent cursor */
|
||||||
{
|
{
|
||||||
btr_cur_t* btr_cursor;
|
const btr_cur_t* btr_cursor;
|
||||||
|
|
||||||
ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
|
ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
|
||||||
|| (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
|
|| (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
|
||||||
@ -169,9 +142,9 @@ UNIV_INLINE
|
|||||||
ulint
|
ulint
|
||||||
btr_pcur_get_low_match(
|
btr_pcur_get_low_match(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
|
const btr_pcur_t* cursor) /*!< in: persistent cursor */
|
||||||
{
|
{
|
||||||
btr_cur_t* btr_cursor;
|
const btr_cur_t* btr_cursor;
|
||||||
|
|
||||||
ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
|
ut_ad((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
|
||||||
|| (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
|
|| (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
|
||||||
|
@ -41,6 +41,8 @@ Created 11/5/1995 Heikki Tuuri
|
|||||||
/* @{ */
|
/* @{ */
|
||||||
#define BUF_GET 10 /*!< get always */
|
#define BUF_GET 10 /*!< get always */
|
||||||
#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
|
#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
|
||||||
|
#define BUF_PEEK_IF_IN_POOL 12 /*!< get if in pool, do not make
|
||||||
|
the block young in the LRU list */
|
||||||
#define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but
|
#define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but
|
||||||
set no latch; we have
|
set no latch; we have
|
||||||
separated this case, because
|
separated this case, because
|
||||||
@ -396,7 +398,7 @@ buf_page_get_gen(
|
|||||||
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
|
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
|
||||||
buf_block_t* guess, /*!< in: guessed block or NULL */
|
buf_block_t* guess, /*!< in: guessed block or NULL */
|
||||||
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
|
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
|
||||||
BUF_GET_NO_LATCH or
|
BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH or
|
||||||
BUF_GET_IF_IN_POOL_OR_WATCH */
|
BUF_GET_IF_IN_POOL_OR_WATCH */
|
||||||
const char* file, /*!< in: file name */
|
const char* file, /*!< in: file name */
|
||||||
ulint line, /*!< in: line where called */
|
ulint line, /*!< in: line where called */
|
||||||
|
@ -70,10 +70,10 @@ UNIV_INTERN
|
|||||||
ulint
|
ulint
|
||||||
buf_read_ahead_linear(
|
buf_read_ahead_linear(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
ulint space, /*!< in: space id */
|
ulint space, /*!< in: space id */
|
||||||
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
|
ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
|
||||||
ulint offset);/*!< in: page number of a page; NOTE: the current thread
|
ulint offset, /*!< in: page number; see NOTE 3 above */
|
||||||
must want access to this page (see NOTE 3 above) */
|
ibool inside_ibuf); /*!< in: TRUE if we are inside ibuf routine */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Issues read requests for pages which the ibuf module wants to read in, in
|
Issues read requests for pages which the ibuf module wants to read in, in
|
||||||
order to contract the insert buffer tree. Technically, this function is like
|
order to contract the insert buffer tree. Technically, this function is like
|
||||||
|
@ -173,6 +173,15 @@ innobase_strcasecmp(
|
|||||||
const char* a, /*!< in: first string to compare */
|
const char* a, /*!< in: first string to compare */
|
||||||
const char* b); /*!< in: second string to compare */
|
const char* b); /*!< in: second string to compare */
|
||||||
|
|
||||||
|
/******************************************************************//**
|
||||||
|
Strip dir name from a full path name and return only its file name.
|
||||||
|
@return file name or "null" if no file name */
|
||||||
|
UNIV_INTERN
|
||||||
|
const char*
|
||||||
|
innobase_basename(
|
||||||
|
/*==============*/
|
||||||
|
const char* path_name); /*!< in: full path name */
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
Returns true if the thread is executing a SELECT statement.
|
Returns true if the thread is executing a SELECT statement.
|
||||||
@return true if thd is executing SELECT */
|
@return true if thd is executing SELECT */
|
||||||
|
@ -104,6 +104,22 @@ UNIV_INTERN
|
|||||||
void
|
void
|
||||||
ibuf_update_max_tablespace_id(void);
|
ibuf_update_max_tablespace_id(void);
|
||||||
/*===============================*/
|
/*===============================*/
|
||||||
|
/***************************************************************//**
|
||||||
|
Starts an insert buffer mini-transaction. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
ibuf_mtr_start(
|
||||||
|
/*===========*/
|
||||||
|
mtr_t* mtr) /*!< out: mini-transaction */
|
||||||
|
__attribute__((nonnull));
|
||||||
|
/***************************************************************//**
|
||||||
|
Commits an insert buffer mini-transaction. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
ibuf_mtr_commit(
|
||||||
|
/*============*/
|
||||||
|
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||||
|
__attribute__((nonnull));
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Initializes an ibuf bitmap page. */
|
Initializes an ibuf bitmap page. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
@ -224,10 +240,12 @@ routine.
|
|||||||
For instance, a read-ahead of non-ibuf pages is forbidden by threads
|
For instance, a read-ahead of non-ibuf pages is forbidden by threads
|
||||||
that are executing an insert buffer routine.
|
that are executing an insert buffer routine.
|
||||||
@return TRUE if inside an insert buffer routine */
|
@return TRUE if inside an insert buffer routine */
|
||||||
UNIV_INTERN
|
UNIV_INLINE
|
||||||
ibool
|
ibool
|
||||||
ibuf_inside(void);
|
ibuf_inside(
|
||||||
/*=============*/
|
/*========*/
|
||||||
|
const mtr_t* mtr) /*!< in: mini-transaction */
|
||||||
|
__attribute__((nonnull, pure));
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Checks if a page address is an ibuf bitmap page (level 3 page) address.
|
Checks if a page address is an ibuf bitmap page (level 3 page) address.
|
||||||
@return TRUE if a bitmap page */
|
@return TRUE if a bitmap page */
|
||||||
|
@ -37,6 +37,30 @@ buffer inserts to this page. If there is this much of free space, the
|
|||||||
corresponding bits are set in the ibuf bitmap. */
|
corresponding bits are set in the ibuf bitmap. */
|
||||||
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
|
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
|
||||||
|
|
||||||
|
/***************************************************************//**
|
||||||
|
Starts an insert buffer mini-transaction. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
ibuf_mtr_start(
|
||||||
|
/*===========*/
|
||||||
|
mtr_t* mtr) /*!< out: mini-transaction */
|
||||||
|
{
|
||||||
|
mtr_start(mtr);
|
||||||
|
mtr->inside_ibuf = TRUE;
|
||||||
|
}
|
||||||
|
/***************************************************************//**
|
||||||
|
Commits an insert buffer mini-transaction. */
|
||||||
|
UNIV_INLINE
|
||||||
|
void
|
||||||
|
ibuf_mtr_commit(
|
||||||
|
/*============*/
|
||||||
|
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||||
|
{
|
||||||
|
ut_ad(mtr->inside_ibuf);
|
||||||
|
ut_d(mtr->inside_ibuf = FALSE);
|
||||||
|
mtr_commit(mtr);
|
||||||
|
}
|
||||||
|
|
||||||
/** Insert buffer struct */
|
/** Insert buffer struct */
|
||||||
struct ibuf_struct{
|
struct ibuf_struct{
|
||||||
ulint size; /*!< current size of the ibuf index
|
ulint size; /*!< current size of the ibuf index
|
||||||
@ -120,6 +144,22 @@ ibuf_should_try(
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************//**
|
||||||
|
Returns TRUE if the current OS thread is performing an insert buffer
|
||||||
|
routine.
|
||||||
|
|
||||||
|
For instance, a read-ahead of non-ibuf pages is forbidden by threads
|
||||||
|
that are executing an insert buffer routine.
|
||||||
|
@return TRUE if inside an insert buffer routine */
|
||||||
|
UNIV_INLINE
|
||||||
|
ibool
|
||||||
|
ibuf_inside(
|
||||||
|
/*========*/
|
||||||
|
const mtr_t* mtr) /*!< in: mini-transaction */
|
||||||
|
{
|
||||||
|
return(mtr->inside_ibuf);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Checks if a page address is an ibuf bitmap page address.
|
Checks if a page address is an ibuf bitmap page address.
|
||||||
@return TRUE if a bitmap page */
|
@return TRUE if a bitmap page */
|
||||||
|
@ -190,21 +190,21 @@ functions). The page number parameter was originally written as 0. @{ */
|
|||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Starts a mini-transaction and creates a mini-transaction handle
|
Starts a mini-transaction. */
|
||||||
and buffer in the memory buffer given by the caller.
|
|
||||||
@return mtr buffer which also acts as the mtr handle */
|
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
mtr_t*
|
void
|
||||||
mtr_start(
|
mtr_start(
|
||||||
/*======*/
|
/*======*/
|
||||||
mtr_t* mtr); /*!< in: memory buffer for the mtr buffer */
|
mtr_t* mtr) /*!< out: mini-transaction */
|
||||||
|
__attribute__((nonnull));
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Commits a mini-transaction. */
|
Commits a mini-transaction. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
mtr_commit(
|
mtr_commit(
|
||||||
/*=======*/
|
/*=======*/
|
||||||
mtr_t* mtr); /*!< in: mini-transaction */
|
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||||
|
__attribute__((nonnull));
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Sets and returns a savepoint in mtr.
|
Sets and returns a savepoint in mtr.
|
||||||
@return savepoint */
|
@return savepoint */
|
||||||
@ -378,6 +378,8 @@ struct mtr_struct{
|
|||||||
#endif
|
#endif
|
||||||
dyn_array_t memo; /*!< memo stack for locks etc. */
|
dyn_array_t memo; /*!< memo stack for locks etc. */
|
||||||
dyn_array_t log; /*!< mini-transaction log */
|
dyn_array_t log; /*!< mini-transaction log */
|
||||||
|
ibool inside_ibuf;
|
||||||
|
/*!< TRUE if inside ibuf changes */
|
||||||
ibool modifications;
|
ibool modifications;
|
||||||
/* TRUE if the mtr made modifications to
|
/* TRUE if the mtr made modifications to
|
||||||
buffer pool pages */
|
buffer pool pages */
|
||||||
|
@ -30,26 +30,23 @@ Created 11/26/1995 Heikki Tuuri
|
|||||||
#include "mach0data.h"
|
#include "mach0data.h"
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Starts a mini-transaction and creates a mini-transaction handle
|
Starts a mini-transaction. */
|
||||||
and a buffer in the memory buffer given by the caller.
|
|
||||||
@return mtr buffer which also acts as the mtr handle */
|
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
mtr_t*
|
void
|
||||||
mtr_start(
|
mtr_start(
|
||||||
/*======*/
|
/*======*/
|
||||||
mtr_t* mtr) /*!< in: memory buffer for the mtr buffer */
|
mtr_t* mtr) /*!< out: mini-transaction */
|
||||||
{
|
{
|
||||||
dyn_array_create(&(mtr->memo));
|
dyn_array_create(&(mtr->memo));
|
||||||
dyn_array_create(&(mtr->log));
|
dyn_array_create(&(mtr->log));
|
||||||
|
|
||||||
mtr->log_mode = MTR_LOG_ALL;
|
mtr->log_mode = MTR_LOG_ALL;
|
||||||
mtr->modifications = FALSE;
|
mtr->modifications = FALSE;
|
||||||
|
mtr->inside_ibuf = FALSE;
|
||||||
mtr->n_log_recs = 0;
|
mtr->n_log_recs = 0;
|
||||||
|
|
||||||
ut_d(mtr->state = MTR_ACTIVE);
|
ut_d(mtr->state = MTR_ACTIVE);
|
||||||
ut_d(mtr->magic_n = MTR_MAGIC_N);
|
ut_d(mtr->magic_n = MTR_MAGIC_N);
|
||||||
|
|
||||||
return(mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************//**
|
/***************************************************//**
|
||||||
|
@ -952,7 +952,7 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_rec_validate(
|
page_rec_validate(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
rec_t* rec, /*!< in: physical record */
|
const rec_t* rec, /*!< in: physical record */
|
||||||
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Checks that the first directory slot points to the infimum record and
|
Checks that the first directory slot points to the infimum record and
|
||||||
@ -972,7 +972,7 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_simple_validate_old(
|
page_simple_validate_old(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
page_t* page); /*!< in: old-style index page */
|
const page_t* page); /*!< in: index page in ROW_FORMAT=REDUNDANT */
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
This function checks the consistency of an index page when we do not
|
This function checks the consistency of an index page when we do not
|
||||||
know the index. This is also resilient so that this should never crash
|
know the index. This is also resilient so that this should never crash
|
||||||
@ -982,7 +982,7 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_simple_validate_new(
|
page_simple_validate_new(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
page_t* block); /*!< in: new-style index page */
|
const page_t* page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
This function checks the consistency of an index page.
|
This function checks the consistency of an index page.
|
||||||
@return TRUE if ok */
|
@return TRUE if ok */
|
||||||
@ -990,7 +990,7 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_validate(
|
page_validate(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
page_t* page, /*!< in: index page */
|
const page_t* page, /*!< in: index page */
|
||||||
dict_index_t* index); /*!< in: data dictionary index containing
|
dict_index_t* index); /*!< in: data dictionary index containing
|
||||||
the page record type definition */
|
the page record type definition */
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
|
@ -600,6 +600,7 @@ ulint
|
|||||||
rec_offs_size(
|
rec_offs_size(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Returns a pointer to the start of the record.
|
Returns a pointer to the start of the record.
|
||||||
@return pointer to start */
|
@return pointer to start */
|
||||||
@ -607,7 +608,7 @@ UNIV_INLINE
|
|||||||
byte*
|
byte*
|
||||||
rec_get_start(
|
rec_get_start(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
rec_t* rec, /*!< in: pointer to record */
|
const rec_t* rec, /*!< in: pointer to record */
|
||||||
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Returns a pointer to the end of the record.
|
Returns a pointer to the end of the record.
|
||||||
@ -616,8 +617,12 @@ UNIV_INLINE
|
|||||||
byte*
|
byte*
|
||||||
rec_get_end(
|
rec_get_end(
|
||||||
/*========*/
|
/*========*/
|
||||||
rec_t* rec, /*!< in: pointer to record */
|
const rec_t* rec, /*!< in: pointer to record */
|
||||||
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
||||||
|
#else /* UNIV_DEBUG */
|
||||||
|
# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets))
|
||||||
|
# define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets))
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Copies a physical record to a buffer.
|
Copies a physical record to a buffer.
|
||||||
@return pointer to the origin of the copy */
|
@return pointer to the origin of the copy */
|
||||||
|
@ -1462,6 +1462,7 @@ rec_offs_size(
|
|||||||
return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
|
return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Returns a pointer to the end of the record.
|
Returns a pointer to the end of the record.
|
||||||
@return pointer to end */
|
@return pointer to end */
|
||||||
@ -1469,11 +1470,11 @@ UNIV_INLINE
|
|||||||
byte*
|
byte*
|
||||||
rec_get_end(
|
rec_get_end(
|
||||||
/*========*/
|
/*========*/
|
||||||
rec_t* rec, /*!< in: pointer to record */
|
const rec_t* rec, /*!< in: pointer to record */
|
||||||
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
||||||
{
|
{
|
||||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||||
return(rec + rec_offs_data_size(offsets));
|
return((rec_t*) rec + rec_offs_data_size(offsets));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
@ -1483,12 +1484,13 @@ UNIV_INLINE
|
|||||||
byte*
|
byte*
|
||||||
rec_get_start(
|
rec_get_start(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
rec_t* rec, /*!< in: pointer to record */
|
const rec_t* rec, /*!< in: pointer to record */
|
||||||
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
||||||
{
|
{
|
||||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||||
return(rec - rec_offs_extra_size(offsets));
|
return((rec_t*) rec - rec_offs_extra_size(offsets));
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Copies a physical record to a buffer.
|
Copies a physical record to a buffer.
|
||||||
|
@ -442,16 +442,8 @@ typedef enum srv_stats_method_name_enum srv_stats_method_name_t;
|
|||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
/** Types of threads existing in the system. */
|
/** Types of threads existing in the system. */
|
||||||
enum srv_thread_type {
|
enum srv_thread_type {
|
||||||
SRV_COM = 1, /**< threads serving communication and queries */
|
SRV_WORKER = 0, /**< threads serving parallelized queries and
|
||||||
SRV_CONSOLE, /**< thread serving console */
|
|
||||||
SRV_WORKER, /**< threads serving parallelized queries and
|
|
||||||
queries released from lock wait */
|
queries released from lock wait */
|
||||||
#if 0
|
|
||||||
/* Utility threads */
|
|
||||||
SRV_BUFFER, /**< thread flushing dirty buffer blocks */
|
|
||||||
SRV_RECOVERY, /**< threads finishing a recovery */
|
|
||||||
SRV_INSERT, /**< thread flushing the insert buffer to disk */
|
|
||||||
#endif
|
|
||||||
SRV_MASTER /**< the master thread, (whose type number must
|
SRV_MASTER /**< the master thread, (whose type number must
|
||||||
be biggest) */
|
be biggest) */
|
||||||
};
|
};
|
||||||
@ -490,13 +482,6 @@ ulint
|
|||||||
srv_get_n_threads(void);
|
srv_get_n_threads(void);
|
||||||
/*===================*/
|
/*===================*/
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Returns the calling thread type.
|
|
||||||
@return SRV_COM, ... */
|
|
||||||
|
|
||||||
enum srv_thread_type
|
|
||||||
srv_get_thread_type(void);
|
|
||||||
/*=====================*/
|
|
||||||
/*********************************************************************//**
|
|
||||||
Check whether thread type has reserved a slot.
|
Check whether thread type has reserved a slot.
|
||||||
@return slot number or UNDEFINED if not found*/
|
@return slot number or UNDEFINED if not found*/
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
|
@ -115,8 +115,11 @@ Prints warnings of long semaphore waits to stderr.
|
|||||||
@return TRUE if fatal semaphore wait threshold was exceeded */
|
@return TRUE if fatal semaphore wait threshold was exceeded */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ibool
|
ibool
|
||||||
sync_array_print_long_waits(void);
|
sync_array_print_long_waits(
|
||||||
/*=============================*/
|
/*========================*/
|
||||||
|
os_thread_id_t* waiter, /*!< out: longest waiting thread */
|
||||||
|
const void** sema) /*!< out: longest-waited-for semaphore */
|
||||||
|
__attribute__((nonnull));
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Validates the integrity of the wait array. Checks
|
Validates the integrity of the wait array. Checks
|
||||||
that the number of reserved cells equals the count variable. */
|
that the number of reserved cells equals the count variable. */
|
||||||
|
@ -110,7 +110,6 @@ extern mysql_pfs_key_t syn_arr_mutex_key;
|
|||||||
extern mysql_pfs_key_t sync_thread_mutex_key;
|
extern mysql_pfs_key_t sync_thread_mutex_key;
|
||||||
# endif /* UNIV_SYNC_DEBUG */
|
# endif /* UNIV_SYNC_DEBUG */
|
||||||
extern mysql_pfs_key_t trx_doublewrite_mutex_key;
|
extern mysql_pfs_key_t trx_doublewrite_mutex_key;
|
||||||
extern mysql_pfs_key_t thr_local_mutex_key;
|
|
||||||
extern mysql_pfs_key_t trx_undo_mutex_key;
|
extern mysql_pfs_key_t trx_undo_mutex_key;
|
||||||
#endif /* UNIV_PFS_MUTEX */
|
#endif /* UNIV_PFS_MUTEX */
|
||||||
|
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 1995, 2009, Innobase Oy. 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 the Free Software
|
|
||||||
Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
||||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**************************************************//**
|
|
||||||
@file include/thr0loc.h
|
|
||||||
The thread local storage
|
|
||||||
|
|
||||||
Created 10/5/1995 Heikki Tuuri
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
/* This module implements storage private to each thread,
|
|
||||||
a capability useful in some situations like storing the
|
|
||||||
OS handle to the current thread, or its priority. */
|
|
||||||
|
|
||||||
#ifndef thr0loc_h
|
|
||||||
#define thr0loc_h
|
|
||||||
|
|
||||||
#include "univ.i"
|
|
||||||
#include "os0thread.h"
|
|
||||||
|
|
||||||
/****************************************************************//**
|
|
||||||
Initializes the thread local storage module. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_init(void);
|
|
||||||
/*================*/
|
|
||||||
/****************************************************************//**
|
|
||||||
Close the thread local storage module. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_close(void);
|
|
||||||
/*=================*/
|
|
||||||
/*******************************************************************//**
|
|
||||||
Creates a local storage struct for the calling new thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_create(void);
|
|
||||||
/*==================*/
|
|
||||||
/*******************************************************************//**
|
|
||||||
Frees the local storage struct for the specified thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_free(
|
|
||||||
/*===========*/
|
|
||||||
os_thread_id_t id); /*!< in: thread id */
|
|
||||||
/*******************************************************************//**
|
|
||||||
Gets the slot number in the thread table of a thread.
|
|
||||||
@return slot number */
|
|
||||||
UNIV_INTERN
|
|
||||||
ulint
|
|
||||||
thr_local_get_slot_no(
|
|
||||||
/*==================*/
|
|
||||||
os_thread_id_t id); /*!< in: thread id of the thread */
|
|
||||||
/*******************************************************************//**
|
|
||||||
Sets in the local storage the slot number in the thread table of a thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_set_slot_no(
|
|
||||||
/*==================*/
|
|
||||||
os_thread_id_t id, /*!< in: thread id of the thread */
|
|
||||||
ulint slot_no);/*!< in: slot number */
|
|
||||||
/*******************************************************************//**
|
|
||||||
Returns pointer to the 'in_ibuf' field within the current thread local
|
|
||||||
storage.
|
|
||||||
@return pointer to the in_ibuf field */
|
|
||||||
UNIV_INTERN
|
|
||||||
ibool*
|
|
||||||
thr_local_get_in_ibuf_field(void);
|
|
||||||
/*=============================*/
|
|
||||||
|
|
||||||
#ifndef UNIV_NONINL
|
|
||||||
#include "thr0loc.ic"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 1995, 2009, Innobase Oy. 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 the Free Software
|
|
||||||
Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
||||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**************************************************//**
|
|
||||||
@file include/thr0loc.ic
|
|
||||||
Thread local storage
|
|
||||||
|
|
||||||
Created 10/4/1995 Heikki Tuuri
|
|
||||||
*******************************************************/
|
|
@ -24,6 +24,8 @@ but is included in mem0mem.* !
|
|||||||
Created 6/9/1994 Heikki Tuuri
|
Created 6/9/1994 Heikki Tuuri
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
#ifdef UNIV_MEM_DEBUG
|
#ifdef UNIV_MEM_DEBUG
|
||||||
# ifndef UNIV_HOTBACKUP
|
# ifndef UNIV_HOTBACKUP
|
||||||
/* The mutex which protects in the debug version the hash table
|
/* The mutex which protects in the debug version the hash table
|
||||||
@ -400,7 +402,7 @@ mem_hash_remove(
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Memory heap or buffer freed in %s line %lu"
|
"Memory heap or buffer freed in %s line %lu"
|
||||||
" did not exist.\n",
|
" did not exist.\n",
|
||||||
file_name, (ulong) line);
|
innobase_basename(file_name), (ulong) line);
|
||||||
ut_error;
|
ut_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,8 +421,9 @@ mem_hash_remove(
|
|||||||
"in %s line %lu and tried to free in %s line %lu.\n"
|
"in %s line %lu and tried to free in %s line %lu.\n"
|
||||||
"Hex dump of 400 bytes around memory heap"
|
"Hex dump of 400 bytes around memory heap"
|
||||||
" first block start:\n",
|
" first block start:\n",
|
||||||
node->nth_heap, node->file_name, (ulong) node->line,
|
node->nth_heap,
|
||||||
file_name, (ulong) line);
|
innobase_basename(node->file_name), (ulong) node->line,
|
||||||
|
innobase_basename(file_name), (ulong) line);
|
||||||
ut_print_buf(stderr, (byte*)node->heap - 200, 400);
|
ut_print_buf(stderr, (byte*)node->heap - 200, 400);
|
||||||
fputs("\nDump of the mem heap:\n", stderr);
|
fputs("\nDump of the mem heap:\n", stderr);
|
||||||
mem_heap_validate_or_print(node->heap, NULL, TRUE, &error,
|
mem_heap_validate_or_print(node->heap, NULL, TRUE, &error,
|
||||||
@ -763,7 +766,8 @@ mem_validate_no_assert(void)
|
|||||||
"Inconsistency in memory heap"
|
"Inconsistency in memory heap"
|
||||||
" or buffer created\n"
|
" or buffer created\n"
|
||||||
"in %s line %lu.\n",
|
"in %s line %lu.\n",
|
||||||
node->file_name, node->line);
|
innobase_basename(node->file_name),
|
||||||
|
node->line);
|
||||||
|
|
||||||
mutex_exit(&mem_hash_mutex);
|
mutex_exit(&mem_hash_mutex);
|
||||||
|
|
||||||
@ -989,7 +993,8 @@ mem_print_info_low(
|
|||||||
fprintf(outfile,
|
fprintf(outfile,
|
||||||
"%lu: file %s line %lu of size %lu phys.size %lu"
|
"%lu: file %s line %lu of size %lu phys.size %lu"
|
||||||
" with %lu blocks, type %lu\n",
|
" with %lu blocks, type %lu\n",
|
||||||
node->nth_heap, node->file_name, node->line,
|
node->nth_heap,
|
||||||
|
innobase_basename(node->file_name), node->line,
|
||||||
allocated_mem, ph_size, n_blocks,
|
allocated_mem, ph_size, n_blocks,
|
||||||
(node->heap)->type);
|
(node->heap)->type);
|
||||||
next_heap:
|
next_heap:
|
||||||
|
@ -251,6 +251,7 @@ mtr_commit(
|
|||||||
ut_ad(mtr);
|
ut_ad(mtr);
|
||||||
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
||||||
ut_ad(mtr->state == MTR_ACTIVE);
|
ut_ad(mtr->state == MTR_ACTIVE);
|
||||||
|
ut_ad(!mtr->inside_ibuf);
|
||||||
ut_d(mtr->state = MTR_COMMITTING);
|
ut_d(mtr->state = MTR_COMMITTING);
|
||||||
|
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
|
@ -166,11 +166,11 @@ static
|
|||||||
ibool
|
ibool
|
||||||
page_dir_slot_check(
|
page_dir_slot_check(
|
||||||
/*================*/
|
/*================*/
|
||||||
page_dir_slot_t* slot) /*!< in: slot */
|
const page_dir_slot_t* slot) /*!< in: slot */
|
||||||
{
|
{
|
||||||
page_t* page;
|
const page_t* page;
|
||||||
ulint n_slots;
|
ulint n_slots;
|
||||||
ulint n_owned;
|
ulint n_owned;
|
||||||
|
|
||||||
ut_a(slot);
|
ut_a(slot);
|
||||||
|
|
||||||
@ -1803,12 +1803,12 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_rec_validate(
|
page_rec_validate(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
rec_t* rec, /*!< in: physical record */
|
const rec_t* rec, /*!< in: physical record */
|
||||||
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
||||||
{
|
{
|
||||||
ulint n_owned;
|
ulint n_owned;
|
||||||
ulint heap_no;
|
ulint heap_no;
|
||||||
page_t* page;
|
const page_t* page;
|
||||||
|
|
||||||
page = page_align(rec);
|
page = page_align(rec);
|
||||||
ut_a(!page_is_comp(page) == !rec_offs_comp(offsets));
|
ut_a(!page_is_comp(page) == !rec_offs_comp(offsets));
|
||||||
@ -1889,16 +1889,16 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_simple_validate_old(
|
page_simple_validate_old(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
page_t* page) /*!< in: old-style index page */
|
const page_t* page) /*!< in: index page in ROW_FORMAT=REDUNDANT */
|
||||||
{
|
{
|
||||||
page_dir_slot_t* slot;
|
const page_dir_slot_t* slot;
|
||||||
ulint slot_no;
|
ulint slot_no;
|
||||||
ulint n_slots;
|
ulint n_slots;
|
||||||
rec_t* rec;
|
const rec_t* rec;
|
||||||
byte* rec_heap_top;
|
const byte* rec_heap_top;
|
||||||
ulint count;
|
ulint count;
|
||||||
ulint own_count;
|
ulint own_count;
|
||||||
ibool ret = FALSE;
|
ibool ret = FALSE;
|
||||||
|
|
||||||
ut_a(!page_is_comp(page));
|
ut_a(!page_is_comp(page));
|
||||||
|
|
||||||
@ -2011,7 +2011,7 @@ page_simple_validate_old(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
own_count++;
|
own_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2072,7 +2072,7 @@ page_simple_validate_old(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
||||||
@ -2099,16 +2099,16 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_simple_validate_new(
|
page_simple_validate_new(
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
page_t* page) /*!< in: new-style index page */
|
const page_t* page) /*!< in: index page in ROW_FORMAT!=REDUNDANT */
|
||||||
{
|
{
|
||||||
page_dir_slot_t* slot;
|
const page_dir_slot_t* slot;
|
||||||
ulint slot_no;
|
ulint slot_no;
|
||||||
ulint n_slots;
|
ulint n_slots;
|
||||||
rec_t* rec;
|
const rec_t* rec;
|
||||||
byte* rec_heap_top;
|
const byte* rec_heap_top;
|
||||||
ulint count;
|
ulint count;
|
||||||
ulint own_count;
|
ulint own_count;
|
||||||
ibool ret = FALSE;
|
ibool ret = FALSE;
|
||||||
|
|
||||||
ut_a(page_is_comp(page));
|
ut_a(page_is_comp(page));
|
||||||
|
|
||||||
@ -2221,7 +2221,7 @@ page_simple_validate_new(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
own_count++;
|
own_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2283,7 +2283,7 @@ page_simple_validate_new(
|
|||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
||||||
@ -2308,26 +2308,26 @@ UNIV_INTERN
|
|||||||
ibool
|
ibool
|
||||||
page_validate(
|
page_validate(
|
||||||
/*==========*/
|
/*==========*/
|
||||||
page_t* page, /*!< in: index page */
|
const page_t* page, /*!< in: index page */
|
||||||
dict_index_t* index) /*!< in: data dictionary index containing
|
dict_index_t* index) /*!< in: data dictionary index containing
|
||||||
the page record type definition */
|
the page record type definition */
|
||||||
{
|
{
|
||||||
page_dir_slot_t*slot;
|
const page_dir_slot_t* slot;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
byte* buf;
|
byte* buf;
|
||||||
ulint count;
|
ulint count;
|
||||||
ulint own_count;
|
ulint own_count;
|
||||||
ulint rec_own_count;
|
ulint rec_own_count;
|
||||||
ulint slot_no;
|
ulint slot_no;
|
||||||
ulint data_size;
|
ulint data_size;
|
||||||
rec_t* rec;
|
const rec_t* rec;
|
||||||
rec_t* old_rec = NULL;
|
const rec_t* old_rec = NULL;
|
||||||
ulint offs;
|
ulint offs;
|
||||||
ulint n_slots;
|
ulint n_slots;
|
||||||
ibool ret = FALSE;
|
ibool ret = FALSE;
|
||||||
ulint i;
|
ulint i;
|
||||||
ulint* offsets = NULL;
|
ulint* offsets = NULL;
|
||||||
ulint* old_offsets = NULL;
|
ulint* old_offsets = NULL;
|
||||||
|
|
||||||
if (UNIV_UNLIKELY((ibool) !!page_is_comp(page)
|
if (UNIV_UNLIKELY((ibool) !!page_is_comp(page)
|
||||||
!= dict_table_is_comp(index->table))) {
|
!= dict_table_is_comp(index->table))) {
|
||||||
@ -2482,7 +2482,7 @@ page_validate(
|
|||||||
count++;
|
count++;
|
||||||
own_count++;
|
own_count++;
|
||||||
old_rec = rec;
|
old_rec = rec;
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
|
|
||||||
/* set old_offsets to offsets; recycle offsets */
|
/* set old_offsets to offsets; recycle offsets */
|
||||||
{
|
{
|
||||||
@ -2556,7 +2556,7 @@ n_owned_zero:
|
|||||||
buf[offs + i] = 1;
|
buf[offs + i] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next_const(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) {
|
||||||
|
@ -653,13 +653,13 @@ page_zip_dir_encode(
|
|||||||
Allocate memory for zlib. */
|
Allocate memory for zlib. */
|
||||||
static
|
static
|
||||||
void*
|
void*
|
||||||
page_zip_malloc(
|
page_zip_zalloc(
|
||||||
/*============*/
|
/*============*/
|
||||||
void* opaque, /*!< in/out: memory heap */
|
void* opaque, /*!< in/out: memory heap */
|
||||||
uInt items, /*!< in: number of items to allocate */
|
uInt items, /*!< in: number of items to allocate */
|
||||||
uInt size) /*!< in: size of an item in bytes */
|
uInt size) /*!< in: size of an item in bytes */
|
||||||
{
|
{
|
||||||
return(mem_heap_alloc(opaque, items * size));
|
return(mem_heap_zalloc(opaque, items * size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************//**
|
/**********************************************************************//**
|
||||||
@ -684,7 +684,7 @@ page_zip_set_alloc(
|
|||||||
{
|
{
|
||||||
z_stream* strm = stream;
|
z_stream* strm = stream;
|
||||||
|
|
||||||
strm->zalloc = page_zip_malloc;
|
strm->zalloc = page_zip_zalloc;
|
||||||
strm->zfree = page_zip_free;
|
strm->zfree = page_zip_free;
|
||||||
strm->opaque = heap;
|
strm->opaque = heap;
|
||||||
}
|
}
|
||||||
@ -2912,19 +2912,18 @@ zlib_error:
|
|||||||
|
|
||||||
page_zip_set_alloc(&d_stream, heap);
|
page_zip_set_alloc(&d_stream, heap);
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
|
|
||||||
!= Z_OK)) {
|
|
||||||
ut_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_stream.next_in = page_zip->data + PAGE_DATA;
|
d_stream.next_in = page_zip->data + PAGE_DATA;
|
||||||
/* Subtract the space reserved for
|
/* Subtract the space reserved for
|
||||||
the page header and the end marker of the modification log. */
|
the page header and the end marker of the modification log. */
|
||||||
d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1);
|
d_stream.avail_in = page_zip_get_size(page_zip) - (PAGE_DATA + 1);
|
||||||
|
|
||||||
d_stream.next_out = page + PAGE_ZIP_START;
|
d_stream.next_out = page + PAGE_ZIP_START;
|
||||||
d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START;
|
d_stream.avail_out = UNIV_PAGE_SIZE - PAGE_ZIP_START;
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(inflateInit2(&d_stream, UNIV_PAGE_SIZE_SHIFT)
|
||||||
|
!= Z_OK)) {
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decode the zlib header and the index information. */
|
/* Decode the zlib header and the index information. */
|
||||||
if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
|
if (UNIV_UNLIKELY(inflate(&d_stream, Z_BLOCK) != Z_OK)) {
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@ Created 10/8/1995 Heikki Tuuri
|
|||||||
#include "mem0mem.h"
|
#include "mem0mem.h"
|
||||||
#include "mem0pool.h"
|
#include "mem0pool.h"
|
||||||
#include "sync0sync.h"
|
#include "sync0sync.h"
|
||||||
#include "thr0loc.h"
|
|
||||||
#include "que0que.h"
|
#include "que0que.h"
|
||||||
#include "log0recv.h"
|
#include "log0recv.h"
|
||||||
#include "pars0pars.h"
|
#include "pars0pars.h"
|
||||||
@ -690,7 +689,7 @@ Unix.*/
|
|||||||
struct srv_slot_struct{
|
struct srv_slot_struct{
|
||||||
os_thread_id_t id; /*!< thread id */
|
os_thread_id_t id; /*!< thread id */
|
||||||
os_thread_t handle; /*!< thread handle */
|
os_thread_t handle; /*!< thread handle */
|
||||||
unsigned type:3; /*!< thread type: user, utility etc. */
|
unsigned type:1; /*!< thread type: user, utility etc. */
|
||||||
unsigned in_use:1; /*!< TRUE if this slot is in use */
|
unsigned in_use:1; /*!< TRUE if this slot is in use */
|
||||||
unsigned suspended:1; /*!< TRUE if the thread is waiting
|
unsigned suspended:1; /*!< TRUE if the thread is waiting
|
||||||
for the event of this slot */
|
for the event of this slot */
|
||||||
@ -797,6 +796,7 @@ srv_table_get_nth_slot(
|
|||||||
/*===================*/
|
/*===================*/
|
||||||
ulint index) /*!< in: index of the slot */
|
ulint index) /*!< in: index of the slot */
|
||||||
{
|
{
|
||||||
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
ut_a(index < OS_THREAD_MAX_N);
|
ut_a(index < OS_THREAD_MAX_N);
|
||||||
|
|
||||||
return(srv_sys->threads + index);
|
return(srv_sys->threads + index);
|
||||||
@ -815,7 +815,7 @@ srv_get_n_threads(void)
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
for (i = SRV_COM; i < SRV_MASTER + 1; i++) {
|
for (i = 0; i < SRV_MASTER + 1; i++) {
|
||||||
|
|
||||||
n_threads += srv_n_threads[i];
|
n_threads += srv_n_threads[i];
|
||||||
}
|
}
|
||||||
@ -825,13 +825,46 @@ srv_get_n_threads(void)
|
|||||||
return(n_threads);
|
return(n_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Reserves a slot in the thread table for the current thread. Also creates the
|
Validates the type of a thread table slot.
|
||||||
thread local storage struct for the current thread. NOTE! The server mutex
|
@return TRUE if ok */
|
||||||
has to be reserved by the caller!
|
|
||||||
@return reserved slot index */
|
|
||||||
static
|
static
|
||||||
ulint
|
ibool
|
||||||
|
srv_thread_type_validate(
|
||||||
|
/*=====================*/
|
||||||
|
enum srv_thread_type type) /*!< in: thread type */
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case SRV_WORKER:
|
||||||
|
case SRV_MASTER:
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
ut_error;
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
|
/*********************************************************************//**
|
||||||
|
Gets the type of a thread table slot.
|
||||||
|
@return thread type */
|
||||||
|
static
|
||||||
|
enum srv_thread_type
|
||||||
|
srv_slot_get_type(
|
||||||
|
/*==============*/
|
||||||
|
const srv_slot_t* slot) /*!< in: thread slot */
|
||||||
|
{
|
||||||
|
enum srv_thread_type type = (enum srv_thread_type) slot->type;
|
||||||
|
ut_ad(srv_thread_type_validate(type));
|
||||||
|
return(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************//**
|
||||||
|
Reserves a slot in the thread table for the current thread.
|
||||||
|
NOTE! The server mutex has to be reserved by the caller!
|
||||||
|
@return reserved slot */
|
||||||
|
static
|
||||||
|
srv_slot_t*
|
||||||
srv_table_reserve_slot(
|
srv_table_reserve_slot(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
enum srv_thread_type type) /*!< in: type of the thread */
|
enum srv_thread_type type) /*!< in: type of the thread */
|
||||||
@ -839,8 +872,7 @@ srv_table_reserve_slot(
|
|||||||
srv_slot_t* slot;
|
srv_slot_t* slot;
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
ut_a(type > 0);
|
ut_ad(srv_thread_type_validate(type));
|
||||||
ut_a(type <= SRV_MASTER);
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -851,53 +883,40 @@ srv_table_reserve_slot(
|
|||||||
slot = srv_table_get_nth_slot(i);
|
slot = srv_table_get_nth_slot(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_a(slot->in_use == FALSE);
|
|
||||||
|
|
||||||
slot->in_use = TRUE;
|
slot->in_use = TRUE;
|
||||||
slot->suspended = FALSE;
|
slot->suspended = FALSE;
|
||||||
slot->type = type;
|
slot->type = type;
|
||||||
|
ut_ad(srv_slot_get_type(slot) == type);
|
||||||
slot->id = os_thread_get_curr_id();
|
slot->id = os_thread_get_curr_id();
|
||||||
slot->handle = os_thread_get_curr();
|
slot->handle = os_thread_get_curr();
|
||||||
|
|
||||||
thr_local_create();
|
return(slot);
|
||||||
|
|
||||||
thr_local_set_slot_no(os_thread_get_curr_id(), i);
|
|
||||||
|
|
||||||
return(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Suspends the calling thread to wait for the event in its thread slot.
|
Suspends the calling thread to wait for the event in its thread slot.
|
||||||
NOTE! The server mutex has to be reserved by the caller!
|
NOTE! The server mutex has to be reserved by the caller! */
|
||||||
@return event for the calling thread to wait */
|
|
||||||
static
|
static
|
||||||
os_event_t
|
void
|
||||||
srv_suspend_thread(void)
|
srv_suspend_thread(
|
||||||
/*====================*/
|
/*===============*/
|
||||||
|
srv_slot_t* slot) /*!< in/out: thread slot */
|
||||||
{
|
{
|
||||||
srv_slot_t* slot;
|
|
||||||
os_event_t event;
|
|
||||||
ulint slot_no;
|
|
||||||
enum srv_thread_type type;
|
enum srv_thread_type type;
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
ut_ad(slot->in_use);
|
||||||
slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
|
ut_ad(!slot->suspended);
|
||||||
|
ut_ad(slot->id == os_thread_get_curr_id());
|
||||||
|
|
||||||
if (srv_print_thread_releases) {
|
if (srv_print_thread_releases) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Suspending thread %lu to slot %lu\n",
|
"Suspending thread %lu to slot %lu\n",
|
||||||
(ulong) os_thread_get_curr_id(), (ulong) slot_no);
|
(ulong) os_thread_get_curr_id(),
|
||||||
|
(ulong) (slot - srv_sys->threads));
|
||||||
}
|
}
|
||||||
|
|
||||||
slot = srv_table_get_nth_slot(slot_no);
|
type = srv_slot_get_type(slot);
|
||||||
|
|
||||||
type = slot->type;
|
|
||||||
|
|
||||||
ut_ad(type >= SRV_WORKER);
|
|
||||||
ut_ad(type <= SRV_MASTER);
|
|
||||||
|
|
||||||
event = slot->event;
|
|
||||||
|
|
||||||
slot->suspended = TRUE;
|
slot->suspended = TRUE;
|
||||||
|
|
||||||
@ -905,9 +924,7 @@ srv_suspend_thread(void)
|
|||||||
|
|
||||||
srv_n_threads_active[type]--;
|
srv_n_threads_active[type]--;
|
||||||
|
|
||||||
os_event_reset(event);
|
os_event_reset(slot->event);
|
||||||
|
|
||||||
return(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
@ -926,8 +943,7 @@ srv_release_threads(
|
|||||||
ulint i;
|
ulint i;
|
||||||
ulint count = 0;
|
ulint count = 0;
|
||||||
|
|
||||||
ut_ad(type >= SRV_WORKER);
|
ut_ad(srv_thread_type_validate(type));
|
||||||
ut_ad(type <= SRV_MASTER);
|
|
||||||
ut_ad(n > 0);
|
ut_ad(n > 0);
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
@ -935,7 +951,8 @@ srv_release_threads(
|
|||||||
|
|
||||||
slot = srv_table_get_nth_slot(i);
|
slot = srv_table_get_nth_slot(i);
|
||||||
|
|
||||||
if (slot->in_use && slot->type == type && slot->suspended) {
|
if (slot->in_use && slot->suspended
|
||||||
|
&& srv_slot_get_type(slot) == type) {
|
||||||
|
|
||||||
slot->suspended = FALSE;
|
slot->suspended = FALSE;
|
||||||
|
|
||||||
@ -962,34 +979,6 @@ srv_release_threads(
|
|||||||
return(count);
|
return(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Returns the calling thread type.
|
|
||||||
@return SRV_COM, ... */
|
|
||||||
UNIV_INTERN
|
|
||||||
enum srv_thread_type
|
|
||||||
srv_get_thread_type(void)
|
|
||||||
/*=====================*/
|
|
||||||
{
|
|
||||||
ulint slot_no;
|
|
||||||
srv_slot_t* slot;
|
|
||||||
enum srv_thread_type type;
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
|
||||||
|
|
||||||
slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
|
|
||||||
|
|
||||||
slot = srv_table_get_nth_slot(slot_no);
|
|
||||||
|
|
||||||
type = slot->type;
|
|
||||||
|
|
||||||
ut_ad(type >= SRV_WORKER);
|
|
||||||
ut_ad(type <= SRV_MASTER);
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
|
||||||
|
|
||||||
return(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Check whether thread type has reserved a slot. Return the first slot that
|
Check whether thread type has reserved a slot. Return the first slot that
|
||||||
is found. This works because we currently have only 1 thread of each type.
|
is found. This works because we currently have only 1 thread of each type.
|
||||||
@ -1003,6 +992,7 @@ srv_thread_has_reserved_slot(
|
|||||||
ulint i;
|
ulint i;
|
||||||
ulint slot_no = ULINT_UNDEFINED;
|
ulint slot_no = ULINT_UNDEFINED;
|
||||||
|
|
||||||
|
ut_ad(srv_thread_type_validate(type));
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
||||||
@ -1040,22 +1030,18 @@ srv_init(void)
|
|||||||
mutex_create(srv_innodb_monitor_mutex_key,
|
mutex_create(srv_innodb_monitor_mutex_key,
|
||||||
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
|
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
|
||||||
|
|
||||||
srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
|
srv_sys->threads = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
|
||||||
|
|
||||||
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
||||||
slot = srv_table_get_nth_slot(i);
|
slot = srv_sys->threads + i;
|
||||||
slot->in_use = FALSE;
|
|
||||||
slot->type=0; /* Avoid purify errors */
|
|
||||||
slot->event = os_event_create(NULL);
|
slot->event = os_event_create(NULL);
|
||||||
ut_a(slot->event);
|
ut_a(slot->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
|
srv_mysql_table = mem_zalloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
|
||||||
|
|
||||||
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
for (i = 0; i < OS_THREAD_MAX_N; i++) {
|
||||||
slot = srv_mysql_table + i;
|
slot = srv_mysql_table + i;
|
||||||
slot->in_use = FALSE;
|
|
||||||
slot->type = 0;
|
|
||||||
slot->event = os_event_create(NULL);
|
slot->event = os_event_create(NULL);
|
||||||
ut_a(slot->event);
|
ut_a(slot->event);
|
||||||
}
|
}
|
||||||
@ -1142,7 +1128,6 @@ srv_general_init(void)
|
|||||||
os_sync_init();
|
os_sync_init();
|
||||||
sync_init();
|
sync_init();
|
||||||
mem_init(srv_mem_pool_size);
|
mem_init(srv_mem_pool_size);
|
||||||
thr_local_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================= InnoDB Server FIFO queue =======================*/
|
/*======================= InnoDB Server FIFO queue =======================*/
|
||||||
@ -1501,7 +1486,7 @@ srv_table_reserve_slot_for_mysql(void)
|
|||||||
while (slot->in_use) {
|
while (slot->in_use) {
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i >= OS_THREAD_MAX_N) {
|
if (UNIV_UNLIKELY(i >= OS_THREAD_MAX_N)) {
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
|
|
||||||
@ -2382,6 +2367,12 @@ srv_error_monitor_thread(
|
|||||||
ib_uint64_t old_lsn;
|
ib_uint64_t old_lsn;
|
||||||
ib_uint64_t new_lsn;
|
ib_uint64_t new_lsn;
|
||||||
ib_int64_t sig_count;
|
ib_int64_t sig_count;
|
||||||
|
/* longest waiting thread for a semaphore */
|
||||||
|
os_thread_id_t waiter = os_thread_get_curr_id();
|
||||||
|
os_thread_id_t old_waiter = waiter;
|
||||||
|
/* the semaphore that is being waited for */
|
||||||
|
const void* sema = NULL;
|
||||||
|
const void* old_sema = NULL;
|
||||||
|
|
||||||
old_lsn = srv_start_lsn;
|
old_lsn = srv_start_lsn;
|
||||||
|
|
||||||
@ -2435,7 +2426,8 @@ loop:
|
|||||||
|
|
||||||
sync_arr_wake_threads_if_sema_free();
|
sync_arr_wake_threads_if_sema_free();
|
||||||
|
|
||||||
if (sync_array_print_long_waits()) {
|
if (sync_array_print_long_waits(&waiter, &sema)
|
||||||
|
&& sema == old_sema && os_thread_eq(waiter, old_waiter)) {
|
||||||
fatal_cnt++;
|
fatal_cnt++;
|
||||||
if (fatal_cnt > 10) {
|
if (fatal_cnt > 10) {
|
||||||
|
|
||||||
@ -2450,6 +2442,8 @@ loop:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fatal_cnt = 0;
|
fatal_cnt = 0;
|
||||||
|
old_waiter = waiter;
|
||||||
|
old_sema = sema;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush stderr so that a database user gets the output
|
/* Flush stderr so that a database user gets the output
|
||||||
@ -2489,7 +2483,7 @@ srv_is_any_background_thread_active(void)
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
for (i = SRV_COM; i <= SRV_MASTER; ++i) {
|
for (i = 0; i <= SRV_MASTER; ++i) {
|
||||||
if (srv_n_threads_active[i] != 0) {
|
if (srv_n_threads_active[i] != 0) {
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -2643,7 +2637,7 @@ srv_master_thread(
|
|||||||
os_thread_create */
|
os_thread_create */
|
||||||
{
|
{
|
||||||
buf_pool_stat_t buf_stat;
|
buf_pool_stat_t buf_stat;
|
||||||
os_event_t event;
|
srv_slot_t* slot;
|
||||||
ulint old_activity_count;
|
ulint old_activity_count;
|
||||||
ulint n_pages_purged = 0;
|
ulint n_pages_purged = 0;
|
||||||
ulint n_bytes_merged;
|
ulint n_bytes_merged;
|
||||||
@ -2671,7 +2665,7 @@ srv_master_thread(
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
srv_table_reserve_slot(SRV_MASTER);
|
slot = srv_table_reserve_slot(SRV_MASTER);
|
||||||
|
|
||||||
srv_n_threads_active[SRV_MASTER]++;
|
srv_n_threads_active[SRV_MASTER]++;
|
||||||
|
|
||||||
@ -3060,7 +3054,7 @@ suspend_thread:
|
|||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
event = srv_suspend_thread();
|
srv_suspend_thread(slot);
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
@ -3070,7 +3064,7 @@ suspend_thread:
|
|||||||
manual also mentions this string in several places. */
|
manual also mentions this string in several places. */
|
||||||
srv_main_thread_op_info = "waiting for server activity";
|
srv_main_thread_op_info = "waiting for server activity";
|
||||||
|
|
||||||
os_event_wait(event);
|
os_event_wait(slot->event);
|
||||||
|
|
||||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||||
/* This is only extra safety, the thread should exit
|
/* This is only extra safety, the thread should exit
|
||||||
@ -3084,8 +3078,6 @@ suspend_thread:
|
|||||||
main thread goes back to loop. */
|
main thread goes back to loop. */
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
@ -3100,7 +3092,6 @@ srv_purge_thread(
|
|||||||
{
|
{
|
||||||
srv_slot_t* slot;
|
srv_slot_t* slot;
|
||||||
ulint retries = 0;
|
ulint retries = 0;
|
||||||
ulint slot_no = ULINT_UNDEFINED;
|
|
||||||
ulint n_total_purged = ULINT_UNDEFINED;
|
ulint n_total_purged = ULINT_UNDEFINED;
|
||||||
|
|
||||||
ut_a(srv_n_purge_threads == 1);
|
ut_a(srv_n_purge_threads == 1);
|
||||||
@ -3116,9 +3107,7 @@ srv_purge_thread(
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
slot_no = srv_table_reserve_slot(SRV_WORKER);
|
slot = srv_table_reserve_slot(SRV_WORKER);
|
||||||
|
|
||||||
slot = srv_table_get_nth_slot(slot_no);
|
|
||||||
|
|
||||||
++srv_n_threads_active[SRV_WORKER];
|
++srv_n_threads_active[SRV_WORKER];
|
||||||
|
|
||||||
@ -3137,15 +3126,13 @@ srv_purge_thread(
|
|||||||
|| (n_total_purged == 0
|
|| (n_total_purged == 0
|
||||||
&& retries >= TRX_SYS_N_RSEGS)) {
|
&& retries >= TRX_SYS_N_RSEGS)) {
|
||||||
|
|
||||||
os_event_t event;
|
|
||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
event = srv_suspend_thread();
|
srv_suspend_thread(slot);
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
os_event_wait(event);
|
os_event_wait(slot->event);
|
||||||
|
|
||||||
retries = 0;
|
retries = 0;
|
||||||
}
|
}
|
||||||
@ -3179,16 +3166,11 @@ srv_purge_thread(
|
|||||||
|
|
||||||
mutex_enter(&kernel_mutex);
|
mutex_enter(&kernel_mutex);
|
||||||
|
|
||||||
ut_ad(srv_table_get_nth_slot(slot_no) == slot);
|
|
||||||
|
|
||||||
/* Decrement the active count. */
|
/* Decrement the active count. */
|
||||||
srv_suspend_thread();
|
srv_suspend_thread(slot);
|
||||||
|
|
||||||
slot->in_use = FALSE;
|
slot->in_use = FALSE;
|
||||||
|
|
||||||
/* Free the thread local memory. */
|
|
||||||
thr_local_free(os_thread_get_curr_id());
|
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG_THREAD_CREATION
|
#ifdef UNIV_DEBUG_THREAD_CREATION
|
||||||
|
@ -85,7 +85,6 @@ Created 2/16/1996 Heikki Tuuri
|
|||||||
# include "row0row.h"
|
# include "row0row.h"
|
||||||
# include "row0mysql.h"
|
# include "row0mysql.h"
|
||||||
# include "btr0pcur.h"
|
# include "btr0pcur.h"
|
||||||
# include "thr0loc.h"
|
|
||||||
# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
|
# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
# include "zlib.h" /* for ZLIB_VERSION */
|
# include "zlib.h" /* for ZLIB_VERSION */
|
||||||
|
|
||||||
@ -2210,7 +2209,6 @@ innobase_shutdown_for_mysql(void)
|
|||||||
ibuf_close();
|
ibuf_close();
|
||||||
log_shutdown();
|
log_shutdown();
|
||||||
lock_sys_close();
|
lock_sys_close();
|
||||||
thr_local_close();
|
|
||||||
trx_sys_file_format_close();
|
trx_sys_file_format_close();
|
||||||
trx_sys_close();
|
trx_sys_close();
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ Created 9/5/1995 Heikki Tuuri
|
|||||||
#include "os0sync.h"
|
#include "os0sync.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
WAIT ARRAY
|
WAIT ARRAY
|
||||||
@ -478,8 +479,8 @@ sync_array_cell_print(
|
|||||||
fprintf(file,
|
fprintf(file,
|
||||||
"--Thread %lu has waited at %s line %lu"
|
"--Thread %lu has waited at %s line %lu"
|
||||||
" for %.2f seconds the semaphore:\n",
|
" for %.2f seconds the semaphore:\n",
|
||||||
(ulong) os_thread_pf(cell->thread), cell->file,
|
(ulong) os_thread_pf(cell->thread),
|
||||||
(ulong) cell->line,
|
innobase_basename(cell->file), (ulong) cell->line,
|
||||||
difftime(time(NULL), cell->reservation_time));
|
difftime(time(NULL), cell->reservation_time));
|
||||||
|
|
||||||
if (type == SYNC_MUTEX) {
|
if (type == SYNC_MUTEX) {
|
||||||
@ -493,7 +494,8 @@ sync_array_cell_print(
|
|||||||
"Last time reserved in file %s line %lu, "
|
"Last time reserved in file %s line %lu, "
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
"waiters flag %lu\n",
|
"waiters flag %lu\n",
|
||||||
(void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
|
(void*) mutex, innobase_basename(mutex->cfile_name),
|
||||||
|
(ulong) mutex->cline,
|
||||||
(ulong) mutex->lock_word,
|
(ulong) mutex->lock_word,
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
mutex->file_name, (ulong) mutex->line,
|
mutex->file_name, (ulong) mutex->line,
|
||||||
@ -512,7 +514,7 @@ sync_array_cell_print(
|
|||||||
|
|
||||||
fprintf(file,
|
fprintf(file,
|
||||||
" RW-latch at %p created in file %s line %lu\n",
|
" RW-latch at %p created in file %s line %lu\n",
|
||||||
(void*) rwlock, rwlock->cfile_name,
|
(void*) rwlock, innobase_basename(rwlock->cfile_name),
|
||||||
(ulong) rwlock->cline);
|
(ulong) rwlock->cline);
|
||||||
writer = rw_lock_get_writer(rwlock);
|
writer = rw_lock_get_writer(rwlock);
|
||||||
if (writer != RW_LOCK_NOT_LOCKED) {
|
if (writer != RW_LOCK_NOT_LOCKED) {
|
||||||
@ -533,7 +535,7 @@ sync_array_cell_print(
|
|||||||
(ulong) rw_lock_get_reader_count(rwlock),
|
(ulong) rw_lock_get_reader_count(rwlock),
|
||||||
(ulong) rwlock->waiters,
|
(ulong) rwlock->waiters,
|
||||||
rwlock->lock_word,
|
rwlock->lock_word,
|
||||||
rwlock->last_s_file_name,
|
innobase_basename(rwlock->last_s_file_name),
|
||||||
(ulong) rwlock->last_s_line,
|
(ulong) rwlock->last_s_line,
|
||||||
rwlock->last_x_file_name,
|
rwlock->last_x_file_name,
|
||||||
(ulong) rwlock->last_x_line);
|
(ulong) rwlock->last_x_line);
|
||||||
@ -913,8 +915,10 @@ Prints warnings of long semaphore waits to stderr.
|
|||||||
@return TRUE if fatal semaphore wait threshold was exceeded */
|
@return TRUE if fatal semaphore wait threshold was exceeded */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
ibool
|
ibool
|
||||||
sync_array_print_long_waits(void)
|
sync_array_print_long_waits(
|
||||||
/*=============================*/
|
/*========================*/
|
||||||
|
os_thread_id_t* waiter, /*!< out: longest waiting thread */
|
||||||
|
const void** sema) /*!< out: longest-waited-for semaphore */
|
||||||
{
|
{
|
||||||
sync_cell_t* cell;
|
sync_cell_t* cell;
|
||||||
ibool old_val;
|
ibool old_val;
|
||||||
@ -922,6 +926,7 @@ sync_array_print_long_waits(void)
|
|||||||
ulint i;
|
ulint i;
|
||||||
ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
|
ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
|
||||||
ibool fatal = FALSE;
|
ibool fatal = FALSE;
|
||||||
|
double longest_diff = 0;
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG_VALGRIND
|
#ifdef UNIV_DEBUG_VALGRIND
|
||||||
/* Increase the timeouts if running under valgrind because it executes
|
/* Increase the timeouts if running under valgrind because it executes
|
||||||
@ -937,22 +942,36 @@ sync_array_print_long_waits(void)
|
|||||||
|
|
||||||
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
|
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
|
||||||
|
|
||||||
|
double diff;
|
||||||
|
void* wait_object;
|
||||||
|
|
||||||
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
|
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
|
||||||
|
|
||||||
if (cell->wait_object != NULL && cell->waiting
|
wait_object = cell->wait_object;
|
||||||
&& difftime(time(NULL), cell->reservation_time)
|
|
||||||
> SYNC_ARRAY_TIMEOUT) {
|
if (wait_object == NULL || !cell->waiting) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff = difftime(time(NULL), cell->reservation_time);
|
||||||
|
|
||||||
|
if (diff > SYNC_ARRAY_TIMEOUT) {
|
||||||
fputs("InnoDB: Warning: a long semaphore wait:\n",
|
fputs("InnoDB: Warning: a long semaphore wait:\n",
|
||||||
stderr);
|
stderr);
|
||||||
sync_array_cell_print(stderr, cell);
|
sync_array_cell_print(stderr, cell);
|
||||||
noticed = TRUE;
|
noticed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->wait_object != NULL && cell->waiting
|
if (diff > fatal_timeout) {
|
||||||
&& difftime(time(NULL), cell->reservation_time)
|
|
||||||
> fatal_timeout) {
|
|
||||||
fatal = TRUE;
|
fatal = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diff > longest_diff) {
|
||||||
|
longest_diff = diff;
|
||||||
|
*sema = wait_object;
|
||||||
|
*waiter = cell->thread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noticed) {
|
if (noticed) {
|
||||||
|
@ -39,6 +39,7 @@ Created 9/11/1995 Heikki Tuuri
|
|||||||
#include "mem0mem.h"
|
#include "mem0mem.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
|
#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
|
||||||
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IMPLEMENTATION OF THE RW_LOCK
|
IMPLEMENTATION OF THE RW_LOCK
|
||||||
@ -407,7 +408,8 @@ lock_loop:
|
|||||||
" cfile %s cline %lu rnds %lu\n",
|
" cfile %s cline %lu rnds %lu\n",
|
||||||
(ulong) os_thread_pf(os_thread_get_curr_id()),
|
(ulong) os_thread_pf(os_thread_get_curr_id()),
|
||||||
(void*) lock,
|
(void*) lock,
|
||||||
lock->cfile_name, (ulong) lock->cline, (ulong) i);
|
innobase_basename(lock->cfile_name),
|
||||||
|
(ulong) lock->cline, (ulong) i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We try once again to obtain the lock */
|
/* We try once again to obtain the lock */
|
||||||
@ -442,7 +444,8 @@ lock_loop:
|
|||||||
"Thread %lu OS wait rw-s-lock at %p"
|
"Thread %lu OS wait rw-s-lock at %p"
|
||||||
" cfile %s cline %lu\n",
|
" cfile %s cline %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()),
|
os_thread_pf(os_thread_get_curr_id()),
|
||||||
(void*) lock, lock->cfile_name,
|
(void*) lock,
|
||||||
|
innobase_basename(lock->cfile_name),
|
||||||
(ulong) lock->cline);
|
(ulong) lock->cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,7 +667,8 @@ lock_loop:
|
|||||||
"Thread %lu spin wait rw-x-lock at %p"
|
"Thread %lu spin wait rw-x-lock at %p"
|
||||||
" cfile %s cline %lu rnds %lu\n",
|
" cfile %s cline %lu rnds %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
|
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
|
||||||
lock->cfile_name, (ulong) lock->cline, (ulong) i);
|
innobase_basename(lock->cfile_name),
|
||||||
|
(ulong) lock->cline, (ulong) i);
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_array_reserve_cell(sync_primary_wait_array,
|
sync_array_reserve_cell(sync_primary_wait_array,
|
||||||
@ -687,7 +691,8 @@ lock_loop:
|
|||||||
"Thread %lu OS wait for rw-x-lock at %p"
|
"Thread %lu OS wait for rw-x-lock at %p"
|
||||||
" cfile %s cline %lu\n",
|
" cfile %s cline %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
|
os_thread_pf(os_thread_get_curr_id()), (void*) lock,
|
||||||
lock->cfile_name, (ulong) lock->cline);
|
innobase_basename(lock->cfile_name),
|
||||||
|
(ulong) lock->cline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* these stats may not be accurate */
|
/* these stats may not be accurate */
|
||||||
|
@ -43,6 +43,7 @@ Created 9/5/1995 Heikki Tuuri
|
|||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
# include "srv0start.h" /* srv_is_being_started */
|
# include "srv0start.h" /* srv_is_being_started */
|
||||||
#endif /* UNIV_SYNC_DEBUG */
|
#endif /* UNIV_SYNC_DEBUG */
|
||||||
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
|
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
|
||||||
@ -543,7 +544,8 @@ spin_loop:
|
|||||||
"Thread %lu spin wait mutex at %p"
|
"Thread %lu spin wait mutex at %p"
|
||||||
" cfile %s cline %lu rnds %lu\n",
|
" cfile %s cline %lu rnds %lu\n",
|
||||||
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
|
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
|
||||||
mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
|
innobase_basename(mutex->cfile_name),
|
||||||
|
(ulong) mutex->cline, (ulong) i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutex_spin_round_count += i;
|
mutex_spin_round_count += i;
|
||||||
@ -620,7 +622,8 @@ spin_loop:
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
|
"Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
|
||||||
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
|
(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
|
||||||
mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
|
innobase_basename(mutex->cfile_name),
|
||||||
|
(ulong) mutex->cline, (ulong) i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutex_os_wait_count++;
|
mutex_os_wait_count++;
|
||||||
@ -869,7 +872,8 @@ sync_print_warning(
|
|||||||
if (mutex->magic_n == MUTEX_MAGIC_N) {
|
if (mutex->magic_n == MUTEX_MAGIC_N) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Mutex created at %s %lu\n",
|
"Mutex created at %s %lu\n",
|
||||||
mutex->cfile_name, (ulong) mutex->cline);
|
innobase_basename(mutex->cfile_name),
|
||||||
|
(ulong) mutex->cline);
|
||||||
|
|
||||||
if (mutex_get_lock_word(mutex) != 0) {
|
if (mutex_get_lock_word(mutex) != 0) {
|
||||||
ulint line;
|
ulint line;
|
||||||
|
@ -1,307 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 1995, 2009, Innobase Oy. 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 the Free Software
|
|
||||||
Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
||||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**************************************************//**
|
|
||||||
@file thr/thr0loc.c
|
|
||||||
The thread local storage
|
|
||||||
|
|
||||||
Created 10/5/1995 Heikki Tuuri
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
#include "thr0loc.h"
|
|
||||||
#ifdef UNIV_NONINL
|
|
||||||
#include "thr0loc.ic"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "sync0sync.h"
|
|
||||||
#include "hash0hash.h"
|
|
||||||
#include "mem0mem.h"
|
|
||||||
#include "srv0srv.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
IMPLEMENTATION OF THREAD LOCAL STORAGE
|
|
||||||
======================================
|
|
||||||
|
|
||||||
The threads sometimes need private data which depends on the thread id.
|
|
||||||
This is implemented as a hash table, where the hash value is calculated
|
|
||||||
from the thread id, to prepare for a large number of threads. The hash table
|
|
||||||
is protected by a mutex. If you need modify the program and put new data to
|
|
||||||
the thread local storage, just add it to struct thr_local_struct in the
|
|
||||||
header file. */
|
|
||||||
|
|
||||||
/** Mutex protecting thr_local_hash */
|
|
||||||
static mutex_t thr_local_mutex;
|
|
||||||
|
|
||||||
/** The hash table. The module is not yet initialized when it is NULL. */
|
|
||||||
static hash_table_t* thr_local_hash = NULL;
|
|
||||||
|
|
||||||
/** Thread local data */
|
|
||||||
typedef struct thr_local_struct thr_local_t;
|
|
||||||
|
|
||||||
#ifdef UNIV_PFS_MUTEX
|
|
||||||
/* Key to register the mutex with performance schema */
|
|
||||||
UNIV_INTERN mysql_pfs_key_t thr_local_mutex_key;
|
|
||||||
#endif /* UNIV_PFS_MUTEX */
|
|
||||||
|
|
||||||
/** @brief Thread local data.
|
|
||||||
The private data for each thread should be put to
|
|
||||||
the structure below and the accessor functions written
|
|
||||||
for the field. */
|
|
||||||
struct thr_local_struct{
|
|
||||||
os_thread_id_t id; /*!< id of the thread which owns this struct */
|
|
||||||
os_thread_t handle; /*!< operating system handle to the thread */
|
|
||||||
ulint slot_no;/*!< the index of the slot in the thread table
|
|
||||||
for this thread */
|
|
||||||
ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf
|
|
||||||
operation */
|
|
||||||
hash_node_t hash; /*!< hash chain node */
|
|
||||||
ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** The value of thr_local_struct::magic_n */
|
|
||||||
#define THR_LOCAL_MAGIC_N 1231234
|
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
/*******************************************************************//**
|
|
||||||
Validates thread local data.
|
|
||||||
@return TRUE if valid */
|
|
||||||
static
|
|
||||||
ibool
|
|
||||||
thr_local_validate(
|
|
||||||
/*===============*/
|
|
||||||
const thr_local_t* local) /*!< in: data to validate */
|
|
||||||
{
|
|
||||||
ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
|
|
||||||
ut_ad(local->slot_no == ULINT_UNDEFINED
|
|
||||||
|| local->slot_no < OS_THREAD_MAX_N);
|
|
||||||
ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE);
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Returns the local storage struct for a thread.
|
|
||||||
@return local storage */
|
|
||||||
static
|
|
||||||
thr_local_t*
|
|
||||||
thr_local_get(
|
|
||||||
/*==========*/
|
|
||||||
os_thread_id_t id) /*!< in: thread id of the thread */
|
|
||||||
{
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
try_again:
|
|
||||||
ut_ad(thr_local_hash);
|
|
||||||
ut_ad(mutex_own(&thr_local_mutex));
|
|
||||||
|
|
||||||
/* Look for the local struct in the hash table */
|
|
||||||
|
|
||||||
local = NULL;
|
|
||||||
|
|
||||||
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
|
|
||||||
thr_local_t*, local, ut_ad(thr_local_validate(local)),
|
|
||||||
os_thread_eq(local->id, id));
|
|
||||||
if (local == NULL) {
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
|
|
||||||
thr_local_create();
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
goto try_again;
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(thr_local_validate(local));
|
|
||||||
|
|
||||||
return(local);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Gets the slot number in the thread table of a thread.
|
|
||||||
@return slot number */
|
|
||||||
UNIV_INTERN
|
|
||||||
ulint
|
|
||||||
thr_local_get_slot_no(
|
|
||||||
/*==================*/
|
|
||||||
os_thread_id_t id) /*!< in: thread id of the thread */
|
|
||||||
{
|
|
||||||
ulint slot_no;
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
local = thr_local_get(id);
|
|
||||||
|
|
||||||
slot_no = local->slot_no;
|
|
||||||
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
|
|
||||||
return(slot_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Sets the slot number in the thread table of a thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_set_slot_no(
|
|
||||||
/*==================*/
|
|
||||||
os_thread_id_t id, /*!< in: thread id of the thread */
|
|
||||||
ulint slot_no)/*!< in: slot number */
|
|
||||||
{
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
local = thr_local_get(id);
|
|
||||||
|
|
||||||
local->slot_no = slot_no;
|
|
||||||
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Returns pointer to the 'in_ibuf' field within the current thread local
|
|
||||||
storage.
|
|
||||||
@return pointer to the in_ibuf field */
|
|
||||||
UNIV_INTERN
|
|
||||||
ibool*
|
|
||||||
thr_local_get_in_ibuf_field(void)
|
|
||||||
/*=============================*/
|
|
||||||
{
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
local = thr_local_get(os_thread_get_curr_id());
|
|
||||||
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
|
|
||||||
return(&(local->in_ibuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Creates a local storage struct for the calling new thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_create(void)
|
|
||||||
/*==================*/
|
|
||||||
{
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
if (thr_local_hash == NULL) {
|
|
||||||
thr_local_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
local = mem_alloc(sizeof(thr_local_t));
|
|
||||||
|
|
||||||
local->id = os_thread_get_curr_id();
|
|
||||||
local->handle = os_thread_get_curr();
|
|
||||||
local->magic_n = THR_LOCAL_MAGIC_N;
|
|
||||||
local->slot_no = ULINT_UNDEFINED;
|
|
||||||
local->in_ibuf = FALSE;
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
HASH_INSERT(thr_local_t, hash, thr_local_hash,
|
|
||||||
os_thread_pf(os_thread_get_curr_id()),
|
|
||||||
local);
|
|
||||||
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************//**
|
|
||||||
Frees the local storage struct for the specified thread. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_free(
|
|
||||||
/*===========*/
|
|
||||||
os_thread_id_t id) /*!< in: thread id */
|
|
||||||
{
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
mutex_enter(&thr_local_mutex);
|
|
||||||
|
|
||||||
/* Look for the local struct in the hash table */
|
|
||||||
|
|
||||||
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
|
|
||||||
thr_local_t*, local, ut_ad(thr_local_validate(local)),
|
|
||||||
os_thread_eq(local->id, id));
|
|
||||||
if (local == NULL) {
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HASH_DELETE(thr_local_t, hash, thr_local_hash,
|
|
||||||
os_thread_pf(id), local);
|
|
||||||
|
|
||||||
mutex_exit(&thr_local_mutex);
|
|
||||||
|
|
||||||
ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
|
|
||||||
ut_ad(thr_local_validate(local));
|
|
||||||
|
|
||||||
mem_free(local);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************//**
|
|
||||||
Initializes the thread local storage module. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_init(void)
|
|
||||||
/*================*/
|
|
||||||
{
|
|
||||||
|
|
||||||
ut_a(thr_local_hash == NULL);
|
|
||||||
|
|
||||||
thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
|
|
||||||
|
|
||||||
mutex_create(thr_local_mutex_key,
|
|
||||||
&thr_local_mutex, SYNC_THR_LOCAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************
|
|
||||||
Close the thread local storage module. */
|
|
||||||
UNIV_INTERN
|
|
||||||
void
|
|
||||||
thr_local_close(void)
|
|
||||||
/*=================*/
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
|
|
||||||
ut_a(thr_local_hash != NULL);
|
|
||||||
|
|
||||||
/* Free the hash elements. We don't remove them from the table
|
|
||||||
because we are going to destroy the table anyway. */
|
|
||||||
for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
|
|
||||||
thr_local_t* local;
|
|
||||||
|
|
||||||
local = HASH_GET_FIRST(thr_local_hash, i);
|
|
||||||
|
|
||||||
while (local) {
|
|
||||||
thr_local_t* prev_local = local;
|
|
||||||
|
|
||||||
local = HASH_GET_NEXT(hash, prev_local);
|
|
||||||
ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
|
|
||||||
ut_ad(thr_local_validate(prev_local));
|
|
||||||
mem_free(prev_local);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_table_free(thr_local_hash);
|
|
||||||
thr_local_hash = NULL;
|
|
||||||
}
|
|
@ -518,7 +518,7 @@ fill_trx_row(
|
|||||||
query[stmt_len] = '\0';
|
query[stmt_len] = '\0';
|
||||||
|
|
||||||
row->trx_query = ha_storage_put_memlim(
|
row->trx_query = ha_storage_put_memlim(
|
||||||
cache->storage, stmt, stmt_len + 1,
|
cache->storage, query, stmt_len + 1,
|
||||||
MAX_ALLOWED_FOR_STORAGE(cache));
|
MAX_ALLOWED_FOR_STORAGE(cache));
|
||||||
|
|
||||||
row->trx_query_cs = innobase_get_charset(trx->mysql_thd);
|
row->trx_query_cs = innobase_get_charset(trx->mysql_thd);
|
||||||
|
@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "usr0sess.h"
|
#include "usr0sess.h"
|
||||||
#include "read0read.h"
|
#include "read0read.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
#include "thr0loc.h"
|
|
||||||
#include "btr0sea.h"
|
#include "btr0sea.h"
|
||||||
#include "os0proc.h"
|
#include "os0proc.h"
|
||||||
#include "trx0xa.h"
|
#include "trx0xa.h"
|
||||||
|
@ -25,6 +25,7 @@ Created 1/30/1994 Heikki Tuuri
|
|||||||
|
|
||||||
#include "univ.i"
|
#include "univ.i"
|
||||||
#include "ut0dbg.h"
|
#include "ut0dbg.h"
|
||||||
|
#include "ha_prototypes.h"
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||||
#else
|
#else
|
||||||
@ -55,12 +56,13 @@ ut_dbg_assertion_failed(
|
|||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
#ifdef UNIV_HOTBACKUP
|
#ifdef UNIV_HOTBACKUP
|
||||||
fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
|
fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
|
||||||
file, line);
|
innobase_basename(file), line);
|
||||||
#else /* UNIV_HOTBACKUP */
|
#else /* UNIV_HOTBACKUP */
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" InnoDB: Assertion failure in thread %lu"
|
" InnoDB: Assertion failure in thread %lu"
|
||||||
" in file %s line %lu\n",
|
" in file %s line %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()), file, line);
|
os_thread_pf(os_thread_get_curr_id()),
|
||||||
|
innobase_basename(file), line);
|
||||||
#endif /* UNIV_HOTBACKUP */
|
#endif /* UNIV_HOTBACKUP */
|
||||||
if (expr) {
|
if (expr) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -93,7 +95,8 @@ ut_dbg_stop_thread(
|
|||||||
{
|
{
|
||||||
#ifndef UNIV_HOTBACKUP
|
#ifndef UNIV_HOTBACKUP
|
||||||
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
|
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
|
||||||
os_thread_pf(os_thread_get_curr_id()), file, line);
|
os_thread_pf(os_thread_get_curr_id()),
|
||||||
|
innobase_basename(file), line);
|
||||||
os_thread_sleep(1000000000);
|
os_thread_sleep(1000000000);
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user