~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/dict/dict0boot.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
13
 
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file dict/dict0boot.c
21
 
Data dictionary creation and booting
22
 
 
23
 
Created 4/18/1996 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
#include "dict0boot.h"
27
 
 
28
 
#ifdef UNIV_NONINL
29
 
#include "dict0boot.ic"
30
 
#endif
31
 
 
32
 
#include "dict0crea.h"
33
 
#include "btr0btr.h"
34
 
#include "dict0load.h"
35
 
#include "dict0load.h"
36
 
#include "trx0trx.h"
37
 
#include "srv0srv.h"
38
 
#include "ibuf0ibuf.h"
39
 
#include "buf0flu.h"
40
 
#include "log0recv.h"
41
 
#include "os0file.h"
42
 
 
43
 
/**********************************************************************//**
44
 
Gets a pointer to the dictionary header and x-latches its page.
45
 
@return pointer to the dictionary header, page x-latched */
46
 
UNIV_INTERN
47
 
dict_hdr_t*
48
 
dict_hdr_get(
49
 
/*=========*/
50
 
        mtr_t*  mtr)    /*!< in: mtr */
51
 
{
52
 
        buf_block_t*    block;
53
 
        dict_hdr_t*     header;
54
 
 
55
 
        block = buf_page_get(DICT_HDR_SPACE, 0, DICT_HDR_PAGE_NO,
56
 
                             RW_X_LATCH, mtr);
57
 
        header = DICT_HDR + buf_block_get_frame(block);
58
 
 
59
 
        buf_block_dbg_add_level(block, SYNC_DICT_HEADER);
60
 
 
61
 
        return(header);
62
 
}
63
 
 
64
 
/**********************************************************************//**
65
 
Returns a new table, index, or space id. */
66
 
UNIV_INTERN
67
 
void
68
 
dict_hdr_get_new_id(
69
 
/*================*/
70
 
        table_id_t*     table_id,       /*!< out: table id
71
 
                                        (not assigned if NULL) */
72
 
        index_id_t*     index_id,       /*!< out: index id
73
 
                                        (not assigned if NULL) */
74
 
        ulint*          space_id)       /*!< out: space id
75
 
                                        (not assigned if NULL) */
76
 
{
77
 
        dict_hdr_t*     dict_hdr;
78
 
        ib_id_t         id;
79
 
        mtr_t           mtr;
80
 
 
81
 
        mtr_start(&mtr);
82
 
 
83
 
        dict_hdr = dict_hdr_get(&mtr);
84
 
 
85
 
        if (table_id) {
86
 
                id = mach_read_from_8(dict_hdr + DICT_HDR_TABLE_ID);
87
 
                id++;
88
 
                mlog_write_ull(dict_hdr + DICT_HDR_TABLE_ID, id, &mtr);
89
 
                *table_id = id;
90
 
        }
91
 
 
92
 
        if (index_id) {
93
 
                id = mach_read_from_8(dict_hdr + DICT_HDR_INDEX_ID);
94
 
                id++;
95
 
                mlog_write_ull(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr);
96
 
                *index_id = id;
97
 
        }
98
 
 
99
 
        if (space_id) {
100
 
                *space_id = mtr_read_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
101
 
                                           MLOG_4BYTES, &mtr);
102
 
                if (fil_assign_new_space_id(space_id)) {
103
 
                        mlog_write_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
104
 
                                         *space_id, MLOG_4BYTES, &mtr);
105
 
                }
106
 
        }
107
 
 
108
 
        mtr_commit(&mtr);
109
 
}
110
 
 
111
 
/**********************************************************************//**
112
 
Writes the current value of the row id counter to the dictionary header file
113
 
page. */
114
 
UNIV_INTERN
115
 
void
116
 
dict_hdr_flush_row_id(void)
117
 
/*=======================*/
118
 
