1 /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 of the License.
6 
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11 
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
15 
16 /* Initialize an maria-database */
17 
18 #include "maria_def.h"
19 #include <ft_global.h>
20 #include "ma_blockrec.h"
21 #include "trnman_public.h"
22 #include "ma_checkpoint.h"
23 #include <hash.h>
24 
25 void history_state_free(MARIA_STATE_HISTORY_CLOSED *closed_history)
26 {
27   MARIA_STATE_HISTORY *history, *next;
28 
29   /*
30     Free all active history
31     In case of maria_open() this list should be empty as the history is moved
32     to handler->share.
33  */
34   for (history= closed_history->state_history; history ; history= next)
35   {
36     next= history->next;
37     my_free(history);
main() -> Result<(), Box<dyn Error>>38   }
39   my_free(closed_history);
40 }
41 
42 
43 static int dummy_maria_create_trn_hook(MARIA_HA *info __attribute__((unused)))
44 {
45   return 0;
46 }
47 
48 /*
49   Initialize maria
50 
51   SYNOPSIS
52     maria_init()
53 
54   TODO
55     Open log files and do recovery if need
56 
57   RETURN
58   0  ok
59   #  error number
60 */
61 
62 int maria_init(void)
63 {
64   DBUG_ASSERT(maria_block_size &&
65               maria_block_size % MARIA_MIN_KEY_BLOCK_LENGTH == 0);
66   if (!maria_inited)
67   {
68     maria_inited= TRUE;
69     mysql_mutex_init(key_THR_LOCK_maria, &THR_LOCK_maria, MY_MUTEX_INIT_SLOW);
70     _ma_init_block_record_data();
71     trnman_end_trans_hook= _ma_trnman_end_trans_hook;
72     maria_create_trn_hook= dummy_maria_create_trn_hook;
73   }
74   my_hash_init(&maria_stored_state, &my_charset_bin, 32,
75             0, sizeof(LSN), 0, (my_hash_free_key) history_state_free, 0);
76   DBUG_PRINT("info",("dummy_transaction_object: %p",
77                      &dummy_transaction_object));
78   return 0;
79 }
80 
81 
82 void maria_end(void)
83 {
84   DBUG_ENTER("maria_end");
85   if (maria_inited)
86   {
87     TrID trid;
88     maria_inited= maria_multi_threaded= FALSE;
89     ft_free_stopwords();
90     ma_checkpoint_end();
91     if (translog_status == TRANSLOG_OK)
92     {
93       translog_soft_sync_end();
94       translog_sync();
95     }
96     if ((trid= trnman_get_max_trid()) > max_trid_in_control_file)
97     {
98       /*
99         Store max transaction id into control file, in case logs are removed
100         by user, or maria_chk wants to check tables (it cannot access max trid
101         from the log, as it cannot process REDOs).
102       */
103       (void)ma_control_file_write_and_force(last_checkpoint_lsn, last_logno,
104                                             trid, recovery_failures);
105     }
106     trnman_destroy();
107     if (translog_status == TRANSLOG_OK || translog_status == TRANSLOG_READONLY)
108       translog_destroy();
109     end_pagecache(maria_log_pagecache, TRUE);
110     end_pagecache(maria_pagecache, TRUE);
111     ma_control_file_end();
112     mysql_mutex_destroy(&THR_LOCK_maria);
113     my_hash_free(&maria_stored_state);
114   }
115   DBUG_VOID_RETURN;
116 }
117 
118 /**
119    Upgrade from older Aria versions:
120 
121   - In MariaDB 5.1, the name of the control file and log files had the
122     'maria' prefix, now they have the 'aria' prefix.
123 
124   @return: 0 ok
125            1 error
126 
127 */
128 
129 my_bool maria_upgrade()
130 {
131   char name[FN_REFLEN], new_name[FN_REFLEN];
132   DBUG_ENTER("maria_upgrade");
133 
134   fn_format(name, "maria_log_control", maria_data_root, "", MYF(MY_WME));
135 
136   if (!my_access(name,F_OK))
137   {
138     /*
139       Old style control file found; Rename the control file and the log files.
140       We start by renaming all log files, so that if we get a crash
141       we will continue from where we left.
142     */
143     uint i;
144     MY_DIR *dir= my_dir(maria_data_root, MYF(MY_WME));
145     if (!dir)
146       DBUG_RETURN(1);
147 
148     my_message(HA_ERR_INITIALIZATION,
149                "Found old style Maria log files; "
150                "Converting them to Aria names",
151                MYF(ME_JUST_INFO));
152 
153     for (i= 0; i < dir->number_of_files; i++)
154     {
155       const char *file= dir->dir_entry[i].name;
156       if (strncmp(file, "maria_log.", 10) == 0 &&
157           file[10] >= '0' && file[10] <= '9' &&
158         file[11] >= '0' && file[11] <= '9' &&
159         file[12] >= '0' && file[12] <= '9' &&
160         file[13] >= '0' && file[13] <= '9' &&
161         file[14] >= '0' && file[14] <= '9' &&
162         file[15] >= '0' && file[15] <= '9' &&
163         file[16] >= '0' && file[16] <= '9' &&
164         file[17] >= '0' && file[17] <= '9' &&
165         file[18] == '\0')
166       {
167         /* Remove the 'm' in 'maria' */
168         char old_logname[FN_REFLEN], new_logname[FN_REFLEN];
169         fn_format(old_logname, file, maria_data_root, "", MYF(0));
170         fn_format(new_logname, file+1, maria_data_root, "", MYF(0));
171         if (mysql_file_rename(key_file_translog, old_logname,
172                               new_logname, MYF(MY_WME)))
173         {
174           my_dirend(dir);
175           DBUG_RETURN(1);
176         }
177       }
178     }
179     my_dirend(dir);
180 
181     fn_format(new_name, CONTROL_FILE_BASE_NAME, maria_data_root, "", MYF(0));
182     if (mysql_file_rename(key_file_control, name, new_name, MYF(MY_WME)))
183       DBUG_RETURN(1);
184   }
185   DBUG_RETURN(0);
186 }
187