MySQL8.0 新特性:Partial Update of LOB Column

MySQL8.0对json进行了比较完善的支持, 我们知道json具有比较特殊的存储格式,通常存在多个key value键值对,对于类似更新操作通常不会更新整个json列,而是某些键值。

对于某些复杂的应用,json列的数据可能会变的非常庞大,这时候一个突出的问题是:innodb并不识别json类型,对它而言这些存储统一都是LOB类型,而在之前的版本中Innodb处理LOB更新的方式是标记删除旧记录,并插入新记录,显然这会带来一些存储上的开销(尽管Purge线程会去后台清理),而写入的redo log和Binlog的量也会偏高,对于超大列,可能会严重影响到性能。为了解决这个问题,MySQL8.0引入了LOB列部分更新的策略。

官方博客有几篇文章介绍的非常清楚,感兴趣的可以直接跳过本文,直接阅读官方博客:

1: partial update of json values
2: introduces lob index for faster update
3: MVCC of Large Objects

以及相关的开发worklog:

WL#8963: Support for partial update of JSON in the optimizer
WL#8985: InnoDB: Refactor compressed BLOB code to facilitate partial fetch/update
WL#9141: InnoDB: Refactor uncompressed BLOB code to facilitate partial fetch/update
WL#9263: InnoDB: Enable partial access of LOB using multiple zlib streams
WL#8960: InnoDB: Partial Fetch and Update of BLOB
WL#10570: Provide logical diffs for partial update of JSON values
WL#2955: RBR replication of partial JSON updates

本文仅仅是笔者在理解该特性时做的一些简单的笔记,,记录的主要目的是用于以后如果涉及到相关的工作可以快速展开,因此比较凌乱

目前partial update需要通过JSON_SET, 或者JSON_REPLACE等特定接口来进行json列的更新,并且不是所有的更新都能够满足条件:

  • 没有增加新的元素
  • 空间足够大,可以容纳替换的新值

    • 但类似数据长度(10 =>更新成7=>更新成9)是允许的

下面以json_set更新json列为例来看看相关的关键堆栈

检查是否支持partial update

如上所述,需要指定的json函数接口才能进行partial update

mysql_execute_command
    |--> Sql_cmd_dml::execute
             |--> Sql_cmd_dml::prepare
                         |--> Sql_cmd_update::prepare_inner
                                     |---> prepare_partial_update
                                           |-->Item_json_func::supports_partial_update

这里只是做预检查,对于json列的更新如果全部是通过json_set/replace/remove进行的,则将其标记为候选partial update的列(TABLE::mark_column_for_partial_update), 存储在bitmap结构TABLE::m_partial_update_columns

设置partial update

猜你喜欢

转载自my.oschina.net/u/3611008/blog/1821863