{
119
 
        dict_hdr_t*     dict_hdr;
120
 
        row_id_t        id;
121
 
        mtr_t           mtr;
122
 
 
123
 
        ut_ad(mutex_own(&(dict_sys->mutex)));
124
 
 
125
 
        id = dict_sys->row_id;
126
 
 
127
 
        mtr_start(&mtr);
128
 
 
129
 
        dict_hdr = dict_hdr_get(&mtr);
130
 
 
131
 
        mlog_write_ull(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
132
 
 
133
 
        mtr_commit(&mtr);
134
 
}
135
 
 
136
 
/*****************************************************************//**
137
 
Creates the file page for the dictionary header. This function is
138
 
called only at the database creation.
139
 
@return TRUE if succeed */
140
 
static
141
 
ibool
142
 
dict_hdr_create(
143
 
/*============*/
144
 
        mtr_t*  mtr)    /*!< in: mtr */
145
 
{
146
 
        buf_block_t*    block;
147
 
        dict_hdr_t*     dict_header;
148
 
        ulint           root_page_no;
149
 
 
150
 
        ut_ad(mtr);
151
 
 
152
 
        /* Create the dictionary header file block in a new, allocated file
153
 
        segment in the system tablespace */
154
 
        block = fseg_create(DICT_HDR_SPACE, 0,
155
 
                            DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
156
 
 
157
 
        ut_a(DICT_HDR_PAGE_NO == buf_block_get_page_no(block));
158
 
 
159
 
        dict_header = dict_hdr_get(mtr);
160
 
 
161
 
        /* Start counting row, table, index, and tree ids from
162
 
        DICT_HDR_FIRST_ID */
163
 
        mlog_write_ull(dict_header + DICT_HDR_ROW_ID,
164
 
                       DICT_HDR_FIRST_ID, mtr);
165
 
 
166
 
        mlog_write_ull(dict_header + DICT_HDR_TABLE_ID,
167
 
                       DICT_HDR_FIRST_ID, mtr);
168
 
 
169
 
        mlog_write_ull(dict_header + DICT_HDR_INDEX_ID,
170
 
                       DICT_HDR_FIRST_ID, mtr);
171
 
 
172
 
        mlog_write_ulint(dict_header + DICT_HDR_MAX_SPACE_ID,
173
 
                         0, MLOG_4BYTES, mtr);
174
 
 
175
 
        /* Obsolete, but we must initialize it anyway. */
176
 
        mlog_write_ulint(dict_header + DICT_HDR_MIX_ID_LOW,
177
 
                         DICT_HDR_FIRST_ID, MLOG_4BYTES, mtr);
178
 
 
179
 
        /* Create the B-tree roots for the clustered indexes of the basic
180
 
        system tables */
181
 
 
182
 
        /*--------------------------*/
183
 
        root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
184
 
                                  DICT_HDR_SPACE, 0, DICT_TABLES_ID,
185
 
                                  dict_ind_redundant, mtr);
186
 
        if (root_page_no == FIL_NULL) {
187
 
 
188
 
                return(FALSE);
189
 
        }
190
 
 
191
 
        mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
192
 
                         MLOG_4BYTES, mtr);
193
 
        /*--------------------------*/
194
 
        root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, 0,
195
 
                                  DICT_TABLE_IDS_ID,
196
 
                                  dict_ind_redundant, mtr);
197
 
        if (root_page_no == FIL_NULL) {
198
 
 
199
 
                return(FALSE);
200
 
        }
201
 
 
202
 
        mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
203
 
                         MLOG_4BYTES, mtr);
204
 
        /*--------------------------*/
205
 
        root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
206
 
                                  DICT_HDR_SPACE, 0, DICT_COLUMNS_ID,
207
 
                                  dict_ind_redundant, mtr);
208
 
        if (root_page_no == FIL_NULL) {
209
 
 
210
 
                return(FALSE);
211
 
        }
212
 
 
213
 
        mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
214
 
                         MLOG_4BYTES, mtr);
215
 
        /*--------------------------*/
216
 
        root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
217
 
                                  DICT_HDR_SPACE, 0, DICT_INDEXES_ID,
218
 
                                  dict_ind_redundant, mtr);
219
 
        if (root_page_no == FIL_NULL) {
220
 
 
221
 
                return(FALSE);
222
 
        }
223
 
 
224
 
        mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
225
 
                         MLOG_4BYTES, mtr);
226
 
        /*--------------------------*/
227
 
        root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
228
 
                                  DICT_HDR_SPACE, 0, DICT_FIELDS_ID,
229
 
                                  dict_ind_redundant, mtr);
230
 
        if (root_page_no == FIL_NULL) {
231
 
 
232
 
                return(FALSE);
233
 
        }
234
 
 
235
 
        mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
236
 
                         MLOG_4BYTES, mtr);
237
 
        /*--------------------------*/
238
 
 
239
 
        return(TRUE);
240
 
}
241
 
 
242
 
/*****************************************************************//**
243
 
Initializes the data dictionary memory structures when the database is
244
 
started. This function is also called when the data dictionary is created. */
245
 
UNIV_INTERN
246
 
void
247
 
dict_boot(void)
248
 
/*===========*/
249
 
