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 */
40
header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
42
#ifdef UNIV_SYNC_DEBUG
43
buf_page_dbg_add_level(header, 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 */
112
dict_hdr_t* dict_header;
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
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
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) {
156
mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
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) {
166
mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
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) {
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, DICT_INDEXES_ID, FALSE, mtr);
181
if (root_page_no == FIL_NULL) {
186
mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
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) {
196
mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
198
/*--------------------------*/
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. */
213
dict_hdr_t* dict_hdr;
219
/* Create the hash tables etc. */
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
239
dict_sys->row_id = ut_dulint_add(
240
ut_dulint_align_up(mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID,
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
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",
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,
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,
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",
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,
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"
331
#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
332
#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
334
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
335
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
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",
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,
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;
367
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
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,
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
401
dict_insert_initial_data(void)
402
/*==========================*/
404
/* Does nothing yet */
407
/*********************************************************************
408
Creates and initializes the data dictionary at the database creation. */
418
dict_hdr_create(&mtr);
424
dict_insert_initial_data();