~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innobase/dict/dict0boot.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
Data dictionary creation and booting
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 4/18/1996 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#include "dict0boot.h"
 
10
 
 
11
#ifdef UNIV_NONINL
 
12
#include "dict0boot.ic"
 
13
#endif
 
14
 
 
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"
 
25
 
 
26
/**************************************************************************
 
27
Gets a pointer to the dictionary header and x-latches its page. */
 
28
 
 
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 */
 
35
{
 
36
        dict_hdr_t*     header;
 
37
 
 
38
        ut_ad(mtr);
 
39
 
 
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);
 
46
}
 
47
 
 
48
/**************************************************************************
 
49
Returns a new table, index, or tree id. */
 
50
 
 
51
dulint
 
52
dict_hdr_get_new_id(
 
53
/*================*/
 
54
                        /* out: the new id */
 
55
        ulint   type)   /* in: DICT_HDR_ROW_ID, ... */
 
56
{
 
57
        dict_hdr_t*     dict_hdr;
 
58
        dulint          id;
 
59
        mtr_t           mtr;
 
60
 
 
61
        ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID));
 
62
 
 
63
        mtr_start(&mtr);
 
64
 
 
65
        dict_hdr = dict_hdr_get(&mtr);
 
66
 
 
67
        id = mtr_read_dulint(dict_hdr + type, &mtr);
 
68
        id = ut_dulint_add(id, 1);
 
69
 
 
70
        mlog_write_dulint(dict_hdr + type, id, &mtr);
 
71
 
 
72
        mtr_commit(&mtr);
 
73
 
 
74
        return(id);
 
75
}
 
76
 
 
77
/**************************************************************************
 
78
Writes the current value of the row id counter to the dictionary header file
 
79
page. */
 
80
 
 
81
void
 
82
dict_hdr_flush_row_id(void)
 
83
/*=======================*/
 
84
{
 
85
        dict_hdr_t*     dict_hdr;
 
86
        dulint          id;
 
87
        mtr_t           mtr;
 
88
 
 
89
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
90
 
 
91
        id = dict_sys->row_id;
 
92
 
 
93
        mtr_start(&mtr);
 
94
 
 
95
        dict_hdr = dict_hdr_get(&mtr);
 
96
 
 
97
        mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr);
 
98
 
 
99
        mtr_commit(&mtr);
 
100
}
 
101
 
 
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 */
 
111
{
 
112
        dict_hdr_t*     dict_header;
 
113
        ulint           hdr_page_no;
 
114
        ulint           root_page_no;
 
115
        page_t*         page;
 
116
 
 
117
        ut_ad(mtr);
 
118
 
 
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);
 
123
 
 
124
        hdr_page_no = buf_frame_get_page_no(page);
 
125
 
 
126
        ut_a(DICT_HDR_PAGE_NO == hdr_page_no);
 
127
 
 
128
        dict_header = dict_hdr_get(mtr);
 
129
 
 
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);
 
134
 
 
135
        mlog_write_dulint(dict_header + DICT_HDR_TABLE_ID,
 
136
                          ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
 
137
 
 
138
        mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
 
139
                          ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
 
140
 
 
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);
 
144
 
 
145
        /* Create the B-tree roots for the clustered indexes of the basic
 
146
        system tables */
 
147
 
 
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) {
 
152
 
 
153
                return(FALSE);
 
154
        }
 
155
 
 
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) {
 
162
 
 
163
                return(FALSE);
 
164
        }
 
165
 
 
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) {
 
172
 
 
173
                return(FALSE);
 
174
        }
 
175
 
 
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) {
 
182
 
 
183
                return(FALSE);
 
184
        }
 
185
 
 
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) {
 
192
 
 
193
                return(FALSE);
 
194
        }
 
195
 
 
196
        mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
 
197
                         MLOG_4BYTES, mtr);
 
198
        /*--------------------------*/
 
199
 
 
200
        return(TRUE);
 
201
}
 
202
 
 
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. */
 
206
 
 
207
void
 
208
dict_boot(void)
 
