mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 02:46:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			132 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright (C) 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | |
| 
 | |
| #include "maria_def.h"
 | |
| #include "trnman.h"
 | |
| #include "ma_trnman.h"
 | |
| 
 | |
| /**
 | |
|    writes a COMMIT record to log and commits transaction in memory
 | |
| 
 | |
|    @param  trn              transaction
 | |
| 
 | |
|    @return Operation status
 | |
|      @retval 0      ok
 | |
|      @retval 1      error (disk error or out of memory)
 | |
| */
 | |
| 
 | |
| int ma_commit(TRN *trn)
 | |
| {
 | |
|   int res;
 | |
|   LSN commit_lsn;
 | |
|   LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS];
 | |
|   DBUG_ENTER("ma_commit");
 | |
| 
 | |
|   DBUG_ASSERT(trn->rec_lsn == LSN_IMPOSSIBLE);
 | |
|   if (trn->undo_lsn == 0) /* no work done, rollback (cheaper than commit) */
 | |
|     DBUG_RETURN(trnman_rollback_trn(trn));
 | |
|   /*
 | |
|     - if COMMIT record is written before trnman_commit_trn():
 | |
|     if Checkpoint comes in the middle it will see trn is not committed,
 | |
|     then if crash, Recovery might roll back trn (if MY_MIN(rec_lsn) is after
 | |
|     COMMIT record) and this is not an issue as
 | |
|     * transaction's updates were not made visible to other transactions
 | |
|     * "commit ok" was not sent to client
 | |
|     Alternatively, Recovery might commit trn (if MY_MIN(rec_lsn) is before
 | |
|     COMMIT record), which is ok too. All in all it means that "trn committed"
 | |
|     is not 100% equal to "COMMIT record written".
 | |
|     - if COMMIT record is written after trnman_commit_trn():
 | |
|     if crash happens between the two, trn will be rolled back which is an
 | |
|     issue (transaction's updates were made visible to other transactions).
 | |
|     So we need to go the first way.
 | |
| 
 | |
|     Note that we have to use | here to ensure that all calls are made.
 | |
|   */
 | |
| 
 | |
|   /*
 | |
|     We do not store "thd->transaction.xid_state.xid" for now, it will be
 | |
|     needed only when we support XA.
 | |
|   */
 | |
|   res= (translog_write_record(&commit_lsn, LOGREC_COMMIT,
 | |
|                              trn, NULL, 0,
 | |
|                              sizeof(log_array)/sizeof(log_array[0]),
 | |
|                              log_array, NULL, NULL) |
 | |
|         translog_flush(commit_lsn));
 | |
| 
 | |
|   DBUG_EXECUTE_IF("maria_sleep_in_commit",
 | |
|                   {
 | |
|                     DBUG_PRINT("info", ("maria_sleep_in_commit"));
 | |
|                     sleep(3);
 | |
|                   });
 | |
|   res|= trnman_commit_trn(trn);
 | |
| 
 | |
| 
 | |
|   /*
 | |
|     Note: if trnman_commit_trn() fails above, we have already
 | |
|     written the COMMIT record, so Checkpoint and Recovery will see the
 | |
|     transaction as committed.
 | |
|   */
 | |
|   DBUG_RETURN(res);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|    Writes a COMMIT record for a transaction associated with a file
 | |
| 
 | |
|    @param  info              Maria handler
 | |
| 
 | |
|    @return Operation status
 | |
|      @retval 0      ok
 | |
|      @retval #      error (disk error or out of memory)
 | |
| */
 | |
| 
 | |
| int maria_commit(MARIA_HA *info)
 | |
| {
 | |
|   TRN *trn;
 | |
|   if (!info->s->now_transactional)
 | |
|     return 0;
 | |
|   trn= info->trn;
 | |
|   _ma_reset_trn_for_table(info);
 | |
|   return ma_commit(trn);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|    Starts a transaction on a file handle
 | |
| 
 | |
|    @param  info              Maria handler
 | |
| 
 | |
|    @return Operation status
 | |
|      @retval 0      ok
 | |
|      @retval #      Error code.
 | |
| 
 | |
|    @note this can be used only in single-threaded programs (tests),
 | |
|    because we create a transaction (trnman_new_trn) with WT_THD=0.
 | |
|    XXX it needs to be fixed when we'll start using maria_begin from SQL.
 | |
| */
 | |
| 
 | |
| int maria_begin(MARIA_HA *info)
 | |
| {
 | |
|   DBUG_ENTER("maria_begin");
 | |
| 
 | |
|   if (info->s->now_transactional)
 | |
|   {
 | |
|     TRN *trn= trnman_new_trn(0);
 | |
|     if (unlikely(!trn))
 | |
|       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 | |
|     _ma_set_trn_for_table(info, trn);
 | |
|   }
 | |
|   DBUG_RETURN(0);
 | |
| }
 | 
