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();