209
/*===========*/
 
210
{
 
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;
 
216
 
 
217
        mtr_start(&mtr);
 
218
 
 
219
        /* Create the hash tables etc. */
 
220
        dict_init();
 
221
 
 
222
        heap = mem_heap_create(450);
 
223
 
 
224
        mutex_enter(&(dict_sys->mutex));
 
225
 
 
226
        /* Get the dictionary header */
 
227
        dict_hdr = dict_hdr_get(&mtr);
 
228
 
 
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. */
 
238
 
 
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);
 
244
 
 
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);
 
249
 
 
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);
 
258
 
 
259
        table->id = DICT_TABLES_ID;
 
260
 
 
261
        dict_table_add_to_cache(table, heap);
 
262
        dict_sys->sys_tables = table;
 
263
        mem_heap_empty(heap);
 
264
 
 
265
        index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
 
266
                                      DICT_HDR_SPACE,
 
267
                                      DICT_UNIQUE | DICT_CLUSTERED, 1);
 
268
 
 
269
        dict_mem_index_add_field(index, "NAME", 0);
 
270
 
 
271
        index->id = DICT_TABLES_ID;
 
272
 
 
273
        dict_index_add_to_cache(table, index,
 
274
                                mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
 
275
                                               MLOG_4BYTES, &mtr));
 
276
 
 
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);
 
281
 
 
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));
 
286
 
 
287
        /*-------------------------*/
 
288
        table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
 
289
 
 
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);
 
297
 
 
298
        table->id = DICT_COLUMNS_ID;
 
299
 
 
300
        dict_table_add_to_cache(table, heap);
 
301
        dict_sys->sys_columns = table;
 
302
        mem_heap_empty(heap);
 
303
 
 
304
        index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
 
305
                                      DICT_HDR_SPACE,
 
306
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
307
 
 
308
        dict_mem_index_add_field(index, "TABLE_ID", 0);
 
309
        dict_mem_index_add_field(index, "POS", 0);
 
310
 
 
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));
 
315
 
 
316
        /*-------------------------*/
 
317
        table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
 
318
 
 
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);
 
326
 
 
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
 
337
 
 
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);
 
342
 
 
343
        index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
 
344
                                      DICT_HDR_SPACE,
 
345
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
346
 
 
347
        dict_mem_index_add_field(index, "TABLE_ID", 0);
 
348
        dict_mem_index_add_field(index, "ID", 0);
 
349
 
 
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));
 
354
 
 
355
        /*-------------------------*/
 
356
        table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
 
357
 
 
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);
 
361
 
 
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);
 
366
 
 
367
        index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
 
368
                                      DICT_HDR_SPACE,
 
369
                                      DICT_UNIQUE | DICT_CLUSTERED, 2);
 
370
 
 
371
        dict_mem_index_add_field(index, "INDEX_ID", 0);
 
372
        dict_mem_index_add_field(index, "POS", 0);
 
373
 
 
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));
 
378
 
 
379
        mtr_commit(&mtr);
 
380
        /*-------------------------*/
 
381
 
 
382
        /* Initialize the insert buffer table and index for each tablespace */
 
383
 
 
384
        ibuf_init_at_db_start();
 
385
 
 
386
        /* Load definitions of other indexes on system tables */
 
387
 
 
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);
 
392
 
 
393
        mutex_exit(&(dict_sys->mutex));
 
394
}
 
395
 
 
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
/*==========================*/
 
403
{
 
404
        /* Does nothing yet */
 
405
}
 
406
 
 
407
/*********************************************************************
 
408
Creates and initializes the data dictionary at the database creation. */
 
409
 
 
410
void
 
411
dict_create(void)
 
412
/*=============*/
 
413
{
 
414
        mtr_t   mtr;
 
415
 
 
416
        mtr_start(&mtr);
 
417
 
 
418
        dict_hdr_create(&mtr);
 
419
 
 
420
        mtr_commit(&mtr);
 
421
 
 
422
        dict_boot();
 
423
 
 
424
        dict_insert_initial_data();
 
425
}