dict0boot.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:11k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Data dictionary creation and booting
  3. (c) 1996 Innobase Oy
  4. Created 4/18/1996 Heikki Tuuri
  5. *******************************************************/
  6. #include "dict0boot.h"
  7. #ifdef UNIV_NONINL
  8. #include "dict0boot.ic"
  9. #endif
  10. #include "dict0crea.h"
  11. #include "btr0btr.h"
  12. #include "dict0load.h"
  13. #include "dict0load.h"
  14. #include "trx0trx.h"
  15. #include "srv0srv.h"
  16. #include "ibuf0ibuf.h"
  17. #include "buf0flu.h"
  18. #include "log0recv.h"
  19. #include "os0file.h"
  20. /**************************************************************************
  21. Gets a pointer to the dictionary header and x-latches its page. */
  22. dict_hdr_t*
  23. dict_hdr_get(
  24. /*=========*/
  25. /* out: pointer to the dictionary header, 
  26. page x-latched */
  27. mtr_t* mtr) /* in: mtr */
  28. {
  29. dict_hdr_t* header;
  30. ut_ad(mtr);
  31. header = DICT_HDR + buf_page_get(DICT_HDR_SPACE, DICT_HDR_PAGE_NO,
  32. RW_X_LATCH, mtr);
  33. #ifdef UNIV_SYNC_DEBUG
  34. buf_page_dbg_add_level(header, SYNC_DICT_HEADER);
  35. #endif /* UNIV_SYNC_DEBUG */
  36. return(header);
  37. }
  38. /**************************************************************************
  39. Returns a new table, index, or tree id. */
  40. dulint
  41. dict_hdr_get_new_id(
  42. /*================*/
  43. /* out: the new id */
  44. ulint type) /* in: DICT_HDR_ROW_ID, ... */
  45. {
  46. dict_hdr_t* dict_hdr;
  47. dulint id;
  48. mtr_t mtr;
  49. ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID)
  50.       || (type == DICT_HDR_MIX_ID));
  51. mtr_start(&mtr);
  52. dict_hdr = dict_hdr_get(&mtr);
  53. id = mtr_read_dulint(dict_hdr + type, &mtr); 
  54. /* Add some dummy code here because otherwise pgcc seems to
  55. compile wrong */
  56. if (0 == ut_dulint_cmp(id, ut_dulint_max)) {
  57. /* TO DO: remove this code, or make it conditional */
  58. ut_dbg_null_ptr = 0;
  59. }
  60. id = ut_dulint_add(id, 1);
  61. mlog_write_dulint(dict_hdr + type, id, &mtr); 
  62. mtr_commit(&mtr);
  63. return(id);
  64. }
  65. /**************************************************************************
  66. Writes the current value of the row id counter to the dictionary header file
  67. page. */
  68. void
  69. dict_hdr_flush_row_id(void)
  70. /*=======================*/
  71. {
  72. dict_hdr_t* dict_hdr;
  73. dulint id;
  74. mtr_t mtr;
  75. #ifdef UNIV_SYNC_DEBUG
  76. ut_ad(mutex_own(&(dict_sys->mutex)));
  77. #endif /* UNIV_SYNC_DEBUG */
  78. id = dict_sys->row_id;
  79. mtr_start(&mtr);
  80. dict_hdr = dict_hdr_get(&mtr);
  81. mlog_write_dulint(dict_hdr + DICT_HDR_ROW_ID, id, &mtr); 
  82. mtr_commit(&mtr);
  83. }
  84. /*********************************************************************
  85. Creates the file page for the dictionary header. This function is
  86. called only at the database creation. */
  87. static
  88. ibool
  89. dict_hdr_create(
  90. /*============*/
  91. /* out: TRUE if succeed */
  92. mtr_t* mtr) /* in: mtr */
  93. {
  94. dict_hdr_t* dict_header;
  95. ulint hdr_page_no;
  96. ulint root_page_no;
  97. page_t* page;
  98. ut_ad(mtr);
  99. /* Create the dictionary header file block in a new, allocated file
  100. segment in the system tablespace */
  101. page = fseg_create(DICT_HDR_SPACE, 0,
  102.   DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
  103. hdr_page_no = buf_frame_get_page_no(page);
  104. ut_a(DICT_HDR_PAGE_NO == hdr_page_no);
  105. dict_header = dict_hdr_get(mtr);
  106. /* Start counting row, table, index, and tree ids from
  107. DICT_HDR_FIRST_ID */
  108. mlog_write_dulint(dict_header + DICT_HDR_ROW_ID,
  109. ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
  110. mlog_write_dulint(dict_header + DICT_HDR_TABLE_ID,
  111. ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
  112. mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
  113. ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
  114. mlog_write_dulint(dict_header + DICT_HDR_MIX_ID,
  115. ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
  116. /* Create the B-tree roots for the clustered indexes of the basic
  117. system tables */
  118. /*--------------------------*/
  119. root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
  120. DICT_HDR_SPACE, DICT_TABLES_ID, mtr);
  121. if (root_page_no == FIL_NULL) {
  122. return(FALSE);
  123. }
  124. mlog_write_ulint(dict_header + DICT_HDR_TABLES, root_page_no,
  125. MLOG_4BYTES, mtr);
  126. /*--------------------------*/
  127. root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE,
  128. DICT_TABLE_IDS_ID, mtr);
  129. if (root_page_no == FIL_NULL) {
  130. return(FALSE);
  131. }
  132. mlog_write_ulint(dict_header + DICT_HDR_TABLE_IDS, root_page_no,
  133. MLOG_4BYTES, mtr);
  134. /*--------------------------*/
  135. root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
  136. DICT_HDR_SPACE, DICT_COLUMNS_ID, mtr);
  137. if (root_page_no == FIL_NULL) {
  138. return(FALSE);
  139. }
  140. mlog_write_ulint(dict_header + DICT_HDR_COLUMNS, root_page_no,
  141. MLOG_4BYTES, mtr);
  142. /*--------------------------*/
  143. root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
  144. DICT_HDR_SPACE, DICT_INDEXES_ID, mtr);
  145. if (root_page_no == FIL_NULL) {
  146. return(FALSE);
  147. }
  148. mlog_write_ulint(dict_header + DICT_HDR_INDEXES, root_page_no,
  149. MLOG_4BYTES, mtr);
  150. /*--------------------------*/
  151. root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
  152. DICT_HDR_SPACE, DICT_FIELDS_ID, mtr);
  153. if (root_page_no == FIL_NULL) {
  154. return(FALSE);
  155. }
  156. mlog_write_ulint(dict_header + DICT_HDR_FIELDS, root_page_no,
  157. MLOG_4BYTES, mtr);
  158. /*--------------------------*/
  159. return(TRUE);
  160. }
  161. /*********************************************************************
  162. Initializes the data dictionary memory structures when the database is
  163. started. This function is also called when the data dictionary is created. */
  164. void
  165. dict_boot(void)
  166. /*===========*/
  167. {
  168. dict_table_t* table;
  169. dict_index_t* index;
  170. dict_hdr_t* dict_hdr;
  171. mtr_t mtr;
  172. mtr_start(&mtr);
  173. /* Create the hash tables etc. */
  174. dict_init();
  175. mutex_enter(&(dict_sys->mutex));
  176. /* Get the dictionary header */
  177. dict_hdr = dict_hdr_get(&mtr);
  178. /* Because we only write new row ids to disk-based data structure
  179. (dictionary header) when it is divisible by
  180. DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
  181. the latest value of the row id counter. Therefore we advance
  182. the counter at the database startup to avoid overlapping values.
  183. Note that when a user after database startup first time asks for
  184. a new row id, then because the counter is now divisible by
  185. ..._MARGIN, it will immediately be updated to the disk-based
  186. header. */
  187. dict_sys->row_id = ut_dulint_add(
  188.      ut_dulint_align_up(
  189. mtr_read_dulint(dict_hdr + DICT_HDR_ROW_ID,
  190. &mtr),
  191. DICT_HDR_ROW_ID_WRITE_MARGIN),
  192.      DICT_HDR_ROW_ID_WRITE_MARGIN);
  193. /* Insert into the dictionary cache the descriptions of the basic
  194. system tables */
  195. /*-------------------------*/
  196. table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE,8);
  197. dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
  198. dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
  199. dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4, 0);
  200. dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
  201. dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0, 0);
  202. dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4, 0);
  203. dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0, 0);
  204. dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
  205. table->id = DICT_TABLES_ID;
  206. dict_table_add_to_cache(table);
  207. dict_sys->sys_tables = table;
  208. index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
  209. DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1);
  210. dict_mem_index_add_field(index, "NAME", 0, 0);
  211. index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
  212. MLOG_4BYTES, &mtr);
  213. index->id = DICT_TABLES_ID;
  214. ut_a(dict_index_add_to_cache(table, index));
  215. /*-------------------------*/
  216. index = dict_mem_index_create("SYS_TABLES", "ID_IND",
  217. DICT_HDR_SPACE, DICT_UNIQUE, 1);
  218. dict_mem_index_add_field(index, "ID", 0, 0);
  219. index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
  220. MLOG_4BYTES, &mtr);
  221. index->id = DICT_TABLE_IDS_ID;
  222. ut_a(dict_index_add_to_cache(table, index));
  223. /*-------------------------*/
  224. table = dict_mem_table_create("SYS_COLUMNS",DICT_HDR_SPACE,7);
  225. dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
  226. dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
  227. dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
  228. dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4, 0);
  229. dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
  230. dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
  231. dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
  232. table->id = DICT_COLUMNS_ID;
  233. dict_table_add_to_cache(table);
  234. dict_sys->sys_columns = table;
  235. index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
  236. DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
  237. dict_mem_index_add_field(index, "TABLE_ID", 0, 0);
  238. dict_mem_index_add_field(index, "POS", 0, 0);
  239. index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
  240. MLOG_4BYTES, &mtr);
  241. index->id = DICT_COLUMNS_ID;
  242. ut_a(dict_index_add_to_cache(table, index));
  243. /*-------------------------*/
  244. table = dict_mem_table_create("SYS_INDEXES",DICT_HDR_SPACE,7);
  245. dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
  246. dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
  247. dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
  248. dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4, 0);
  249. dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
  250. dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
  251. dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4, 0);
  252. /* The '+ 2' below comes from the 2 system fields */
  253. #if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
  254. #error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
  255. #endif
  256. #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
  257. #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
  258. #endif
  259. table->id = DICT_INDEXES_ID;
  260. dict_table_add_to_cache(table);
  261. dict_sys->sys_indexes = table;
  262. index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
  263. DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
  264. dict_mem_index_add_field(index, "TABLE_ID", 0, 0);
  265. dict_mem_index_add_field(index, "ID", 0, 0);
  266. index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
  267. MLOG_4BYTES, &mtr);
  268. index->id = DICT_INDEXES_ID;
  269. ut_a(dict_index_add_to_cache(table, index));
  270. /*-------------------------*/
  271. table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE,3);
  272. dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
  273. dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
  274. dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0,0,0);
  275. table->id = DICT_FIELDS_ID;
  276. dict_table_add_to_cache(table);
  277. dict_sys->sys_fields = table;
  278. index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
  279. DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
  280. dict_mem_index_add_field(index, "INDEX_ID", 0, 0);
  281. dict_mem_index_add_field(index, "POS", 0, 0);
  282. index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
  283. MLOG_4BYTES, &mtr);
  284. index->id = DICT_FIELDS_ID;
  285. ut_a(dict_index_add_to_cache(table, index));
  286. mtr_commit(&mtr);
  287. /*-------------------------*/
  288. /* Initialize the insert buffer table and index for each tablespace */
  289. ibuf_init_at_db_start();
  290. /* Load definitions of other indexes on system tables */
  291. dict_load_sys_table(dict_sys->sys_tables);
  292. dict_load_sys_table(dict_sys->sys_columns);
  293. dict_load_sys_table(dict_sys->sys_indexes);
  294. dict_load_sys_table(dict_sys->sys_fields);
  295. mutex_exit(&(dict_sys->mutex));
  296. }
  297. /*********************************************************************
  298. Inserts the basic system table data into themselves in the database
  299. creation. */
  300. static
  301. void
  302. dict_insert_initial_data(void)
  303. /*==========================*/
  304. {
  305. /* Does nothing yet */
  306. }
  307. /*********************************************************************
  308. Creates and initializes the data dictionary at the database creation. */
  309. void
  310. dict_create(void)
  311. /*=============*/
  312. {
  313. mtr_t mtr;
  314. mtr_start(&mtr);
  315. dict_hdr_create(&mtr);
  316. mtr_commit(&mtr);
  317. dict_boot();
  318. dict_insert_initial_data();
  319. }