1. 程式人生 > >mysql小白系列_04 datablock

mysql小白系列_04 datablock

clas 部分 div text字段 b- 都是 intern -- .html

1.為什麽創建一個InnoDB表只分配了96K而不是1M?

2.解析第2行記錄格式?(用下面的表定義和數據做測試)

技術分享圖片
mysql> create table gyj_t3 (id int,name1 varchar(10),name2 varchar(10),name3 varchar(10),name4 varchar(10),name5 varchar(10));
Query OK, 0 rows affected (0.11 sec)

mysql> insert into gyj_t3 (id,name1,name2,name3,name4) values(1,A,BB,CCC
,DDDD); Query OK, 1 row affected (0.03 sec) mysql> insert into gyj_t3 values(3,aaaaaaaaaa,bbbbbbbbbb,ccccc,dddddd,e); Query OK, 1 row affected (0.06 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> insert into gyj_t3 values(4,aaaaaaaaaa,bbbbbbbbbb,null,dddddd,e
); Query OK, 1 row affected (0.05 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM gyj_t3; +------+------------+------------+-------+--------+-------+ | id | name1 | name2 | name3 | name4 | name5 | +------+------------+------------+-------+--------+-------+ | 1
| A | BB | CCC | DDDD | NULL | | 1 | aaaaaaaaaa | bbbbbbbbbb | ccccc | | NULL | | 3 | aaaaaaaaaa | bbbbbbbbbb | ccccc | dddddd | e | | 4 | aaaaaaaaaa | bbbbbbbbbb | NULL | dddddd | e | +------+------------+------------+-------+--------+-------+
數據

3.詳細描述commit命令發出後,binlog日誌從內存寫到磁盤的過程序?


1.為什麽創建一個InnoDB表只分配了96K而不是1M?

  • innodb在給數據分配存儲空間時,首先給32個的不連續的page

一個extent區是1M

  • 如果32個page不夠用,再分配一段連續的64個page,也就是16384*64=1M,此後每次分配空間都是1M的整數倍
  • 目的:
    • 節省空間
    • 小的undo 32個 page就夠了

問題:linux下查看一個ibd文件,大小是96K,也就是6個頁,那麽32個頁不是一次性給完而是用多少給多少?

-rw-rw----. 1 mysql mysql 8.6K Feb 12 08:38 t3.frm
-rw-rw----. 1 mysql mysql  96K Feb 12 08:38 t3.ibd

32個page是524288字節,差不多是512KB,插入數據使文件達到500多kb時,下一次增長為1M的整數倍


2.解析第2行記錄格式?(用下面的表定義和數據做測試)

+------+------------+------------+-------+--------+-------+
| id   | name1      | name2      | name3 | name4  | name5 |
+------+------------+------------+-------+--------+-------+
|    1 | A          | BB         | CCC   | DDDD   | NULL  |
|    1 | aaaaaaaaaa | bbbbbbbbbb | ccccc |        | NULL  |
|    4 | aaaaaaaaaa | bbbbbbbbbb | ccccc | dddddd | e     |
|    4 | aaaaaaaaaa | bbbbbbbbbb | NULL  | dddddd | e     |
+------+------------+------------+-------+--------+-------+

create table t3 (id int,name1 varchar(10),name2 varchar(10),name3 varchar(10),name4 varchar(10),name5 varchar(10));
insert into t3 (id,name1,name2,name3,name4) values(1,A,BB,CCC,DDDD);
insert into t3 (id,name1,name2,name3,name4) values(1,aaaaaaaaaa,bbbbbbbbbb,ccccc,‘‘);
insert into t3 (id,name1,name2,name3,name4,name5) values(4,aaaaaaaaaa,bbbbbbbbbb,ccccc,dddddd,e);
insert into t3 (id,name1,name2,name4,name5) values(4,aaaaaaaaaa,bbbbbbbbbb,dddddd,e);


技術分享圖片
  • NULL不占空間
  • ‘‘也不占空間

問題:NULL如何標誌哪些列是NULL的?

《MySQL技術內幕InnoDB存儲引擎》106頁及網上大部分都是提了一下,參考http://blog.csdn.net/linux_ever/article/details/64124868

第三行有NULL值,因為NULL標誌位不再是00而是06,轉換成二進制00000110,為1的值表示第2列和第3列的數據為NULL。其後存儲列數據的部分,沒有存儲NULL列,而只存儲了第1列和第4列的非NULL的值

*************************** 3. row ***************************
t1: d
t2: NULL
t3: NULL
t4: fff
3 rows in set (0.00 sec)

這裏的第2和第3列為NULL,NULL標誌位為06,二進制是00000110,是怎麽算出來2、3列的?

本次作業的第1、2行數據第5列為NULL,標誌位是20,二進制是00100000
第4行數據第4列為NULL,標誌位是08,二進制是00001000

技術分享圖片

int長度是4字節,其他可變長name長度是10字節,用多少長多少
https://www.cnblogs.com/wade-luffy/p/6289183.html
http://blog.csdn.net/beiigang/article/details/42175995

ibd文件格式如下
內容16進制地址
File Space Header 0x0008
Insert Buffer Bitmap 0x0005
File Segment Inode 0x0003
Used Page 0x45BF
…… 第N-4個塊
Used Page 第N-3個塊
Free Page 第N-2個塊
…… 第N-2個塊
Free Page 第N-2個塊

https://dev.mysql.com/doc/internals/en/innodb-page-overview.html
https://www.cnblogs.com/crossapply/p/5455620.html

行記錄格式
  • compressed 壓縮頁,默認16K,可以壓縮成8K、4: alter table tabname row_format=compressed,key_block_size=8;
  • Dynamic 存儲LOB/TEXT字段,由20字節+偏移量組成,本身不存儲數據,偏移量指向數據
  • Compact 默認行記錄格式,超出行記錄長度時,由前綴768字節+偏移量組成,本身存儲部分數據,偏移量指向數據
  • Redundant 廢棄
獲取ibd十六進制文本
技術分享圖片
hexdump -C -v t3.ibd > /tmp/t3.ibd.txt

[root@docker01 tmp]# cat t3.ibd.txt |head -n 2
00000000  24 0a 12 cf 00 00 00 00  00 00 00 00 00 00 00 00  |$...............|
00000010  00 00 00 00 00 1a 25 e3  00 08 00 00 00 00 00 00  |......%.........|
[root@docker01 tmp]# cat t3.ibd.txt |head -n 2048| tail -n 1024 |head -n 2
00004000  99 5f 47 61 00 00 00 01  00 00 00 00 00 00 00 00  |._Ga............|
00004010  00 00 00 00 00 1a 16 27  00 05 00 00 00 00 00 00  |...............|
[root@docker01 tmp]# cat t3.ibd.txt |head -n 3072| tail -n 1024 |head -n 2     
00008000  c2 25 6e 67 00 00 00 02  00 00 00 00 00 00 00 00  |.%ng............|
00008010  00 00 00 00 00 1a 25 e3  00 03 00 00 00 00 00 00  |......%.........|
[root@docker01 tmp]# cat t3.ibd.txt |head -n 4096| tail -n 1024 |head -n 2    
0000c000  48 81 1b 2c 00 00 00 03  ff ff ff ff ff ff ff ff  |H..,............|
0000c010  00 00 00 00 00 1a 3e 2e  45 bf 00 00 00 00 00 00  |......>.E.......|
截取第4頁

0000c000  48 81 1b 2c 00 00 00 03  ff ff ff ff ff ff ff ff  |H..,............|
0000c010  00 00 00 00 00 1a 3e 2e  45 bf 00 00 00 00 00 00  |......>.E.......|
0000c020  00 00 00 00 00 0d 00 02  01 5b 80 06 00 00 00 00  |.........[......|
0000c030  01 29 00 02 00 03 00 04  00 00 00 00 00 00 00 00  |.)..............|
0000c040  00 00 00 00 00 00 00 00  00 1b 00 00 00 0d 00 00  |................|
0000c050  00 02 00 f2 00 00 00 0d  00 00 00 02 00 32 01 00  |.............2..|
0000c060  02 00 1f 69 6e 66 69 6d  75 6d 00 05 00 0b 00 00  |...infimum......|
0000c070  73 75 70 72 65 6d 75 6d  04 03 02 01 20 00 00 10  |supremum.... ...|
0000c080  00 2b 00 00 00 00 03 10  00 00 00 00 0b 52 b7 00  |.+...........R..|
0000c090  00 01 6b 01 10 80 00 00  01 41 42 42 43 43 43 44  |..k......ABBCCCD|
0000c0a0  44 44 44 00 05 0a 0a 20  00 00 18 00 3b 00 00 00  |DDD.... ....;...|
0000c0b0  00 03 11 00 00 00 00 0b  52 b7 00 00 01 6b 01 1e  |........R....k..|
0000c0c0  80 00 00 01 61 61 61 61  61 61 61 61 61 61 62 62  |....aaaaaaaaaabb|
0000c0d0  62 62 62 62 62 62 62 62  63 63 63 63 63 01 06 05  |bbbbbbbbccccc...|
0000c0e0  0a 0a 00 00 00 20 00 41  00 00 00 00 03 12 00 00  |..... .A........|
0000c0f0  00 00 0b 52 b7 00 00 01  6b 01 2c 80 00 00 04 61  |...R....k.,....a|
0000c100  61 61 61 61 61 61 61 61  61 62 62 62 62 62 62 62  |aaaaaaaaabbbbbbb|
0000c110  62 62 62 63 63 63 63 63  64 64 64 64 64 64 65 01  |bbbcccccdddddde.|
0000c120  06 0a 0a 08 00 00 28 ff  47 00 00 00 00 03 13 00  |......(.G.......|
0000c130  00 00 00 0b 52 b7 00 00  01 6b 01 3a 80 00 00 04  |....R....k.:....|
0000c140  61 61 61 61 61 61 61 61  61 61 62 62 62 62 62 62  |aaaaaaaaaabbbbbb|
0000c150  62 62 62 62 64 64 64 64  64 64 65 00 00 00 00 00  |bbbbdddddde.....|
.....
0000fff0  00 00 00 00 00 70 00 63  8b 8a 26 91 00 1a 3e 2e  |.....p.c..&...>.|
hexdump

3.詳細描述commit命令發出後,binlog日誌從內存寫到磁盤的過程序?

  • 先做write操作
    • 日誌會被write到每個線程對應的文件句柄的緩存中,也就是標準的IO緩存中
    • 每個線程會緩存到自己的IO緩存中,每個線程產生的日誌其他線程是不可見的

此時發生宕機,日誌丟失,臟塊丟失

  • 再做flush操作
    • 將私有緩存中的日誌寫到公共可見的操作系統文件緩存,此時不同線程都可以看到其他線程的日誌內容

此時宕機,依然丟失數據

  • 最後做sync持久化
    • 將日誌從內存中寫到硬盤

sync_binlog 1 多少次事務一起寫binlog
innodb_flush_log_at_trx_commit 1 寫redolog


索引:

  • 主鍵索引
  • 非空唯一索引
  • 都沒有的話走6字節的rowid,但是不能作為where過濾條件

index organized table索引組織表:數據就在葉子節點上,檢索數據不需要回行

回行,先找到索引所在位置,根據索引再一次找到數據 二級索引、輔助索引,葉子節點只存儲索引信息,葉子上帶著的信息指向數據所在的主鍵索引的位置

innodb邏輯存儲結構: tablespace - segement - extent - page - row

表空間是否獨立 innodb_file_per_table,默認為ON
如果是獨立表空間,一張表一個表空間
如果是off,就全部放在ibdata1裏面了
查看表ID ,0 代表的是系統表空間 select * from innodb_sys_tables

  • tablespace指的是共享表空間ibdata1,存儲的是undo、插入緩沖索引頁、系統事務、double write buffer,因為寫undo原因,大小隨時變化

  • ib_logfile,每個表自己的空間:數據(跟主鍵索引一起存放)、輔助索引、插入緩存bitmap

  • 插入緩沖

    • 主鍵索引和數據放在一起,其他索引放在索引頁
    • 往輔助索引頁寫東西時,每個被寫入的頁先放在buffer存著
    • 一旦有需要被寫入的索引頁讀入了內存,這是把buffer裏存著的東西一起寫進去
  • segement 段

    • 段等於表,段是數據的物理存儲形式,表是數據的邏輯定義
    • 數據段,聚簇索引,數據段在B-tree的葉子結點
    • 索引段,非葉子結點就是索引
  • extent 區

    • 一個extent是1M,是分配空間的最小單位
    • 1M由64個連續的page組成,一個page是16K
    • innodb為保證extent連續,一次申請多個
    • 一個extent由多個page組成
  • page 頁,類似存儲塊大小

    • 最小的IO單位
    • page默認大小是16K innodb_page_size = 16384
  • ROW 行
  • 事務ID、回滾指針、數據、索引

innodb文件結構
表的組成:

  • tabname.ibd 表數據
  • File Space Header
  • tabname.frm 表結構

hexdump -C -v tabname.ibd 一個page 16K,16進制一行有16個字節,那麽一個page就有1024行 查看第一個塊
hexdump -C -v tabname.ibd |head -n 1024 | head -n 2
2塊
hexdump -C -v tabname.ibd |head -n 2048 |tail -n 1024
3塊
hexdump -C -v tabname.ibd |head -n 3072 |tail -n 1024

mysql小白系列_04 datablock