{
250
 
        dict_table_t*   table;
251
 
        dict_index_t*   index;
252
 
        dict_hdr_t*     dict_hdr;
253
 
        mem_heap_t*     heap;
254
 
        mtr_t           mtr;
255
 
        ulint           error;
256
 
 
257
 
        mtr_start(&mtr);
258
 
 
259
 
        /* Create the hash tables etc. */
260
 
        dict_init();
261
 
 
262
 
        heap = mem_heap_create(450);
263
 
 
264
 
        mutex_enter(&(dict_sys->mutex));
265
 
 
266
 
        /* Get the dictionary header */
267
 
        dict_hdr = dict_hdr_get(&mtr);
268
 
 
269
 
        /* Because we only write new row ids to disk-based data structure
270
 
        (dictionary header) when it is divisible by
271
 
        DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
272
 
        the latest value of the row id counter. Therefore we advance
273
 
        the counter at the database startup to avoid overlapping values.
274
 
        Note that when a user after database startup first time asks for
275
 
        a new row id, then because the counter is now divisible by
276
 
        ..._MARGIN, it will immediately be updated to the disk-based
277
 
        header. */
278
 
 
279
 
        dict_sys->row_id = DICT_HDR_ROW_ID_WRITE_MARGIN
280
 
                + ut_uint64_align_up(mach_read_from_8(dict_hdr + DICT_HDR_ROW_ID),
281
 
                                     DICT_HDR_ROW_ID_WRITE_MARGIN);
282
 
 
283
 
        /* Insert into the dictionary cache the descriptions of the basic
284
 
        system tables */
285
 
        /*-------------------------*/
286
 
        table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
287
 
 
288
 
        dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
289
 
        dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
290
 
        /* ROW_FORMAT = (N_COLS >> 31) ? COMPACT : REDUNDANT */
291
 
        dict_mem_table_add_col(table, heap, "N_COLS", DATA_INT, 0, 4);
292
 
        /* TYPE is either DICT_TABLE_ORDINARY, or (TYPE & DICT_TF_COMPACT)
293
 
        and (TYPE & DICT_TF_FORMAT_MASK) are nonzero and TYPE = table->flags */
294
 
        dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
295
 
        dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
296
 
        /* MIX_LEN may contain additional table flags when
297
 
        ROW_FORMAT!=REDUNDANT.  Currently, these flags include
298
 
        DICT_TF2_TEMPORARY. */
299
 
        dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
300
 
        dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
301
 
        dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
302
 
 
303
 
        table->id = DICT_TABLES_ID;
304
 
 
305
 
        dict_table_add_to_cache(table, heap);
306
 
        dict_sys->sys_tables = table;
307
 
        mem_heap_empty(heap);
308
 
 
309
 
        index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
310
 
                                      DICT_HDR_SPACE,
311
 
                                      DICT_UNIQUE | DICT_CLUSTERED, 1);
312
 
 
313
 
        dict_mem_index_add_field(index, "NAME", 0);
314
 
 
315
 
        index->id = DICT_TABLES_ID;
316
 
 
317
 
        error = dict_index_add_to_cache(table, index,
318
 
                                        mtr_read_ulint(dict_hdr
319
 
                                                       + DICT_HDR_TABLES,
320
 
                                                       MLOG_4BYTES, &mtr),
321
 
                                        FALSE);
322
 
        ut_a(error == DB_SUCCESS);
323
 
 
324
 
        /*-------------------------*/
325
 
        index = dict_mem_index_create("SYS_TABLES", "ID_IND",
326
 
                                      DICT_HDR_SPACE, DICT_UNIQUE, 1);
327
 
        dict_mem_index_add_field(index, "ID", 0);
328
 
 
329
 
        index->id = DICT_TABLE_IDS_ID;
330
 
        error = dict_index_add_to_cache(table, index,
331
 
                                        mtr_read_ulint(dict_hdr
332
 
                                                       + DICT_HDR_TABLE_IDS,
333
 
                                                       MLOG_4BYTES, &mtr),
334
 
                                        FALSE);
335
 
        ut_a(error == DB_SUCCESS);
336
 
 
337
 
        /*-------------------------*/
338
 
        table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
339
 
 
340
 
        dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
341
 
        dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
342
 
        dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
343
 
        dict_mem_table_add_col(table, heap, "MTYPE", DATA_INT, 0, 4);
344
 
        dict_mem_table_add_col(table, heap, "PRTYPE", DATA_INT, 0, 4);
345
 
        dict_mem_table_add_col(table, heap, "LEN", DATA_INT, 0, 4);
346
 
        dict_mem_table_add_col(table, heap, "PREC", DATA_INT, 0, 4);
347
 
 
348
 
        table->id = DICT_COLUMNS_ID;
349
 
 
350
 
        dict_table_add_to_cache(table, heap);
351
 
        dict_sys->sys_columns = table;
352
 
        mem_heap_empty(heap);
353
 
 
354
 
        index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
355
 
                                      DICT_HDR_SPACE,
356
 
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
357
 
 
358
 
        dict_mem_index_add_field(index, "TABLE_ID", 0);
