Some small fixes to the query cache.
Docs/manual.texi: Some small changes to the MySQL-PostgreSQL comparison. sql/item_timefunc.cc: Fixed typo. sql/sql_cache.cc: More debugging sql/sql_cache.h: More debugging
This commit is contained in:
parent
b79170b7fd
commit
51a80eb212
@ -4744,22 +4744,23 @@ MySQL Server offers the following advantages over PostgreSQL:
|
|||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
@code{MySQL} Server is generally much faster than PostgreSQL.
|
@code{MySQL} Server is generally much faster than PostgreSQL. MySQL
|
||||||
|
4.0.1 has also a query cache that can boost up the query speed for
|
||||||
|
mostly-read-only sites many times.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
MySQL has a much larger user base than PostgreSQL, therefore the
|
MySQL has a much larger user base than PostgreSQL, therefore the code is
|
||||||
code is more tested and has historically proven more stable than
|
more tested and has historically proven more stable than PostgreSQL.
|
||||||
PostgreSQL. MySQL Server is the much more used in production
|
MySQL Server is more used in production environments than PostgreSQL,
|
||||||
environments than PostgreSQL, mostly thanks to that MySQL AB,
|
mostly thanks to that MySQL AB, formerly TCX DataKonsult AB, has
|
||||||
formerly TCX DataKonsult AB, has provided top quality commercial support
|
provided top quality commercial support for MySQL Server from the day it
|
||||||
for MySQL Server from the day it was released, whereas until recently
|
was released, whereas until recently PostgreSQL was unsupported.
|
||||||
PostgreSQL was unsupported.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
MySQL Server works better on Windows than PostgreSQL does. MySQL Server runs as a
|
MySQL Server works better on Windows than PostgreSQL does. MySQL Server
|
||||||
native Windows application (a service on NT/Win2000/WinXP), while
|
runs as a native Windows application (a service on NT/Win2000/WinXP),
|
||||||
PostgreSQL is run under the @code{Cygwin} emulation. We have heard
|
while PostgreSQL is run under the @code{Cygwin} emulation. We have
|
||||||
that PostgreSQL is not yet that stable on Windows but we haven't
|
heard that PostgreSQL is not yet that stable on Windows but we haven't
|
||||||
been able to verify this ourselves.
|
been able to verify this ourselves.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
@ -4844,19 +4845,21 @@ You can access many databases from the same connection (depending of course
|
|||||||
on your privileges).
|
on your privileges).
|
||||||
|
|
||||||
@item
|
@item
|
||||||
MySQL Server is coded from the start to be multi-threaded while PostgreSQL uses
|
MySQL Server is coded from the start to be multi-threaded while
|
||||||
processes. Context switching and access to common storage areas is much
|
PostgreSQL uses processes. Context switching and access to common
|
||||||
faster between threads than between separate processes, this gives MySQL Server
|
storage areas is much faster between threads than between separate
|
||||||
a big speed advantage in multi-user applications and also makes it easier
|
processes, this gives MySQL Server a big speed advantage in multi-user
|
||||||
for MySQL Server to take full advantage of symmetric multiprocessor (SMP) systems.
|
applications and also makes it easier for MySQL Server to take full
|
||||||
|
advantage of symmetric multiprocessor (SMP) systems.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
MySQL Server has a much more sophisticated privilege system than PostgreSQL.
|
MySQL Server has a much more sophisticated privilege system than
|
||||||
While PostgreSQL only supports @code{INSERT}, @code{SELECT}, and
|
PostgreSQL. While PostgreSQL only supports @code{INSERT},
|
||||||
@code{UPDATE/DELETE} grants per user on a database or a table, MySQL Server allows
|
@code{SELECT}, and @code{UPDATE/DELETE} grants per user on a database or
|
||||||
you to define a full set of different privileges on database, table and
|
a table, MySQL Server allows you to define a full set of different
|
||||||
column level. MySQL Server also allows you to specify the privilege on host and
|
privileges on database, table and column level. MySQL Server also
|
||||||
user combinations. @xref{GRANT}.
|
allows you to specify the privilege on host and user combinations.
|
||||||
|
@xref{GRANT}.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
MySQL Server supports a compressed client/server protocol which improves
|
MySQL Server supports a compressed client/server protocol which improves
|
||||||
@ -4880,16 +4883,17 @@ of a data file happens, usually from a hardware failure. It allows a
|
|||||||
majority of the data to be recovered.
|
majority of the data to be recovered.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Upgrading MySQL Server is painless. When you are upgrading MySQL Server, you don't need
|
Upgrading MySQL Server is painless. When you are upgrading MySQL
|
||||||
to dump/restore your data, as you have to do with most PostgreSQL upgrades.
|
Server, you don't need to dump/restore your data, as you have to do with
|
||||||
|
most PostgreSQL upgrades.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
Drawbacks with MySQL Server compared to PostgreSQL:
|
Drawbacks with MySQL Server compared to PostgreSQL:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
The transaction support in MySQL Server is not yet as well tested as PostgreSQL's
|
The transaction support in MySQL Server is not yet as well tested as
|
||||||
system.
|
PostgreSQL's system.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Because MySQL Server uses threads, which are not yet flawless on many OSes, one
|
Because MySQL Server uses threads, which are not yet flawless on many OSes, one
|
||||||
@ -4914,10 +4918,10 @@ as in PostgreSQL. @xref{Adding functions}.
|
|||||||
|
|
||||||
@item
|
@item
|
||||||
Updates that run over multiple tables is harder to do in MySQL Server.
|
Updates that run over multiple tables is harder to do in MySQL Server.
|
||||||
This will, however, be fixed in MySQL Server 4.0 with multi-table @code{UPDATE}
|
This will, however, be fixed in MySQL Server 4.0.2 with multi-table
|
||||||
and in MySQL Server 4.1 with subselects.
|
@code{UPDATE} and in MySQL Server 4.1 with subselects. In MySQL Server
|
||||||
In MySQL Server 4.0 one can use multi-table deletes to delete from many tables
|
4.0 one can use multi-table deletes to delete from many tables at the
|
||||||
at the same time. @xref{DELETE}.
|
same time. @xref{DELETE}.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
PostgreSQL currently offers the following advantages over MySQL Server:
|
PostgreSQL currently offers the following advantages over MySQL Server:
|
||||||
|
@ -1127,7 +1127,7 @@ longlong Item_extract::val_int()
|
|||||||
|
|
||||||
void Item_typecast::print(String *str)
|
void Item_typecast::print(String *str)
|
||||||
{
|
{
|
||||||
str->append("CASE(");
|
str->append("CAST(");
|
||||||
args[0]->print(str);
|
args[0]->print(str);
|
||||||
str->append(" AS ");
|
str->append(" AS ");
|
||||||
str->append(func_name());
|
str->append(func_name());
|
||||||
|
@ -344,7 +344,8 @@ inline Query_cache_block * Query_cache_block_table::block()
|
|||||||
void Query_cache_block::init(ulong block_length)
|
void Query_cache_block::init(ulong block_length)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Query_cache_block::init");
|
DBUG_ENTER("Query_cache_block::init");
|
||||||
DBUG_PRINT("qcache", ("init block 0x%lx", (ulong) this));
|
DBUG_PRINT("qcache", ("init block 0x%lx length: %lu", (ulong) this,
|
||||||
|
block_length));
|
||||||
length = block_length;
|
length = block_length;
|
||||||
used = 0;
|
used = 0;
|
||||||
type = Query_cache_block::FREE;
|
type = Query_cache_block::FREE;
|
||||||
@ -587,7 +588,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
||||||
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(););
|
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +616,7 @@ void query_cache_abort(NET *net)
|
|||||||
}
|
}
|
||||||
net->query_cache_query=0;
|
net->query_cache_query=0;
|
||||||
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
||||||
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(););
|
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -662,7 +663,7 @@ void query_cache_end_of_result(NET *net)
|
|||||||
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
|
||||||
}
|
}
|
||||||
net->query_cache_query=0;
|
net->query_cache_query=0;
|
||||||
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(););
|
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -670,7 +671,7 @@ void query_cache_end_of_result(NET *net)
|
|||||||
void query_cache_invalidate_by_MyISAM_filename(const char *filename)
|
void query_cache_invalidate_by_MyISAM_filename(const char *filename)
|
||||||
{
|
{
|
||||||
query_cache.invalidate_by_MyISAM_filename(filename);
|
query_cache.invalidate_by_MyISAM_filename(filename);
|
||||||
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(););
|
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2482,6 +2483,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
*pprev = block->pprev,
|
*pprev = block->pprev,
|
||||||
*pnext = block->pnext,
|
*pnext = block->pnext,
|
||||||
*new_block =(Query_cache_block *) *border;
|
*new_block =(Query_cache_block *) *border;
|
||||||
|
uint tablename_offset = block->table()->table() - block->table()->db();
|
||||||
char *data = (char*) block->data();
|
char *data = (char*) block->data();
|
||||||
byte *key;
|
byte *key;
|
||||||
uint key_length;
|
uint key_length;
|
||||||
@ -2493,7 +2495,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
new_block->type=Query_cache_block::TABLE;
|
new_block->type=Query_cache_block::TABLE;
|
||||||
new_block->used=used;
|
new_block->used=used;
|
||||||
new_block->n_tables=1;
|
new_block->n_tables=1;
|
||||||
memcpy((char*) new_block->data(), data, len-new_block->headers_len());
|
memmove((char*) new_block->data(), data, len-new_block->headers_len());
|
||||||
relink(block, new_block, next, prev, pnext, pprev);
|
relink(block, new_block, next, prev, pnext, pprev);
|
||||||
if (tables_blocks[new_block->table()->type()] == block)
|
if (tables_blocks[new_block->table()->type()] == block)
|
||||||
tables_blocks[new_block->table()->type()] = new_block;
|
tables_blocks[new_block->table()->type()] = new_block;
|
||||||
@ -2515,10 +2517,18 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
nlist_root->prev = tnext;
|
nlist_root->prev = tnext;
|
||||||
tprev->next = nlist_root;
|
tprev->next = nlist_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Go through all queries that uses this table and change them to
|
||||||
|
point to the new table object
|
||||||
|
*/
|
||||||
|
Query_cache_table *new_block_table=new_block->table();
|
||||||
for (;tnext != nlist_root; tnext=tnext->next)
|
for (;tnext != nlist_root; tnext=tnext->next)
|
||||||
tnext->parent = new_block->table();
|
tnext->parent= new_block_table;
|
||||||
*border += len;
|
*border += len;
|
||||||
*before = new_block;
|
*before = new_block;
|
||||||
|
/* Fix pointer to table name */
|
||||||
|
new_block->table()->table(new_block->table()->db() + tablename_offset);
|
||||||
/* Fix hash to point at moved block */
|
/* Fix hash to point at moved block */
|
||||||
hash_replace(&tables, tables.current_record, (byte*) new_block);
|
hash_replace(&tables, tables.current_record, (byte*) new_block);
|
||||||
|
|
||||||
@ -2546,8 +2556,8 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
uint key_length;
|
uint key_length;
|
||||||
key=query_cache_query_get_key((byte*) block, &key_length, 0);
|
key=query_cache_query_get_key((byte*) block, &key_length, 0);
|
||||||
hash_search(&queries, (byte*) key, key_length);
|
hash_search(&queries, (byte*) key, key_length);
|
||||||
|
// Move table of used tables
|
||||||
memcpy((char*) new_block->table(0), (char*) block->table(0),
|
memmove((char*) new_block->table(0), (char*) block->table(0),
|
||||||
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
|
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
|
||||||
block->query()->unlock_n_destroy();
|
block->query()->unlock_n_destroy();
|
||||||
block->destroy();
|
block->destroy();
|
||||||
@ -2555,7 +2565,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
new_block->type=Query_cache_block::QUERY;
|
new_block->type=Query_cache_block::QUERY;
|
||||||
new_block->used=used;
|
new_block->used=used;
|
||||||
new_block->n_tables=n_tables;
|
new_block->n_tables=n_tables;
|
||||||
memcpy((char*) new_block->data(), data, len - new_block->headers_len());
|
memmove((char*) new_block->data(), data, len - new_block->headers_len());
|
||||||
relink(block, new_block, next, prev, pnext, pprev);
|
relink(block, new_block, next, prev, pnext, pprev);
|
||||||
if (queries_blocks == block)
|
if (queries_blocks == block)
|
||||||
queries_blocks = new_block;
|
queries_blocks = new_block;
|
||||||
@ -2620,7 +2630,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
|||||||
new_block->init(len);
|
new_block->init(len);
|
||||||
new_block->type=type;
|
new_block->type=type;
|
||||||
new_block->used=used;
|
new_block->used=used;
|
||||||
memcpy((char*) new_block->data(), data, len - new_block->headers_len());
|
memmove((char*) new_block->data(), data, len - new_block->headers_len());
|
||||||
relink(block, new_block, next, prev, pnext, pprev);
|
relink(block, new_block, next, prev, pnext, pprev);
|
||||||
new_block->result()->parent(query_block);
|
new_block->result()->parent(query_block);
|
||||||
Query_cache_query *query = query_block->query();
|
Query_cache_query *query = query_block->query();
|
||||||
@ -2786,7 +2796,7 @@ void bins_dump() {}
|
|||||||
void cache_dump() {}
|
void cache_dump() {}
|
||||||
void queries_dump() {}
|
void queries_dump() {}
|
||||||
void tables_dump() {}
|
void tables_dump() {}
|
||||||
my_bool check_integrity() { return 0; }
|
my_bool check_integrity(bool not_locked) { return 0; }
|
||||||
my_bool in_list(Query_cache_block * root, Query_cache_block * point,
|
my_bool in_list(Query_cache_block * root, Query_cache_block * point,
|
||||||
const char *name) { return 0;}
|
const char *name) { return 0;}
|
||||||
my_bool in_blocks(Query_cache_block * point) { return 0; }
|
my_bool in_blocks(Query_cache_block * point) { return 0; }
|
||||||
@ -2806,7 +2816,7 @@ void Query_cache::wreck(uint line, const char *message)
|
|||||||
if (thd)
|
if (thd)
|
||||||
thd->killed = 1;
|
thd->killed = 1;
|
||||||
cache_dump();
|
cache_dump();
|
||||||
/* check_integrity(); */ /* Can't call it here because of locks */
|
/* check_integrity(0); */ /* Can't call it here because of locks */
|
||||||
bins_dump();
|
bins_dump();
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -2977,19 +2987,19 @@ void Query_cache::tables_dump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool Query_cache::check_integrity()
|
my_bool Query_cache::check_integrity(bool not_locked)
|
||||||
{
|
{
|
||||||
my_bool result = 0;
|
my_bool result = 0;
|
||||||
uint i;
|
uint i;
|
||||||
STRUCT_LOCK(&structure_guard_mutex);
|
|
||||||
DBUG_ENTER("check_integrity");
|
DBUG_ENTER("check_integrity");
|
||||||
|
|
||||||
if (!initialized )
|
if (!initialized )
|
||||||
{
|
{
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
|
||||||
DBUG_PRINT("qcache", ("Query Cache not initialized"));
|
DBUG_PRINT("qcache", ("Query Cache not initialized"));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
if (!not_locked)
|
||||||
|
STRUCT_LOCK(&structure_guard_mutex);
|
||||||
|
|
||||||
if (hash_check(&queries))
|
if (hash_check(&queries))
|
||||||
{
|
{
|
||||||
@ -3213,6 +3223,7 @@ my_bool Query_cache::check_integrity()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(result == 0);
|
DBUG_ASSERT(result == 0);
|
||||||
|
if (!not_locked)
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ protected:
|
|||||||
void cache_dump();
|
void cache_dump();
|
||||||
void queries_dump();
|
void queries_dump();
|
||||||
void tables_dump();
|
void tables_dump();
|
||||||
my_bool check_integrity();
|
my_bool check_integrity(bool not_locked);
|
||||||
my_bool in_list(Query_cache_block * root, Query_cache_block * point,
|
my_bool in_list(Query_cache_block * root, Query_cache_block * point,
|
||||||
const char *name);
|
const char *name);
|
||||||
my_bool in_blocks(Query_cache_block * point);
|
my_bool in_blocks(Query_cache_block * point);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user