summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2003-05-03 02:29:40 +0300
committerunknown <heikki@hundin.mysql.fi>2003-05-03 02:29:40 +0300
commit8d8f52e902699c260f455075650906025f59f010 (patch)
tree2c18eac77e10f9bfcac7dfb438fb46b3a81d5e67 /sql
parent870397892be8a35afdb343c209be91cba117cee6 (diff)
downloadmariadb-git-8d8f52e902699c260f455075650906025f59f010.tar.gz
Many files:
Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released sql/log.cc: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released sql/handler.cc: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released sql/handler.h: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released sql/ha_innodb.cc: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released sql/ha_innodb.h: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/include/log0log.h: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/include/trx0trx.h: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/os/os0file.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/buf/buf0flu.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/trx/trx0trx.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/log/log0log.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/srv/srv0srv.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released innobase/row/row0mysql.c: Eliminate the LOCK_log bottleneck in group commit in binlogging: flush InnoDB log files only after it has been released
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_innodb.cc64
-rw-r--r--sql/ha_innodb.h2
-rw-r--r--sql/handler.cc30
-rw-r--r--sql/handler.h1
-rw-r--r--sql/log.cc20
5 files changed, 97 insertions, 20 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 73654536083..50bb4275eaa 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -872,8 +872,7 @@ innobase_flush_logs(void)
DBUG_ENTER("innobase_flush_logs");
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE);
DBUG_RETURN(result);
}
@@ -920,7 +919,7 @@ Commits a transaction in an InnoDB database. */
int
innobase_commit(
/*============*/
- /* out: 0 or error number */
+ /* out: 0 */
THD* thd, /* in: MySQL thread handle of the user for whom
the transaction should be committed */
void* trx_handle)/* in: InnoDB trx handle or
@@ -928,7 +927,6 @@ innobase_commit(
that the current SQL statement ended, and we should
mark the start of a new statement with a savepoint */
{
- int error = 0;
trx_t* trx;
DBUG_ENTER("innobase_commit");
@@ -955,29 +953,27 @@ innobase_commit(
innobase_release_stat_resources(trx);
trx_mark_sql_stat_end(trx);
-#ifndef DBUG_OFF
- if (error) {
- DBUG_PRINT("error", ("error: %d", error));
- }
-#endif
/* Tell InnoDB server that there might be work for
utility threads: */
srv_active_wake_master_thread();
- DBUG_RETURN(error);
+ DBUG_RETURN(0);
}
/*********************************************************************
This is called when MySQL writes the binlog entry for the current
transaction. Writes to the InnoDB tablespace info which tells where the
MySQL binlog entry for the current transaction ended. Also commits the
-transaction inside InnoDB. */
+transaction inside InnoDB but does NOT flush InnoDB log files to disk.
+To flush you have to call innobase_flush_log_to_disk. We have separated
+flushing to eliminate the bottleneck of LOCK_log in log.cc which disabled
+InnoDB's group commit capability. */
int
innobase_report_binlog_offset_and_commit(
/*=====================================*/
- /* out: 0 or error code */
+ /* out: 0 */
THD* thd, /* in: user thread */
void* trx_handle, /* in: InnoDB trx handle */
char* log_file_name, /* in: latest binlog file name */
@@ -993,7 +989,39 @@ innobase_report_binlog_offset_and_commit(
trx->mysql_log_file_name = log_file_name;
trx->mysql_log_offset = (ib_longlong)end_offset;
- return(innobase_commit(thd, trx_handle));
+ trx->flush_log_later = TRUE;
+
+ innobase_commit(thd, trx_handle);
+
+ trx->flush_log_later = FALSE;
+
+ return(0);
+}
+
+/*********************************************************************
+This is called after MySQL has written the binlog entry for the current
+transaction. Flushes the InnoDB log files to disk if required. */
+
+int
+innobase_commit_complete(
+/*=====================*/
+ /* out: 0 */
+ void* trx_handle) /* in: InnoDB trx handle */
+{
+ trx_t* trx;
+
+ if (srv_flush_log_at_trx_commit == 0) {
+
+ return(0);
+ }
+
+ trx = (trx_t*)trx_handle;
+
+ ut_a(trx != NULL);
+
+ trx_commit_complete_for_mysql(trx);
+
+ return(0);
}
/*********************************************************************
@@ -3202,7 +3230,7 @@ ha_innobase::create(
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+ log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE);
innobase_table = dict_table_get(norm_name, NULL);
@@ -3277,7 +3305,7 @@ ha_innobase::delete_table(
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+ log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE);
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -3347,7 +3375,7 @@ innobase_drop_database(
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+ log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE);
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -3419,7 +3447,7 @@ ha_innobase::rename_table(
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+ log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE);
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -3936,7 +3964,7 @@ ha_innobase::extra(
case HA_EXTRA_RESET:
case HA_EXTRA_RESET_STATE:
prebuilt->read_just_key = 0;
- break;
+ break;
case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0;
break;
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 5677d22a2ca..8309c5eb440 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -211,6 +211,8 @@ int innobase_report_binlog_offset_and_commit(
void* trx_handle,
char* log_file_name,
my_off_t end_offset);
+int innobase_commit_complete(
+ void* trx_handle);
int innobase_rollback(THD *thd, void* trx_handle);
int innobase_close_connection(THD *thd);
int innobase_drop_database(char *path);
diff --git a/sql/handler.cc b/sql/handler.cc
index 6e3f8486b45..ba7799fef4a 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -243,6 +243,9 @@ int ha_autocommit_or_rollback(THD *thd, int error)
replication. This function also calls the commit of the table
handler, because the order of transactions in the log of the table
handler must be the same as in the binlog.
+ NOTE that to eliminate the bottleneck of the group commit, we do not
+ flush the handler log files here, but only later in a call of
+ ha_commit_complete().
arguments:
thd: the thread handle of the current connection
@@ -269,13 +272,38 @@ int ha_report_binlog_offset_and_commit(THD *thd,
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
- trans->innodb_active_trans=0;
}
#endif
return error;
}
/*
+ Flushes the handler log files (if my.cnf settings do not free us from it)
+ after we have called ha_report_binlog_offset_and_commit(). To eliminate
+ the bottleneck from the group commit, this should be called when
+ LOCK_log has been released in log.cc.
+
+ arguments:
+ thd: the thread handle of the current connection
+ return value: always 0
+*/
+
+int ha_commit_complete(THD *thd)
+{
+#ifdef HAVE_INNOBASE_DB
+ THD_TRANS *trans;
+ trans = &thd->transaction.all;
+ if (trans->innobase_tid)
+ {
+ innobase_commit_complete(trans->innobase_tid);
+
+ trans->innodb_active_trans=0;
+ }
+#endif
+ return 0;
+}
+
+/*
This function should be called when MySQL sends rows of a SELECT result set
or the EOF mark to the client. It releases a possible adaptive hash index
S-latch held by thd in InnoDB and also releases a possible InnoDB query
diff --git a/sql/handler.h b/sql/handler.h
index 72a05d7ebee..fbad36bffdd 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -372,6 +372,7 @@ void ha_resize_key_cache(void);
int ha_start_stmt(THD *thd);
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
my_off_t end_offset);
+int ha_commit_complete(THD *thd);
int ha_release_temporary_latches(THD *thd);
int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
diff --git a/sql/log.cc b/sql/log.cc
index 8a5aba5cd34..f4c78b9c50d 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1033,6 +1033,8 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
bool MYSQL_LOG::write(Log_event* event_info)
{
+ THD *thd=event_info->thd;
+ bool called_handler_commit=0;
bool error=0;
DBUG_ENTER("MYSQL_LOG::write(event)");
@@ -1047,7 +1049,6 @@ bool MYSQL_LOG::write(Log_event* event_info)
if (is_open())
{
bool should_rotate = 0;
- THD *thd=event_info->thd;
const char *local_db = event_info->get_db();
#ifdef USING_TRANSACTIONS
IO_CACHE *file = ((event_info->get_cache_stmt()) ?
@@ -1147,6 +1148,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
{
error = ha_report_binlog_offset_and_commit(thd, log_file_name,
file->pos_in_file);
+ called_handler_commit=1;
}
should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size);
@@ -1172,6 +1174,15 @@ err:
}
pthread_mutex_unlock(&LOCK_log);
+
+ /* Flush the transactional handler log file now that we have released
+ LOCK_log; the flush is placed here to eliminate the bottleneck on the
+ group commit */
+
+ if (called_handler_commit) {
+ ha_commit_complete(thd);
+ }
+
DBUG_RETURN(error);
}
@@ -1277,6 +1288,13 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
}
VOID(pthread_mutex_unlock(&LOCK_log));
+
+ /* Flush the transactional handler log file now that we have released
+ LOCK_log; the flush is placed here to eliminate the bottleneck on the
+ group commit */
+
+ ha_commit_complete(thd);
+
DBUG_RETURN(0);
err: