mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innobase / dict / dict0boot.c
blob5f9aaf71e18341f49ee6a97bb9dc0f2a1d538380
1 /******************************************************
2 Data dictionary creation and booting
4 (c) 1996 Innobase Oy
6 Created 4/18/1996 Heikki Tuuri
7 *******************************************************/
9 #include "dict0boot.h"
11 #ifdef UNIV_NONINL
12 #include "dict0boot.ic"
13 #endif
15 #include "dict0crea.h"
16 #include "btr0btr.h"
17 #include "dict0load.h"
18 #include "dict0load.h"
19 #include "trx0trx.h"
20 #include "srv0srv.h"
21 #include "ibuf0ibuf.h"
22 #include "buf0flu.h"
23 #include "log0recv.h"
24 #include "os0file.h"
26 /**************************************************************************
27 Gets a pointer to the dictionary header and x-latches its page. */
29 dict_hdr_t*
30 dict_hdr_get(
31 /*=========*/
32 /* out: pointer to the dictionary header,
33 page x-latched */
34 mtr_t* mtr) /* in: mtr */
36 dict_hdr_t* header;
38 ut_ad(mtr);
40 header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
41 RW_X_LATCH, mtr);
42 #ifdef UNIV_SYNC_DEBUG
43 buf_page_dbg_add_level(header, SYNC_DICT_HEADER);
44 #endif /* UNIV_SYNC_DEBUG */
45 return(header);
48 /**************************************************************************
49 Returns a new table, index, or tree id. */
51 dulint
52 dict_hdr_get_new_id(
53 /*================*/
54 /* out: the new id */
55 ulint type) /* in: DICT_HDR_ROW_ID, ... */
57 dict_hdr_t* dict_hdr;
58 dulint id;
59 mtr_t mtr;
61 ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID));
63 mtr_start(&mtr);
65 dict_hdr = dict_hdr_get(&mtr);
67 id = mtr_read_dulint(dict_hdr + type, &mtr);
68 id = ut_dulint_add(id, 1);
70 mlog_write_dulint(dict_hdr + type, id, &mtr);
72 mtr_commit(&mtr);
74 return(id);
77 /**************************************************************************
78 Writes the current value of the row id counter to the dictionary header file
79 page. */
81 void
82 dict_hdr_flush_row_id(void)
83 /*=======================*/
85 dict_hdr_t* dict_hdr;
86 dulint id;
87 mtr_t mtr;
89 ut_ad(mutex_own(&(dict_sys->mutex)));
91 id = dict_sys->row_id;
93 mtr_start(&mtr);
95 dict_hdr = dict_hdr_get(&mtr);
97 mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
99 mtr_commit(&mtr);
102 /*********************************************************************
103 Creates the file page for the dictionary header. This function is
104 called only at the database creation. */
105 static
106 ibool
107 dict_hdr_create(
108 /*============*/
109 /* out: TRUE if succeed */
110 mtr_t* mtr) /* in: mtr */
112 dict_hdr_t* dict_header;
113 ulint hdr_page_no;
114 ulint root_page_no;
115 page_t* page;
117 ut_ad(mtr);
119 /* Create the dictionary header file block in a new, allocated file
120 segment in the system tablespace */
121 page = fseg_create(DICT_HDR_SPACE, 0,
122 DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
124 hdr_page_no = buf_frame_get_page_no(page);
126 ut_a(DICT_HDR_PAGE_NO == hdr_page_no);
128 dict_header = dict_hdr_get(mtr);
130 /* Start counting row, table, index, and tree ids from
131 DICT_HDR_FIRST_ID */
132 mlog_write_dulint(dict_header + DICT_HDR_ROW_ID,
133 ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
135 mlog_write_dulint(dict_header + DICT_HDR_TABLE_ID,
136 ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
138 mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
139 ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
141 /* Obsolete, but we must initialize it to 0 anyway. */
142 mlog_write_dulint(dict_header + DICT_HDR_MIX_ID,
143 ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
145 /* Create the B-tree roots for the clustered indexes of the basic
146 system tables */
148 /*--------------------------*/
149 root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
150 DICT_HDR_SPACE, DICT_TABLES_ID, FALSE, mtr);
151 if (root_page_no == FIL_NULL) {
153 return(FALSE);
156 mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
157 MLOG_4BYTES, mtr);
158 /*--------------------------*/
159 root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE,
160 DICT_TABLE_IDS_ID, FALSE, mtr);
161 if (root_page_no == FIL_NULL) {
163 return(FALSE);
166 mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
167 MLOG_4BYTES, mtr);
168 /*--------------------------*/
169 root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
170 DICT_HDR_SPACE, DICT_COLUMNS_ID, FALSE, mtr);
171 if (root_page_no == FIL_NULL) {
173 return(FALSE);
176 mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
177 MLOG_4BYTES, mtr);
178 /*--------------------------*/
179 root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
180 DICT_HDR_SPACE, DICT_INDEXES_ID, FALSE, mtr);
181 if (root_page_no == FIL_NULL) {
183 return(FALSE);
186 mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
187 MLOG_4BYTES, mtr);
188 /*--------------------------*/
189 root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
190 DICT_HDR_SPACE, DICT_FIELDS_ID, FALSE, mtr);
191 if (root_page_no == FIL_NULL) {
193 return(FALSE);
196 mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
197 MLOG_4BYTES, mtr);
198 /*--------------------------*/
200 return(TRUE);
203 /*********************************************************************
204 Initializes the data dictionary memory structures when the database is
205 started. This function is also called when the data dictionary is created. */
207 void
208 dict_boot(void)
209 /*===========*/
211 dict_table_t* table;
212 dict_index_t* index;
213 dict_hdr_t* dict_hdr;
214 mem_heap_t* heap;
215 mtr_t mtr;
217 mtr_start(&mtr);
219 /* Create the hash tables etc. */
220 dict_init();
222 heap = mem_heap_create(450);
224 mutex_enter(&(dict_sys->mutex));
226 /* Get the dictionary header */
227 dict_hdr = dict_hdr_get(&mtr);
229 /* Because we only write new row ids to disk-based data structure
230 (dictionary header) when it is divisible by
231 DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
232 the latest value of the row id counter. Therefore we advance
233 the counter at the database startup to avoid overlapping values.
234 Note that when a user after database startup first time asks for
235 a new row id, then because the counter is now divisible by
236 ..._MARGIN, it will immediately be updated to the disk-based
237 header. */
239 dict_sys->row_id = ut_dulint_add(
240 ut_dulint_align_up(mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID,
241 &mtr),
242 DICT_HDR_ROW_ID_WRITE_MARGIN),
243 DICT_HDR_ROW_ID_WRITE_MARGIN);
245 /* Insert into the dictionary cache the descriptions of the basic
246 system tables */
247 /*-------------------------*/
248 table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
250 dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
251 dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
252 dict_mem_table_add_col(table, heap, "N_COLS", DATA_INT, 0, 4);
253 dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
254 dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
255 dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
256 dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
257 dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
259 table->id = DICT_TABLES_ID;
261 dict_table_add_to_cache(table, heap);
262 dict_sys->sys_tables = table;
263 mem_heap_empty(heap);
265 index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
266 DICT_HDR_SPACE,
267 DICT_UNIQUE | DICT_CLUSTERED, 1);
269 dict_mem_index_add_field(index, "NAME", 0);
271 index->id = DICT_TABLES_ID;
273 dict_index_add_to_cache(table, index,
274 mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
275 MLOG_4BYTES, &mtr));
277 /*-------------------------*/
278 index = dict_mem_index_create("SYS_TABLES", "ID_IND",
279 DICT_HDR_SPACE, DICT_UNIQUE, 1);
280 dict_mem_index_add_field(index, "ID", 0);
282 index->id = DICT_TABLE_IDS_ID;
283 dict_index_add_to_cache(table, index,
284 mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
285 MLOG_4BYTES, &mtr));
287 /*-------------------------*/
288 table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
290 dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
291 dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
292 dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
293 dict_mem_table_add_col(table, heap, "MTYPE", DATA_INT, 0, 4);
294 dict_mem_table_add_col(table, heap, "PRTYPE", DATA_INT, 0, 4);
295 dict_mem_table_add_col(table, heap, "LEN", DATA_INT, 0, 4);
296 dict_mem_table_add_col(table, heap, "PREC", DATA_INT, 0, 4);
298 table->id = DICT_COLUMNS_ID;
300 dict_table_add_to_cache(table, heap);
301 dict_sys->sys_columns = table;
302 mem_heap_empty(heap);
304 index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
305 DICT_HDR_SPACE,
306 DICT_UNIQUE | DICT_CLUSTERED, 2);
308 dict_mem_index_add_field(index, "TABLE_ID", 0);
309 dict_mem_index_add_field(index, "POS", 0);
311 index->id = DICT_COLUMNS_ID;
312 dict_index_add_to_cache(table, index,
313 mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
314 MLOG_4BYTES, &mtr));
316 /*-------------------------*/
317 table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
319 dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
320 dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
321 dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
322 dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4);
323 dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
324 dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
325 dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
327 /* The '+ 2' below comes from the 2 system fields */
328 #if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
329 #error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
330 #endif
331 #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
332 #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
333 #endif
334 #if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
335 #error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
336 #endif
338 table->id = DICT_INDEXES_ID;
339 dict_table_add_to_cache(table, heap);
340 dict_sys->sys_indexes = table;
341 mem_heap_empty(heap);
343 index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
344 DICT_HDR_SPACE,
345 DICT_UNIQUE | DICT_CLUSTERED, 2);
347 dict_mem_index_add_field(index, "TABLE_ID", 0);
348 dict_mem_index_add_field(index, "ID", 0);
350 index->id = DICT_INDEXES_ID;
351 dict_index_add_to_cache(table, index,
352 mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
353 MLOG_4BYTES, &mtr));
355 /*-------------------------*/
356 table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
358 dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
359 dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
360 dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
362 table->id = DICT_FIELDS_ID;
363 dict_table_add_to_cache(table, heap);
364 dict_sys->sys_fields = table;
365 mem_heap_free(heap);
367 index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
368 DICT_HDR_SPACE,
369 DICT_UNIQUE | DICT_CLUSTERED, 2);
371 dict_mem_index_add_field(index, "INDEX_ID", 0);
372 dict_mem_index_add_field(index, "POS", 0);
374 index->id = DICT_FIELDS_ID;
375 dict_index_add_to_cache(table, index,
376 mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
377 MLOG_4BYTES, &mtr));
379 mtr_commit(&mtr);
380 /*-------------------------*/
382 /* Initialize the insert buffer table and index for each tablespace */
384 ibuf_init_at_db_start();
386 /* Load definitions of other indexes on system tables */
388 dict_load_sys_table(dict_sys->sys_tables);
389 dict_load_sys_table(dict_sys->sys_columns);
390 dict_load_sys_table(dict_sys->sys_indexes);
391 dict_load_sys_table(dict_sys->sys_fields);
393 mutex_exit(&(dict_sys->mutex));
396 /*********************************************************************
397 Inserts the basic system table data into themselves in the database
398 creation. */
399 static
400 void
401 dict_insert_initial_data(void)
402 /*==========================*/
404 /* Does nothing yet */
407 /*********************************************************************
408 Creates and initializes the data dictionary at the database creation. */
410 void
411 dict_create(void)
412 /*=============*/
414 mtr_t mtr;
416 mtr_start(&mtr);
418 dict_hdr_create(&mtr);
420 mtr_commit(&mtr);
422 dict_boot();
424 dict_insert_initial_data();