summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2000-12-07 14:08:48 +0200
committerunknown <monty@donna.mysql.com>2000-12-07 14:08:48 +0200
commit29907fc5a4e0982e4bd287355bf79ab6e429795a (patch)
tree8a5c9d678d477bb2c3fa95057c9299dcf9560aab /sql
parente5c585861e6bf411fd64a18d3a08dbacf039d21a (diff)
downloadmariadb-git-29907fc5a4e0982e4bd287355bf79ab6e429795a.tar.gz
Only write full transactions to binary log
A lot of new functions for BDB tables Fix for DROP DATABASE on windows Default server_id variables Docs/manual.texi: Update of BDB info + Changes configure.in: Added test of readlink include/mysqld_error.h: Added new error message sql/ha_berkeley.cc: Added storing of status, CHECK, ANALYZE and OPTIMIZE TABLE sql/ha_berkeley.h: Added storing of status, CHECK, ANALYZE and OPTIMIZE TABLE sql/handler.cc: Only write full transactions to binary log sql/hostname.cc: cleanup sql/log.cc: Only write full transactions to binary log sql/log_event.h: Only write full transactions to binary log sql/mf_iocache.cc: Changes to be able to use IO_CACHE to save statements in a transaction sql/mysql_priv.h: New variables sql/mysqld.cc: Only write full transactions to binary log Added default values for server_id Lots of new bdb options sql/share/czech/errmsg.sys: Added new error message sql/share/czech/errmsg.txt: Added new error message sql/share/danish/errmsg.sys: Added new error message sql/share/danish/errmsg.txt: Added new error message sql/share/dutch/errmsg.sys: Added new error message sql/share/dutch/errmsg.txt: Added new error message sql/share/english/errmsg.sys: Added new error message sql/share/english/errmsg.txt: Added new error message sql/share/estonian/errmsg.sys: Added new error message sql/share/estonian/errmsg.txt: Added new error message sql/share/french/errmsg.sys: Added new error message sql/share/french/errmsg.txt: Added new error message sql/share/german/errmsg.sys: Added new error message sql/share/german/errmsg.txt: Added new error message sql/share/greek/errmsg.sys: Added new error message sql/share/greek/errmsg.txt: Added new error message sql/share/hungarian/errmsg.sys: Added new error message sql/share/hungarian/errmsg.txt: Added new error message sql/share/italian/errmsg.sys: Added new error message sql/share/italian/errmsg.txt: Added new error message sql/share/japanese/errmsg.sys: Added new error message sql/share/japanese/errmsg.txt: Added new error message sql/share/korean/errmsg.sys: Added new error message sql/share/korean/errmsg.txt: Added new error message sql/share/norwegian-ny/errmsg.txt: Added new error message sql/share/norwegian/errmsg.txt: Added new error message sql/share/polish/errmsg.sys: Added new error message sql/share/polish/errmsg.txt: Added new error message sql/share/portuguese/errmsg.sys: Added new error message sql/share/portuguese/errmsg.txt: Added new error message sql/share/romanian/errmsg.txt: Added new error message sql/share/russian/errmsg.sys: Added new error message sql/share/russian/errmsg.txt: Added new error message sql/share/slovak/errmsg.sys: Added new error message sql/share/slovak/errmsg.txt: Added new error message sql/share/spanish/errmsg.sys: Added new error message sql/share/spanish/errmsg.txt: Added new error message sql/share/swedish/errmsg.OLD: Added new error message sql/share/swedish/errmsg.sys: Added new error message sql/share/swedish/errmsg.txt: Added new error message sql/sql_base.cc: cleanup sql/sql_class.cc: Only write full transactions to binary log sql/sql_class.h: Added error handling of failed writes to logs sql/sql_db.cc: Fix for DROP DATABASE on windows sql/sql_delete.cc: Only write full transactions to binary log sql/sql_insert.cc: Only write full transactions to binary log sql/sql_load.cc: Only write full transactions to binary log sql/sql_parse.cc: End transaction at DROP, RENAME, CREATE and TRUNCATE sql/sql_table.cc: Fixes for ALTER TABLE on BDB tables for windows sql/sql_update.cc: Only write full transactions to binary log sql/sql_yacc.yy: AGAINST is not anymore a reserved word support-files/my-huge.cnf.sh: Changed to use binary log support-files/my-large.cnf.sh: Changed to use binary log support-files/my-medium.cnf.sh: Changed to use binary log support-files/my-small.cnf.sh: Changed to use binary log
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_berkeley.cc391
-rw-r--r--sql/ha_berkeley.h26
-rw-r--r--sql/handler.cc24
-rw-r--r--sql/hostname.cc18
-rw-r--r--sql/log.cc240
-rw-r--r--sql/log_event.h10
-rw-r--r--sql/mf_iocache.cc32
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/mysqld.cc80
-rw-r--r--sql/share/czech/errmsg.sysbin10564 -> 10567 bytes
-rw-r--r--sql/share/czech/errmsg.txt1
-rw-r--r--sql/share/danish/errmsg.sysbin10475 -> 10478 bytes
-rw-r--r--sql/share/danish/errmsg.txt1
-rw-r--r--sql/share/dutch/errmsg.sysbin10691 -> 10694 bytes
-rw-r--r--sql/share/dutch/errmsg.txt1
-rw-r--r--sql/share/english/errmsg.sysbin9856 -> 9859 bytes
-rw-r--r--sql/share/english/errmsg.txt1
-rw-r--r--sql/share/estonian/errmsg.sysbin9832 -> 9835 bytes
-rw-r--r--sql/share/estonian/errmsg.txt1
-rw-r--r--sql/share/french/errmsg.sysbin10297 -> 10300 bytes
-rw-r--r--sql/share/french/errmsg.txt1
-rw-r--r--sql/share/german/errmsg.sysbin11318 -> 11321 bytes
-rw-r--r--sql/share/german/errmsg.txt1
-rw-r--r--sql/share/greek/errmsg.sysbin11903 -> 11906 bytes
-rw-r--r--sql/share/greek/errmsg.txt1
-rw-r--r--sql/share/hungarian/errmsg.sysbin10812 -> 10815 bytes
-rw-r--r--sql/share/hungarian/errmsg.txt1
-rw-r--r--sql/share/italian/errmsg.sysbin11466 -> 11469 bytes
-rw-r--r--sql/share/italian/errmsg.txt1
-rw-r--r--sql/share/japanese/errmsg.sysbin10603 -> 10606 bytes
-rw-r--r--sql/share/japanese/errmsg.txt1
-rw-r--r--sql/share/korean/errmsg.sysbin10733 -> 10736 bytes
-rw-r--r--sql/share/korean/errmsg.txt1
-rw-r--r--sql/share/norwegian-ny/errmsg.txt1
-rw-r--r--sql/share/norwegian/errmsg.txt1
-rw-r--r--sql/share/polish/errmsg.sysbin10491 -> 10494 bytes
-rw-r--r--sql/share/polish/errmsg.txt1
-rw-r--r--sql/share/portuguese/errmsg.sysbin10416 -> 10419 bytes
-rw-r--r--sql/share/portuguese/errmsg.txt1
-rw-r--r--sql/share/romanian/errmsg.txt1
-rw-r--r--sql/share/russian/errmsg.sysbin10310 -> 10323 bytes
-rw-r--r--sql/share/russian/errmsg.txt1
-rw-r--r--sql/share/slovak/errmsg.sysbin10076 -> 10079 bytes
-rw-r--r--sql/share/slovak/errmsg.txt1
-rw-r--r--sql/share/spanish/errmsg.sysbin10432 -> 10435 bytes
-rw-r--r--sql/share/spanish/errmsg.txt1
-rw-r--r--sql/share/swedish/errmsg.OLD2
-rw-r--r--sql/share/swedish/errmsg.sysbin10187 -> 10296 bytes
-rw-r--r--sql/share/swedish/errmsg.txt1
-rw-r--r--sql/sql_base.cc18
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_db.cc14
-rw-r--r--sql/sql_delete.cc14
-rw-r--r--sql/sql_insert.cc17
-rw-r--r--sql/sql_load.cc5
-rw-r--r--sql/sql_parse.cc26
-rw-r--r--sql/sql_table.cc14
-rw-r--r--sql/sql_update.cc14
-rw-r--r--sql/sql_yacc.yy1
60 files changed, 719 insertions, 268 deletions
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index f515b151c8b..35e503751af 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -37,12 +37,15 @@
transaction ?)
- When using ALTER TABLE IGNORE, we should not start an transaction, but do
everything wthout transactions.
+ - When we do rollback, we need to subtract the number of changed rows
+ from the updated tables.
Testing of:
- - ALTER TABLE
- LOCK TABLES
- - CHAR keys
- BLOBS
+ - Mark tables that participate in a transaction so that they are not
+ closed during the transaction. We need to test what happens if
+ MySQL closes a table that is updated by a not commit transaction.
*/
@@ -58,19 +61,27 @@
#include <hash.h>
#include "ha_berkeley.h"
#include "sql_manager.h"
+#include <stdarg.h>
#define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_BERKELEY_RANGE_COUNT 100
#define HA_BERKELEY_MAX_ROWS 10000000 /* Max rows in table */
+/* extra rows for estimate_number_of_rows() */
+#define HA_BERKELEY_EXTRA_ROWS 100
+
+/* Bits for share->status */
+#define STATUS_PRIMARY_KEY_INIT 1
+#define STATUS_ROW_COUNT_INIT 2
+#define STATUS_BDB_ANALYZE 4
const char *ha_berkeley_ext=".db";
-bool berkeley_skip=0;
-u_int32_t berkeley_init_flags=0,berkeley_lock_type=DB_LOCK_DEFAULT;
+bool berkeley_skip=0,berkeley_shared_data=0;
+u_int32_t berkeley_init_flags= DB_PRIVATE, berkeley_lock_type=DB_LOCK_DEFAULT;
ulong berkeley_cache_size;
char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
long berkeley_lock_scan_time=0;
ulong berkeley_trans_retry=5;
-ulong berkeley_lock_max;
+ulong berkeley_max_lock;
pthread_mutex_t bdb_mutex;
static DB_ENV *db_env;
@@ -86,11 +97,13 @@ TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names),"",
static void berkeley_print_error(const char *db_errpfx, char *buffer);
static byte* bdb_get_key(BDB_SHARE *share,uint *length,
my_bool not_used __attribute__((unused)));
-static BDB_SHARE *get_share(const char *table_name);
-static void free_share(BDB_SHARE *share);
+static BDB_SHARE *get_share(const char *table_name, TABLE *table);
+static void free_share(BDB_SHARE *share, TABLE *table);
+static void update_status(BDB_SHARE *share, TABLE *table);
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
+
/* General functions */
bool berkeley_init(void)
@@ -121,14 +134,14 @@ bool berkeley_init(void)
db_env->set_cachesize(db_env, 0, berkeley_cache_size, 0);
db_env->set_lk_detect(db_env, berkeley_lock_type);
- if (berkeley_lock_max)
- db_env->set_lk_max(db_env, berkeley_lock_max);
+ if (berkeley_max_lock)
+ db_env->set_lk_max(db_env, berkeley_max_lock);
if (db_env->open(db_env,
berkeley_home,
berkeley_init_flags | DB_INIT_LOCK |
DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN |
- DB_CREATE | DB_THREAD | DB_PRIVATE, 0666))
+ DB_CREATE | DB_THREAD, 0666))
{
db_env->close(db_env,0);
db_env=0;
@@ -336,7 +349,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
if (*key != (table->record[0][key_part->null_offset] &
key_part->null_bit) ? 0 : 1)
return 1;
- if (!*key++) // Null value
+ if (!*key++) // Null value
continue;
}
if ((cmp=key_part->field->pack_cmp(key,key_part->length)))
@@ -345,7 +358,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
key+=length;
key_length-=length;
}
- return 0;
+ return 0; // Identical keys
}
@@ -387,7 +400,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
}
/* Init table lock structure */
- if (!(share=get_share(name)))
+ if (!(share=get_share(name,table)))
{
my_free(rec_buff,MYF(0));
my_free(alloc_ptr,MYF(0));
@@ -397,7 +410,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
if ((error=db_create(&file, db_env, 0)))
{
- free_share(share);
+ free_share(share,table);
my_free(rec_buff,MYF(0));
my_free(alloc_ptr,MYF(0));
my_errno=error;
@@ -413,7 +426,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
2 | 4),
"main", DB_BTREE, open_mode,0))))
{
- free_share(share);
+ free_share(share,table);
my_free(rec_buff,MYF(0));
my_free(alloc_ptr,MYF(0));
my_errno=error;
@@ -459,7 +472,6 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
}
}
}
-
/* Calculate pack_length of primary key */
if (!hidden_primary_key)
{
@@ -470,12 +482,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
ref_length+= key_part->field->max_packed_col_length(key_part->length);
fixed_length_primary_key=
(ref_length == table->key_info[primary_key].key_length);
+ share->status|=STATUS_PRIMARY_KEY_INIT;
}
- else
- {
- if (!share->primary_key_inited)
- update_auto_primary_key();
- }
+ get_status();
DBUG_RETURN(0);
}
@@ -491,7 +500,7 @@ int ha_berkeley::close(void)
if (key_file[i] && (error=key_file[i]->close(key_file[i],0)))
result=error;
}
- free_share(share);
+ free_share(share,table);
my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR));
my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR));
if (result)
@@ -632,8 +641,8 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index)
This will never fail as the key buffer is pre allocated.
*/
-DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
- const byte *record)
+DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
+ const byte *record, int key_length)
{
bzero((char*) key,sizeof(*key));
@@ -647,11 +656,11 @@ DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
KEY *key_info=table->key_info+keynr;
KEY_PART_INFO *key_part=key_info->key_part;
KEY_PART_INFO *end=key_part+key_info->key_parts;
- DBUG_ENTER("pack_key");
+ DBUG_ENTER("create_key");
key->data=buff;
- for ( ; key_part != end ; key_part++)
+ for ( ; key_part != end && key_length > 0; key_part++)
{
if (key_part->null_bit)
{
@@ -666,6 +675,7 @@ DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
}
buff=key_part->field->pack(buff,record + key_part->offset,
key_part->length);
+ key_length-=key_part->length;
}
key->size= (buff - (char*) key->data);
DBUG_DUMP("key",(char*) key->data, key->size);
@@ -729,8 +739,8 @@ int ha_berkeley::write_row(byte * record)
if (table->keys == 1)
{
- error=file->put(file, transaction, pack_key(&prim_key, primary_key,
- key_buff, record),
+ error=file->put(file, transaction, create_key(&prim_key, primary_key,
+ key_buff, record),
&row, key_type[primary_key]);
}
else
@@ -742,8 +752,8 @@ int ha_berkeley::write_row(byte * record)
if ((error=txn_begin(db_env, transaction, &sub_trans, 0)))
break;
DBUG_PRINT("trans",("starting subtransaction"));
- if (!(error=file->put(file, sub_trans, pack_key(&prim_key, primary_key,
- key_buff, record),
+ if (!(error=file->put(file, sub_trans, create_key(&prim_key, primary_key,
+ key_buff, record),
&row, key_type[primary_key])))
{
for (keynr=0 ; keynr < table->keys ; keynr++)
@@ -751,8 +761,8 @@ int ha_berkeley::write_row(byte * record)
if (keynr == primary_key)
continue;
if ((error=key_file[keynr]->put(key_file[keynr], sub_trans,
- pack_key(&key, keynr, key_buff2,
- record),
+ create_key(&key, keynr, key_buff2,
+ record),
&prim_key, key_type[keynr])))
{
last_dup_key=keynr;
@@ -783,6 +793,8 @@ int ha_berkeley::write_row(byte * record)
}
if (error == DB_KEYEXIST)
error=HA_ERR_FOUND_DUPP_KEY;
+ else if (!error)
+ changed_rows++;
DBUG_RETURN(error);
}
@@ -838,7 +850,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
{
// Primary key changed or we are updating a key that can have duplicates.
// Delete the old row and add a new one
- pack_key(&old_key, primary_key, key_buff2, old_row);
+ create_key(&old_key, primary_key, key_buff2, old_row);
if ((error=remove_key(trans, primary_key, old_row, (DBT *) 0, &old_key)))
DBUG_RETURN(error); // This should always succeed
if ((error=pack_row(&row, new_row, 0)))
@@ -893,10 +905,10 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
}
else
{
- pack_key(&prim_key, primary_key, key_buff, new_row);
+ create_key(&prim_key, primary_key, key_buff, new_row);
if ((primary_key_changed=key_cmp(primary_key, old_row, new_row)))
- pack_key(&old_prim_key, primary_key, primary_key_buff, old_row);
+ create_key(&old_prim_key, primary_key, primary_key_buff, old_row);
else
old_prim_key=prim_key;
}
@@ -921,7 +933,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
if ((error=remove_key(sub_trans, keynr, old_row, (DBT*) 0,
&old_prim_key)) ||
(error=key_file[keynr]->put(key_file[keynr], sub_trans,
- pack_key(&key, keynr, key_buff2,
+ create_key(&key, keynr, key_buff2,
new_row),
&prim_key, key_type[keynr])))
{
@@ -980,7 +992,7 @@ int ha_berkeley::remove_key(DB_TXN *sub_trans, uint keynr, const byte *record,
error=key_file[keynr]->del(key_file[keynr], sub_trans,
keynr == primary_key ?
prim_key :
- pack_key(&key, keynr, key_buff2, record),
+ create_key(&key, keynr, key_buff2, record),
0);
}
else
@@ -997,7 +1009,7 @@ int ha_berkeley::remove_key(DB_TXN *sub_trans, uint keynr, const byte *record,
if (!(error=cursor->c_get(cursor,
(keynr == primary_key ?
prim_key :
- pack_key(&key, keynr, key_buff2, record)),
+ create_key(&key, keynr, key_buff2, record)),
(keynr == primary_key ?
packed_record : prim_key),
DB_GET_BOTH)))
@@ -1046,7 +1058,7 @@ int ha_berkeley::delete_row(const byte * record)
if ((error=pack_row(&row, record, 0)))
DBUG_RETURN((error));
- pack_key(&prim_key, primary_key, key_buff, record);
+ create_key(&prim_key, primary_key, key_buff, record);
if (hidden_primary_key)
keys|= (key_map) 1 << primary_key;
@@ -1078,7 +1090,9 @@ int ha_berkeley::delete_row(const byte * record)
if (error != DB_LOCK_DEADLOCK)
break;
}
- DBUG_RETURN(0);
+ if (!error)
+ changed_rows--;
+ DBUG_RETURN(error);
}
@@ -1090,7 +1104,7 @@ int ha_berkeley::index_init(uint keynr)
dbug_assert(cursor == 0);
if ((error=file->cursor(key_file[keynr], transaction, &cursor,
table->reginfo.lock_type > TL_WRITE_ALLOW_READ ?
- 0 : 0)))
+ DB_RMW : 0)))
cursor=0; // Safety
bzero((char*) &last_key,sizeof(last_key));
DBUG_RETURN(error);
@@ -1336,7 +1350,7 @@ void ha_berkeley::position(const byte *record)
memcpy_fixed(ref, (char*) current_ident, BDB_HIDDEN_PRIMARY_KEY_LENGTH);
}
else
- pack_key(&key, primary_key, ref, record);
+ create_key(&key, primary_key, ref, record);
}
@@ -1345,9 +1359,18 @@ void ha_berkeley::info(uint flag)
DBUG_ENTER("info");
if (flag & HA_STATUS_VARIABLE)
{
- records = estimate_number_of_rows(); // Just to get optimisations right
+ records = share->rows; // Just to get optimisations right
deleted = 0;
}
+ if ((flag & HA_STATUS_CONST) || version != share->version)
+ {
+ version=share->version;
+ for (uint i=0 ; i < table->keys ; i++)
+ {
+ table->key_info[i].rec_per_key[table->key_info[i].key_parts-1]=
+ share->rec_per_key[i];
+ }
+ }
else if (flag & HA_STATUS_ERRKEY)
errkey=last_dup_key;
DBUG_VOID_RETURN;
@@ -1424,6 +1447,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
}
}
transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid;
+ changed_rows=0;
}
else
{
@@ -1437,6 +1461,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
current_row.data=0;
}
}
+ thread_safe_add(share->rows, changed_rows, &share->mutex);
current_row.data=0;
if (!--thd->transaction.bdb_lock_count)
{
@@ -1607,6 +1632,142 @@ ha_rows ha_berkeley::records_in_range(int keynr,
DBUG_RETURN(rows <= 1.0 ? (ha_rows) 1 : (ha_rows) rows);
}
+
+longlong ha_berkeley::get_auto_increment()
+{
+ longlong nr=1; // Default if error or new key
+ int error;
+ (void) ha_berkeley::extra(HA_EXTRA_KEYREAD);
+ ha_berkeley::index_init(table->next_number_index);
+
+ if (!table->next_number_key_offset)
+ { // Autoincrement at key-start
+ error=ha_berkeley::index_last(table->record[1]);
+ }
+ else
+ {
+ DBT row;
+ bzero((char*) &row,sizeof(row));
+ uint key_len;
+ KEY *key_info= &table->key_info[active_index];
+
+ /* Reading next available number for a sub key */
+ ha_berkeley::create_key(&last_key, active_index,
+ key_buff, table->record[0],
+ table->next_number_key_offset);
+ /* Store for compare */
+ memcpy(key_buff2, key_buff, (key_len=last_key.size));
+ key_info->handler.bdb_return_if_eq= -1;
+ error=read_row(cursor->c_get(cursor, &last_key, &row, DB_SET_RANGE),
+ table->record[1], active_index, &row, (DBT*) 0, 0);
+ key_info->handler.bdb_return_if_eq= 0;
+ if (!error && !berkeley_key_cmp(table, key_info, key_buff2, key_len))
+ {
+ /*
+ Found matching key; Now search after next key, go one step back
+ and then we should have found the biggest key with the given
+ prefix
+ */
+ (void) read_row(cursor->c_get(cursor, &last_key, &row, DB_NEXT_NODUP),
+ table->record[1], active_index, &row, (DBT*) 0, 0);
+ if (read_row(cursor->c_get(cursor, &last_key, &row, DB_PREV),
+ table->record[1], active_index, &row, (DBT*) 0, 0) ||
+ berkeley_key_cmp(table, key_info, key_buff2, key_len))
+ error=1; // Something went wrong
+ }
+ }
+ nr=(longlong)
+ table->next_number_field->val_int_offset(table->rec_buff_length)+1;
+ ha_berkeley::index_end();
+ (void) ha_berkeley::extra(HA_EXTRA_NO_KEYREAD);
+ return nr;
+}
+
+
+/****************************************************************************
+ Analyzing, checking, and optimizing tables
+****************************************************************************/
+
+
+static void print_msg(THD *thd, const char *table_name, const char *op_name,
+ const char *msg_type, const char *fmt, ...)
+{
+ String* packet = &thd->packet;
+ packet->length(0);
+ char msgbuf[256];
+ msgbuf[0] = 0;
+ va_list args;
+ va_start(args,fmt);
+
+ my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
+ msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
+
+ DBUG_PRINT(msg_type,("message: %s",msgbuf));
+
+ net_store_data(packet, table_name);
+ net_store_data(packet, op_name);
+ net_store_data(packet, msg_type);
+ net_store_data(packet, msgbuf);
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
+ thd->packet.length()))
+ thd->killed=1;
+}
+
+
+int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ DB_BTREE_STAT stat;
+ uint i;
+
+ for (i=0 ; i < table->keys ; i++)
+ {
+ file->stat(key_file[i], (void*) &stat, 0, 0);
+ share->rec_per_key[i]= stat.bt_ndata / stat.bt_nkeys;
+ }
+ /* If hidden primary key */
+ if (hidden_primary_key)
+ file->stat(file, (void*) &stat, 0, 0);
+ pthread_mutex_lock(&share->mutex);
+ share->rows=stat.bt_ndata;
+ share->status|=STATUS_BDB_ANALYZE; // Save status on close
+ share->version++; // Update stat in table
+ pthread_mutex_unlock(&share->mutex);
+ update_status(share,table); // Write status to file
+ return ((share->status & STATUS_BDB_ANALYZE) ? HA_ADMIN_FAILED :
+ HA_ADMIN_OK);
+}
+
+int ha_berkeley::optimize(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ return ha_berkeley::analyze(thd,check_opt);
+}
+
+
+int ha_berkeley::check(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ char name_buff[FN_REFLEN];
+ int error;
+ fn_format(name_buff,share->table_name,"", ha_berkeley_ext, 2 | 4);
+ if ((error=file->verify(file, name_buff, NullS, (FILE*) 0,
+ hidden_primary_key ? 0 : DB_NOORDERCHK)))
+ {
+ print_msg(thd, table->real_name, "check", "error",
+ "Got error %d checking file structure",error);
+ return HA_ADMIN_CORRUPT;
+ }
+ for (uint i=0 ; i < table->keys ; i++)
+ {
+ if ((error=file->verify(key_file[i], name_buff, NullS, (FILE*) 0,
+ DB_ORDERCHKONLY)))
+ {
+ print_msg(thd, table->real_name, "check", "error",
+ "Key %d was not in order",error);
+ return HA_ADMIN_CORRUPT;
+ }
+ }
+ return HA_ADMIN_OK;
+}
+
/****************************************************************************
Handling the shared BDB_SHARE structure that is needed to provide table
locking.
@@ -1619,19 +1780,21 @@ static byte* bdb_get_key(BDB_SHARE *share,uint *length,
return (byte*) share->table_name;
}
-static BDB_SHARE *get_share(const char *table_name)
+static BDB_SHARE *get_share(const char *table_name, TABLE *table)
{
BDB_SHARE *share;
pthread_mutex_lock(&bdb_mutex);
uint length=(uint) strlen(table_name);
if (!(share=(BDB_SHARE*) hash_search(&bdb_open_tables, table_name, length)))
{
- if ((share=(BDB_SHARE *) my_malloc(sizeof(*share)+length+1,
+ if ((share=(BDB_SHARE *) my_malloc(sizeof(*share)+length+1 +
+ sizeof(ha_rows)* table->keys,
MYF(MY_WME | MY_ZEROFILL))))
{
share->table_name_length=length;
share->table_name=(char*) (share+1);
strmov(share->table_name,table_name);
+ share->rec_per_key= (ha_rows*) (share+1);
if (hash_insert(&bdb_open_tables, (char*) share))
{
pthread_mutex_unlock(&bdb_mutex);
@@ -1647,11 +1810,14 @@ static BDB_SHARE *get_share(const char *table_name)
return share;
}
-static void free_share(BDB_SHARE *share)
+static void free_share(BDB_SHARE *share, TABLE *table)
{
pthread_mutex_lock(&bdb_mutex);
if (!--share->use_count)
{
+ update_status(share,table);
+ if (share->status_block)
+ share->status_block->close(share->status_block,0);
hash_delete(&bdb_open_tables, (gptr) share);
thr_lock_delete(&share->lock);
pthread_mutex_destroy(&share->mutex);
@@ -1660,20 +1826,124 @@ static void free_share(BDB_SHARE *share)
pthread_mutex_unlock(&bdb_mutex);
}
+/*
+ Get status information that is stored in the 'status' sub database
+ and the max used value for the hidden primary key.
+*/
-void ha_berkeley::update_auto_primary_key()
+void ha_berkeley::get_status()
{
- pthread_mutex_lock(&share->mutex);
- if (!share->primary_key_inited)
+ if (!test_all_bits(share->status,(STATUS_PRIMARY_KEY_INIT |
+ STATUS_ROW_COUNT_INIT)))
+ {
+ pthread_mutex_lock(&share->mutex);
+ if (!(share->status & STATUS_PRIMARY_KEY_INIT))
+ {
+ (void) extra(HA_EXTRA_KEYREAD);
+ index_init(primary_key);
+ if (!index_last(table->record[1]))
+ share->auto_ident=uint5korr(current_ident);
+ index_end();
+ (void) extra(HA_EXTRA_NO_KEYREAD);
+ }
+ if (! share->status_block)
+ {
+ char name_buff[FN_REFLEN];
+ uint open_mode= (((table->db_stat & HA_READ_ONLY) ? DB_RDONLY : 0)
+ | DB_THREAD);
+ fn_format(name_buff, share->table_name,"", ha_berkeley_ext, 2 | 4);
+ if (!db_create(&share->status_block, db_env, 0))
+ {
+ if (!share->status_block->open(share->status_block, name_buff,
+ "status", DB_BTREE, open_mode, 0))
+ {
+ share->status_block->close(share->status_block, 0);
+ share->status_block=0;
+ }
+ }
+ }
+ if (!(share->status & STATUS_ROW_COUNT_INIT) && share->status_block)
+ {
+ share->org_rows=share->rows=
+ table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
+ if (!file->cursor(share->status_block, 0, &cursor, 0))
+ {
+ DBT row;
+ char rec_buff[64],*pos=rec_buff;
+ bzero((char*) &row,sizeof(row));
+ bzero((char*) &last_key,sizeof(last_key));
+ row.data=rec_buff;
+ row.size=sizeof(rec_buff);
+ row.flags=DB_DBT_USERMEM;
+ if (!cursor->c_get(cursor, &last_key, &row, DB_FIRST))
+ {
+ uint i;
+ share->org_rows=share->rows=uint4korr(pos); pos+=4;
+ for (i=0 ; i < table->keys ; i++)
+ {
+ share->rec_per_key[i]=uint4korr(pos); pos+=4;
+ }
+ }
+ cursor->c_close(cursor);
+ }
+ cursor=0; // Safety
+ }
+ share->status|= STATUS_PRIMARY_KEY_INIT | STATUS_ROW_COUNT_INIT;
+ pthread_mutex_unlock(&share->mutex);
+ }
+}
+
+
+static void update_status(BDB_SHARE *share, TABLE *table)
+{
+ DBUG_ENTER("update_status");
+ if (share->rows != share->org_rows ||
+ (share->status & STATUS_BDB_ANALYZE))
{
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(primary_key);
- if (!index_last(table->record[1]))
- share->auto_ident=uint5korr(current_ident);
- index_end();
- (void) extra(HA_EXTRA_NO_KEYREAD);
+ pthread_mutex_lock(&share->mutex);
+ if (!share->status_block)
+ {
+ /*
+ Create sub database 'status' if it doesn't exist from before
+ (This '*should*' always exist for table created with MySQL)
+ */
+
+ char name_buff[FN_REFLEN];
+ if (db_create(&share->status_block, db_env, 0))
+ goto end;
+ share->status_block->set_flags(share->status_block,0);
+ if (share->status_block->open(share->status_block,
+ fn_format(name_buff,share->table_name,"",
+ ha_berkeley_ext,2 | 4),
+ "status", DB_BTREE,
+ DB_THREAD | DB_CREATE, my_umask))
+ goto end;
+ }
+ {
+ uint i;
+ DBT row,key;
+ char rec_buff[4+MAX_KEY*sizeof(ulong)], *pos=rec_buff;
+ const char *key_buff="status";
+
+ bzero((char*) &row,sizeof(row));
+ bzero((char*) &key,sizeof(key));
+ row.data=rec_buff;
+ key.data=(void*) key_buff;
+ key.size=sizeof(key_buff);
+ row.flags=key.flags=DB_DBT_USERMEM;
+ int4store(pos,share->rows); pos+=4;
+ for (i=0 ; i < table->keys ; i++)
+ {
+ int4store(pos,share->rec_per_key[i]); pos+=4;
+ }
+ row.size=(uint) (pos-rec_buff);
+ (void) share->status_block->put(share->status_block, 0, &key, &row, 0);
+ share->status&= ~STATUS_BDB_ANALYZE;
+ }
+end:
+ pthread_mutex_unlock(&share->mutex);
}
- pthread_mutex_unlock(&share->mutex);
+ DBUG_VOID_RETURN;
}
/*
@@ -1683,14 +1953,7 @@ void ha_berkeley::update_auto_primary_key()
ha_rows ha_berkeley::estimate_number_of_rows()
{
- ulonglong max_ident;
- ulonglong max_rows=table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
- if (!hidden_primary_key)
- return (ha_rows) max_rows;
- pthread_mutex_lock(&share->mutex);
- max_ident=share->auto_ident+EXTRA_RECORDS;
- pthread_mutex_unlock(&share->mutex);
- return (ha_rows) min(max_ident,max_rows);
+ return share->rows + HA_BERKELEY_EXTRA_ROWS;
}
#endif /* HAVE_BERKELEY_DB */
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 3cfcab82ecf..4ee682664a5 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -27,11 +27,13 @@
typedef struct st_berkeley_share {
ulonglong auto_ident;
+ ha_rows rows, org_rows, *rec_per_key;
THR_LOCK lock;
pthread_mutex_t mutex;
char *table_name;
+ DB *status_block;
uint table_name_length,use_count;
- bool primary_key_inited;
+ uint status,version;
} BDB_SHARE;
@@ -49,7 +51,8 @@ class ha_berkeley: public handler
BDB_SHARE *share;
ulong int_option_flag;
ulong alloced_rec_buff_length;
- uint primary_key,last_dup_key, hidden_primary_key;
+ ulong changed_rows;
+ uint primary_key,last_dup_key, hidden_primary_key, version;
bool fixed_length_row, fixed_length_primary_key, key_read;
bool fix_rec_buff_for_blob(ulong length);
byte current_ident[BDB_HIDDEN_PRIMARY_KEY_LENGTH];
@@ -58,7 +61,8 @@ class ha_berkeley: public handler
int pack_row(DBT *row,const byte *record, bool new_row);
void unpack_row(char *record, DBT *row);
void ha_berkeley::unpack_key(char *record, DBT *key, uint index);
- DBT *pack_key(DBT *key, uint keynr, char *buff, const byte *record);
+ DBT *create_key(DBT *key, uint keynr, char *buff, const byte *record,
+ int key_length = MAX_KEY_LENGTH);
DBT *pack_key(DBT *key, uint keynr, char *buff, const byte *key_ptr,
uint key_length);
int remove_key(DB_TXN *trans, uint keynr, const byte *record,
@@ -79,8 +83,9 @@ class ha_berkeley: public handler
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
- HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE),
- last_dup_key((uint) -1)
+ HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
+ HA_AUTO_PART_KEY),
+ last_dup_key((uint) -1),version(0)
{
}
~ha_berkeley() {}
@@ -123,6 +128,10 @@ class ha_berkeley: public handler
int reset(void);
int external_lock(THD *thd, int lock_type);
void position(byte *record);
+ int analyze(THD* thd,HA_CHECK_OPT* check_opt);
+ int optimize(THD* thd, HA_CHECK_OPT* check_opt);
+ int check(THD* thd, HA_CHECK_OPT* check_opt);
+
ha_rows records_in_range(int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
@@ -135,7 +144,7 @@ class ha_berkeley: public handler
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
- void update_auto_primary_key();
+ void get_status();
inline void get_auto_primary_key(byte *to)
{
ulonglong tmp;
@@ -144,11 +153,12 @@ class ha_berkeley: public handler
int5store(to,share->auto_ident);
pthread_mutex_unlock(&share->mutex);
}
+ longlong ha_berkeley::get_auto_increment();
};
-extern bool berkeley_skip;
+extern bool berkeley_skip, berkeley_shared_data;
extern u_int32_t berkeley_init_flags,berkeley_lock_type,berkeley_lock_types[];
-extern ulong berkeley_cache_size, berkeley_lock_max;
+extern ulong berkeley_cache_size, berkeley_max_lock;
extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
extern long berkeley_lock_scan_time;
extern TYPELIB berkeley_lock_typelib;
diff --git a/sql/handler.cc b/sql/handler.cc
index 83ab85ebbbd..7c6a3e32ff2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -191,8 +191,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
{
DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef USING_TRANSACTIONS
- if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)) &&
- !thd->locked_tables)
+ if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
{
if (!error)
{
@@ -211,6 +210,16 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
{
int error=0;
DBUG_ENTER("ha_commit");
+#ifdef USING_TRANSACTIONS
+ /* Update the binary log if we have cached some queries */
+ if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
+ my_b_tell(&thd->transaction.trans_log))
+ {
+ mysql_bin_log.write(&thd->transaction.trans_log);
+ reinit_io_cache(&thd->transaction.trans_log,
+ WRITE_CACHE, (my_off_t) 0, 0, 1);
+ thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
+ }
#ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
{
@@ -224,7 +233,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#endif
#ifdef HAVE_INNOBASE_DB
{
- if ((error=innobase_commit(thd,trans->innobase_tid))
+ if ((error=innobase_commit(thd,trans->innobase_tid)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
@@ -232,6 +241,9 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
trans->innobase_tid=0;
}
#endif
+ if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
+ sql_print_error("Error: Got error during commit; Binlog is not up to date!");
+#endif
DBUG_RETURN(error);
}
@@ -261,6 +273,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
trans->innobase_tid=0;
}
#endif
+#ifdef USING_TRANSACTIONS
+ if (trans == &thd->transaction.all)
+ reinit_io_cache(&thd->transaction.trans_log,
+ WRITE_CACHE, (my_off_t) 0, 0, 1);
+ thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
+#endif
DBUG_RETURN(error);
}
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 47953020ffb..db8f8349446 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -180,20 +180,21 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
VOID(pthread_mutex_lock(&hostname_cache->lock));
if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET)))
{
- DBUG_PRINT("error",("gethostbyaddr returned %d",errno));
VOID(pthread_mutex_unlock(&hostname_cache->lock));
- add_wrong_ip(in);
- DBUG_RETURN(0);
+ DBUG_PRINT("error",("gethostbyaddr returned %d",errno));
+ goto err;
}
- if (!hp->h_name[0])
+ if (!hp->h_name[0]) // Don't allow empty hostnames
{
VOID(pthread_mutex_unlock(&hostname_cache->lock));
DBUG_PRINT("error",("Got an empty hostname"));
- add_wrong_ip(in);
- DBUG_RETURN(0); // Don't allow empty hostnames
+ goto err;
}
if (!(name=my_strdup(hp->h_name,MYF(0))))
+ {
+ VOID(pthread_mutex_unlock(&hostname_cache->lock));
DBUG_RETURN(0); // out of memory
+ }
check=gethostbyname(name);
VOID(pthread_mutex_unlock(&hostname_cache->lock));
if (!check)
@@ -214,8 +215,7 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
{
DBUG_PRINT("error",("mysqld doesn't accept hostnames that starts with a number followed by a '.'"));
my_free(name,MYF(0));
- add_wrong_ip(in);
- DBUG_RETURN(0);
+ goto err;
}
}
@@ -230,6 +230,8 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
}
DBUG_PRINT("error",("Couldn't verify hostname with gethostbyname"));
my_free(name,MYF(0));
+
+err:
add_wrong_ip(in);
DBUG_RETURN(0);
}
diff --git a/sql/log.cc b/sql/log.cc
index 2dda594ea59..1c377ebc3a5 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -16,6 +16,7 @@
/* logging of commands */
+/* TODO: Abort logging when we get an error in reading or writing log files */
#include "mysql_priv.h"
#include "sql_acl.h"
@@ -523,14 +524,12 @@ void MYSQL_LOG::new_file()
}
-void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
+bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
const char *format,...)
{
if (is_open() && (what_to_log & (1L << (uint) command)))
{
- va_list args;
- va_start(args,format);
- char buff[32];
+ int error=0;
VOID(pthread_mutex_lock(&LOCK_log));
/* Test if someone closed after the is_open test */
@@ -538,14 +537,17 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{
time_t skr;
ulong id;
- int error=0;
+ va_list args;
+ va_start(args,format);
+ char buff[32];
+
if (thd)
{ // Normal thread
if ((thd->options & OPTION_LOG_OFF) &&
(thd->master_access & PROCESS_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
- return; // No logging
+ return 0; // No logging
}
id=thd->thread_id;
if (thd->user_time || !(skr=thd->query_start()))
@@ -593,115 +595,184 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
}
+ va_end(args);
+ VOID(pthread_mutex_unlock(&LOCK_log));
}
- va_end(args);
VOID(pthread_mutex_unlock(&LOCK_log));
+ return error != 0;
}
+ return 0;
}
/* Write to binary log in a format to be used for replication */
-void MYSQL_LOG::write(Query_log_event* event_info)
+bool MYSQL_LOG::write(Query_log_event* event_info)
{
+ /* In most cases this is only called if 'is_open()' is true */
+ bool error=1;
+ VOID(pthread_mutex_lock(&LOCK_log));
if (is_open())
{
- VOID(pthread_mutex_lock(&LOCK_log));
- if (is_open())
+ THD *thd=event_info->thd;
+ IO_CACHE *file = (event_info->cache_stmt ? &thd->transaction.trans_log :
+ &log_file);
+ if ((!(thd->options & OPTION_BIN_LOG) &&
+ thd->master_access & PROCESS_ACL) ||
+ !db_ok(event_info->db, binlog_do_db, binlog_ignore_db))
{
- THD *thd=event_info->thd;
- if ((!(thd->options & OPTION_BIN_LOG) &&
- thd->master_access & PROCESS_ACL) ||
- !db_ok(event_info->db, binlog_do_db, binlog_ignore_db))
- {
- VOID(pthread_mutex_unlock(&LOCK_log));
- return;
- }
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return 0;
+ }
- if (thd->last_insert_id_used)
- {
- Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
- if (e.write(&log_file))
- {
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
- }
- }
- if (thd->insert_id_used)
- {
- Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
- if (e.write(&log_file))
- {
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
- }
- }
- if (thd->convert_set)
+ if (thd->last_insert_id_used)
+ {
+ Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->insert_id_used)
+ {
+ Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->convert_set)
+ {
+ char buf[1024] = "SET CHARACTER SET ";
+ char* p = strend(buf);
+ p = strmov(p, thd->convert_set->name);
+ int save_query_length = thd->query_length;
+ // just in case somebody wants it later
+ thd->query_length = (uint)(p - buf);
+ Query_log_event e(thd, buf);
+ if (e.write(file))
+ goto err;
+ thd->query_length = save_query_length; // clean up
+ }
+ if (event_info->write(file) ||
+ file == &log_file && flush_io_cache(file))
+ goto err;
+ error=0;
+
+err:
+ if (error)
+ {
+ if (my_errno == EFBIG)
+ my_error(ER_TRANS_CACHE_FULL, MYF(0));
+ else
+ my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno);
+ write_error=1;
+ }
+ if (file == &log_file)
+ VOID(pthread_cond_broadcast(&COND_binlog_update));
+ }
+ else
+ error=0;
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return error;
+}
+
+/*
+ Write a cached log entry to the binary log
+ We only come here if there is something in the cache.
+ 'cache' needs to be reinitialized after this functions returns.
+*/
+
+bool MYSQL_LOG::write(IO_CACHE *cache)
+{
+ VOID(pthread_mutex_lock(&LOCK_log));
+ bool error=1;
+ if (is_open())
+ {
+ uint length;
+ my_off_t start_pos=my_b_tell(&log_file);
+
+ if (reinit_io_cache(cache, WRITE_CACHE, 0, 0, 0))
+ {
+ if (!write_error)
+ sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno);
+ goto err;
+ }
+ while ((length=my_b_fill(cache)))
+ {
+ if (my_b_write(&log_file, cache->rc_pos, length))
{
- char buf[1024] = "SET CHARACTER SET ";
- char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
- int save_query_length = thd->query_length;
- // just in case somebody wants it later
- thd->query_length = (uint)(p - buf);
- Query_log_event e(thd, buf);
- if (e.write(&log_file))
- {
+ if (!write_error)
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
- }
- thd->query_length = save_query_length; // clean up
+ goto err;
}
- if (event_info->write(&log_file) || flush_io_cache(&log_file))
- {
+ cache->rc_pos=cache->rc_end; // Mark buffer used up
+ }
+ if (flush_io_cache(&log_file))
+ {
+ if (!write_error)
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- }
- err:
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ goto err;
+ }
+ if (cache->error) // Error on read
+ {
+ if (!write_error)
+ sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
+ goto err;
}
- VOID(pthread_mutex_unlock(&LOCK_log));
}
+ error=0;
+
+err:
+ if (error)
+ write_error=1;
+ else
+ VOID(pthread_cond_broadcast(&COND_binlog_update));
+
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return error;
}
-void MYSQL_LOG::write(Load_log_event* event_info)
+
+bool MYSQL_LOG::write(Load_log_event* event_info)
{
+ bool error=0;
+ VOID(pthread_mutex_lock(&LOCK_log));
if (is_open())
{
- VOID(pthread_mutex_lock(&LOCK_log));
- if (is_open())
+ THD *thd=event_info->thd;
+ if ((thd->options & OPTION_BIN_LOG) ||
+ !(thd->master_access & PROCESS_ACL))
{
- THD *thd=event_info->thd;
- if ((thd->options & OPTION_BIN_LOG) ||
- !(thd->master_access & PROCESS_ACL))
+ if (event_info->write(&log_file) || flush_io_cache(&log_file))
{
- if (event_info->write(&log_file) || flush_io_cache(&log_file))
+ if (!write_error)
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ error=write_error=1;
}
+ VOID(pthread_cond_broadcast(&COND_binlog_update));
}
- VOID(pthread_mutex_unlock(&LOCK_log));
}
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return error;
}
/* Write update log in a format suitable for incremental backup */
-void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
+bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
time_t query_start)
{
+ bool error=0;
if (is_open())
{
time_t current_time;
VOID(pthread_mutex_lock(&LOCK_log));
if (is_open())
{ // Safety agains reopen
- int error=0;
+ int tmp_errno=0;
char buff[80],*end;
end=buff;
if (!(thd->options & OPTION_UPDATE_LOG) &&
(thd->master_access & PROCESS_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
- return;
+ return 0;
}
if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start)
{
@@ -722,14 +793,14 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
start->tm_min,
start->tm_sec);
if (my_b_write(&log_file, (byte*) buff,24))
- error=errno;
+ tmp_errno=errno;
}
if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
thd->priv_user,
thd->user,
thd->host ? thd->host : "",
thd->ip ? thd->ip : "") == (uint) -1)
- error=errno;
+ tmp_errno=errno;
}
if (query_start)
{
@@ -739,12 +810,12 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
(ulong) (current_time - query_start),
(ulong) (thd->time_after_lock - query_start),
(ulong) thd->sent_row_count) == (uint) -1)
- error=errno;
+ tmp_errno=errno;
}
if (thd->db && strcmp(thd->db,db))
{ // Database changed
if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
- error=errno;
+ tmp_errno=errno;
strmov(db,thd->db);
}
if (thd->last_insert_id_used)
@@ -777,7 +848,7 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
*end=0;
if (my_b_write(&log_file, (byte*) "SET ",4) ||
my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)-1))
- error=errno;
+ tmp_errno=errno;
}
if (!query)
{
@@ -787,29 +858,22 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
if (my_b_write(&log_file, (byte*) query,query_length) ||
my_b_write(&log_file, (byte*) ";\n",2) ||
flush_io_cache(&log_file))
- error=errno;
- if (error && ! write_error)
+ tmp_errno=errno;
+ if (tmp_errno)
{
- write_error=1;
- sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
+ error=1;
+ if (! write_error)
+ {
+ write_error=1;
+ sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
+ }
}
}
VOID(pthread_mutex_unlock(&LOCK_log));
}
+ return error;
}
-#ifdef TO_BE_REMOVED
-void MYSQL_LOG::flush()
-{
- if (is_open())
- if (flush_io_cache(log_file) && ! write_error)
- {
- write_error=1;
- sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
- }
-}
-#endif
-
void MYSQL_LOG::close(bool exiting)
{ // One can't set log_type here!
diff --git a/sql/log_event.h b/sql/log_event.h
index b31d444ad21..3d307000b13 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -118,16 +118,18 @@ public:
ulong thread_id;
#if !defined(MYSQL_CLIENT)
THD* thd;
- Query_log_event(THD* thd_arg, const char* query_arg):
- Log_event(thd_arg->start_time,0,0,thd_arg->server_id), data_buf(0),
+ bool cache_stmt;
+ Query_log_event(THD* thd_arg, const char* query_arg, bool using_trans=0):
+ Log_event(thd_arg->start_time,0,1,thd_arg->server_id), data_buf(0),
query(query_arg), db(thd_arg->db), q_len(thd_arg->query_length),
error_code(thd_arg->net.last_errno),
- thread_id(thd_arg->thread_id), thd(thd_arg)
+ thread_id(thd_arg->thread_id), thd(thd_arg),
+ cache_stmt(using_trans &&
+ (thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
{
time_t end_time;
time(&end_time);
exec_time = (ulong) (end_time - thd->start_time);
- valid_exec_time = 1;
db_len = (db) ? (uint32) strlen(db) : 0;
}
#endif
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index f723e35ca93..cddacaa820f 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -121,7 +121,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
}
/* end_of_file may be changed by user later */
info->end_of_file= ((type == READ_NET || type == READ_FIFO ) ? 0
- : MY_FILEPOS_ERROR);
+ : ~(my_off_t) 0);
info->type=type;
info->error=0;
info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read; /* net | file */
@@ -176,6 +176,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
DBUG_ENTER("reinit_io_cache");
info->seek_not_done= test(info->file >= 0); /* Seek not done */
+
+ /* If the whole file is in memory, avoid flushing to disk */
if (! clear_cache &&
seek_offset >= info->pos_in_file &&
seek_offset <= info->pos_in_file +
@@ -186,8 +188,12 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->rc_end=info->rc_pos;
info->end_of_file=my_b_tell(info);
}
- else if (info->type == READ_CACHE && type == WRITE_CACHE)
- info->rc_end=info->buffer+info->buffer_length;
+ else if (type == WRITE_CACHE)
+ {
+ if (info->type == READ_CACHE)
+ info->rc_end=info->buffer+info->buffer_length;
+ info->end_of_file = ~(my_off_t) 0;
+ }
info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
#ifdef HAVE_AIOWAIT
my_aiowait(&info->aio_result); /* Wait for outstanding req */
@@ -195,11 +201,20 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
}
else
{
+ /*
+ If we change from WRITE_CACHE to READ_CACHE, assume that everything
+ after the current positions should be ignored
+ */
if (info->type == WRITE_CACHE && type == READ_CACHE)
info->end_of_file=my_b_tell(info);
- if (flush_io_cache(info))
+ /* No need to flush cache if we want to reuse it */
+ if ((type != WRITE_CACHE || !clear_cache) && flush_io_cache(info))
DBUG_RETURN(1);
- info->pos_in_file=seek_offset;
+ if (info->pos_in_file != seek_offset)
+ {
+ info->pos_in_file=seek_offset;
+ info->seek_not_done=1;
+ }
info->rc_request_pos=info->rc_pos=info->buffer;
if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
{
@@ -210,7 +225,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->rc_end=info->buffer+info->buffer_length-
(seek_offset & (IO_SIZE-1));
info->end_of_file= ((type == READ_NET || type == READ_FIFO) ? 0 :
- MY_FILEPOS_ERROR);
+ ~(my_off_t) 0);
}
}
info->type=type;
@@ -536,6 +551,11 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
Buffer+=rest_length;
Count-=rest_length;
info->rc_pos+=rest_length;
+ if (info->pos_in_file+info->buffer_length > info->end_of_file)
+ {
+ my_errno=errno=EFBIG;
+ return info->error = -1;
+ }
if (flush_io_cache(info))
return 1;
if (Count >= IO_SIZE)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6dd3c06c236..7c3b1cfadef 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -507,9 +507,9 @@ extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
net_read_timeout,net_write_timeout,
what_to_log,flush_time,
max_tmp_tables,max_heap_table_size,query_buff_size,
- lower_case_table_names,thread_stack,thread_stack_min;
-extern ulong specialflag;
-extern ulong current_pid;
+ lower_case_table_names,thread_stack,thread_stack_min,
+ binlog_cache_size, max_binlog_cache_size;
+extern ulong specialflag, current_pid;
extern bool low_priority_updates;
extern bool opt_sql_bin_update;
extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 143d9267425..1122a770523 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -201,10 +201,10 @@ ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
query_buff_size, lower_case_table_names, mysqld_net_retry_count,
net_interactive_timeout, slow_launch_time = 2L,
net_read_timeout,net_write_timeout,slave_open_temp_tables=0;
-ulong thread_cache_size=0;
+ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
volatile ulong cached_thread_count=0;
-// replication parameters, if master_host is not NULL, we are slaving off the master
+// replication parameters, if master_host is not NULL, we are a slave
my_string master_user = (char*) "test", master_password = 0, master_host=0,
master_info_file = (char*) "master.info";
const char *localhost=LOCAL_HOST;
@@ -1496,23 +1496,21 @@ int main(int argc, char **argv)
if (opt_update_log)
open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
LOG_NEW);
+
+ if (!server_id)
+ server_id= !master_host ? 1 : 2;
if (opt_bin_log)
{
- if(server_id)
- {
- if (!opt_bin_logname)
- {
- char tmp[FN_REFLEN];
- strnmov(tmp,glob_hostname,FN_REFLEN-5);
- strmov(strcend(tmp,'.'),"-bin");
- opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
- }
- mysql_bin_log.set_index_file_name(opt_binlog_index_name);
- open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
- LOG_BIN);
- }
- else
- sql_print_error("Server id is not set - binary logging disabled");
+ if (!opt_bin_logname)
+ {
+ char tmp[FN_REFLEN];
+ strnmov(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-bin");
+ opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ mysql_bin_log.set_index_file_name(opt_binlog_index_name);
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ LOG_BIN);
}
if (opt_slow_log)
@@ -1620,19 +1618,14 @@ int main(int argc, char **argv)
}
// slave thread
- if(master_host)
+ if (master_host)
{
- if(server_id)
- {
- pthread_t hThread;
- if(!opt_skip_slave_start &&
- pthread_create(&hThread, &connection_attrib, handle_slave, 0))
- sql_print_error("Warning: Can't create thread to handle slave");
- else if(opt_skip_slave_start)
- init_master_info(&glob_mi);
- }
- else
- sql_print_error("Server id is not set, slave thread will not be started");
+ pthread_t hThread;
+ if(!opt_skip_slave_start &&
+ pthread_create(&hThread, &connection_attrib, handle_slave, 0))
+ sql_print_error("Warning: Can't create thread to handle slave");
+ else if(opt_skip_slave_start)
+ init_master_info(&glob_mi);
}
printf(ER(ER_READY),my_progname,server_version,"");
@@ -2205,7 +2198,8 @@ enum options {
OPT_BDB_HOME, OPT_BDB_LOG,
OPT_BDB_TMP, OPT_BDB_NOSYNC,
OPT_BDB_LOCK, OPT_BDB_SKIP,
- OPT_BDB_RECOVER, OPT_MASTER_HOST,
+ OPT_BDB_RECOVER, OPT_BDB_SHARED,
+ OPT_MASTER_HOST,
OPT_MASTER_USER, OPT_MASTER_PASSWORD,
OPT_MASTER_PORT, OPT_MASTER_INFO_FILE,
OPT_MASTER_CONNECT_RETRY, OPT_SQL_BIN_UPDATE_SAME,
@@ -2233,6 +2227,7 @@ static struct option long_options[] = {
{"bdb-logdir", required_argument, 0, (int) OPT_BDB_LOG},
{"bdb-recover", no_argument, 0, (int) OPT_BDB_RECOVER},
{"bdb-no-sync", no_argument, 0, (int) OPT_BDB_NOSYNC},
+ {"bdb-shared-data", required_argument, 0, (int) OPT_BDB_SHARED},
{"bdb-tmpdir", required_argument, 0, (int) OPT_BDB_TMP},
#endif
{"big-tables", no_argument, 0, (int) OPT_BIG_TABLES},
@@ -2323,7 +2318,7 @@ static struct option long_options[] = {
(int) OPT_REPLICATE_REWRITE_DB},
{"safe-mode", no_argument, 0, (int) OPT_SAFE},
{"socket", required_argument, 0, (int) OPT_SOCKET},
- {"server-id", required_argument, 0, (int)OPT_SERVER_ID},
+ {"server-id", required_argument, 0, (int) OPT_SERVER_ID},
{"set-variable", required_argument, 0, 'O'},
#ifdef HAVE_BERKELEY_DB
{"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP},
@@ -2363,9 +2358,14 @@ CHANGEABLE_VAR changeable_vars[] = {
#ifdef HAVE_BERKELEY_DB
{ "bdb_cache_size", (long*) &berkeley_cache_size,
KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
- { "bdb_lock_max", (long*) &berkeley_lock_max,
+ { "bdb_max_lock", (long*) &berkeley_max_lock,
+ 1000, 0, (long) ~0, 0, 1 },
+ /* QQ: The following should be removed soon! */
+ { "bdb_lock_max", (long*) &berkeley_max_lock,
1000, 0, (long) ~0, 0, 1 },
#endif
+ { "binlog_cache_size", (long*) &binlog_cache_size,
+ 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE },
{ "connect_timeout", (long*) &connect_timeout,
CONNECT_TIMEOUT, 2, 65535, 0, 1 },
{ "delayed_insert_timeout", (long*) &delayed_insert_timeout,
@@ -2390,7 +2390,7 @@ CHANGEABLE_VAR changeable_vars[] = {
{"innobase_buffer_pool_size",
(long*) &innobase_buffer_pool_size, 8*1024*1024L, 1024*1024L,
~0L, 0, 1024*1024L},
- {"innobase_additional_mem_pool_size_mb",
+ {"innobase_additional_mem_pool_size",
(long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
~0L, 0, 1024},
{"innobase_file_io_threads",
@@ -2408,6 +2408,8 @@ CHANGEABLE_VAR changeable_vars[] = {
IF_WIN(1,0), 0, 1, 0, 1 },
{ "max_allowed_packet", (long*) &max_allowed_packet,
1024*1024L, 80, 17*1024*1024L, MALLOC_OVERHEAD, 1024 },
+ { "max_binlog_cache_size", (long*) &max_binlog_cache_size,
+ ~0L, IO_SIZE, ~0L, 0, IO_SIZE },
{ "max_connections", (long*) &max_connections,
100, 1, 16384, 0, 1 },
{ "max_connect_errors", (long*) &max_connect_errors,
@@ -2465,10 +2467,12 @@ struct show_var_st init_vars[]= {
#ifdef HAVE_BERKELEY_DB
{"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
{"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
- {"bdb_lock_max", (char*) &berkeley_lock_max, SHOW_LONG},
+ {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
{"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
+ {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
{"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
#endif
+ {"binlog_cache_size", (char*) &binlog_cache_size, SHOW_LONG},
{"character_set", default_charset, SHOW_CHAR},
{"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
{"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
@@ -2497,6 +2501,7 @@ struct show_var_st init_vars[]= {
{"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL},
{"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG},
{"max_allowed_packet", (char*) &max_allowed_packet, SHOW_LONG},
+ {"max_binlog_cache_size", (char*) &max_binlog_cache_size, SHOW_LONG},
{"max_connections", (char*) &max_connections, SHOW_LONG},
{"max_connect_errors", (char*) &max_connect_errors, SHOW_LONG},
{"max_delayed_threads", (char*) &max_insert_delayed_threads, SHOW_LONG},
@@ -2711,8 +2716,9 @@ static void usage(void)
--bdb-lock-detect=# Berkeley lock detect\n\
(DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\
--bdb-logdir=directory Berkeley DB log file directory\n\
- --bdb-nosync Don't synchronously flush logs\n\
+ --bdb-no-sync Don't synchronously flush logs\n\
--bdb-recover Start Berkeley DB in recover mode\n\
+ --bdb-shared-data Start Berkeley DB in multi-process mode\n\
--bdb-tmpdir=directory Berkeley DB tempfile name\n\
--skip-bdb Don't use berkeley db (will save memory)\n\
");
@@ -3224,6 +3230,10 @@ static void get_options(int argc,char **argv)
}
break;
}
+ case OPT_BDB_SHARED:
+ berkeley_init_flags&= ~(DB_PRIVATE);
+ berkeley_shared_data=1;
+ break;
case OPT_BDB_SKIP:
berkeley_skip=1;
break;
diff --git a/sql/share/czech/errmsg.sys b/sql/share/czech/errmsg.sys
index ebb6e9ba348..68ce82eeb9e 100644
--- a/sql/share/czech/errmsg.sys
+++ b/sql/share/czech/errmsg.sys
Binary files differ
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 437702240c7..c10d59dc21c 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -207,3 +207,4 @@
"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena",-A
"Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila",-A
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/danish/errmsg.sys b/sql/share/danish/errmsg.sys
index d55c0ada743..1e358664792 100644
--- a/sql/share/danish/errmsg.sys
+++ b/sql/share/danish/errmsg.sys
Binary files differ
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index b1faff2fffb..79d7ae5efc4 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -201,3 +201,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/dutch/errmsg.sys b/sql/share/dutch/errmsg.sys
index 7a35b102cf1..c00dc0f3c0c 100644
--- a/sql/share/dutch/errmsg.sys
+++ b/sql/share/dutch/errmsg.sys
Binary files differ
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 18029c32a97..1cfdbee8d43 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/english/errmsg.sys b/sql/share/english/errmsg.sys
index 903f2958129..af1b051e1cd 100644
--- a/sql/share/english/errmsg.sys
+++ b/sql/share/english/errmsg.sys
Binary files differ
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index 6395180f4fd..4900e4bd7ad 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/estonian/errmsg.sys b/sql/share/estonian/errmsg.sys
index fe9b221ce58..f27359c76e0 100644
--- a/sql/share/estonian/errmsg.sys
+++ b/sql/share/estonian/errmsg.sys
Binary files differ
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index b90b5d205ec..cb609f66432 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -202,3 +202,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/french/errmsg.sys b/sql/share/french/errmsg.sys
index 75c1c8328f1..6bac623b236 100644
--- a/sql/share/french/errmsg.sys
+++ b/sql/share/french/errmsg.sys
Binary files differ
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index e5d90a93733..0e1b9cf8e01 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/german/errmsg.sys b/sql/share/german/errmsg.sys
index 46a68a5ef7f..d9f835e8dbe 100644
--- a/sql/share/german/errmsg.sys
+++ b/sql/share/german/errmsg.sys
Binary files differ
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 4ebd1ffe751..4d36544fedc 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -201,3 +201,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/greek/errmsg.sys b/sql/share/greek/errmsg.sys
index bed966bdab4..d831fac812d 100644
--- a/sql/share/greek/errmsg.sys
+++ b/sql/share/greek/errmsg.sys
Binary files differ
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index d5ff3d1253f..eb43678ddcf 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/hungarian/errmsg.sys b/sql/share/hungarian/errmsg.sys
index da976080e27..6c2d550e7ac 100644
--- a/sql/share/hungarian/errmsg.sys
+++ b/sql/share/hungarian/errmsg.sys
Binary files differ
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index f864fe7ff0d..eacc8a967a9 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -200,3 +200,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/italian/errmsg.sys b/sql/share/italian/errmsg.sys
index 7aea0464d7a..e63175d0230 100644
--- a/sql/share/italian/errmsg.sys
+++ b/sql/share/italian/errmsg.sys
Binary files differ
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 44dbfd63a7b..f5e333696cf 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -198,3 +198,4 @@
"La tabella '%-.64s' e' segnalata come rovinata e deve essere riparata",
"La tabella '%-.64s' e' segnalata come rovinata e l'ultima ricostruzione (automatica?) e' fallita",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/japanese/errmsg.sys b/sql/share/japanese/errmsg.sys
index 41618a4ffea..d0d8cfe1c41 100644
--- a/sql/share/japanese/errmsg.sys
+++ b/sql/share/japanese/errmsg.sys
Binary files differ
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index c2650178002..4b7a3fd30e1 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -200,3 +200,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/korean/errmsg.sys b/sql/share/korean/errmsg.sys
index c94649378f4..a47cab2da19 100644
--- a/sql/share/korean/errmsg.sys
+++ b/sql/share/korean/errmsg.sys
Binary files differ
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index e49eead2210..d772f8c46d5 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 0dd18ba9ecb..d6c29026c0b 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -200,3 +200,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index eb12dafbd6d..4d0c1ef87f0 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -200,3 +200,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/polish/errmsg.sys b/sql/share/polish/errmsg.sys
index 551ff4d81a6..6246eac84f9 100644
--- a/sql/share/polish/errmsg.sys
+++ b/sql/share/polish/errmsg.sys
Binary files differ
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 84991513129..a77f64b8b37 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -202,3 +202,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/portuguese/errmsg.sys b/sql/share/portuguese/errmsg.sys
index 5a6e038c1ce..df54263f7d7 100644
--- a/sql/share/portuguese/errmsg.sys
+++ b/sql/share/portuguese/errmsg.sys
Binary files differ
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index dbb881f21d5..946a64df5d0 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -198,3 +198,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 4b48d4347a9..7c325b9c662 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -202,3 +202,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/russian/errmsg.sys b/sql/share/russian/errmsg.sys
index e2497d5e356..e7dbcac4f0e 100644
--- a/sql/share/russian/errmsg.sys
+++ b/sql/share/russian/errmsg.sys
Binary files differ
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index a759a495c37..7a83573e0ff 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -201,3 +201,4 @@
"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÄÏÌÖÎÁ ÂÙÔØ ÉÓÐÒÁ×ÌÅÎÁ",
"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÐÏÓÌÅÄÎÑÑ ÐÏÐÙÔËÁ ÉÓÐÒÁ×ÌÅÎÉÑ (Á×ÔÏÍÁÔÉÞÅÓËÁÑ?) ÎÅ ÕÄÁÌÁÓØ",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/slovak/errmsg.sys b/sql/share/slovak/errmsg.sys
index 8e0c6ab4b79..2a8f977d3ea 100644
--- a/sql/share/slovak/errmsg.sys
+++ b/sql/share/slovak/errmsg.sys
Binary files differ
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index 1ca1632bd57..774047be656 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -206,3 +206,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/spanish/errmsg.sys b/sql/share/spanish/errmsg.sys
index bb301f89d3e..d651bd4c555 100644
--- a/sql/share/spanish/errmsg.sys
+++ b/sql/share/spanish/errmsg.sys
Binary files differ
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index 7a76c438bad..0003e435183 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -199,3 +199,4 @@
"Table '%-.64s' is marked as crashed and should be repaired",
"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
"Warning: Some non-transactional changed tables couldn't be rolled back",
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
diff --git a/sql/share/swedish/errmsg.OLD b/sql/share/swedish/errmsg.OLD
index 78dfa51a806..ea8c2b78e3f 100644
--- a/sql/share/swedish/errmsg.OLD
+++ b/sql/share/swedish/errmsg.OLD
@@ -198,3 +198,5 @@
"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE",
"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades",
"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
+#ER_TRANS_CACHE_FULL
+"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt",
diff --git a/sql/share/swedish/errmsg.sys b/sql/share/swedish/errmsg.sys
index 011968008e8..3cf1b59746a 100644
--- a/sql/share/swedish/errmsg.sys
+++ b/sql/share/swedish/errmsg.sys
Binary files differ
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 78dfa51a806..ee3d913e51a 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -198,3 +198,4 @@
"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE",
"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades",
"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
+"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt",
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 75add1e7a5f..63c17dae740 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -454,15 +454,15 @@ void close_temporary_tables(THD *thd)
next=table->next;
close_temporary(table);
}
- if(query && mysql_bin_log.is_open())
- {
- uint save_query_len = thd->query_length;
- *--p = 0;
- thd->query_length = (uint)(p-query);
- Query_log_event qinfo(thd, query);
- mysql_bin_log.write(&qinfo);
- thd->query_length = save_query_len;
- }
+ if (query && mysql_bin_log.is_open())
+ {
+ uint save_query_len = thd->query_length;
+ *--p = 0;
+ thd->query_length = (uint)(p-query);
+ Query_log_event qinfo(thd, query);
+ mysql_bin_log.write(&qinfo);
+ thd->query_length = save_query_len;
+ }
thd->temporary_tables=0;
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b93b0a5b909..b310d0f44bb 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -121,8 +121,10 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log,
- mysql_tmpdir,LOG_PREFIX,0,MYF(MY_WME)))
+ mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
+ MYF(MY_WME)))
killed=1;
+ transaction.trans_log.end_of_file= max_binlog_cache_size;
#endif
#ifdef __WIN__
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7e3864fad01..4943e334aa0 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -74,12 +74,12 @@ public:
void open(const char *log_name,enum_log_type log_type,
const char *new_name=0);
void new_file(void);
- void write(THD *thd, enum enum_server_command command,const char *format,...);
- void write(THD *thd, const char *query, uint query_length,
+ bool write(THD *thd, enum enum_server_command command,const char *format,...);
+ bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
- void write(Query_log_event* event_info); // binary log write
- void write(Load_log_event* event_info);
-
+ bool write(Query_log_event* event_info); // binary log write
+ bool write(Load_log_event* event_info);
+ bool write(IO_CACHE *cache);
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 4ac78a9853e..89e7faa237c 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -158,14 +158,14 @@ exit:
are 2 digits (raid directories).
*/
-static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
- uint level)
+static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
+ uint level)
{
long deleted=0;
ulong found_other_files=0;
char filePath[FN_REFLEN];
DBUG_ENTER("mysql_rm_known_files");
- DBUG_PRINT("enter",("path: %s", path));
+ DBUG_PRINT("enter",("path: %s", org_path));
/* remove all files with known extensions */
for (uint idx=2 ;
@@ -181,7 +181,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
{
char newpath[FN_REFLEN];
MY_DIR *new_dirp;
- strxmov(newpath,path,"/",file->name,NullS);
+ strxmov(newpath,org_path,"/",file->name,NullS);
unpack_filename(newpath,newpath);
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
{
@@ -199,7 +199,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
found_other_files++;
continue;
}
- strxmov(filePath,path,"/",file->name,NullS);
+ strxmov(filePath,org_path,"/",file->name,NullS);
unpack_filename(filePath,filePath);
if (my_delete(filePath,MYF(MY_WME)))
{
@@ -224,9 +224,9 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
*/
if (!found_other_files)
{
-#ifdef HAVE_READLINK
char tmp_path[FN_REFLEN];
- path=unpack_filename(tmp_path,path);
+ char *path=unpack_filename(tmp_path,org_path);
+#ifdef HAVE_READLINK
int linkcount = readlink(path,filePath,sizeof(filePath)-1);
if (linkcount > 0) // If the path was a symbolic link
{
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 807464552a7..dbcd2640dbc 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -126,7 +126,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
SQL_SELECT *select;
READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR;
- bool use_generate_table;
+ bool use_generate_table,using_transactions;
DBUG_ENTER("mysql_delete");
if (!table_list->db)
@@ -214,18 +214,20 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
(void) table->file->extra(HA_EXTRA_READCHECK);
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_NORMAL);
- if (deleted)
+ using_transactions=table->file->has_transactions();
+ if (deleted && (error == 0 || !using_transactions))
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ Query_log_event qinfo(thd, thd->query, using_transactions);
+ if (mysql_bin_log.write(&qinfo) && using_transactions)
+ error=1;
}
- if (!table->file->has_transactions())
+ if (!using_transactions)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (ha_autocommit_or_rollback(thd,error >= 0))
+ if (using_transactions && ha_autocommit_or_rollback(thd,error >= 0))
error=1;
if (thd->lock)
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index b1ae918a791..baaf65d4197 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -102,6 +102,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
int error;
bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
!(thd->master_access & PROCESS_ACL));
+ bool using_transactions;
uint value_count;
uint save_time_stamp;
ulong counter = 1;
@@ -254,18 +255,21 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->insert_id(id); // For update log
else if (table->next_number_field)
id=table->next_number_field->val_int(); // Return auto_increment value
- if (info.copied || info.deleted)
+ using_transactions=table->file->has_transactions();
+ if ((info.copied || info.deleted) && (error == 0 || !using_transactions))
{
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ Query_log_event qinfo(thd, thd->query, using_transactions);
+ if (mysql_bin_log.write(&qinfo) && using_transactions)
+ error=1;
}
- if (!table->file->has_transactions())
+ if (!using_transactions)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- error=ha_autocommit_or_rollback(thd,error);
+ if (using_transactions)
+ error=ha_autocommit_or_rollback(thd,error);
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -1265,7 +1269,8 @@ bool select_insert::send_eof()
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
+ Query_log_event qinfo(thd, thd->query,
+ table->file->has_transactions());
mysql_bin_log.write(&qinfo);
}
return 0;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1cb042537fc..7c2d77ce3fc 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -245,10 +245,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (!table->file->has_transactions())
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
- if (!read_file_from_client)
+ if (!read_file_from_client && mysql_bin_log.is_open())
{
ex->skip_lines = save_skip_lines;
- Load_log_event qinfo(thd, ex, table->table_name, fields, handle_duplicates);
+ Load_log_event qinfo(thd, ex, table->table_name, fields,
+ handle_duplicates);
mysql_bin_log.write(&qinfo);
}
DBUG_RETURN(0);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 85a1847feab..88a9df7543a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -172,7 +172,7 @@ check_connections(THD *thd)
vio_description(net->vio)));
if (!thd->host) // If TCP/IP connection
{
- char ip[17];
+ char ip[30];
if (vio_peer_addr(net->vio,ip))
return (ER_BAD_HOST_ERROR);
@@ -718,7 +718,7 @@ bool do_command(THD *thd)
case COM_DROP_DB:
{
char *db=thd->strdup(packet+1);
- if (check_access(thd,DROP_ACL,db,0,1))
+ if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd))
break;
mysql_log.write(thd,command,db);
mysql_rm_db(thd,db,0);
@@ -1136,7 +1136,10 @@ mysql_execute_command(void)
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INDEX_ACL,tables))
goto error;
- res = mysql_create_index(thd, tables, lex->key_list);
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_create_index(thd, tables, lex->key_list);
break;
case SQLCOM_SLAVE_START:
@@ -1224,7 +1227,9 @@ mysql_execute_command(void)
goto error;
}
}
- if (mysql_rename_tables(thd,tables))
+ if (end_active_trans(thd))
+ res= -1;
+ else if (mysql_rename_tables(thd,tables))
res= -1;
break;
}
@@ -1428,7 +1433,10 @@ mysql_execute_command(void)
{
if (check_table_access(thd,DROP_ACL,tables))
goto error; /* purecov: inspected */
- res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_rm_table(thd,tables,lex->drop_if_exists);
}
break;
case SQLCOM_DROP_INDEX:
@@ -1438,7 +1446,10 @@ mysql_execute_command(void)
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INDEX_ACL,tables))
goto error;
- res = mysql_drop_index(thd, tables, lex->drop_list);
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_drop_index(thd, tables, lex->drop_list);
break;
case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
@@ -1643,7 +1654,8 @@ mysql_execute_command(void)
}
case SQLCOM_DROP_DB:
{
- if (check_access(thd,DROP_ACL,lex->name,0,1))
+ if (check_access(thd,DROP_ACL,lex->name,0,1) ||
+ end_active_trans(thd))
break;
mysql_rm_db(thd,lex->name,lex->drop_if_exists);
break;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 804a592b6e1..dc1ceb1112b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1427,6 +1427,17 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
new_table->time_stamp=save_time_stamp;
+#if defined( __WIN__) || defined( __EMX__)
+ /*
+ We must do the COMMIT here so that we can close and rename the
+ temporary table (as windows can't rename open tables)
+ */
+ if (ha_commit_stmt(thd))
+ error=1;
+ if (ha_commit(thd))
+ error=1;
+#endif
+
if (table->tmp_table)
{
/* We changed a temporary table */
@@ -1544,6 +1555,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
}
+
+#if !(defined( __WIN__) || defined( __EMX__))
/* The ALTER TABLE is always in it's own transaction */
error = ha_commit_stmt(thd);
if (ha_commit(thd))
@@ -1554,6 +1567,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
+#endif
thd->proc_info="end";
mysql_update_log.write(thd, thd->query,thd->query_length);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 25e990e9f62..54f85eb2ec7 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -49,7 +49,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
thr_lock_type lock_type)
{
bool using_limit=limit != HA_POS_ERROR;
- bool used_key_is_modified;
+ bool used_key_is_modified, using_transactions;
int error=0;
uint save_time_stamp, used_index;
key_map old_used_keys;
@@ -237,18 +237,20 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_READCHECK));
table->time_stamp=save_time_stamp; // Restore auto timestamp pointer
- if (updated)
+ using_transactions=table->file->has_transactions();
+ if (updated && (error == 0 || !using_transactions))
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ Query_log_event qinfo(thd, thd->query, using_transactions);
+ if (mysql_bin_log.write(&qinfo) && using_transactions)
+ error=1;
}
- if (!table->file->has_transactions())
+ if (!using_transactions)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (ha_autocommit_or_rollback(thd, error >= 0))
+ if (using_transactions && ha_autocommit_or_rollback(thd, error >= 0))
error=1;
if (thd->lock)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6735498b8f2..e301c290894 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2451,6 +2451,7 @@ user:
keyword:
ACTION {}
| AFTER_SYM {}
+ | AGAINST {}
| AGGREGATE_SYM {}
| AUTOCOMMIT {}
| AVG_ROW_LENGTH {}