359
 
        dict_mem_index_add_field(index, "POS", 0);
360
 
 
361
 
        index->id = DICT_COLUMNS_ID;
362
 
        error = dict_index_add_to_cache(table, index,
363
 
                                        mtr_read_ulint(dict_hdr
364
 
                                                       + DICT_HDR_COLUMNS,
365
 
                                                       MLOG_4BYTES, &mtr),
366
 
                                        FALSE);
367
 
        ut_a(error == DB_SUCCESS);
368
 
 
369
 
        /*-------------------------*/
370
 
        table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
371
 
 
372
 
        dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
373
 
        dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
374
 
        dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
375
 
        dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4);
376
 
        dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
377
 
        dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
378
 
        dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
379
 
 
380
 
        /* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
381
 
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
382
 
#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
383
 
#endif
384
 
#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
385
 
#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
386
 
#endif
387
 
#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2
388
 
#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2"
389
 
#endif
390
 
#if DICT_SYS_INDEXES_NAME_FIELD != 2 + 2
391
 
#error "DICT_SYS_INDEXES_NAME_FIELD != 2 + 2"
392
 
#endif
393
 
 
394
 
        table->id = DICT_INDEXES_ID;
395
 
        dict_table_add_to_cache(table, heap);
396
 
        dict_sys->sys_indexes = table;
397
 
        mem_heap_empty(heap);
398
 
 
399
 
        index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
400
 
                                      DICT_HDR_SPACE,
401
 
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
402
 
 
403
 
        dict_mem_index_add_field(index, "TABLE_ID", 0);
404
 
        dict_mem_index_add_field(index, "ID", 0);
405
 
 
406
 
        index->id = DICT_INDEXES_ID;
407
 
        error = dict_index_add_to_cache(table, index,
408
 
                                        mtr_read_ulint(dict_hdr
409
 
                                                       + DICT_HDR_INDEXES,
410
 
                                                       MLOG_4BYTES, &mtr),
411
 
                                        FALSE);
412
 
        ut_a(error == DB_SUCCESS);
413
 
 
414
 
        /*-------------------------*/
415
 
        table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
416
 
 
417
 
        dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
418
 
        dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
419
 
        dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
420
 
 
421
 
        table->id = DICT_FIELDS_ID;
422
 
        dict_table_add_to_cache(table, heap);
423
 
        dict_sys->sys_fields = table;
424
 
        mem_heap_free(heap);
425
 
 
426
 
        index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
427
 
                                      DICT_HDR_SPACE,
428
 
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
429
 
 
430
 
        dict_mem_index_add_field(index, "INDEX_ID", 0);
431
 
        dict_mem_index_add_field(index, "POS", 0);
432
 
 
433
 
        index->id = DICT_FIELDS_ID;
434
 
        error = dict_index_add_to_cache(table, index,
435
 
                                        mtr_read_ulint(dict_hdr
436
 
                                                       + DICT_HDR_FIELDS,
437
 
                                                       MLOG_4BYTES, &mtr),
438
 
                                        FALSE);
439
 
        ut_a(error == DB_SUCCESS);
440
 
 
441
 
        mtr_commit(&mtr);
442
 
        /*-------------------------*/
443
 
 
444
 
        /* Initialize the insert buffer table and index for each tablespace */
445
 
 
446
 
        ibuf_init_at_db_start();
447
 
 
448
 
        /* Load definitions of other indexes on system tables */
449
 
 
450
 
        dict_load_sys_table(dict_sys->sys_tables);
451
 
        dict_load_sys_table(dict_sys->sys_columns);
452
 
        dict_load_sys_table(dict_sys->sys_indexes);
453
 
        dict_load_sys_table(dict_sys->sys_fields);
454
 
 
455
 
        mutex_exit(&(dict_sys->mutex));
456
 
}
457
 
 
458
 
/*****************************************************************//**
459
 
Inserts the basic system table data into themselves in the database
460
 
creation. */
461
 
static
462
 
void
463
 
dict_insert_initial_data(void)
464
 
/*==========================*/
465
 
{
466
 
        /* Does nothing yet */
467
 
}
468
 
 
469
 
/*****************************************************************//**
470
 
Creates and initializes the data dictionary at the database creation. */
471
 
UNIV_INTERN
472
 
void
473
 
dict_create(void)
474
 
/*=============*/
475
 
{
476
 
        mtr_t   mtr;
477
 
 
478
 
        mtr_start(&mtr);
479
 
 
480
 
        dict_hdr_create(&mtr);
481
 
 
482
 
        mtr_commit(&mtr);
483
 
 
484
 
        dict_boot();
485
 
 
486
 
        dict_insert_initial_data();
487
 
}