<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
MySQL的dd表是用來存放表結構和各種建表資訊的,使用者端建的表都存在mysql.table和mysql.columns表裡,還有一個表mysql.column_type_elements比較特殊,用來存放SET和ENUM型別的欄位集合值資訊。看一下下面這張表的mysql.columns表和mysql.column_type_elements資訊。為了縮短顯示長度,這裡只展示幾個重要的值。
#建表: CREATE TABLE t1(id int not null auto_increment primary key,col1 number,col2 VARCHAR(100),col3 pls_integer, col4 enum('x','y') default 'x',col5 set('x1','y1')) partition by hash(id) partitions 3; SET SESSION debug='+d,skip_dd_table_access_check'; mysql> select name,ordinal_position,type,default_value_utf8,options,column_type_utf8 from mysql.columns where table_id=383; +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ | name | ordinal_position | type | default_value_utf8 | options | column_type_utf8 | +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ | col1 | 2 | MYSQL_TYPE_NEWDECIMAL | NULL | interval_count=0; | decimal(65,0) | | col2 | 3 | MYSQL_TYPE_VARCHAR | NULL | interval_count=0; | varchar(100) | | col3 | 4 | MYSQL_TYPE_LONG | NULL | interval_count=0; | int | | col4 | 5 | MYSQL_TYPE_ENUM | x | interval_count=2; | enum('x','y') | | col5 | 6 | MYSQL_TYPE_SET | NULL | interval_count=2; | set('x1','y1') | | DB_ROLL_PTR | 8 | MYSQL_TYPE_LONGLONG | NULL | NULL | | | DB_TRX_ID | 7 | MYSQL_TYPE_INT24 | NULL | NULL | | | id | 1 | MYSQL_TYPE_LONG | NULL | interval_count=0; | int | +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ 8 rows in set (0.00 sec)
mysql.columns表說明如下:
ordinal_position
是該欄位在表裡的偏移量,這裡多了3個欄位,DB_ROLL_PTR
、DB_TRX_ID
、id
是用來執行undo的,記錄了欄位的版本資訊。
default_value_utf8
是用來儲存預設值的。options裡面有interval_count用來儲存集合型別的數值數的。columns表的options的key一共有如下幾種:
static const std::set<String_type> default_valid_option_keys = { "column_format", "geom_type", "interval_count", "not_secondary", "storage", "treat_bit_as_char", "zip_dict_id", "is_array"};
mysql> select * from mysql.column_type_elements where column_id=4286; +-----------+---------------+------+ | column_id | element_index | name | +-----------+---------------+------+ | 4286 | 1 | x | | 4286 | 2 | y | +-----------+---------------+------+ 2 rows in set (0.01 sec) <strong>#這裡的column_id=4286是col4的id值,x和y分別對應了set定義時候的2個集合值。</strong>
現在重新啟動資料庫,跟蹤一下這個columns表怎麼轉為程式碼裡面的TABLE的field物件。首先找到表的dd資訊然後開啟表獲取field資訊。
mysql> select * from t1;
輸入該命令後找到columns錶轉為field的程式碼:
#0 fill_column_from_dd ( thd=0x555558b35a06 <std::char_traits<char>::compare(char const*, char const*, unsigned long)+61>, share=0x7fffe83f1b60, col_obj=0x555558bb0a5e <std::__cxx11::basic_string<char, std::char_traits<char>, Stateless_allocator<char, dd::String_type_alloc, My_free_functor> >::compare(std::__cxx11::basic_string<char, std::char_traits<char>, Stateless_allocator<char, dd::String_type_alloc, My_free_functor> > const&) const+142>, null_pos=0x7fffe83f1880 " 05", null_bit_pos=32767, rec_pos=0x7fff2c05ac10 "explicit_encryption", field_nr=0) at /mysql/sql/dd_table_share.cc:955 #1 0x00005555593c4c17 in fill_columns_from_dd (thd=0x7fff2c006890, share=0x7fff2cbf19e8, tab_obj=0x7fff2cbb9b38) at /mysql/sql/dd_table_share.cc:1235 #2 0x00005555593c9e54 in open_table_def (thd=0x7fff2c006890, share=0x7fff2cbf19e8, table_def=...) at /mysql/sql/dd_table_share.cc:2408 #3 0x0000555558e76a13 in get_table_share (thd=0x7fff2c006890, db=0x7fff2cbeeff0 "db1", table_name=0x7fff2cc03210 "t1", key=0x7fff2cbeed87 "db1", key_length=7, open_view=true, open_secondary=false) at /mysql/sql/sql_base.cc:801 #4 0x0000555558e76f08 in get_table_share_with_discover (thd=0x7fff2c006890, table_list=0x7fff2cbee9b8, key=0x7fff2cbeed87 "db1", key_length=7, open_secondary=false, error=0x7fffe83f1ea4) at /mysql/sql/sql_base.cc:889 #5 0x0000555558e7cd34 in open_table (thd=0x7fff2c006890, table_list=0x7fff2cbee9b8, ot_ctx=0x7fffe83f2380) at /mysql/sql/sql_base.cc:3230 #6 0x0000555558e81769 in open_and_process_table (thd=0x7fff2c006890, lex=0x7fff2c01bdf0, tables=0x7fff2cbee9b8, counter=0x7fff2c01be48, prelocking_strategy=0x7fffe83f2408, has_prelocking_list=false, ot_ctx=0x7fffe83f2380) at /mysql/sql/sql_base.cc:5118 #7 0x0000555558e833bd in open_tables (thd=0x7fff2c006890, start=0x7fffe83f23f0, counter=0x7fff2c01be48, flags=0, prelocking_strategy=0x7fffe83f2408) at /mysql/sql/sql_base.cc:5928 #8 0x0000555558e85626 in open_tables_for_query (thd=0x7fff2c006890, tables=0x7fff2cbee9b8, flags=0) at /mysql/sql/sql_base.cc:6904 #9 0x0000555559075720 in Sql_cmd_dml::prepare (this=0x7fff2cbef400, thd=0x7fff2c006890) at /mysql/sql/sql_select.cc:372 #10 0x00005555590760bf in Sql_cmd_dml::execute (this=0x7fff2cbef400, thd=0x7fff2c006890) at /mysql/sql/sql_select.cc:527 #11 0x0000555558fedc8e in mysql_execute_command (thd=0x7fff2c006890, first_level=true) at /mysql/sql/sql_parse.cc:4794 #12 0x0000555558fefe25 in dispatch_sql_command (thd=0x7fff2c006890, parser_state=0x7fffe83f3990, update_userstat=false) at /mysql/sql/sql_parse.cc:5399 #13 0x0000555558fe52d3 in dispatch_command (thd=0x7fff2c006890, com_data=0x7fffe83f4b70, command=COM_QUERY) at /mysql/sql/sql_parse.cc:2000 #14 0x0000555558fe3643 in do_command (thd=0x7fff2c006890) at /mysql/sql/sql_parse.cc:1448 #15 0x000055555920e200 in handle_connection (arg=0x555560a65790) at /mysql/sql/conn_handler/connection_handler_per_thread.cc:307 #16 0x000055555ae36375 in pfs_spawn_thread (arg=0x5555608a2e20) at /mysql/storage/perfschema/pfs.cc:2899 #17 0x00007ffff77a6609 in start_thread (arg=<optimized out>) at pthread_create.c:477 #18 0x00007ffff76cb163 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
<strong>#fill_column_from_dd函數裡面最重要的是make_field函數,把欄位從dd::Column轉為table的field然後賦值給TABLE_SHARE。 reg_field = make_field(*col_obj, charset, share, rec_pos, null_pos, null_bit_pos);</strong>
session每次獲取表的資訊都是在第一次開啟表的時候就做好了,下次如果表沒有變化就從Table_cache直接獲取表資訊。現在假設我們要改col4欄位的集合值又不想通過alter語句來執行,那就可以直接對dd表進行操作。注意,該操作對生產環境有很大風險,這裡只用來進行知識實踐,不能用來在生產環境實際操作。
把col4的x,y值改為a,b:首先試著插入col4=x的記錄,現在還沒更改dd表所以插入成功。
mysql> insert into t1 values(1,1,'aa',1,'x','x1'); Query OK, 1 row affected (0.03 sec)
接著開始改col4的集合值:
mysql> SET SESSION debug='+d,skip_dd_table_access_check'; Query OK, 0 rows affected (0.02 sec) mysql> update mysql.columns set default_value_utf8='a' ,column_type_utf8='enum('a','b'))' where table_id=383 and name='col4'; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select name,ordinal_position,type,default_value_utf8,options,column_type_utf8 from mysql.columns where table_id=383; +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ | name | ordinal_position | type | default_value_utf8 | options | column_type_utf8 | +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ | col1 | 2 | MYSQL_TYPE_NEWDECIMAL | NULL | interval_count=0; | decimal(65,0) | | col2 | 3 | MYSQL_TYPE_VARCHAR | NULL | interval_count=0; | varchar(100) | | col3 | 4 | MYSQL_TYPE_LONG | NULL | interval_count=0; | int | | col4 | 5 | MYSQL_TYPE_ENUM | a | interval_count=2; | enum('a','b')) |集合值已改 | col5 | 6 | MYSQL_TYPE_SET | NULL | interval_count=2; | set('x1','y1') | | DB_ROLL_PTR | 8 | MYSQL_TYPE_LONGLONG | NULL | NULL | | | DB_TRX_ID | 7 | MYSQL_TYPE_INT24 | NULL | NULL | | | id | 1 | MYSQL_TYPE_LONG | NULL | interval_count=0; | int | +-------------+------------------+-----------------------+--------------------+-------------------+------------------+ 8 rows in set (0.00 sec) mysql> update mysql.column_type_elements set name='a' where column_id=4286 and element_index=1; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update mysql.column_type_elements set name='b' where column_id=4286 and element_index=2; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from mysql.column_type_elements where column_id=4286; +-----------+---------------+------+ | column_id | element_index | name | +-----------+---------------+------+ | 4286 | 1 | a |<strong>集合值已改</strong> | 4286 | 2 | b |<strong>集合值已改</strong> +-----------+---------------+------+ 2 rows in set (0.00 sec)
現在再插入一條col4=x的記錄發現還是成功的,這是因為t1沒有重新從dd錶轉為TABLE資訊,需要重啟後再試。
mysql> insert into t1 values(2,1,'aa',1,'x','x1'); Query OK, 1 row affected (0.02 sec)
重啟資料庫,然後登入。再次插入col4=x發現報錯了,因為這時候的TABLE資訊是重新從dd錶轉化的。
mysql> insert into t1 values(2,1,'aa',1,'x','x1'); ERROR 1265 (01000): Data truncated for column 'col4' at row 1
插入col4=a的記錄成功,說明更改成功。
mysql> insert into t1 values(3,1,'aa',1,'a','x1'); Query OK, 1 row affected (0.02 sec)
檢視建表資訊,發現已經成功更改。
mysql> show create table t1; +-------+-------------------------+ | Table | Create Table | +-------+-------------------------+ | t1 | CREATE TABLE `t1` ( `id` int NOT NULL AUTO_INCREMENT, `col1` decimal(65,0) DEFAULT NULL, `col2` varchar(100) DEFAULT NULL, `col3` int DEFAULT NULL, `col4` enum('a','b') DEFAULT 'a',更改成功 `col5` set('x1','y1') DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!50100 PARTITION BY HASH (`id`) PARTITIONS 3 */ +-------+-------------------------+
實際上更改表結構如果通過alter命令來改流程跟上面也是一樣的,也是通過更新dd表來實現表結構的變更,這裡只是從更底層來介紹。以上的操作在實際生產中不能直接操作,風險很大,會影響現有的記錄和相關的功能。這裡只是作為一個案例來更好的說明dd的工作流程,幫助大家遇到問題知道怎麼從底層排查。
到此這篇關於MySQL中dd::columns表結構轉table過程及應用詳解的文章就介紹到這了,更多相關mysql dd::columns表結構內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45