想要查看TokuDB某个表占了多少磁盘空间,目前还没有太好的方法。 如果你使用’show table status’命令,得到的结果只会让你更迷茫:

    1. Name: toku
    2. Engine: TokuDB
    3. Version: 10
    4. Row_format: tokudb_zlib
    5. Rows: 28874059
    6. Avg_row_length: 30
    7. Data_length: 868159449
    8. Max_data_length: 9223372036854775807
    9. Index_length: 2099497463
    10. Data_free: 0

    我们来看看test_toku表磁盘文件大小:

    1. $du -b _test_toku*
    2. 124427776 _test_toku_A_B.tokudb --KEY(A,B)索引数据文件
    3. 215959552 _test_toku_B_C.tokudb --KEY(B,C)索引数据文件
    4. 149504000 _test_toku_main.tokudb --主数据文件

    Data_length和Index_length都对不上,而且差的还不是一点,真头疼,总不能每次都要去服务器上du吧?其实,我们可以通过information_schema.TokuDB_fractal_tree_info得到:

    1. mysql> select * from TokuDB_fractal_tree_info where table_name='test_toku'\G;
    2. *************************** 1. row ***************************
    3. dictionary_name: ./test/test_toku_A_B
    4. internal_file_name: _test_toku_A_B.tokudb
    5. bt_num_blocks_allocated: 449
    6. bt_num_blocks_in_use: 449
    7. bt_size_allocated: 124416093
    8. bt_size_in_use: 123563101
    9. table_schema: test
    10. table_name: toku
    11. table_dictionary_name: key-test_toku_A_B
    12. *************************** 2. row ***************************
    13. dictionary_name: ./test/test_toku_B_C
    14. internal_file_name: ./_test_toku_B_C.tokudb
    15. bt_num_blocks_allocated: 612
    16. bt_num_blocks_in_use: 612
    17. bt_size_allocated: 215945353
    18. bt_size_in_use: 214784137
    19. table_schema: test
    20. table_name: toku
    21. table_dictionary_name: key-test_toku_B_C
    22. *************************** 3. row ***************************
    23. dictionary_name: ./test/test_toku-main
    24. internal_file_name: ./_test_toku_main.tokudb
    25. bt_num_blocks_allocated: 486
    26. bt_num_blocks_in_use: 486
    27. bt_size_allocated: 149491745
    28. bt_size_in_use: 148580897
    29. table_schema: test
    30. table_name: toku
    31. table_dictionary_name: main

    bt_size_allocated字段是TokuDB内部维护当前数据文件最后分配的offset,跟数据文件磁盘大小基本一致。

    再回到刚才的问题:show table status里Data_length和Index_length为什么跟实际大小出入这么大呢?

    ha_tokudb::info()里:

    1. stats.data_file_length = dict_stats.bt_dsize;

    bt_dsize的值来自toku_ft_stat64:

    1. bt_dsize = ft->in_memory_stats.numbytes;

    in_memory_stats.numbytes是TokuDB在内存中维护的一个变量,用于记录变更数据的增量大小,每次checkpoint的时候持久化到数据文件(包括索引文件)的header里,所以是个出入比较大的参考变量(无压缩),已不能通过此变量来反应表文件的真实大小。

    这么不爽的地方,我们(RDS MySQL)已准备好patch把它修掉,让show table status可以拿到TokuDB表文件的真实大小。