1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Implement MySQL framework to support consistent read views in

cursors. This should fix Bug#11813 when InnoDB part is in 
(tested with a draft patch).
The idea of the patch is that if a storage engine supports
consistent read views, we open one when open a cursor,
set is as the active view when fetch from the cursor, and close
together with cursor close.
This commit is contained in:
konstantin@mysql.com
2005-07-20 20:02:36 +04:00
parent 4570ace8fb
commit 21957c423e
15 changed files with 151 additions and 95 deletions

View File

@@ -140,16 +140,19 @@ static handlerton archive_hton = {
"archive",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* releas savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* releas savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -77,16 +77,19 @@ static handlerton example_hton= {
"CSV",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -58,16 +58,19 @@ static handlerton tina_hton= {
"CSV",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -121,6 +121,9 @@ static handlerton berkeley_hton = {
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_CLOSE_CURSORS_AT_COMMIT
};

View File

@@ -30,16 +30,19 @@ static handlerton blackhole_hton= {
"BLACKHOLE",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -685,16 +685,19 @@ static handlerton federated_hton= {
"FEDERATED",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -27,16 +27,19 @@ static handlerton heap_hton= {
"MEMORY",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -216,12 +216,9 @@ static handlerton innobase_hton = {
innobase_xa_recover, /* recover */
innobase_commit_by_xid, /* commit_by_xid */
innobase_rollback_by_xid, /* rollback_by_xid */
/*
For now when one opens a cursor, MySQL does not create an own
InnoDB consistent read view for it, and uses the view of the
currently active transaction. Therefore, cursors can not
survive COMMIT or ROLLBACK statements, which free this view.
*/
NULL,
NULL,
NULL,
HTON_CLOSE_CURSORS_AT_COMMIT
};

View File

@@ -50,16 +50,19 @@ static handlerton myisam_hton= {
"MyISAM",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
/*
MyISAM doesn't support transactions and doesn't have
transaction-dependent context: cursors can survive a commit.

View File

@@ -38,16 +38,19 @@ static handlerton myisammrg_hton= {
"MRG_MyISAM",
0, /* slot */
0, /* savepoint size. */
0, /* close_connection */
0, /* savepoint */
0, /* rollback to savepoint */
0, /* release savepoint */
0, /* commit */
0, /* rollback */
0, /* prepare */
0, /* recover */
0, /* commit_by_xid */
0, /* rollback_by_xid */
NULL, /* close_connection */
NULL, /* savepoint */
NULL, /* rollback to savepoint */
NULL, /* release savepoint */
NULL, /* commit */
NULL, /* rollback */
NULL, /* prepare */
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -63,6 +63,9 @@ static handlerton ndbcluster_hton = {
NULL, /* recover */
NULL, /* commit_by_xid */
NULL, /* rollback_by_xid */
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
HTON_NO_FLAGS
};

View File

@@ -106,9 +106,11 @@
/*
Note: the following includes binlog and closing 0.
so: innodb+bdb+ndb+binlog+0
so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
example + csv + heap + blackhole + federated + 0
(yes, the sum is deliberately inaccurate)
*/
#define MAX_HA 6
#define MAX_HA 14
/*
Bits in index_ddl_flags(KEY *wanted_index)
@@ -349,6 +351,9 @@ typedef struct
int (*recover)(XID *xid_list, uint len);
int (*commit_by_xid)(XID *xid);
int (*rollback_by_xid)(XID *xid);
void *(*create_cursor_read_view)();
void (*set_cursor_read_view)(void *);
void (*close_cursor_read_view)(void *);
uint32 flags; /* global handler flags */
} handlerton;

View File

@@ -1712,12 +1712,14 @@ Cursor::Cursor(THD *thd)
/* We will overwrite it at open anyway. */
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
thr_lock_owner_init(&lock_id, &thd->lock_info);
bzero((void*) ht_info, sizeof(ht_info));
}
void
Cursor::init_from_thd(THD *thd)
{
Engine_info *info;
/*
We need to save and reset thd->mem_root, otherwise it'll be freed
later in mysql_parse.
@@ -1749,15 +1751,16 @@ Cursor::init_from_thd(THD *thd)
thd->lock_info.n_cursors++;
close_at_commit= FALSE; /* reset in case we're reusing the cursor */
for (TABLE *table= open_tables; table; table= table->next)
info= &ht_info[0];
for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
{
const handlerton *ht= table->file->ht;
if (ht)
close_at_commit|= (ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
else
const handlerton *ht= *pht;
close_at_commit|= (ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
if (ht->create_cursor_read_view)
{
close_at_commit= TRUE; /* handler status is unknown */
break;
info->ht= ht;
info->read_view= (ht->create_cursor_read_view)();
++info;
}
}
/*
@@ -1853,6 +1856,9 @@ Cursor::fetch(ulong num_rows)
/* save references to memory, allocated during fetch */
thd->set_n_backup_item_arena(this, &backup_arena);
for (Engine_info *info= ht_info; info->read_view ; info++)
(info->ht->set_cursor_read_view)(info->read_view);
join->fetch_limit+= num_rows;
error= sub_select(join, join_tab, 0);
@@ -1869,6 +1875,9 @@ Cursor::fetch(ulong num_rows)
/* Grab free_list here to correctly free it in close */
thd->restore_backup_item_arena(this, &backup_arena);
for (Engine_info *info= ht_info; info->read_view; info++)
(info->ht->set_cursor_read_view)(0);
if (error == NESTED_LOOP_CURSOR_LIMIT)
{
/* Fetch limit worked, possibly more rows are there */
@@ -1909,6 +1918,13 @@ Cursor::close(bool is_active)
else
(void) join->select_lex->cleanup();
for (Engine_info *info= ht_info; info->read_view; info++)
{
(info->ht->close_cursor_read_view)(info->read_view);
info->read_view= 0;
info->ht= 0;
}
if (is_active)
close_thread_tables(thd);
else

View File

@@ -389,6 +389,12 @@ class Cursor: public Sql_alloc, public Query_arena
TABLE *derived_tables;
/* List of items created during execution */
query_id_t query_id;
struct Engine_info
{
const handlerton *ht;
void *read_view;
};
Engine_info ht_info[MAX_HA];
public:
Item_change_list change_list;
select_send result;

View File

@@ -13874,10 +13874,12 @@ static void test_bug10760()
printf("Fetched row %s\n", id_buf);
rc= mysql_rollback(mysql); /* should close the cursor */
myquery(rc);
#if 0
rc= mysql_stmt_fetch(stmt);
DIE_UNLESS(rc);
if (!opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
#endif
}
mysql_stmt_close(stmt);