1
/******************************************************
2
Data dictionary creation and booting
6
Created 4/18/1996 Heikki Tuuri
7
*******************************************************/
12
#include "dict0boot.ic"
15
#include "dict0crea.h"
17
#include "dict0load.h"
18
#include "dict0load.h"
21
#include "ibuf0ibuf.h"
26
/**************************************************************************
27
Gets a pointer to the dictionary header and x-latches its page. */
32
/* out: pointer to the dictionary header,
34
mtr_t* mtr) /* in: mtr */
39
block = buf_page_get(DICT_HDR_SPACE, 0, DICT_HDR_PAGE_NO,
41
header = DICT_HDR + buf_block_get_frame(block);
42
#ifdef UNIV_SYNC_DEBUG
43
buf_block_dbg_add_level(block, SYNC_DICT_HEADER);
44
#endif /* UNIV_SYNC_DEBUG */
48
/**************************************************************************
49
Returns a new table, index, or tree id. */
55
ulint type) /* in: DICT_HDR_ROW_ID, ... */
61
ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID));
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);
77
/**************************************************************************
78
Writes the current value of the row id counter to the dictionary header file
82
dict_hdr_flush_row_id(void)
83
/*=======================*/
89
ut_ad(mutex_own(&(dict_sys->mutex)));
91
id = dict_sys->row_id;
95
dict_hdr = dict_hdr_get(&mtr);
97
mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
102
/*********************************************************************
103
Creates the file page for the dictionary header. This function is
104
called only at the database creation. */
109
/* out: TRUE if succeed */
110
mtr_t* mtr) /* in: mtr */
113
dict_hdr_t* dict_header;
118
/* Create the dictionary header file block in a new, allocated file
119
segment in the system tablespace */
120
block = fseg_create(DICT_HDR_SPACE, 0,
121
DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
123
ut_a(DICT_HDR_PAGE_NO == buf_block_get_page_no(block));
125
dict_header = dict_hdr_get(mtr);
127
/* Start counting row, table, index, and tree ids from
129
mlog_write_dulint(dict_header + DICT_HDR_ROW_ID,
130
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
132
mlog_write_dulint(dict_header + DICT_HDR_TABLE_ID,
133
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
135
mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
136
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
138
/* Obsolete, but we must initialize it to 0 anyway. */
139
mlog_write_dulint(dict_header + DICT_HDR_MIX_ID,
140
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
142
/* Create the B-tree roots for the clustered indexes of the basic
145
/*--------------------------*/
146
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
147
DICT_HDR_SPACE, 0, DICT_TABLES_ID,
148
srv_sys->dummy_ind1, mtr);
149
if (root_page_no == FIL_NULL) {
154
mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
156
/*--------------------------*/
157
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, 0,
159
srv_sys->dummy_ind1, mtr);
160
if (root_page_no == FIL_NULL) {
165
mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
167
/*--------------------------*/
168
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
169
DICT_HDR_SPACE, 0, DICT_COLUMNS_ID,
170
srv_sys->dummy_ind1, mtr);
171
if (root_page_no == FIL_NULL) {
176
mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
178
/*--------------------------*/
179
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
180
DICT_HDR_SPACE, 0, DICT_INDEXES_ID,
181
srv_sys->dummy_ind1, mtr);
182
if (root_page_no == FIL_NULL) {
187
mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
189
/*--------------------------*/
190
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
191
DICT_HDR_SPACE, 0, DICT_FIELDS_ID,
192
srv_sys->dummy_ind1, mtr);
193
if (root_page_no == FIL_NULL) {
198
mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
200
/*--------------------------*/
205
/*********************************************************************
206
Initializes the data dictionary memory structures when the database is
207
started. This function is also called when the data dictionary is created. */
215
dict_hdr_t* dict_hdr;
222
/* Create the hash tables etc. */
225
heap = mem_heap_create(450);
227
mutex_enter(&(dict_sys->mutex));
229
/* Get the dictionary header */
230
dict_hdr = dict_hdr_get(&mtr);
232
/* Because we only write new row ids to disk-based data structure
233
(dictionary header) when it is divisible by
234
DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
235
the latest value of the row id counter. Therefore we advance
236
the counter at the database startup to avoid overlapping values.
237
Note that when a user after database startup first time asks for
238
a new row id, then because the counter is now divisible by
239
..._MARGIN, it will immediately be updated to the disk-based
242
dict_sys->row_id = ut_dulint_add(
243
ut_dulint_align_up(mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID,
245
DICT_HDR_ROW_ID_WRITE_MARGIN),
246
DICT_HDR_ROW_ID_WRITE_MARGIN);
248
/* Insert into the dictionary cache the descriptions of the basic
250
/*-------------------------*/
251
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
253
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
254
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
255
/* ROW_FORMAT = (N_COLS >> 31) ? COMPACT : REDUNDANT */
256
dict_mem_table_add_col(table, heap, "N_COLS", DATA_INT, 0, 4);
257
/* TYPE is either DICT_TABLE_ORDINARY, or (TYPE & DICT_TF_COMPACT)
258
and (TYPE & DICT_TF_FORMAT_MASK) are nonzero and TYPE = table->flags */
259
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
260
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
261
dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
262
dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
263
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
265
table->id = DICT_TABLES_ID;
267
dict_table_add_to_cache(table, heap);
268
dict_sys->sys_tables = table;
269
mem_heap_empty(heap);
271
index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
273
DICT_UNIQUE | DICT_CLUSTERED, 1);
275
dict_mem_index_add_field(index, "NAME", 0);
277
index->id = DICT_TABLES_ID;
279
error = dict_index_add_to_cache(table, index,
280
mtr_read_ulint(dict_hdr
283
ut_a(error == DB_SUCCESS);
285
/*-------------------------*/
286
index = dict_mem_index_create("SYS_TABLES", "ID_IND",
287
DICT_HDR_SPACE, DICT_UNIQUE, 1);
288
dict_mem_index_add_field(index, "ID", 0);
290
index->id = DICT_TABLE_IDS_ID;
291
error = dict_index_add_to_cache(table, index,
292
mtr_read_ulint(dict_hdr
293
+ DICT_HDR_TABLE_IDS,
295
ut_a(error == DB_SUCCESS);
297
/*-------------------------*/
298
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
300
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
301
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
302
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
303
dict_mem_table_add_col(table, heap, "MTYPE", DATA_INT, 0, 4);
304
dict_mem_table_add_col(table, heap, "PRTYPE", DATA_INT, 0, 4);
305
dict_mem_table_add_col(table, heap, "LEN", DATA_INT, 0, 4);
306
dict_mem_table_add_col(table, heap, "PREC", DATA_INT, 0, 4);
308
table->id = DICT_COLUMNS_ID;
310
dict_table_add_to_cache(table, heap);
311
dict_sys->sys_columns = table;
312
mem_heap_empty(heap);
314
index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
316
DICT_UNIQUE | DICT_CLUSTERED, 2);
318
dict_mem_index_add_field(index, "TABLE_ID", 0);
319
dict_mem_index_add_field(index, "POS", 0);
321
index->id = DICT_COLUMNS_ID;
322
error = dict_index_add_to_cache(table, index,
323
mtr_read_ulint(dict_hdr
326
ut_a(error == DB_SUCCESS);
328
/*-------------------------*/
329
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
331
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
332
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
333
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
334
dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4);
335
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
336
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
337
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
339
/* The '+ 2' below comes from the 2 system fields */
340
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
341
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
343
#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
344
#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
346
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
347
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
350
table->id = DICT_INDEXES_ID;
351
dict_table_add_to_cache(table, heap);
352
dict_sys->sys_indexes = table;
353
mem_heap_empty(heap);
355
index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
357
DICT_UNIQUE | DICT_CLUSTERED, 2);
359
dict_mem_index_add_field(index, "TABLE_ID", 0);
360
dict_mem_index_add_field(index, "ID", 0);
362
index->id = DICT_INDEXES_ID;
363
error = dict_index_add_to_cache(table, index,
364
mtr_read_ulint(dict_hdr
367
ut_a(error == DB_SUCCESS);
369
/*-------------------------*/
370
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
372
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
373
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
374
dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
376
table->id = DICT_FIELDS_ID;
377
dict_table_add_to_cache(table, heap);
378
dict_sys->sys_fields = table;
381
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
383
DICT_UNIQUE | DICT_CLUSTERED, 2);
385
dict_mem_index_add_field(index, "INDEX_ID", 0);
386
dict_mem_index_add_field(index, "POS", 0);
388
index->id = DICT_FIELDS_ID;
389
error = dict_index_add_to_cache(table, index,
390
mtr_read_ulint(dict_hdr
393
ut_a(error == DB_SUCCESS);
396
/*-------------------------*/
398
/* Initialize the insert buffer table and index for each tablespace */
400
ibuf_init_at_db_start();
402
/* Load definitions of other indexes on system tables */
404
dict_load_sys_table(dict_sys->sys_tables);
405
dict_load_sys_table(dict_sys->sys_columns);
406
dict_load_sys_table(dict_sys->sys_indexes);
407
dict_load_sys_table(dict_sys->sys_fields);
409
mutex_exit(&(dict_sys->mutex));
412
/*********************************************************************
413
Inserts the basic system table data into themselves in the database
417
dict_insert_initial_data(void)
418
/*==========================*/
420
/* Does nothing yet */
423
/*********************************************************************
424
Creates and initializes the data dictionary at the database creation. */
434
dict_hdr_create(&mtr);
440
dict_insert_initial_data();